From 0f759f9df4ca9505b9e10e17c1f9fafa351b552e Mon Sep 17 00:00:00 2001
From: psychobunny <psycho.bunny@hotmail.com>
Date: Wed, 8 Oct 2014 15:37:10 -0400
Subject: [PATCH] ... not sure why that didn't all go through in one commit

---
 public/src/forum/account/edit.js              | 336 -------------
 public/src/forum/account/favourites.js        |  45 --
 public/src/forum/account/followers.js         |  19 -
 public/src/forum/account/following.js         |  15 -
 public/src/forum/account/header.js            |  34 --
 public/src/forum/account/posts.js             |  46 --
 public/src/forum/account/profile.js           | 127 -----
 public/src/forum/account/settings.js          |  71 ---
 public/src/forum/account/topics.js            |  44 --
 .../src/forum/admin/appearance/customise.js   |  33 --
 public/src/forum/admin/appearance/skins.js    |  73 ---
 public/src/forum/admin/appearance/themes.js   |  93 ----
 public/src/forum/admin/extend/plugins.js      |  83 ----
 public/src/forum/admin/extend/widgets.js      | 198 --------
 public/src/forum/admin/footer.js              | 190 --------
 public/src/forum/admin/general/dashboard.js   | 445 -----------------
 public/src/forum/admin/general/languages.js   |   8 -
 public/src/forum/admin/general/sounds.js      |  32 --
 public/src/forum/admin/iconSelect.js          |  47 --
 public/src/forum/admin/manage/categories.js   | 391 ---------------
 public/src/forum/admin/manage/flags.js        |  68 ---
 public/src/forum/admin/manage/groups.js       | 263 ----------
 public/src/forum/admin/manage/tags.js         | 110 -----
 public/src/forum/admin/manage/users.js        | 289 -----------
 public/src/forum/admin/settings.js            | 169 -------
 public/src/forum/category.js                  | 351 --------------
 public/src/forum/categoryTools.js             | 205 --------
 public/src/forum/chats.js                     | 275 -----------
 public/src/forum/footer.js                    |  69 ---
 public/src/forum/groups/details.js            |  16 -
 public/src/forum/home.js                      |  77 ---
 public/src/forum/infinitescroll.js            |  92 ----
 public/src/forum/login.js                     |  39 --
 public/src/forum/notifications.js             |  16 -
 public/src/forum/pagination.js                | 108 -----
 public/src/forum/popular.js                   |  19 -
 public/src/forum/recent.js                    | 140 ------
 public/src/forum/register.js                  | 198 --------
 public/src/forum/reset.js                     |  28 --
 public/src/forum/reset_code.js                |  55 ---
 public/src/forum/search.js                    |  35 --
 public/src/forum/tag.js                       |  42 --
 public/src/forum/tags.js                      |  59 ---
 public/src/forum/topic.js                     | 452 ------------------
 public/src/forum/topic/browsing.js            |  95 ----
 public/src/forum/topic/events.js              | 180 -------
 public/src/forum/topic/fork.js                | 136 ------
 public/src/forum/topic/move.js                | 100 ----
 public/src/forum/topic/postTools.js           | 322 -------------
 public/src/forum/topic/threadTools.js         | 169 -------
 public/src/forum/unread.js                    | 151 ------
 public/src/forum/users.js                     | 186 -------
 52 files changed, 6844 deletions(-)
 delete mode 100644 public/src/forum/account/edit.js
 delete mode 100644 public/src/forum/account/favourites.js
 delete mode 100644 public/src/forum/account/followers.js
 delete mode 100644 public/src/forum/account/following.js
 delete mode 100644 public/src/forum/account/header.js
 delete mode 100644 public/src/forum/account/posts.js
 delete mode 100644 public/src/forum/account/profile.js
 delete mode 100644 public/src/forum/account/settings.js
 delete mode 100644 public/src/forum/account/topics.js
 delete mode 100644 public/src/forum/admin/appearance/customise.js
 delete mode 100644 public/src/forum/admin/appearance/skins.js
 delete mode 100644 public/src/forum/admin/appearance/themes.js
 delete mode 100644 public/src/forum/admin/extend/plugins.js
 delete mode 100644 public/src/forum/admin/extend/widgets.js
 delete mode 100644 public/src/forum/admin/footer.js
 delete mode 100644 public/src/forum/admin/general/dashboard.js
 delete mode 100644 public/src/forum/admin/general/languages.js
 delete mode 100644 public/src/forum/admin/general/sounds.js
 delete mode 100644 public/src/forum/admin/iconSelect.js
 delete mode 100644 public/src/forum/admin/manage/categories.js
 delete mode 100644 public/src/forum/admin/manage/flags.js
 delete mode 100644 public/src/forum/admin/manage/groups.js
 delete mode 100644 public/src/forum/admin/manage/tags.js
 delete mode 100644 public/src/forum/admin/manage/users.js
 delete mode 100644 public/src/forum/admin/settings.js
 delete mode 100644 public/src/forum/category.js
 delete mode 100644 public/src/forum/categoryTools.js
 delete mode 100644 public/src/forum/chats.js
 delete mode 100644 public/src/forum/footer.js
 delete mode 100644 public/src/forum/groups/details.js
 delete mode 100644 public/src/forum/home.js
 delete mode 100644 public/src/forum/infinitescroll.js
 delete mode 100644 public/src/forum/login.js
 delete mode 100644 public/src/forum/notifications.js
 delete mode 100644 public/src/forum/pagination.js
 delete mode 100644 public/src/forum/popular.js
 delete mode 100644 public/src/forum/recent.js
 delete mode 100644 public/src/forum/register.js
 delete mode 100644 public/src/forum/reset.js
 delete mode 100644 public/src/forum/reset_code.js
 delete mode 100644 public/src/forum/search.js
 delete mode 100644 public/src/forum/tag.js
 delete mode 100644 public/src/forum/tags.js
 delete mode 100644 public/src/forum/topic.js
 delete mode 100644 public/src/forum/topic/browsing.js
 delete mode 100644 public/src/forum/topic/events.js
 delete mode 100644 public/src/forum/topic/fork.js
 delete mode 100644 public/src/forum/topic/move.js
 delete mode 100644 public/src/forum/topic/postTools.js
 delete mode 100644 public/src/forum/topic/threadTools.js
 delete mode 100644 public/src/forum/unread.js
 delete mode 100644 public/src/forum/users.js

diff --git a/public/src/forum/account/edit.js b/public/src/forum/account/edit.js
deleted file mode 100644
index a99c6c448f..0000000000
--- a/public/src/forum/account/edit.js
+++ /dev/null
@@ -1,336 +0,0 @@
-'use strict';
-
-/* globals define, ajaxify, socket, app, config, utils, translator, bootbox */
-
-define('forum/account/edit', ['forum/account/header', 'uploader'], function(header, uploader) {
-	var AccountEdit = {},
-		gravatarPicture = '',
-		uploadedPicture = '',
-		selectedImageType = '',
-		currentEmail;
-
-	AccountEdit.init = function() {
-		gravatarPicture = ajaxify.variables.get('gravatarpicture');
-		uploadedPicture = ajaxify.variables.get('uploadedpicture');
-
-		header.init();
-
-		$('#submitBtn').on('click', updateProfile);
-
-		$('#inputBirthday').datepicker({
-			changeMonth: true,
-			changeYear: true,
-			yearRange: '1900:+0'
-		});
-
-		currentEmail = $('#inputEmail').val();
-
-		handleImageChange();
-		handleAccountDelete();
-		handleImageUpload();
-		handleEmailConfirm();
-		handlePasswordChange();
-		updateSignature();
-		updateImages();
-	};
-
-	function updateProfile() {
-		var userData = {
-			uid: $('#inputUID').val(),
-			username: $('#inputUsername').val(),
-			email: $('#inputEmail').val(),
-			fullname: $('#inputFullname').val(),
-			website: $('#inputWebsite').val(),
-			birthday: $('#inputBirthday').val(),
-			location: $('#inputLocation').val(),
-			signature: $('#inputSignature').val()
-		};
-
-		socket.emit('user.updateProfile', userData, function(err, data) {
-			if (err) {
-				return app.alertError(err.message);
-			}
-
-			app.alertSuccess('[[user:profile_update_success]]');
-
-			if (data.picture) {
-				$('#user-current-picture').attr('src', data.picture);
-				$('#user_label img').attr('src', data.picture);
-			}
-
-			if (data.gravatarpicture) {
-				$('#user-gravatar-picture').attr('src', data.gravatarpicture);
-				gravatarPicture = data.gravatarpicture;
-			}
-
-			if (data.userslug) {
-				var oldslug = $('.account-username-box').attr('data-userslug');
-				$('.account-username-box a').each(function(index) {
-					$(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug));
-				});
-
-				$('.account-username-box').attr('data-userslug', data.userslug);
-
-				$('#user-profile-link').attr('href', config.relative_path + '/user/' + data.userslug);
-				$('#user-header-name').text(userData.username);
-			}
-
-			if (currentEmail !== data.email) {
-				currentEmail = data.email;
-				$('#confirm-email').removeClass('hide');
-			}
-		});
-
-		return false;
-	}
-
-	function handleImageChange() {
-		function selectImageType(type) {
-			$('#gravatar-box .fa-check').toggle(type === 'gravatar');
-			$('#uploaded-box .fa-check').toggle(type === 'uploaded');
-			selectedImageType = type;
-		}
-
-		$('#changePictureBtn').on('click', function() {
-			selectedImageType = '';
-			updateImages();
-
-			$('#change-picture-modal').modal('show');
-			$('#change-picture-modal').removeClass('hide');
-
-			return false;
-		});
-
-		$('#gravatar-box').on('click', function() {
-			selectImageType('gravatar');
-		});
-
-		$('#uploaded-box').on('click', function() {
-			selectImageType('uploaded');
-		});
-
-		$('#savePictureChangesBtn').on('click', function() {
-			$('#change-picture-modal').modal('hide');
-
-			if (selectedImageType) {
-				changeUserPicture(selectedImageType);
-
-				if (selectedImageType === 'gravatar') {
-					$('#user-current-picture').attr('src', gravatarPicture);
-					$('#user-header-picture').attr('src', gravatarPicture);
-				} else if (selectedImageType === 'uploaded') {
-					$('#user-current-picture').attr('src', uploadedPicture);
-					$('#user-header-picture').attr('src', uploadedPicture);
-				}
-			}
-		});
-	}
-
-	function handleAccountDelete() {
-		$('#deleteAccountBtn').on('click', function() {
-			translator.translate('[[user:delete_account_confirm]]', function(translated) {
-				bootbox.confirm(translated + '<p><input type="text" class="form-control" id="confirm-username" /></p>', function(confirm) {
-					if (!confirm) {
-						return;
-					}
-
-					if ($('#confirm-username').val() !== app.username) {
-						app.alertError('[[error:invalid-username]]');
-						return false;
-					} else {
-						socket.emit('user.deleteAccount', {}, function(err) {
-							if (!err) {
-								app.logout();
-							}
-						});
-					}
-				});
-			});
-			return false;
-		});
-	}
-
-	function handleImageUpload() {
-		function onUploadComplete(urlOnServer) {
-			urlOnServer = urlOnServer + '?' + new Date().getTime();
-
-			$('#user-current-picture').attr('src', urlOnServer);
-			$('#user-uploaded-picture').attr('src', urlOnServer);
-			$('#user-header-picture').attr('src', urlOnServer);
-			uploadedPicture = urlOnServer;
-		}
-
-
-		$('#upload-picture-modal').on('hide', function() {
-			$('#userPhotoInput').val('');
-		});
-
-		$('#uploadPictureBtn').on('click', function() {
-
-			$('#change-picture-modal').modal('hide');
-			uploader.open(config.relative_path + '/api/user/' + ajaxify.variables.get('userslug') + '/uploadpicture', {}, config.maximumProfileImageSize, function(imageUrlOnServer) {
-				onUploadComplete(imageUrlOnServer);
-			});
-
-			return false;
-		});
-
-		$('#uploadFromUrlBtn').on('click', function() {
-			$('#change-picture-modal').modal('hide');
-			var uploadModal = $('#upload-picture-from-url-modal');
-			uploadModal.modal('show').removeClass('hide');
-
-			uploadModal.find('.upload-btn').on('click', function() {
-				var url = uploadModal.find('#uploadFromUrl').val();
-				if (!url) {
-					return;
-				}
-				socket.emit('user.uploadProfileImageFromUrl', url, function(err, imageUrlOnServer) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-					onUploadComplete(imageUrlOnServer);
-
-					uploadModal.modal('hide');
-				});
-
-				return false;
-			});
-			return false;
-		});
-	}
-
-	function handleEmailConfirm() {
-		$('#confirm-email').on('click', function() {
-			socket.emit('user.emailConfirm', {}, function(err) {
-				if (err) {
-					return app.alertError(err.message);
-				}
-				app.alertSuccess('[[notifications:email-confirm-sent]]');
-			});
-		});
-	}
-
-	function handlePasswordChange() {
-		var currentPassword = $('#inputCurrentPassword');
-		var password_notify = $('#password-notify');
-		var password_confirm_notify = $('#password-confirm-notify');
-		var password = $('#inputNewPassword');
-		var password_confirm = $('#inputNewPasswordAgain');
-		var passwordvalid = false;
-		var passwordsmatch = false;
-		var successIcon = '<i class="fa fa-check"></i>';
-
-		function onPasswordChanged() {
-			passwordvalid = utils.isPasswordValid(password.val());
-			if (password.val().length < config.minimumPasswordLength) {
-				showError(password_notify, '[[user:change_password_error_length]]');
-			} else if (!passwordvalid) {
-				showError(password_notify, '[[user:change_password_error]]');
-			} else {
-				showSuccess(password_notify, successIcon);
-			}
-		}
-
-		function onPasswordConfirmChanged() {
-			if(password.val()) {
-				if (password.val() !== password_confirm.val()) {
-					showError(password_confirm_notify, '[[user:change_password_error_match]]');
-					passwordsmatch = false;
-				} else {
-					showSuccess(password_confirm_notify, successIcon);
-					passwordsmatch = true;
-				}
-			}
-		}
-
-		password.on('blur', onPasswordChanged);
-		password_confirm.on('blur', onPasswordConfirmChanged);
-
-		$('#changePasswordBtn').on('click', function() {
-			if ((passwordvalid && passwordsmatch) || app.isAdmin) {
-				socket.emit('user.changePassword', {
-					'currentPassword': currentPassword.val(),
-					'newPassword': password.val(),
-					'uid': ajaxify.variables.get('theirid')
-				}, function(err) {
-					currentPassword.val('');
-					password.val('');
-					password_confirm.val('');
-					passwordsmatch = false;
-					passwordvalid = false;
-
-					if (err) {
-						return app.alertError(err.message);
-					}
-
-					app.alertSuccess('[[user:change_password_success]]');
-				});
-			}
-			return false;
-		});
-	}
-
-	function changeUserPicture(type) {
-		socket.emit('user.changePicture', {
-			type: type,
-			uid: ajaxify.variables.get('theirid')
-		}, function(err) {
-			if(err) {
-				app.alertError(err.message);
-			}
-		});
-	}
-
-	function updateImages() {
-		var currentPicture = $('#user-current-picture').attr('src');
-
-		if (gravatarPicture) {
-			$('#user-gravatar-picture').attr('src', gravatarPicture);
-		}
-
-		if (uploadedPicture) {
-			$('#user-uploaded-picture').attr('src', uploadedPicture);
-		}
-
-		$('#gravatar-box').toggle(!!gravatarPicture);
-		$('#uploaded-box').toggle(!!uploadedPicture);
-
-		$('#gravatar-box .fa-check').toggle(currentPicture !== uploadedPicture);
-		$('#uploaded-box .fa-check').toggle(currentPicture === uploadedPicture);
-	}
-
-	function updateSignature() {
-		function getSignatureCharsLeft() {
-			return $('#inputSignature').length ? '(' + $('#inputSignature').val().length + '/' + config.maximumSignatureLength + ')' : '';
-		}
-
-		$('#signatureCharCountLeft').html(getSignatureCharsLeft());
-
-		$('#inputSignature').on('keyup change', function(ev) {
-			$('#signatureCharCountLeft').html(getSignatureCharsLeft());
-		});
-	}
-
-	function showError(element, msg) {
-		translator.translate(msg, function(msg) {
-			element.html(msg);
-			element.parent()
-				.removeClass('alert-success')
-				.addClass('alert-danger');
-			element.show();
-		});
-	}
-
-	function showSuccess(element, msg) {
-		translator.translate(msg, function(msg) {
-			element.html(msg);
-			element.parent()
-				.removeClass('alert-danger')
-				.addClass('alert-success');
-			element.show();
-		});
-	}
-
-	return AccountEdit;
-});
diff --git a/public/src/forum/account/favourites.js b/public/src/forum/account/favourites.js
deleted file mode 100644
index 6a08a814a5..0000000000
--- a/public/src/forum/account/favourites.js
+++ /dev/null
@@ -1,45 +0,0 @@
-'use strict';
-
-/* globals define, app, utils */
-
-define('forum/account/favourites', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
-	var Favourites = {};
-
-	Favourites.init = function() {
-		header.init();
-
-		$('.user-favourite-posts img').addClass('img-responsive');
-
-		infinitescroll.init(loadMore);
-	};
-
-	function loadMore(direction) {
-		if (direction < 0) {
-			return;
-		}
-
-		infinitescroll.loadMore('posts.loadMoreFavourites', {
-			after: $('.user-favourite-posts').attr('data-nextstart')
-		}, function(data, done) {
-			if (data.posts && data.posts.length) {
-				onPostsLoaded(data.posts, done);
-				$('.user-favourite-posts').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-		});
-	}
-
-	function onPostsLoaded(posts, callback) {
-		infinitescroll.parseAndTranslate('account/favourites', 'posts', {posts: posts}, function(html) {
-			$('.user-favourite-posts').append(html);
-			html.find('img').addClass('img-responsive');
-			html.find('span.timeago').timeago();
-			app.createUserTooltips();
-			utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			callback();
-		});
-	}
-
-	return Favourites;
-});
diff --git a/public/src/forum/account/followers.js b/public/src/forum/account/followers.js
deleted file mode 100644
index 6dfb3bf83c..0000000000
--- a/public/src/forum/account/followers.js
+++ /dev/null
@@ -1,19 +0,0 @@
-define('forum/account/followers', ['forum/account/header'], function(header) {
-	var	Followers = {};
-
-	Followers.init = function() {
-		header.init();
-
-		var yourid = ajaxify.variables.get('yourid'),
-			theirid = ajaxify.variables.get('theirid'),
-			followersCount = ajaxify.variables.get('followersCount');
-
-
-		if (parseInt(followersCount, 10) === 0) {
-			$('#no-followers-notice').removeClass('hide');
-		}
-
-	};
-
-	return Followers;
-});
diff --git a/public/src/forum/account/following.js b/public/src/forum/account/following.js
deleted file mode 100644
index 0e27a235aa..0000000000
--- a/public/src/forum/account/following.js
+++ /dev/null
@@ -1,15 +0,0 @@
-define('forum/account/following', ['forum/account/header'], function(header) {
-	var	Following = {};
-
-	Following.init = function() {
-		header.init();
-
-		var followingCount = ajaxify.variables.get('followingCount');
-
-		if (parseInt(followingCount, 10) === 0) {
-			$('#no-following-notice').removeClass('hide');
-		}
-	};
-
-	return Following;
-});
diff --git a/public/src/forum/account/header.js b/public/src/forum/account/header.js
deleted file mode 100644
index f552bf4056..0000000000
--- a/public/src/forum/account/header.js
+++ /dev/null
@@ -1,34 +0,0 @@
-define('forum/account/header', function() {
-	var	AccountHeader = {};
-
-	AccountHeader.init = function() {
-		displayAccountMenus();
-		selectActivePill();
-	};
-
-	function displayAccountMenus() {
-		var yourid = ajaxify.variables.get('yourid'),
-			theirid = ajaxify.variables.get('theirid');
-
-		if (parseInt(yourid, 10) !== 0 && parseInt(yourid, 10) === parseInt(theirid, 10)) {
-			$('#editLink, #settingsLink, #favouritesLink').removeClass('hide');
-		} else {
-			$('.account-sub-links .plugin-link').each(function() {
-				var $this = $(this);
-				$this.toggleClass('hide', $this.hasClass('private'));
-			});
-		}
-	}
-
-	function selectActivePill() {
-		$('.account-sub-links li').removeClass('active').each(function() {
-			var href = $(this).find('a').attr('href');
-			if (window.location.href.indexOf(href) !== -1) {
-				$(this).addClass('active');
-				return false;
-			}
-		});
-	}
-
-	return AccountHeader;
-});
diff --git a/public/src/forum/account/posts.js b/public/src/forum/account/posts.js
deleted file mode 100644
index 70410e0819..0000000000
--- a/public/src/forum/account/posts.js
+++ /dev/null
@@ -1,46 +0,0 @@
-'use strict';
-
-/* globals define, app, socket, utils */
-
-define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
-	var AccountPosts = {};
-
-	AccountPosts.init = function() {
-		header.init();
-
-		$('.user-favourite-posts img').addClass('img-responsive');
-
-		infinitescroll.init(loadMore);
-	};
-
-	function loadMore(direction) {
-		if (direction < 0) {
-			return;
-		}
-
-		infinitescroll.loadMore('posts.loadMoreUserPosts', {
-			uid: $('.account-username-box').attr('data-uid'),
-			after: $('.user-favourite-posts').attr('data-nextstart')
-		}, function(data, done) {
-			if (data.posts && data.posts.length) {
-				onPostsLoaded(data.posts, done);
-				$('.user-favourite-posts').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-		});
-	}
-
-	function onPostsLoaded(posts, callback) {
-		infinitescroll.parseAndTranslate('account/posts', 'posts', {posts: posts}, function(html) {
-			$('.user-favourite-posts').append(html);
-			html.find('img').addClass('img-responsive');
-			html.find('span.timeago').timeago();
-			app.createUserTooltips();
-			utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			callback();
-		});
-	}
-
-	return AccountPosts;
-});
diff --git a/public/src/forum/account/profile.js b/public/src/forum/account/profile.js
deleted file mode 100644
index 2d273a33ca..0000000000
--- a/public/src/forum/account/profile.js
+++ /dev/null
@@ -1,127 +0,0 @@
-'use strict';
-
-/* globals define, ajaxify, app, utils, socket, translator*/
-
-define('forum/account/profile', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
-	var Account = {},
-		yourid,
-		theirid,
-		isFollowing;
-
-	Account.init = function() {
-		header.init();
-
-		yourid = ajaxify.variables.get('yourid');
-		theirid = ajaxify.variables.get('theirid');
-		isFollowing = ajaxify.variables.get('isFollowing');
-
-		app.enterRoom('user/' + theirid);
-
-		processPage();
-
-		updateButtons();
-
-		$('#follow-btn').on('click', function() {
-			return toggleFollow('follow');
-		});
-
-		$('#unfollow-btn').on('click', function() {
-			return toggleFollow('unfollow');
-		});
-
-		$('#chat-btn').on('click', function() {
-			app.openChat($('.account-username').html(), theirid);
-		});
-
-		socket.removeListener('event:user_status_change', onUserStatusChange);
-		socket.on('event:user_status_change', onUserStatusChange);
-
-		if (yourid !== theirid) {
-			socket.emit('user.increaseViewCount', theirid);
-		}
-
-		infinitescroll.init(loadMoreTopics);
-	};
-
-	function processPage() {
-		$('.user-recent-posts img, .post-signature img').addClass('img-responsive');
-	}
-
-	function updateButtons() {
-		var isSelfOrNotLoggedIn = yourid === theirid || parseInt(yourid, 10) === 0;
-		$('#follow-btn').toggleClass('hide', isFollowing || isSelfOrNotLoggedIn);
-		$('#unfollow-btn').toggleClass('hide', !isFollowing || isSelfOrNotLoggedIn);
-		$('#chat-btn').toggleClass('hide', isSelfOrNotLoggedIn);
-	}
-
-	function toggleFollow(type) {
-		socket.emit('user.' + type, {
-			uid: theirid
-		}, function(err) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			$('#follow-btn').toggleClass('hide', type === 'follow');
-			$('#unfollow-btn').toggleClass('hide', type === 'unfollow');
-			app.alertSuccess('[[global:alert.' + type + ', ' + $('.account-username').html() + ']]');
-		});
-		return false;
-	}
-
-	function onUserStatusChange(data) {
-		var onlineStatus = $('.account-online-status');
-
-		if(parseInt(ajaxify.variables.get('theirid'), 10) !== parseInt(data.uid, 10)) {
-			return;
-		}
-
-		translator.translate('[[global:' + data.status + ']]', function(translated) {
-			onlineStatus.attr('class', 'account-online-status fa fa-circle status ' + data.status)
-				.attr('title', translated)
-				.attr('data-original-title', translated);
-		});
-
-	}
-
-	function loadMoreTopics(direction) {
-		if(direction < 0 || !$('.user-recent-posts').length) {
-			return;
-		}
-
-		$('.loading-indicator').removeClass('hidden');
-
-		infinitescroll.loadMore('user.loadMoreRecentPosts', {
-			after: $('.user-recent-posts').attr('data-nextstart'),
-			uid: theirid
-		}, function(data, done) {
-			if (data.posts && data.posts.length) {
-				onPostsLoaded(data.posts, done);
-				$('.user-recent-posts').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-			$('.loading-indicator').addClass('hidden');
-		});
-	}
-
-	function onPostsLoaded(posts, callback) {
-		posts = posts.filter(function(post) {
-			return !$('.user-recent-posts div[data-pid=' + post.pid + ']').length;
-		});
-
-		if (!posts.length) {
-			return callback();
-		}
-
-		infinitescroll.parseAndTranslate('account/profile', 'posts', {posts: posts}, function(html) {
-
-			$('.user-recent-posts .loading-indicator').before(html);
-			html.find('span.timeago').timeago();
-
-			callback();
-		});
-	}
-
-	return Account;
-});
diff --git a/public/src/forum/account/settings.js b/public/src/forum/account/settings.js
deleted file mode 100644
index 107e766c77..0000000000
--- a/public/src/forum/account/settings.js
+++ /dev/null
@@ -1,71 +0,0 @@
-define('forum/account/settings', ['forum/account/header'], function(header) {
-	var	AccountSettings = {};
-
-	AccountSettings.init = function() {
-		header.init();
-
-		$('#submitBtn').on('click', function() {
-			var settings = {};
-
-			$('.account').find('input, textarea, select').each(function(id, input) {
-				input = $(input);
-				var setting = input.attr('data-property');
-				if (input.is('select')) {
-					settings[setting] = input.val();
-					return;
-				}
-
-				switch (input.attr('type')) {
-					case 'text':
-					case 'textarea':
-						settings[setting] = input.val();
-						break;
-					case 'checkbox':
-						settings[setting] = input.is(':checked') ? 1 : 0;
-						break;
-				}
-			});
-
-			socket.emit('user.saveSettings', {uid: ajaxify.variables.get('theirid'), settings: settings}, function(err) {
-				if (err) {
-					return app.alertError(err.message);
-				}
-
-				app.alertSuccess('[[success:settings-saved]]');
-				app.loadConfig();
-				if (parseInt(app.uid, 10) === parseInt(ajaxify.variables.get('theirid'), 10)) {
-					ajaxify.refresh();
-				}
-			});
-
-			return false;
-		});
-
-		socket.emit('user.getSettings', {uid: ajaxify.variables.get('theirid')}, function(err, settings) {
-			var inputs = $('.account').find('input, textarea, select');
-
-			inputs.each(function(index, input) {
-				input = $(input);
-				var setting = input.attr('data-property');
-				if (setting) {
-					if (input.is('select')) {
-						input.val(settings[setting]);
-						return;
-					}
-
-					switch (input.attr('type')) {
-						case 'text' :
-						case 'textarea' :
-							input.val(settings[setting]);
-							break;
-						case 'checkbox' :
-							input.prop('checked', !!settings[setting]);
-							break;
-					}
-				}
-			});
-		});
-	};
-
-	return AccountSettings;
-});
diff --git a/public/src/forum/account/topics.js b/public/src/forum/account/topics.js
deleted file mode 100644
index 231ddfd5ec..0000000000
--- a/public/src/forum/account/topics.js
+++ /dev/null
@@ -1,44 +0,0 @@
-'use strict';
-
-/* globals define, app, socket, utils */
-
-define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
-	var AccountTopics = {};
-
-	AccountTopics.init = function() {
-		header.init();
-
-		infinitescroll.init(loadMore);
-	};
-
-	function loadMore(direction) {
-		if (direction < 0) {
-			return;
-		}
-
-		infinitescroll.loadMore('topics.loadMoreFromSet', {
-			set: 'uid:' + $('.account-username-box').attr('data-uid') + ':topics',
-			after: $('.user-topics').attr('data-nextstart')
-		}, function(data, done) {
-
-			if (data.topics && data.topics.length) {
-				onTopicsLoaded(data.topics, done);
-				$('.user-topics').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-		});
-	}
-
-	function onTopicsLoaded(topics, callback) {
-		infinitescroll.parseAndTranslate('account/topics', 'topics', {topics: topics}, function(html) {
-			$('#topics-container').append(html);
-			html.find('span.timeago').timeago();
-			app.createUserTooltips();
-			utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			callback();
-		});
-	}
-
-	return AccountTopics;
-});
diff --git a/public/src/forum/admin/appearance/customise.js b/public/src/forum/admin/appearance/customise.js
deleted file mode 100644
index 482dd7fb6d..0000000000
--- a/public/src/forum/admin/appearance/customise.js
+++ /dev/null
@@ -1,33 +0,0 @@
-"use strict";
-/* global define, app, socket */
-
-define('forum/admin/appearance/customise', ['forum/admin/settings'], function(Settings) {
-	var Customise = {};
-	
-	Customise.init = function() {		
-		Settings.prepare(function() {
-			$('#customCSS').text($('#customCSS-holder').val());
-			$('#customHTML').text($('#customHTML-holder').val());
-			
-			var customCSS = ace.edit("customCSS"),
-				customHTML = ace.edit("customHTML");
-
-			customCSS.setTheme("ace/theme/twilight");
-			customCSS.getSession().setMode("ace/mode/css");	
-
-			customCSS.on('change', function(e) {
-			    $('#customCSS-holder').val(customCSS.getValue());
-			}); 
-
-			customHTML.setTheme("ace/theme/twilight");
-			customHTML.getSession().setMode("ace/mode/html");
-
-			customHTML.on('change', function(e) {
-			    $('#customHTML-holder').val(customHTML.getValue());
-			}); 
-		});
-	};
-
-	return Customise;
-});
-	
\ No newline at end of file
diff --git a/public/src/forum/admin/appearance/skins.js b/public/src/forum/admin/appearance/skins.js
deleted file mode 100644
index 75a57e60e5..0000000000
--- a/public/src/forum/admin/appearance/skins.js
+++ /dev/null
@@ -1,73 +0,0 @@
-"use strict";
-/* global define, app, socket */
-
-define('forum/admin/appearance/skins', function() {
-	var Skins = {};
-	
-	Skins.init = function() {
-		var scriptEl = $('<script />');
-		scriptEl.attr('src', '//bootswatch.aws.af.cm/3/?callback=bootswatchListener');
-		$('body').append(scriptEl);
-
-		$('#bootstrap_themes').on('click', function(e){
-			var target = $(e.target),
-				action = target.attr('data-action');
-
-			if (action && action === 'use') {
-				var parentEl = target.parents('li'),
-					themeType = parentEl.attr('data-type'),
-					cssSrc = parentEl.attr('data-css'),
-					themeId = parentEl.attr('data-theme');
-
-				socket.emit('admin.themes.set', {
-					type: themeType,
-					id: themeId,
-					src: cssSrc
-				}, function(err) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-					highlightSelectedTheme(themeId);
-
-					app.alert({
-						alert_id: 'admin:theme',
-						type: 'info',
-						title: 'Theme Changed',
-						message: 'Please restart your NodeBB to fully activate this theme',
-						timeout: 5000,
-						clickfn: function() {
-							socket.emit('admin.restart');
-						}
-					});
-				});
-			}
-		});
-	};
-
-	Skins.render = function(bootswatch) {
-		var themeContainer = $('#bootstrap_themes');
-
-		templates.parse('admin/partials/theme_list', {
-			themes: bootswatch.themes.map(function(theme) {
-				return {
-					type: 'bootswatch',
-					id: theme.name,
-					name: theme.name,
-					description: theme.description,
-					screenshot_url: theme.thumbnail,
-					url: theme.preview,
-					css: theme.cssCdn
-				};
-			})
-		}, function(html) {
-			themeContainer.html(html);
-		});
-	};
-
-	function highlightSelectedTheme(themeId) {
-		$('.themes li[data-theme]').removeClass('btn-warning');
-		$('.themes li[data-theme="' + themeId + '"]').addClass('btn-warning');
-	}
-
-	return Skins;
-});
diff --git a/public/src/forum/admin/appearance/themes.js b/public/src/forum/admin/appearance/themes.js
deleted file mode 100644
index d61c1061f7..0000000000
--- a/public/src/forum/admin/appearance/themes.js
+++ /dev/null
@@ -1,93 +0,0 @@
-"use strict";
-/* global define, app, socket */
-
-define('forum/admin/appearance/themes', function() {
-	var Themes = {};
-	
-	Themes.init = function() {
-		$('#installed_themes').on('click', function(e){
-			var target = $(e.target),
-				action = target.attr('data-action');
-
-			if (action && action === 'use') {
-				var parentEl = target.parents('li'),
-					themeType = parentEl.attr('data-type'),
-					cssSrc = parentEl.attr('data-css'),
-					themeId = parentEl.attr('data-theme');
-
-				socket.emit('admin.themes.set', {
-					type: themeType,
-					id: themeId,
-					src: cssSrc
-				}, function(err) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-					highlightSelectedTheme(themeId);
-
-					app.alert({
-						alert_id: 'admin:theme',
-						type: 'info',
-						title: 'Theme Changed',
-						message: 'Please restart your NodeBB to fully activate this theme',
-						timeout: 5000,
-						clickfn: function() {
-							socket.emit('admin.restart');
-						}
-					});
-				});
-			}
-		});
-
-		$('#revert_theme').on('click', function() {
-			bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) {
-				if (confirm) {
-					socket.emit('admin.themes.set', {
-						type: 'local',
-						id: 'nodebb-theme-vanilla'
-					}, function(err) {
-						if (err) {
-							return app.alertError(err.message);
-						}
-						highlightSelectedTheme('nodebb-theme-vanilla');
-						app.alert({
-							alert_id: 'admin:theme',
-							type: 'success',
-							title: 'Theme Changed',
-							message: 'You have successfully reverted your NodeBB back to it\'s default theme.',
-							timeout: 3500
-						});
-					});
-				}
-			});
-		});
-
-		// Installed Themes
-		socket.emit('admin.themes.getInstalled', function(err, themes) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			var instListEl = $('#installed_themes');
-
-			if (!themes.length) {
-				instListEl.append($('<li/ >').addClass('no-themes').html('No installed themes found'));
-				return;
-			} else {
-				templates.parse('admin/partials/theme_list', {
-					themes: themes
-				}, function(html) {
-					instListEl.html(html);
-					highlightSelectedTheme(config['theme:id']);
-				});
-			}
-		});
-	};
-
-	function highlightSelectedTheme(themeId) {
-		$('.themes li[data-theme]').removeClass('btn-warning');
-		$('.themes li[data-theme="' + themeId + '"]').addClass('btn-warning');
-	}
-
-	return Themes;
-});
diff --git a/public/src/forum/admin/extend/plugins.js b/public/src/forum/admin/extend/plugins.js
deleted file mode 100644
index 22c178e2e8..0000000000
--- a/public/src/forum/admin/extend/plugins.js
+++ /dev/null
@@ -1,83 +0,0 @@
-"use strict";
-/* global define, app, socket */
-
-define('forum/admin/extend/plugins', function() {
-	var Plugins = {
-		init: function() {
-			var pluginsList = $('.plugins'),
-				numPlugins = pluginsList[0].querySelectorAll('li').length,
-				pluginID;
-
-			if (numPlugins > 0) {
-
-				pluginsList.on('click', 'button[data-action="toggleActive"]', function() {
-					pluginID = $(this).parents('li').attr('data-plugin-id');
-					var btn = $(this);
-					socket.emit('admin.plugins.toggleActive', pluginID, function(err, status) {
-						btn.html('<i class="fa fa-power-off"></i> ' + (status.active ? 'Deactivate' : 'Activate'));
-						btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active);
-
-						app.alert({
-							alert_id: 'plugin_toggled',
-							title: 'Plugin ' + (status.active ? 'Enabled' : 'Disabled'),
-							message: status.active ? 'Please restart your NodeBB to fully activate this plugin' : 'Plugin successfully deactivated',
-							type: status.active ? 'warning' : 'success',
-							timeout: 5000,
-							clickfn: function() {
-								socket.emit('admin.restart');
-							}
-						});
-					});
-				});
-
-				pluginsList.on('click', 'button[data-action="toggleInstall"]', function() {
-					pluginID = $(this).parents('li').attr('data-plugin-id');
-
-					var btn = $(this);
-					var activateBtn = btn.siblings('[data-action="toggleActive"]');
-					btn.html(btn.html() + 'ing')
-						.attr('disabled', true)
-						.find('i').attr('class', 'fa fa-refresh fa-spin');
-
-					socket.emit('admin.plugins.toggleInstall', pluginID, function(err, status) {
-						if (err) {
-							return app.alertError(err.message);
-						}
-
-						if (status.installed) {
-							btn.html('<i class="fa fa-trash-o"></i> Uninstall');
-						} else {
-							btn.html('<i class="fa fa-download"></i> Install');
-
-						}
-						activateBtn.toggleClass('hidden', !status.installed);
-
-						btn.toggleClass('btn-danger', status.installed).toggleClass('btn-success', !status.installed)
-							.attr('disabled', false);
-
-						app.alert({
-							alert_id: 'plugin_toggled',
-							title: 'Plugin ' + (status.installed ? 'Installed' : 'Uninstalled'),
-							message: status.installed ? 'Plugin successfully installed, please activate the plugin.' : 'The plugin has been successfully deactivated and uninstalled.',
-							type: 'info',
-							timeout: 5000
-						});
-					});
-				});
-
-				$('#plugin-search').on('input propertychange', function() {
-					var term = $(this).val();
-					$('.plugins li').each(function() {
-						var pluginId = $(this).attr('data-plugin-id');
-						$(this).toggleClass('hide', pluginId && pluginId.indexOf(term) === -1);
-					});
-				});
-
-			} else {
-				pluginsList.append('<li><p><i>No plugins found.</i></p></li>');
-			}
-		}
-	};
-
-	return Plugins;
-});
diff --git a/public/src/forum/admin/extend/widgets.js b/public/src/forum/admin/extend/widgets.js
deleted file mode 100644
index 393a58df4b..0000000000
--- a/public/src/forum/admin/extend/widgets.js
+++ /dev/null
@@ -1,198 +0,0 @@
-"use strict";
-/* global define, app, socket */
-
-define('forum/admin/extend/widgets', function() {
-	var Widgets = {};
-	
-	Widgets.init = function() {		
-		prepareWidgets();
-
-		$('#widgets .nav-pills a').on('click', function(ev) {
-			var $this = $(this);
-			$('#widgets .nav-pills li').removeClass('active');
-			$this.parent().addClass('active');
-
-			$('#widgets .tab-pane').removeClass('active');
-			$('#widgets .tab-pane[data-template="' + $this.attr('data-template') + '"]').addClass('active');
-
-			ev.preventDefault();
-			return false;
-		});
-	};
-
-	function prepareWidgets() {
-		$('[data-location="drafts"]').insertAfter($('[data-location="drafts"]').closest('.tab-content'));
-
-		$('#widgets .available-widgets .widget-panel').draggable({
-			helper: function(e) {
-				return $(e.target).parents('.widget-panel').clone().addClass('block').width($(e.target.parentNode).width());
-			},
-			distance: 10,
-			connectToSortable: ".widget-area"
-		});
-
-		$('#widgets .available-containers .containers > [data-container-html]').draggable({
-			helper: function(e) {
-				var target = $(e.target);
-				target = target.attr('data-container-html') ? target : target.parents('[data-container-html]');
-
-				return target.clone().addClass('block').width(target.width()).css('opacity', '0.5');
-			},
-			distance: 10
-		});
-
-		function appendToggle(el) {
-			if (!el.hasClass('block')) {
-				el.addClass('block')
-					.droppable({
-						accept: '[data-container-html]',
-						drop: function(event, ui) {
-							var el = $(this);
-
-							el.find('.panel-body .container-html').val(ui.draggable.attr('data-container-html'));
-							el.find('.panel-body').removeClass('hidden');
-						},
-						hoverClass: "panel-info"
-					})
-					.children('.panel-heading')
-					.append('<div class="pull-right pointer"><span class="delete-widget"><i class="fa fa-times-circle"></i></span></div><div class="pull-left pointer"><span class="toggle-widget"><i class="fa fa-chevron-circle-down"></i></span>&nbsp;</div>')
-					.children('small').html('');
-			}
-		}
-
-		$('#widgets .widget-area').sortable({
-			update: function (event, ui) {
-				appendToggle(ui.item);
-			},
-			connectWith: "div"
-		}).on('click', '.toggle-widget', function() {
-			$(this).parents('.widget-panel').children('.panel-body').toggleClass('hidden');
-		}).on('click', '.delete-widget', function() {
-			var panel = $(this).parents('.widget-panel');
-
-			bootbox.confirm('Are you sure you wish to delete this widget?', function(confirm) {
-				if (confirm) {
-					panel.remove();
-				}
-			});
-		}).on('dblclick', '.panel-heading', function() {
-			$(this).parents('.widget-panel').children('.panel-body').toggleClass('hidden');
-		});
-
-		$('#widgets .save').on('click', saveWidgets);
-
-		function saveWidgets() {
-			var total = $('#widgets [data-template][data-location]').length;
-
-			$('#widgets [data-template][data-location]').each(function(i, el) {
-				el = $(el);
-
-				var template = el.attr('data-template'),
-					location = el.attr('data-location'),
-					area = el.children('.widget-area'),
-					widgets = [];
-
-				area.find('.widget-panel[data-widget]').each(function() {
-					var widgetData = {},
-						data = $(this).find('form').serializeArray();
-
-					for (var d in data) {
-						if (data.hasOwnProperty(d)) {
-							if (data[d].name) {
-								widgetData[data[d].name] = data[d].value;
-							}
-						}
-					}
-
-					widgets.push({
-						widget: $(this).attr('data-widget'),
-						data: widgetData
-					});
-				});
-
-				socket.emit('admin.widgets.set', {
-					template: template,
-					location: location,
-					widgets: widgets
-				}, function(err) {
-					total--;
-
-					if (err) {
-						app.alertError(err.message);
-					}
-
-					if (total === 0) {
-						app.alert({
-							alert_id: 'admin:widgets',
-							type: 'success',
-							title: 'Widgets Updated',
-							message: 'Successfully updated widgets',
-							timeout: 2500
-						});
-					}
-
-				});
-			});
-		}
-
-		function populateWidget(widget, data) {
-			if (data.title) {
-				var title = widget.find('.panel-heading strong');
-				title.text(title.text() + ' - ' + data.title);
-			}
-
-			widget.find('input, textarea').each(function() {
-				var input = $(this),
-					value = data[input.attr('name')];
-
-				if (this.type === 'checkbox') {
-					input.attr('checked', !!value);
-				} else {
-					input.val(value);
-				}
-			});
-
-			return widget;
-		}
-
-		$.get(RELATIVE_PATH + '/api/admin/extend/widgets', function(data) {
-			var areas = data.areas;
-
-			for(var i=0; i<areas.length; ++i) {
-				var area = areas[i],
-					widgetArea = $('#widgets .area[data-template="' + area.template + '"][data-location="' + area.location + '"]').find('.widget-area');
-
-				widgetArea.html('');
-
-				for (var k=0; k<area.data.length; ++k) {
-					var widgetData = area.data[k],
-						widgetEl = $('.available-widgets [data-widget="' + widgetData.widget + '"]').clone(true);
-
-					widgetArea.append(populateWidget(widgetEl, widgetData.data));
-					appendToggle(widgetEl);
-				}
-			}
-		});
-
-		$('.color-selector').on('click', '.btn', function() {
-			var btn = $(this),
-				selector = btn.parents('.color-selector'),
-				container = selector.parents('[data-container-html]'),
-				classList = [];
-
-			selector.children().each(function() {
-				classList.push($(this).attr('data-class'));
-			});
-
-			container
-				.removeClass(classList.join(' '))
-				.addClass(btn.attr('data-class'));
-
-			container.attr('data-container-html', container.attr('data-container-html')
-				.replace(/class="[a-zA-Z0-9-\s]+"/, 'class="' + container[0].className.replace(' pointer ui-draggable', '') + '"')
-			);
-		});
-	}
-
-	return Widgets;
-});
diff --git a/public/src/forum/admin/footer.js b/public/src/forum/admin/footer.js
deleted file mode 100644
index 062b7ed7e8..0000000000
--- a/public/src/forum/admin/footer.js
+++ /dev/null
@@ -1,190 +0,0 @@
-"use strict";
-/*global define, app, socket, Hammer, RELATIVE_PATH */
-
-define('forum/admin/footer', ['forum/admin/settings'], function(Settings) {
-	var acpIndex;
-
-	$(document).ready(function() {
-		if(!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
-			getSearchIndex();
-		} else {
-			activateMobile();
-		}
-
-		$(window).on('action:ajaxify.end', function(ev, data) {
-			var url = data.url;
-
-			selectMenuItem(data.url);
-		});
-
-		setupMainMenu();
-	});
-
-	function activateMobile() {
-		$('.admin').addClass('mobile');
-		$('#main-menu').addClass('transitioning');
-
-		Hammer(document.body).on('swiperight', function(e) {
-			$('#main-menu').addClass('open');
-		});
-
-		Hammer(document.body).on('swipeleft', function(e) {
-			$('#main-menu').removeClass('open');
-		});
-
-		Hammer($('#main-menu')[0]).on('swiperight', function(e) {
-			$('#main-menu').addClass('open');
-		});
-
-		Hammer($('#main-menu')[0]).on('swipeleft', function(e) {
-			$('#main-menu').removeClass('open');
-		});
-
-		$(window).on('scroll', function() {
-			$('#main-menu').height($(window).height() + 20);
-		});
-	}
-
-	function setupMainMenu() {
-		$('.sidebar-nav .nav-header').on('click', function() {
-			$(this).parents('.sidebar-nav').toggleClass('open');
-			setTimeout(function() {
-				$('.nano').nanoScroller();
-			}, 500); // replace with animationend event
-		});
-
-		$('.nano').nanoScroller();
-
-		$('#main-menu .nav-list > li a').append('<span class="pull-right"><i class="fa fa-inverse fa-arrow-circle-right"></i>&nbsp;</span>');
-	}
-
-	function selectMenuItem(url) {
-		$('#main-menu .nav-list > li').removeClass('active').each(function() {
-			var menu = $(this),
-				category = menu.parents('.sidebar-nav'),
-				href = menu.children('a').attr('href');
-
-			if (href && href.slice(1).indexOf(url) !== -1) {
-				category.addClass('open');
-				menu.addClass('active');
-				modifyBreadcrumb(category.find('.nav-header').text(), menu.text());
-				return false;
-			}
-		});
-	}
-
-	function modifyBreadcrumb() {
-		var caret = ' <i class="fa fa-angle-right"></i> ';
-		
-		$('#breadcrumbs').html(caret + Array.prototype.slice.call(arguments).join(caret));
-	}
-
-	function getSearchIndex() {
-		$.getJSON(RELATIVE_PATH + '/templates/indexed.json', function (data) {
-			acpIndex = data;
-			for (var file in acpIndex) {
-				if (acpIndex.hasOwnProperty(file)) {
-					acpIndex[file] = acpIndex[file].replace(/<img/g, '<none'); // can't think of a better solution, see #2153
-					acpIndex[file] = $('<div class="search-container">' + acpIndex[file] + '</div>');
-					acpIndex[file].find('script').remove();
-
-					acpIndex[file] = acpIndex[file].text().toLowerCase().replace(/[ |\r|\n]+/g, ' ');
-				}
-			}
-
-			delete acpIndex['/admin/header.tpl'];
-			delete acpIndex['/admin/footer.tpl'];
-
-			setupACPSearch();
-		});
-	}
-	
-	function setupACPSearch() {
-		var menu = $('#acp-search .dropdown-menu'),
-			routes = [],
-			input = $('#acp-search input'),
-			firstResult = null;
-
-		input.on('keyup', function() {
-			$('#acp-search .dropdown').addClass('open');
-		});
-
-		$('#acp-search').parents('form').on('submit', function(ev) {
-			var input = $(this).find('input'),
-				href = firstResult ? firstResult : RELATIVE_PATH + '/search/' + input.val();
-
-			ajaxify.go(href.replace(/^\//, ''));
-
-			setTimeout(function() {
-				$('#acp-search .dropdown').removeClass('open');
-				$(input).blur();
-			}, 150);
-
-			ev.preventDefault();
-			return false;
-		});
-
-		$('.sidebar-nav a').each(function(idx, link) {
-			routes.push($(link).attr('href'));
-		});
-
-		input.on('blur', function() {
-			$(this).val('').attr('placeholder', '/');
-		});
-
-		input.on('keyup focus', function() {
-			var $input = $(this),
-				value = $input.val().toLowerCase(),
-				menuItems = $('#acp-search .dropdown-menu').html('');
-
-			function toUpperCase(txt){
-				return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
-			}
-
-			$input.attr('placeholder', '');
-
-			firstResult = null;
-
-			if (value.length >= 3) {
-				for (var file in acpIndex) {
-					if (acpIndex.hasOwnProperty(file)) {
-						var position = acpIndex[file].indexOf(value);
-
-						if (position !== -1) {
-							var href = file.replace('.tpl', ''),
-								title = href.replace(/^\/admin\//, '').split('/'),
-								description = acpIndex[file].substring(Math.max(0, position - 25), Math.min(acpIndex[file].length - 1, position + 25))
-									.replace(value, '<span class="search-match">' + value + '</span>');
-
-							for (var t in title) {
-								if (title.hasOwnProperty(t)) {
-									title[t] = title[t]
-										.replace('-', ' ')
-										.replace(/\w\S*/g, toUpperCase);
-								}
-							}
-
-							title = title.join(' > ');
-							href = RELATIVE_PATH + href;
-							firstResult = firstResult ? firstResult : href;
-
-							if ($.inArray(href, routes) !== -1) {
-								menuItems.append('<li role="presentation"><a role="menuitem" href="' + href + '">' + title + '<br /><small><code>...' + description + '...</code></small></a></li>');
-							}
-						}
-					}
-				}
-
-				if (menuItems.html() !== '') {
-					menuItems.append('<li role="presentation" class="divider"></li>');
-				}
-			}
-
-			if (value.length > 0) {
-				menuItems.append('<li role="presentation"><a role="menuitem" href="' + RELATIVE_PATH + '/search/' + value + '">Search the forum for <strong>' + value + '</strong></a></li>');
-			} else {
-				menuItems.append('<li role="presentation"><a role="menuitem" href="#">Start typing to see results...</a></li>');
-			}
-		});
-	}
-});
\ No newline at end of file
diff --git a/public/src/forum/admin/general/dashboard.js b/public/src/forum/admin/general/dashboard.js
deleted file mode 100644
index 4f9868ac34..0000000000
--- a/public/src/forum/admin/general/dashboard.js
+++ /dev/null
@@ -1,445 +0,0 @@
-"use strict";
-/*global define, ajaxify, app, socket, RELATIVE_PATH*/
-
-define('forum/admin/general/dashboard', ['semver'], function(semver) {
-	var	Admin = {},
-		intervals = {
-			rooms: false,
-			graphs: false
-		},
-		isMobile = false;
-
-
-	Admin.init = function() {
-		app.enterRoom('admin');
-		socket.emit('meta.rooms.getAll', Admin.updateRoomUsage);
-
-		isMobile = !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
-
-		intervals.rooms = setInterval(function() {
-			if (app.isFocused && app.isConnected) {
-				socket.emit('meta.rooms.getAll', Admin.updateRoomUsage);
-			}
-		}, 5000);
-
-		$(window).on('action:ajaxify.start', function(ev, data) {
-			clearInterval(intervals.rooms);
-			clearInterval(intervals.graphs);
-
-			intervals.rooms = null;
-			intervals.graphs = null;
-		});
-
-		$('#logout-link').on('click', function() {
-			$.post(RELATIVE_PATH + '/logout', function() {
-				window.location.href = RELATIVE_PATH + '/';
-			});
-		});
-
-		$.get('https://api.github.com/repos/NodeBB/NodeBB/tags', function(releases) {
-			// Re-sort the releases, as they do not follow Semver (wrt pre-releases)
-			releases = releases.sort(function(a, b) {
-				a = a.name.replace(/^v/, '');
-				b = b.name.replace(/^v/, '');
-				return semver.lt(a, b) ? 1 : -1;
-			});
-
-			var	version = $('#version').html(),
-				latestVersion = releases[0].name.slice(1),
-				checkEl = $('.version-check');
-			checkEl.html($('.version-check').html().replace('<i class="fa fa-spinner fa-spin"></i>', 'v' + latestVersion));
-
-			// Alter box colour accordingly
-			if (semver.eq(latestVersion, version)) {
-				checkEl.removeClass('alert-info').addClass('alert-success');
-				checkEl.append('<p>You are <strong>up-to-date</strong> <i class="fa fa-check"></i></p>');
-			} else if (semver.gt(latestVersion, version)) {
-				checkEl.removeClass('alert-info').addClass('alert-danger');
-				checkEl.append('<p>A new version (v' + latestVersion + ') has been released. Consider upgrading your NodeBB.</p>');
-			} else if (semver.gt(version, latestVersion)) {
-				checkEl.removeClass('alert-info').addClass('alert-warning');
-				checkEl.append('<p>You are running a <strong>development version</strong>! Unintended bugs may occur. <i class="fa fa-warning"></i></p>');
-			}
-		});
-
-		$('.restart').on('click', function() {
-			bootbox.confirm('Are you sure you wish to restart NodeBB?', function(confirm) {
-				if (confirm) {
-					app.alert({
-						alert_id: 'instance_restart',
-						type: 'info',
-						title: 'Restarting... <i class="fa fa-spin fa-refresh"></i>',
-						message: 'NodeBB is restarting.',
-						timeout: 5000
-					});
-
-					$(window).one('action:reconnected', function() {
-						app.alert({
-							alert_id: 'instance_restart',
-							type: 'success',
-							title: '<i class="fa fa-check"></i> Success',
-							message: 'NodeBB has successfully restarted.',
-							timeout: 5000
-						});
-					});
-
-					socket.emit('admin.restart');
-				}
-			});
-		});
-
-		$('.reload').on('click', function() {
-			app.alert({
-				alert_id: 'instance_reload',
-				type: 'info',
-				title: 'Reloading... <i class="fa fa-spin fa-refresh"></i>',
-				message: 'NodeBB is reloading.',
-				timeout: 5000
-			});
-
-			socket.emit('admin.reload', function(err) {
-				if (!err) {
-					app.alert({
-						alert_id: 'instance_reload',
-						type: 'success',
-						title: '<i class="fa fa-check"></i> Success',
-						message: 'NodeBB has successfully reloaded.',
-						timeout: 5000
-					});
-				} else {
-					app.alert({
-						alert_id: 'instance_reload',
-						type: 'danger',
-						title: '[[global:alert.error]]',
-						message: '[[error:reload-failed, ' + err.message + ']]'
-					});
-				}
-			});
-		});
-
-		setupGraphs();
-	};
-
-	Admin.updateRoomUsage = function(err, data) {
-		if (err) {
-			return app.alertError(err.message);
-		}
-
-		var html = '<div class="text-center pull-left">' + 
-						'<div>'+ data.onlineRegisteredCount +'</div>' + 
-						'<div>Users</div>' +
-					'</div>' +
-					'<div class="text-center pull-left">' + 
-						'<div>'+ data.onlineGuestCount +'</div>' + 
-						'<div>Guests</div>' +
-					'</div>' +
-					'<div class="text-center pull-left">' + 
-						'<div>'+ (data.onlineRegisteredCount + data.onlineGuestCount) +'</div>' + 
-						'<div>Total</div>' +
-					'</div>' +
-					'<div class="text-center pull-left">' + 
-						'<div>'+ data.socketCount +'</div>' + 
-						'<div>Connections</div>' +
-					'</div>';
-
-		var idle = data.socketCount - (data.users.home + data.users.topics + data.users.category);
-
-		updateRegisteredGraph(data.onlineRegisteredCount, data.onlineGuestCount);
-		updatePresenceGraph(data.users.home, data.users.topics, data.users.category, idle);
-		updateTopicsGraph(data.topics);
-
-		$('#active-users').html(html);
-	};
-
-	var graphs = {
-		traffic: null,
-		registered: null,
-		presence: null,
-		topics: null
-	};
-
-	var topicColors = ["#bf616a","#5B90BF","#d08770","#ebcb8b","#a3be8c","#96b5b4","#8fa1b3","#b48ead","#ab7967","#46BFBD"],
-		usedTopicColors = [];
-
-	// from chartjs.org
-	function lighten(col, amt) {
-		var usePound = false;
-
-		if (col[0] == "#") {
-			col = col.slice(1);
-			usePound = true;
-		}
-
-		var num = parseInt(col,16);
-
-		var r = (num >> 16) + amt;
-
-		if (r > 255) r = 255;
-		else if  (r < 0) r = 0;
-
-		var b = ((num >> 8) & 0x00FF) + amt;
-
-		if (b > 255) b = 255;
-		else if  (b < 0) b = 0;
-
-		var g = (num & 0x0000FF) + amt;
-
-		if (g > 255) g = 255;
-		else if (g < 0) g = 0;
-
-		return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
-	}
-
-	function getHoursArray() {
-		var currentHour = new Date().getHours(),
-			labels = [];
-
-		for (var i = currentHour, ii = currentHour - 12; i > ii; i--) {
-			var hour = i < 0 ? 24 + i : i;
-			labels.push(hour + ':00 ');
-		}
-
-		return labels.reverse();
-	}
-
-	function setupGraphs() {
-		var trafficCanvas = document.getElementById('analytics-traffic'),
-			registeredCanvas = document.getElementById('analytics-registered'),
-			presenceCanvas = document.getElementById('analytics-presence'),
-			topicsCanvas = document.getElementById('analytics-topics'),
-			trafficCtx = trafficCanvas.getContext('2d'),
-			registeredCtx = registeredCanvas.getContext('2d'),
-			presenceCtx = presenceCanvas.getContext('2d'),
-			topicsCtx = topicsCanvas.getContext('2d'),
-			trafficLabels = getHoursArray();
-
-		if (isMobile) {
-			Chart.defaults.global.showTooltips = false;
-		}
-
-		var data = {
-				labels: trafficLabels,
-				datasets: [
-					{
-						label: "Page Views",
-						fillColor: "rgba(220,220,220,0.2)",
-						strokeColor: "rgba(220,220,220,1)",
-						pointColor: "rgba(220,220,220,1)",
-						pointStrokeColor: "#fff",
-						pointHighlightFill: "#fff",
-						pointHighlightStroke: "rgba(220,220,220,1)",
-						data: [0,0,0,0,0,0,0,0,0,0,0,0]
-					},
-					{
-						label: "Unique Visitors",
-						fillColor: "rgba(151,187,205,0.2)",
-						strokeColor: "rgba(151,187,205,1)",
-						pointColor: "rgba(151,187,205,1)",
-						pointStrokeColor: "#fff",
-						pointHighlightFill: "#fff",
-						pointHighlightStroke: "rgba(151,187,205,1)",
-						data: [0,0,0,0,0,0,0,0,0,0,0,0]
-					}
-				]
-			};
-
-		trafficCanvas.width = $(trafficCanvas).parent().width(); // is this necessary
-		graphs.traffic = new Chart(trafficCtx).Line(data, {
-			responsive: true
-		});
-
-		graphs.registered = new Chart(registeredCtx).Doughnut([{
-		        value: 1,
-		        color:"#F7464A",
-		        highlight: "#FF5A5E",
-		        label: "Registered Users"
-		    },
-		    {
-		        value: 1,
-		        color: "#46BFBD",
-		        highlight: "#5AD3D1",
-		        label: "Anonymous Users"
-		    }], {
-		    	responsive: true
-		    });
-
-		graphs.presence = new Chart(presenceCtx).Doughnut([{
-		        value: 1,
-		        color:"#F7464A",
-		        highlight: "#FF5A5E",
-		        label: "On homepage"
-		    },
-		    {
-		        value: 1,
-		        color: "#46BFBD",
-		        highlight: "#5AD3D1",
-		        label: "Reading posts"
-		    },
-		    {
-		        value: 1,
-		        color: "#FDB45C",
-		        highlight: "#FFC870",
-		        label: "Browsing topics"
-		    },
-		    {
-		        value: 1,
-		        color: "#949FB1",
-		        highlight: "#A8B3C5",
-		        label: "Idle"
-		    }], {
-		    	responsive: true
-		    });
-
-		graphs.topics = new Chart(topicsCtx).Doughnut([], {responsive: true});
-		topicsCanvas.onclick = function(evt){
-			var obj = graphs.topics.getSegmentsAtEvent(evt);
-			window.open(RELATIVE_PATH + '/topic/' + obj[0].tid);
-		};
-
-		intervals.graphs = setInterval(updateTrafficGraph, 15000);
-		updateTrafficGraph();
-
-		$(window).on('resize', adjustPieCharts);
-		adjustPieCharts();
-	}
-
-	function adjustPieCharts() {
-		$('.pie-chart.legend-up').each(function() {
-			var $this = $(this);
-
-			if ($this.width() < 320) {
-				$this.addClass('compact');
-			} else {
-				$this.removeClass('compact');
-			}
-		});
-	}
-
-	function updateTrafficGraph() {
-		if (!app.isFocused  || !app.isConnected) {
-			return;
-		}
-
-		socket.emit('admin.analytics.get', {graph: "traffic"}, function (err, data) {
-			for (var i = 0, ii = data.pageviews.length; i < ii;  i++) {
-				graphs.traffic.datasets[0].points[i].value = data.pageviews[i];
-				graphs.traffic.datasets[1].points[i].value = data.uniqueVisitors[i];
-			}
-
-			var currentHour = new Date().getHours();
-
-			graphs.traffic.scale.xLabels = getHoursArray();
-			graphs.traffic.update();
-		});
-	}
-
-	function updateRegisteredGraph(registered, anonymous) {
-		graphs.registered.segments[0].value = registered;
-		graphs.registered.segments[1].value = anonymous;
-		graphs.registered.update();
-	}
-
-	function updatePresenceGraph(homepage, posts, topics, idle) {
-		graphs.presence.segments[0].value = homepage;
-		graphs.presence.segments[1].value = posts;
-		graphs.presence.segments[2].value = topics;
-		graphs.presence.segments[3].value = idle;
-		graphs.presence.update();
-	}
-
-	function updateTopicsGraph(topics) {
-		if (!Object.keys(topics).length) {
-			topics = {"0": {
-				title: "No users browsing",
-				value: 1
-			}};
-		}
-
-		var tids = Object.keys(topics),
-			segments = graphs.topics.segments;
-
-		function reassignExistingTopics() {
-			for (var i = 0, ii = segments.length; i < ii; i++ ) {
-				if (!segments[i]) {
-					continue;
-				}
-
-				var tid = segments[i].tid;
-
-				if ($.inArray(tid, tids) === -1) {
-					usedTopicColors.splice($.inArray(segments[i].color, usedTopicColors), 1);
-					graphs.topics.removeData(i);
-				} else {
-					graphs.topics.segments[i].value = topics[tid].value;
-					delete topics[tid];
-				}
-			}
-		}
-
-		function assignNewTopics() {
-			while (segments.length < 10 && tids.length > 0) {
-				var tid = tids.pop(),
-					data = topics[tid],
-					color = null;
-
-				if (!data) {
-					continue;
-				}
-
-				if (tid === '0') {
-					color = '#4D5360';
-				} else {
-					do {
-						for (var i = 0, ii = topicColors.length; i < ii; i++) {
-							var chosenColor = topicColors[i];
-
-							if ($.inArray(chosenColor, usedTopicColors) === -1) {
-								color = chosenColor;
-								usedTopicColors.push(color);
-								break;
-							}
-						}
-					} while (color === null && usedTopicColors.length < topicColors.length);
-				}
-
-				if (color) {
-					graphs.topics.addData({
-						value: data.value,
-						color: color,
-						highlight: lighten(color, 10),
-						label: data.title
-					});
-
-					segments[segments.length - 1].tid = tid;
-				}
-			}
-		}
-
-		function buildTopicsLegend() {
-			var legend = $('#topics-legend').html('');
-
-			for (var i = 0, ii = segments.length; i < ii; i++) {
-				var topic = segments[i],
-					label = topic.tid === '0' ? topic.label : '<a title="' + topic.label + '"href="' + RELATIVE_PATH + '/topic/' + topic.tid + '" target="_blank"> ' + topic.label + '</a>';
-
-				legend.append(
-					'<li>' +
-						'<div style="background-color: ' + topic.highlightColor + '; border-color: ' + topic.strokeColor + '"></div>' +
-						'<span>' + label + '</span>' +
-					'</li>');
-			}
-		}
-
-		reassignExistingTopics();
-		assignNewTopics();
-		buildTopicsLegend();
-
-		graphs.topics.update();
-	}
-
-	function buildTopicsLegend() {
-
-	}
-
-	return Admin;
-});
diff --git a/public/src/forum/admin/general/languages.js b/public/src/forum/admin/general/languages.js
deleted file mode 100644
index 0d3b4ddf6e..0000000000
--- a/public/src/forum/admin/general/languages.js
+++ /dev/null
@@ -1,8 +0,0 @@
-"use strict";
-/*global define*/
-
-define('forum/admin/general/languages', ['forum/admin/settings'], function(Settings) {
-	$(function() {
-		Settings.prepare();
-	});
-});
diff --git a/public/src/forum/admin/general/sounds.js b/public/src/forum/admin/general/sounds.js
deleted file mode 100644
index 63d83789f4..0000000000
--- a/public/src/forum/admin/general/sounds.js
+++ /dev/null
@@ -1,32 +0,0 @@
-"use strict";
-/* global define, socket */
-
-define('forum/admin/general/sounds', ['sounds', 'settings'], function(Sounds, Settings) {
-	var	SoundsAdmin = {};
-
-	SoundsAdmin.init = function() {
-		// Sounds tab
-		$('.sounds').find('button[data-action="play"]').on('click', function(e) {
-			e.preventDefault();
-
-			var	fileName = $(this).parent().parent().find('select').val();
-			Sounds.playFile(fileName);
-		});
-
-		// Load Form Values
-		Settings.load('sounds', $('.sounds form'));
-
-		// Saving of Form Values
-		var	saveEl = $('#save');
-		saveEl.on('click', function() {
-			Settings.save('sounds', $('.sounds form'), function() {
-				socket.emit('admin.fireEvent', {
-					name: 'event:sounds.reloadMapping'
-				});
-				app.alertSuccess('Settings Saved');
-			});
-		});
-	};
-
-	return SoundsAdmin;
-});
diff --git a/public/src/forum/admin/iconSelect.js b/public/src/forum/admin/iconSelect.js
deleted file mode 100644
index 348619bf37..0000000000
--- a/public/src/forum/admin/iconSelect.js
+++ /dev/null
@@ -1,47 +0,0 @@
-
-'use strict';
-
-/* globals define, bootbox */
-
-define(function() {
-	var iconSelect = {};
-
-	iconSelect.init = function(el, onModified) {
-		onModified = onModified || function() {};
-		var selected = el.attr('class').replace('fa-2x', '').replace('fa', '').replace(/\s+/g, '');
-		$('#icons .selected').removeClass('selected');
-
-		if (selected === '') {
-			selected = 'fa-doesnt-exist';
-		}
-		if (selected) {
-			$('#icons .fa-icons .fa.' + selected).parent().addClass('selected');
-		}
-
-		bootbox.confirm('<h2>Select an icon.</h2>' + $('#icons').html(), function(confirm) {
-			if (confirm) {
-				var iconClass = $('.bootbox .selected').attr('class');
-				var categoryIconClass = $('<div/>').addClass(iconClass).removeClass('fa').removeClass('selected').attr('class');
-				if (categoryIconClass === 'fa-doesnt-exist') {
-					categoryIconClass = '';
-				}
-
-				el.attr('class', 'fa fa-2x ' + categoryIconClass);
-				el.val(categoryIconClass);
-				el.attr('value', categoryIconClass);
-
-				onModified(el);
-			}
-		});
-
-		setTimeout(function() { //bootbox was rewritten for BS3 and I had to add this timeout for the previous code to work. TODO: to look into
-			$('.bootbox .fa-icons i').on('click', function() {
-				$('.bootbox .selected').removeClass('selected');
-				$(this).addClass('selected');
-			});
-		}, 500);
-	};
-
-	return iconSelect;
-});
-
diff --git a/public/src/forum/admin/manage/categories.js b/public/src/forum/admin/manage/categories.js
deleted file mode 100644
index c5d97212ec..0000000000
--- a/public/src/forum/admin/manage/categories.js
+++ /dev/null
@@ -1,391 +0,0 @@
-"use strict";
-/*global define, socket, app, bootbox, templates, ajaxify, RELATIVE_PATH*/
-
-define('forum/admin/manage/categories', ['uploader', 'forum/admin/iconSelect'], function(uploader, iconSelect) {
-	var	Categories = {};
-
-	Categories.init = function() {
-		var modified_categories = {};
-
-		function modified(el) {
-			var cid = $(el).parents('li').attr('data-cid');
-			if(cid) {
-				modified_categories[cid] = modified_categories[cid] || {};
-				modified_categories[cid][$(el).attr('data-name')] = $(el).val();
-			}
-		}
-
-		function save() {
-			if(Object.keys(modified_categories).length) {
-				socket.emit('admin.categories.update', modified_categories, function(err, result) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-
-					if (result && result.length) {
-						app.alert({
-							title: 'Updated Categories',
-							message: 'Category IDs ' + result.join(', ') + ' was successfully updated.',
-							type: 'success',
-							timeout: 2000
-						});
-					}
-				});
-				modified_categories = {};
-			}
-			return false;
-		}
-
-		function update_blockclass(el) {
-			el.parentNode.parentNode.className = 'entry-row ' + el.value;
-		}
-
-		function updateCategoryOrders() {
-			var categories = $('.admin-categories #entry-container').children();
-			for(var i = 0; i<categories.length; ++i) {
-				var input = $(categories[i]).find('input[data-name="order"]');
-
-				input.val(i+1).attr('data-value', i+1);
-				modified(input);
-			}
-		}
-
-		$('#entry-container').sortable({
-			stop: function(event, ui) {
-				updateCategoryOrders();
-			},
-			distance: 10
-		});
-
-		$('.blockclass, .admin-categories form select').each(function() {
-			var $this = $(this);
-			$this.val($this.attr('data-value'));
-		});
-
-		function showCreateCategoryModal() {
-			$('#new-category-modal').modal();
-		}
-
-		function createNewCategory() {
-			var category = {
-				name: $('#inputName').val(),
-				description: $('#inputDescription').val(),
-				icon: $('#new-category-modal i').attr('value'),
-				bgColor: '#0059b2',
-				color: '#fff',
-				order: $('.admin-categories #entry-container').children().length + 1
-			};
-
-			socket.emit('admin.categories.create', category, function(err, data) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-
-				app.alert({
-					alert_id: 'category_created',
-					title: 'Created',
-					message: 'Category successfully created!',
-					type: 'success',
-					timeout: 2000
-				});
-
-				$('#new-category-modal').modal('hide');
-				ajaxify.refresh();
-			});
-		}
-
-		function enableColorPicker(idx, inputEl) {
-			var $inputEl = $(inputEl),
-				previewEl = $inputEl.parents('[data-cid]').find('.preview-box');
-
-			admin.enableColorPicker($inputEl, function(hsb, hex) {
-				if ($inputEl.attr('data-name') === 'bgColor') {
-					previewEl.css('background', '#' + hex);
-				} else if ($inputEl.attr('data-name') === 'color') {
-					previewEl.css('color', '#' + hex);
-				}
-
-				modified($inputEl[0]);
-			});
-		}
-
-		function setupEditTargets() {
-			$('[data-edit-target]').on('click', function() {
-				var $this = $(this),
-					target = $($this.attr('data-edit-target'));
-
-				$this.addClass('hide');
-				target.removeClass('hide').on('blur', function() {
-					$this.removeClass('hide').children('span').html(this.value);
-					$(this).addClass('hide');
-				}).val($this.children('span').html());
-
-				target.focus();
-			});
-		}
-
-		$(function() {
-			var url = window.location.href,
-				parts = url.split('/'),
-				active = parts[parts.length - 1];
-
-			$('.nav-pills li').removeClass('active');
-			$('.nav-pills li a').each(function() {
-				var $this = $(this);
-				if ($this.attr('href').match(active)) {
-					$this.parent().addClass('active');
-					return false;
-				}
-			});
-
-
-			$('#addNew').on('click', showCreateCategoryModal);
-			$('#create-category-btn').on('click', createNewCategory);
-
-			$('#entry-container, #new-category-modal').on('click', '.icon', function(ev) {
-				iconSelect.init($(this).find('i'), modified);
-			});
-
-			$('.admin-categories form input, .admin-categories form select').on('change', function(ev) {
-				modified(ev.target);
-			});
-
-			$('.dropdown').on('click', '[data-disabled]', function(ev) {
-				var btn = $(this),
-					categoryRow = btn.parents('li'),
-					cid = categoryRow.attr('data-cid'),
-					disabled = btn.attr('data-disabled') === 'false' ? '1' : '0';
-
-				categoryRow.remove();
-				modified_categories[cid] = modified_categories[cid] || {};
-				modified_categories[cid].disabled = disabled;
-
-				save();
-				return false;
-			});
-
-			// Colour Picker
-			$('[data-name="bgColor"], [data-name="color"]').each(enableColorPicker);
-
-			$('.admin-categories').on('click', '.save', save);
-			$('.admin-categories').on('click', '.purge', function() {
-				var categoryRow = $(this).parents('li[data-cid]');
-				var	cid = categoryRow.attr('data-cid');
-
-				bootbox.confirm('Do you really want to purge this category "' + categoryRow.find('#cid-' + cid + '-name').val() + '"?<br/><strong class="text-danger">Warning!</strong> All topics and posts in this category will be purged!', function(confirm) {
-					if (!confirm) {
-						return;
-					}
-					socket.emit('admin.categories.purge', cid, function(err) {
-						if (err) {
-							return app.alertError(err.message);
-						}
-						app.alertSuccess('Category purged!');
-						categoryRow.remove();
-					});
-				});
-			});
-
-			$('.admin-categories').on('click', '.permissions', function() {
-				var	cid = $(this).parents('li[data-cid]').attr('data-cid');
-				Categories.launchPermissionsModal(cid);
-				return false;
-			});
-
-
-			$('.admin-categories').on('click', '.upload-button', function() {
-				var inputEl = $(this),
-					cid = inputEl.parents('li[data-cid]').attr('data-cid');
-
-				uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', { cid: cid }, 0, function(imageUrlOnServer) {
-					inputEl.val(imageUrlOnServer);
-					var previewBox = inputEl.parents('li[data-cid]').find('.preview-box');
-					previewBox.css('background', 'url(' + imageUrlOnServer + '?' + new Date().getTime() + ')')
-						.css('background-size', 'cover');
-					modified(inputEl[0]);
-				});
-			});
-
-			$('.admin-categories').on('click', '.delete-image', function() {
-				var parent = $(this).parents('li[data-cid]'),
-					inputEl = parent.find('.upload-button'),
-					preview = parent.find('.preview-box'),
-					bgColor = parent.find('.category_bgColor').val();
-
-				inputEl.val('');
-				modified(inputEl[0]);
-
-				preview.css('background', bgColor);
-
-				$(this).addClass('hide').hide();
-			});
-
-			$('#revertChanges').on('click', function() {
-				ajaxify.refresh();
-			});
-
-			setupEditTargets();
-
-			$('button[data-action="setParent"]').on('click', function() {
-				var cid = $(this).parents('[data-cid]').attr('data-cid'),
-					modal = $('#setParent');
-
-				modal.find('select').val($(this).attr('data-parentCid'));
-				modal.attr('data-cid', cid).modal();
-			});
-
-			$('button[data-action="removeParent"]').on('click', function() {
-				var cid = $(this).parents('[data-cid]').attr('data-cid');
-				var payload= {};
-				payload[cid] = {
-					parentCid: 0
-				};
-				socket.emit('admin.categories.update', payload, function(err) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-					ajaxify.go('admin/manage/categories/active');
-				});
-			});
-
-			$('#setParent [data-cid]').on('click', function() {
-				var modalEl = $('#setParent'),
-					parentCid = $(this).attr('data-cid'),
-					payload = {};
-
-				payload[modalEl.attr('data-cid')] = {
-					parentCid: parentCid
-				};
-
-				socket.emit('admin.categories.update', payload, function(err) {
-					modalEl.one('hidden.bs.modal', function() {
-						ajaxify.go('admin/manage/categories/active');
-					});
-					modalEl.modal('hide');
-				});
-			});
-		});
-	};
-
-	Categories.launchPermissionsModal = function(cid) {
-		var	modal = $('#category-permissions-modal'),
-			searchEl = modal.find('#permission-search'),
-			resultsEl = modal.find('.search-results.users'),
-			groupsResultsEl = modal.find('.search-results.groups'),
-			searchDelay;
-
-		// Clear the search field and results
-		searchEl.val('');
-		resultsEl.html('');
-
-		searchEl.off().on('keyup', function() {
-			var	searchEl = this,
-				liEl;
-
-			clearTimeout(searchDelay);
-
-			searchDelay = setTimeout(function() {
-				socket.emit('admin.categories.search', {
-					username: searchEl.value,
-					cid: cid
-				}, function(err, results) {
-					if(err) {
-						return app.alertError(err.message);
-					}
-
-					templates.parse('admin/partials/categories/users', {
-						users: results
-					}, function(html) {
-						resultsEl.html(html);
-					});
-				});
-			}, 250);
-		});
-
-		Categories.refreshPrivilegeList(cid);
-
-		resultsEl.off().on('click', '[data-priv]', function(e) {
-			var	anchorEl = $(this),
-				uid = anchorEl.parents('li[data-uid]').attr('data-uid'),
-				privilege = anchorEl.attr('data-priv');
-			e.preventDefault();
-			e.stopPropagation();
-
-			socket.emit('admin.categories.setPrivilege', {
-				cid: cid,
-				uid: uid,
-				privilege: privilege,
-				set: !anchorEl.hasClass('active')
-			}, function(err) {
-				if (err) {
-					return app.alertError(err.message);
-				}
-				anchorEl.toggleClass('active', !anchorEl.hasClass('active'));
-				Categories.refreshPrivilegeList(cid);
-			});
-		});
-
-		modal.off().on('click', '.members li > img', function() {
-			searchEl.val($(this).attr('title'));
-			searchEl.keyup();
-		});
-
-		// User Groups and privileges
-		socket.emit('admin.categories.groupsList', cid, function(err, results) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			templates.parse('admin/partials/categories/groups', {
-				groups: results
-			}, function(html) {
-				groupsResultsEl.html(html);
-			});
-		});
-
-		groupsResultsEl.off().on('click', '[data-priv]', function(e) {
-			var	anchorEl = $(this),
-				name = anchorEl.parents('li[data-name]').attr('data-name'),
-				privilege = anchorEl.attr('data-priv');
-			e.preventDefault();
-			e.stopPropagation();
-
-			socket.emit('admin.categories.setGroupPrivilege', {
-				cid: cid,
-				name: name,
-				privilege: privilege,
-				set: !anchorEl.hasClass('active')
-			}, function(err) {
-				if (!err) {
-					anchorEl.toggleClass('active');
-				}
-			});
-		});
-
-		modal.modal();
-	};
-
-	Categories.refreshPrivilegeList = function (cid) {
-		var	modalEl = $('#category-permissions-modal'),
-			memberList = $('.members');
-
-		socket.emit('admin.categories.getPrivilegeSettings', cid, function(err, privilegeList) {
-			var	membersLength = privilegeList.length,
-				liEl, x, userObj;
-
-			memberList.html('');
-			if (membersLength > 0) {
-				for(x = 0; x < membersLength; x++) {
-					userObj = privilegeList[x];
-					liEl = $('<li/>').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
-					memberList.append(liEl);
-				}
-			} else {
-				liEl = $('<li/>').addClass('empty').html('None.');
-				memberList.append(liEl);
-			}
-		});
-	};
-
-	return Categories;
-});
\ No newline at end of file
diff --git a/public/src/forum/admin/manage/flags.js b/public/src/forum/admin/manage/flags.js
deleted file mode 100644
index fc2e300d74..0000000000
--- a/public/src/forum/admin/manage/flags.js
+++ /dev/null
@@ -1,68 +0,0 @@
-"use strict";
-/*global define, socket, app, admin, utils, bootbox, RELATIVE_PATH*/
-
-define('forum/admin/manage/flags', ['forum/infinitescroll', 'admin/selectable'], function(infinitescroll, selectable) {
-	var	Flags = {};
-
-	Flags.init = function() {
-		handleDismiss();
-		handleDelete();
-		handleInfiniteScroll();
-	};
-
-	function handleDismiss() {
-		$('.flags').on('click', '.dismiss', function() {
-			var btn = $(this);
-			var pid = btn.siblings('[data-pid]').attr('data-pid');
-
-			socket.emit('admin.dismissFlag', pid, function(err) {
-				done(err, btn);
-			});
- 		});
-	}
-
-	function handleDelete() {
-		$('.flags').on('click', '.delete', function() {
-			var btn = $(this);
-			var pid = btn.siblings('[data-pid]').attr('data-pid');
-			var tid = btn.siblings('[data-pid]').attr('data-tid');
-			socket.emit('posts.delete', {pid: pid, tid: tid}, function(err) {
-				done(err, btn);
-			});
-		});
-	}
-
-	function done(err, btn) {
-		if (err) {
-			return app.alertError(err.messaage);
-		}
-		btn.parent().fadeOut(function() {
-			btn.remove();
-		});
-		if (!$('.flags [data-pid]').length) {
-			$('.post-container').text('No flagged posts!');
-		}
-	}
-
-	function handleInfiniteScroll() {
-		infinitescroll.init(function(direction) {
-			if (direction < 0 && !$('.flags').length) {
-				return;
-			}
-
-			infinitescroll.loadMore('admin.getMoreFlags', $('[data-next]').attr('data-next'), function(data, done) {
-				if (data.posts && data.posts.length) {
-					infinitescroll.parseAndTranslate('admin/manage/flags', 'posts', {posts: data.posts}, function(html) {
-						$('[data-next]').attr('data-next', data.next);
-						$('.post-container').append(html);
-						done();
-					});
-				} else {
-					done();
-				}
-			});
-		});
-	}
-
-	return Flags;
-});
\ No newline at end of file
diff --git a/public/src/forum/admin/manage/groups.js b/public/src/forum/admin/manage/groups.js
deleted file mode 100644
index b0b5d282c7..0000000000
--- a/public/src/forum/admin/manage/groups.js
+++ /dev/null
@@ -1,263 +0,0 @@
-"use strict";
-/*global define, templates, socket, ajaxify, app, bootbox*/
-
-define('forum/admin/manage/groups', ['forum/admin/iconSelect'], function(iconSelect) {
-	var	Groups = {};
-
-	Groups.init = function() {
-		var yourid = ajaxify.variables.get('yourid'),
-			createModal = $('#create-modal'),
-			createGroupName = $('#create-group-name'),
-			create = $('#create'),
-			createModalGo = $('#create-modal-go'),
-			createGroupDesc = $('#create-group-desc'),
-			createModalError = $('#create-modal-error'),
-			groupDetailsModal = $('#group-details-modal'),
-			groupDetailsSearch = $('#group-details-search'),
-			groupDetailsSearchResults = $('#group-details-search-results'),
-			groupMembersEl = $('ul.current_members'),
-			formEl = groupDetailsModal.find('form'),
-			detailsModalSave = $('#details-modal-save'),
-			groupsList = $('#groups-list'),
-			groupIcon = $('#group-icon'),
-			changeGroupIcon = $('#change-group-icon'),
-			changeGroupName = $('#change-group-name'),
-			changeGroupDesc = $('#change-group-desc'),
-			changeGroupUserTitle = $('#change-group-user-title'),
-			changeGroupLabelColor = $('#change-group-label-color'),
-			groupIcon = $('#group-icon'),
-			groupLabelPreview = $('#group-label-preview'),
-			searchDelay;
-
-		// Tooltips
-		$('#groups-list .members li').tooltip();
-
-		createModal.on('keypress', function(e) {
-			switch(e.keyCode) {
-				case 13:
-					createModalGo.click();
-					break;
-				default:
-					break;
-			}
-		});
-
-		create.on('click', function() {
-			createModal.modal('show');
-			setTimeout(function() {
-				createGroupName.focus();
-			}, 250);
-		});
-
-		createModalGo.on('click', function() {
-			var submitObj = {
-					name: createGroupName.val(),
-					description: createGroupDesc.val()
-				},
-				errorText;
-
-			socket.emit('admin.groups.create', submitObj, function(err, data) {
-				if (err) {
-					switch (err) {
-						case 'group-exists':
-							errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>';
-							break;
-						case 'name-too-short':
-							errorText = '<strong>Please specify a group name</strong><p>A group name is required for administrative purposes.</p>';
-							break;
-						default:
-							errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>';
-							break;
-					}
-
-					createModalError.html(errorText).removeClass('hide');
-				} else {
-					createModalError.addClass('hide');
-					createGroupName.val('');
-					createModal.on('hidden.bs.modal', function() {
-						ajaxify.go('admin/groups');
-					});
-					createModal.modal('hide');
-				}
-			});
-		});
-
-		formEl.keypress(function(e) {
-			switch(e.keyCode) {
-				case 13:
-					detailsModalSave.click();
-					break;
-				default:
-					break;
-			}
-		});
-
-		changeGroupUserTitle.keydown(function() {
-			setTimeout(function() {
-				groupLabelPreview.text(changeGroupUserTitle.val());
-			}, 0);
-		});
-
-		changeGroupLabelColor.keydown(function() {
-			setTimeout(function() {
-				groupLabelPreview.css('background', changeGroupLabelColor.val() || '#000000');
-			}, 0);	
-		});
-
-		groupsList.on('click', 'button[data-action]', function() {
-			var el = $(this),
-				action = el.attr('data-action'),
-				groupName = el.parents('li[data-groupname]').attr('data-groupname');
-
-			switch (action) {
-			case 'delete':
-				bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) {
-					if (confirm) {
-						socket.emit('admin.groups.delete', groupName, function(err, data) {
-							if(err) {
-								return app.alertError(err.message);
-							}
-
-							ajaxify.go('admin/groups');
-						});
-					}
-				});
-				break;
-			case 'members':
-				socket.emit('admin.groups.get', groupName, function(err, groupObj) {
-
-					changeGroupName.val(groupObj.name).prop('readonly', groupObj.system);
-					changeGroupDesc.val(groupObj.description);
-					changeGroupUserTitle.val(groupObj.userTitle);
-					groupIcon.attr('class', 'fa fa-2x ' + groupObj.icon).attr('value', groupObj.icon);
-					changeGroupLabelColor.val(groupObj.labelColor);
-					groupLabelPreview.css('background', groupObj.labelColor || '#000000').text(groupObj.userTitle);
-					groupMembersEl.empty();
-
-					if (groupObj.members.length > 0) {
-						for (var x = 0; x < groupObj.members.length; x++) {
-							var memberIcon = $('<li />')
-								.attr('data-uid', groupObj.members[x].uid)
-								.append($('<img />').attr('src', groupObj.members[x].picture))
-								.append($('<span />').html(groupObj.members[x].username));
-							groupMembersEl.append(memberIcon);
-						}
-					}
-
-					groupDetailsModal.attr('data-groupname', groupObj.name);
-					groupDetailsModal.modal('show');
-				});
-				break;
-			}
-		});
-
-		groupDetailsSearch.on('keyup', function() {
-
-			if (searchDelay) {
-				clearTimeout(searchDelay);
-			}
-
-			searchDelay = setTimeout(function() {
-				var searchText = groupDetailsSearch.val(),
-					foundUser;
-
-				socket.emit('admin.user.search', searchText, function(err, results) {
-					if (!err && results && results.users.length > 0) {
-						var numResults = results.users.length, x;
-						if (numResults > 4) {
-							numResults = 4;
-						}
-
-						groupDetailsSearchResults.empty();
-						for (x = 0; x < numResults; x++) {
-							foundUser = $('<li />');
-							foundUser
-								.attr({title: results.users[x].username, 'data-uid': results.users[x].uid})
-								.append($('<img />').attr('src', results.users[x].picture))
-								.append($('<span />').html(results.users[x].username));
-
-							groupDetailsSearchResults.append(foundUser);
-						}
-					} else {
-						groupDetailsSearchResults.html('<li>No Users Found</li>');
-					}
-				});
-			}, 200);
-		});
-
-		groupDetailsSearchResults.on('click', 'li[data-uid]', function() {
-			var userLabel = $(this),
-				uid = parseInt(userLabel.attr('data-uid'), 10),
-				groupName = groupDetailsModal.attr('data-groupname'),
-				members = [];
-
-			groupMembersEl.find('li[data-uid]').each(function() {
-				members.push(parseInt($(this).attr('data-uid'), 10));
-			});
-
-			if (members.indexOf(uid) === -1) {
-				socket.emit('admin.groups.join', {
-					groupName: groupName,
-					uid: uid
-				}, function(err, data) {
-					if (!err) {
-						groupMembersEl.append(userLabel.clone(true));
-					}
-				});
-			}
-		});
-
-		groupMembersEl.on('click', 'li[data-uid]', function() {
-			var uid = $(this).attr('data-uid'),
-				groupName = groupDetailsModal.attr('data-groupname');
-
-			socket.emit('admin.groups.get', groupName, function(err, groupObj){
-				if (!err){
-					bootbox.confirm('Are you sure you want to remove this user?', function(confirm) {
-						if (confirm){
-							socket.emit('admin.groups.leave', {
-								groupName: groupName,
-								uid: uid
-							}, function(err, data) {
-								if (!err) {
-									groupMembersEl.find('li[data-uid="' + uid + '"]').remove();
-								}
-							});
-						}
-					});
-				}
-			});
-		});
-
-		changeGroupIcon.on('click', function() {
-			iconSelect.init(groupIcon);
-		});
-
-		admin.enableColorPicker(changeGroupLabelColor, function(hsb, hex) {
-			groupLabelPreview.css('background-color', '#' + hex);
-		});
-
-		detailsModalSave.on('click', function() {
-			socket.emit('admin.groups.update', {
-				groupName: groupDetailsModal.attr('data-groupname'),
-				values: {
-					name: changeGroupName.val(),
-					userTitle: changeGroupUserTitle.val(),
-					description: changeGroupDesc.val(),
-					icon: groupIcon.attr('value'),
-					labelColor: changeGroupLabelColor.val()
-				}
-			}, function(err) {
-				if (!err) {
-					groupDetailsModal.on('hidden.bs.modal', function() {
-						ajaxify.go('admin/groups');
-					});
-					groupDetailsModal.modal('hide');
-				}
-			});
-		});
-
-	};
-
-	return Groups;
-});
diff --git a/public/src/forum/admin/manage/tags.js b/public/src/forum/admin/manage/tags.js
deleted file mode 100644
index 97ba2bcd6a..0000000000
--- a/public/src/forum/admin/manage/tags.js
+++ /dev/null
@@ -1,110 +0,0 @@
-"use strict";
-/*global define, socket, app, admin, utils, bootbox, RELATIVE_PATH*/
-
-define('forum/admin/manage/tags', ['forum/infinitescroll', 'admin/selectable'], function(infinitescroll, selectable) {
-	var	Tags = {},
-		timeoutId = 0;
-
-	Tags.init = function() {
-		handleColorPickers();
-		selectable.enable('.tag-management', '.tag-row');
-
-		$('#tag-search').on('input propertychange', function() {
-			if (timeoutId) {
-				clearTimeout(timeoutId);
-				timeoutId = 0;
-			}
-
-			timeoutId = setTimeout(function() {
-				socket.emit('topics.searchAndLoadTags', {query: $('#tag-search').val()}, function(err, tags) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-
-					infinitescroll.parseAndTranslate('admin/manage/tags', 'tags', {tags: tags}, function(html) {
-						$('.tag-list').html(html);
-						utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-						timeoutId = 0;
-
-						selectable.enable('.tag-management', '.tag-row');
-					});
-				});
-			}, 100);
-		});
-
-		$('#modify').on('click', function(ev) {
-			var tagsToModify = $('.tag-row.selected');
-			if (!tagsToModify.length) {
-				return;
-			}
-
-			var firstTag = $(tagsToModify[0]),
-				title = tagsToModify.length > 1 ? 'Editing multiple tags' : 'Editing ' + firstTag.find('.tag-item').text() + ' tag';
-
-			bootbox.dialog({
-				title:  title,
-				message: firstTag.find('.tag-modal').html(),
-				buttons: {
-					success: {
-						label: "Save",
-						className: "btn-primary save",
-						callback: function() {
-							var modal = $('.bootbox'),
-								bgColor = modal.find('[data-name="bgColor"]').val(),
-								color = modal.find('[data-name="color"]').val();
-
-							tagsToModify.each(function(idx, tag) {
-								tag = $(tag);
-
-								tag.find('[data-name="bgColor"]').val(bgColor);
-								tag.find('[data-name="color"]').val(color);
-								tag.find('.tag-item').css('background-color', bgColor).css('color', color);
-
-								save(tag);
-							});
-						}
-					}
-				}
-			});
-
-			setTimeout(function() {
-				handleColorPickers();
-			}, 500); // bootbox made me do it.
-		});
-	};
-
-	function handleColorPickers() {
-		function enableColorPicker(idx, inputEl) {
-			var $inputEl = $(inputEl),
-				previewEl = $inputEl.parents('.tag-row').find('.tag-item');
-
-			admin.enableColorPicker($inputEl, function(hsb, hex) {
-				if ($inputEl.attr('data-name') === 'bgColor') {
-					previewEl.css('background-color', '#' + hex);
-				} else if ($inputEl.attr('data-name') === 'color') {
-					previewEl.css('color', '#' + hex);
-				}
-			});
-		}
-
-		$('[data-name="bgColor"], [data-name="color"]').each(enableColorPicker);
-	}
-
-	function save(tag) {
-		var data = {
-			tag: tag.attr('data-tag'),
-			bgColor : tag.find('[data-name="bgColor"]').val(),
-			color : tag.find('[data-name="color"]').val()
-		};
-		
-		socket.emit('admin.tags.update', data, function(err) {
-			if (err) {
-				return app.alertError(err.message);
-			}
-
-			app.alertSuccess('Tag Updated!');
-		});
-	}
-
-	return Tags;
-});
\ No newline at end of file
diff --git a/public/src/forum/admin/manage/users.js b/public/src/forum/admin/manage/users.js
deleted file mode 100644
index 26ccada4d6..0000000000
--- a/public/src/forum/admin/manage/users.js
+++ /dev/null
@@ -1,289 +0,0 @@
-"use strict";
-/* global socket, define, templates, bootbox, app, ajaxify,  */
-define('forum/admin/manage/users', ['admin/selectable'], function(selectable) {
-	var Users = {};
-
-	Users.init = function() {
-		var yourid = ajaxify.variables.get('yourid');
-
-		selectable.enable('#users-container', '.user-selectable');
-
-		function getSelectedUids() {
-			var uids = [];
-			$('#users-container .users-box .selected').each(function() {
-				uids.push($(this).parents('[data-uid]').attr('data-uid'));
-			});
-
-			return uids;
-		}
-
-		function update(className, state) {
-			$('#users-container .users-box .selected').siblings('.labels').find(className).each(function() {
-				$(this).toggleClass('hide', !state);
-			});
-		}
-
-		function unselectAll() {
-			$('#users-container .users-box .selected').removeClass('selected');
-		}
-
-		function removeSelected() {
-			$('#users-container .users-box .selected').remove();
-		}
-
-		function done(successMessage, className, flag) {
-			return function(err) {
-				if (err) {
-					return app.alertError(err.message);
-				}
-				app.alertSuccess(successMessage);
-				if (className) {
-					update(className, flag);
-				}
-				unselectAll();
-			};
-		}
-
-		$('.ban-user').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return false;
-			}
-
-			bootbox.confirm('Do you really want to ban?', function(confirm) {
-				if (confirm) {
-					socket.emit('admin.user.banUsers', uids, done('User(s) banned!', '.ban', true));
-				}
-			});
-			return false;
-		});
-
-		$('.unban-user').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			socket.emit('admin.user.unbanUsers', uids, done('User(s) unbanned!', '.ban', false));
-			return false;
-		});
-
-		$('.reset-lockout').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			socket.emit('admin.user.resetLockouts', uids, done('Lockout(s) reset!'));
-			return false;
-		});
-
-		$('.admin-user').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			if (uids.indexOf(yourid) !== -1) {
-				app.alertError('You can\'t remove yourself as Administrator!');
-			} else {
-				socket.emit('admin.user.makeAdmins', uids, done('User(s) are now administrators.', '.administrator', true));
-			}
-			return false;
-		});
-
-		$('.remove-admin-user').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			if (uids.indexOf(yourid.toString()) !== -1) {
-				app.alertError('You can\'t remove yourself as Administrator!');
-			} else {
-				bootbox.confirm('Do you really want to remove admins?', function(confirm) {
-					if (confirm) {
-						socket.emit('admin.user.removeAdmins', uids, done('User(s) are no longer administrators.', '.administrator', false));
-					}
-				});
-			}
-			return false;
-		});
-
-		$('.validate-email').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			bootbox.confirm('Do you want to validate email(s) of these user(s)?', function(confirm) {
-				if (confirm) {
-					socket.emit('admin.user.validateEmail', uids, done('Emails validated', '.notvalidated', false));
-				}
-			});
-			return false;
-		});
-
-		$('.delete-user').on('click', function() {
-			var uids = getSelectedUids();
-			if (!uids.length) {
-				return;
-			}
-
-			bootbox.confirm('<b>Warning!</b><br/>Do you really want to delete user(s)?<br/> This action is not reversable, all user data and content will be erased!', function(confirm) {
-				if (confirm) {
-					socket.emit('admin.user.deleteUsers', uids, function(err) {
-						if (err) {
-							return app.alertError(err.message);
-						}
-
-						app.alertSuccess('User(s) Deleted!');
-						removeSelected();
-						unselectAll();
-					});
-				}
-			});
-			return false;
-		});
-
-		function handleUserCreate() {
-			var errorEl = $('#create-modal-error');
-			$('#createUser').on('click', function() {
-				$('#create-modal').modal('show');
-				$('#create-modal form')[0].reset();
-				errorEl.addClass('hide');
-			});
-
-			$('#create-modal-go').on('click', function() {
-				var username = $('#create-user-name').val(),
-					email = $('#create-user-email').val(),
-					password = $('#create-user-password').val(),
-					passwordAgain = $('#create-user-password-again').val();
-
-
-				if(password !== passwordAgain) {
-					return errorEl.html('<strong>Error</strong><p>Passwords must match!</p>').removeClass('hide');
-				}
-
-				var user = {
-					username: username,
-					email: email,
-					password: password
-				};
-
-				socket.emit('admin.user.createUser', user, function(err) {
-					if(err) {
-						return errorEl.html('<strong>Error</strong><p>' + err.message + '</p>').removeClass('hide');
-					}
-					$('#create-modal').modal('hide');
-					$('#create-modal').on('hidden.bs.modal', function() {
-						ajaxify.go('admin/users');
-					});
-					app.alertSuccess('User created!');
-				});
-
-			});
-		}
-
-		var timeoutId = 0,
-			loadingMoreUsers = false;
-
-		var url = window.location.href,
-			parts = url.split('/'),
-			active = parts[parts.length - 1];
-
-		$('.nav-pills li').removeClass('active');
-		$('.nav-pills li a').each(function() {
-			var $this = $(this);
-			if ($this.attr('href').match(active)) {
-				$this.parent().addClass('active');
-				return false;
-			}
-		});
-
-		$('#search-user').on('keyup', function() {
-			if (timeoutId !== 0) {
-				clearTimeout(timeoutId);
-				timeoutId = 0;
-			}
-
-			timeoutId = setTimeout(function() {
-				var username = $('#search-user').val();
-
-				$('.fa-spinner').removeClass('hidden');
-
-				socket.emit('admin.user.search', username, function(err, data) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-
-					templates.parse('admin/manage/users', 'users', data, function(html) {
-						$('#users-container').html(html);
-
-						$('.fa-spinner').addClass('hidden');
-
-						if (data && data.users.length === 0) {
-							$('#user-notfound-notify').html('User not found!')
-								.show()
-								.addClass('label-danger')
-								.removeClass('label-success');
-						} else {
-							$('#user-notfound-notify').html(data.users.length + ' user' + (data.users.length > 1 ? 's' : '') + ' found! Search took ' + data.timing + ' ms.')
-								.show()
-								.addClass('label-success')
-								.removeClass('label-danger');
-						}
-
-						selectable.enable('#users-container', '.user-selectable');
-					});
-				});
-			}, 250);
-		});
-
-		handleUserCreate();
-
-		function onUsersLoaded(users) {
-			templates.parse('admin/manage/users', 'users', {users: users}, function(html) {
-				$('#users-container').append($(html));
-			});
-		}
-
-		function loadMoreUsers() {
-			var set = '';
-			if (active === 'latest') {
-				set = 'users:joindate';
-			} else if (active === 'sort-posts') {
-				set = 'users:postcount';
-			} else if (active === 'sort-reputation') {
-				set = 'users:reputation';
-			}
-
-			if (set) {
-				loadingMoreUsers = true;
-				socket.emit('user.loadMore', {
-					set: set,
-					after: $('#users-container').children().length
-				}, function(err, data) {
-					if (data && data.users.length) {
-						onUsersLoaded(data.users);
-					}
-					loadingMoreUsers = false;
-				});
-			}
-		}
-
-		$('#load-more-users-btn').on('click', loadMoreUsers);
-
-		$(window).off('scroll').on('scroll', function() {
-			var bottom = ($(document).height() - $(window).height()) * 0.9;
-
-			if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
-				loadMoreUsers();
-			}
-		});
-
-
-	};
-
-	return Users;
-});
diff --git a/public/src/forum/admin/settings.js b/public/src/forum/admin/settings.js
deleted file mode 100644
index a2c32f7f7f..0000000000
--- a/public/src/forum/admin/settings.js
+++ /dev/null
@@ -1,169 +0,0 @@
-"use strict";
-/*global define, app, socket, ajaxify, RELATIVE_PATH */
-
-define('forum/admin/settings', ['uploader', 'sounds'], function(uploader, sounds) {
-	var Settings = {};
-
-	Settings.init = function() {
-		Settings.prepare();
-	};
-
-	Settings.prepare = function(callback) {
-		// Come back in 125ms if the config isn't ready yet
-		if (!app.config) {
-			setTimeout(function() {
-				Settings.prepare(callback);
-			}, 125);
-			return;
-		}
-
-		// Populate the fields on the page from the config
-		var fields = $('#content [data-field]'),
-			numFields = fields.length,
-			saveBtn = $('#save'),
-			revertBtn = $('#revert'),
-			x, key, inputType, field;
-
-		for (x = 0; x < numFields; x++) {
-			field = fields.eq(x);
-			key = field.attr('data-field');
-			inputType = field.attr('type');
-			if (field.is('input')) {
-				if (app.config[key]) {
-					switch (inputType) {
-					case 'text':
-					case 'hidden':
-					case 'password':
-					case 'textarea':
-					case 'number':
-						field.val(app.config[key]);
-						break;
-
-					case 'checkbox':
-						field.prop('checked', parseInt(app.config[key], 10) === 1);
-						break;
-					}
-				}
-			} else if (field.is('textarea')) {
-				if (app.config[key]) {
-					field.val(app.config[key]);
-				}
-			} else if (field.is('select')) {
-				if (app.config[key]) {
-					field.val(app.config[key]);
-				}
-			}
-		}
-
-		revertBtn.off('click').on('click', function(e) {
-			ajaxify.refresh();
-		});
-
-		saveBtn.off('click').on('click', function(e) {
-			e.preventDefault();
-
-			saveFields(fields, function onFieldsSaved(err) {
-				if (err) {
-					return app.alert({
-						alert_id: 'config_status',
-						timeout: 2500,
-						title: 'Changes Not Saved',
-						message: 'NodeBB encountered a problem saving your changes',
-						type: 'danger'
-					});
-				}
-				app.alert({
-					alert_id: 'config_status',
-					timeout: 2500,
-					title: 'Changes Saved',
-					message: 'Your changes to the NodeBB configuration have been saved.',
-					type: 'success'
-				});
-			});
-		});
-
-		handleUploads();
-
-		$('button[data-action="email.test"]').off('click').on('click', function() {
-			socket.emit('admin.email.test', function(err) {
-				app.alert({
-					alert_id: 'test_email_sent',
-					type: !err ? 'info' : 'danger',
-					title: 'Test Email Sent',
-					message: err ? err.message : '',
-					timeout: 2500
-				});
-			});
-		});
-
-		if (typeof callback === 'function') {
-			callback();
-		}
-	};
-
-	function handleUploads() {
-		$('#content input[data-action="upload"]').each(function() {
-			var uploadBtn = $(this);
-			uploadBtn.on('click', function() {
-				uploader.open(uploadBtn.attr('data-route'), {}, 0, function(image) {
-					$('#' + uploadBtn.attr('data-target')).val(image);
-				});
-
-				uploader.hideAlerts();
-			});
-		});
-	}
-
-	Settings.remove = function(key) {
-		socket.emit('admin.config.remove', key);
-	};
-
-	function saveFields(fields, callback) {
-		var data = {};
-
-		fields.each(function() {
-			var field = $(this);
-			var key = field.attr('data-field'),
-				value, inputType;
-
-			if (field.is('input')) {
-				inputType = field.attr('type');
-				switch (inputType) {
-				case 'text':
-				case 'password':
-				case 'hidden':
-				case 'textarea':
-				case 'number':
-					value = field.val();
-					break;
-
-				case 'checkbox':
-					value = field.prop('checked') ? '1' : '0';
-					break;
-				}
-			} else if (field.is('textarea') || field.is('select')) {
-				value = field.val();
-			}
-
-			data[key] = value;
-		});
-
-		socket.emit('admin.config.setMultiple', data, function(err) {
-			if (err) {
-				return callback(err);
-			}
-
-			if (app.config) {
-				for(var field in data) {
-					if (data.hasOwnProperty(field)) {
-						app.config[field] = data[field];
-					}
-				}
-			}
-
-			callback();
-		});
-	}
-
-	return Settings;
-});
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
deleted file mode 100644
index 30bcf629f1..0000000000
--- a/public/src/forum/category.js
+++ /dev/null
@@ -1,351 +0,0 @@
-"use strict";
-/* global define, config, templates, app, utils, ajaxify, socket, translator */
-
-define('forum/category', ['composer', 'forum/pagination', 'forum/infinitescroll', 'share', 'navigator', 'forum/categoryTools'], function(composer, pagination, infinitescroll, share, navigator, categoryTools) {
-	var Category = {};
-
-	$(window).on('action:ajaxify.start', function(ev, data) {
-		if(data && data.url.indexOf('category') !== 0) {
-			navigator.hide();
-
-			removeListeners();
-		}
-	});
-
-	function removeListeners() {
-		socket.removeListener('event:new_topic', Category.onNewTopic);
-		categoryTools.removeListeners();
-	}
-
-	Category.init = function() {
-		var	cid = ajaxify.variables.get('category_id');
-
-		app.enterRoom('category_' + cid);
-
-		share.addShareHandlers(ajaxify.variables.get('category_name'));
-
-		$('#new_post').on('click', function () {
-			composer.newTopic(cid);
-		});
-
-		socket.on('event:new_topic', Category.onNewTopic);
-
-		categoryTools.init(cid);
-
-		enableInfiniteLoadingOrPagination();
-
-		if (!config.usePagination) {
-			navigator.init('#topics-container > .category-item', ajaxify.variables.get('topic_count'), Category.toTop, Category.toBottom, Category.navigatorCallback);
-		}
-
-		$('#topics-container').on('click', '.topic-title', function() {
-			var clickedTid = $(this).parents('li.category-item[data-tid]').attr('data-tid');
-			$('#topics-container li.category-item').each(function(index, el) {
-				if($(el).offset().top - $(window).scrollTop() > 0) {
-					localStorage.setItem('category:' + cid + ':bookmark', $(el).attr('data-tid'));
-					localStorage.setItem('category:' + cid + ':bookmark:clicked', clickedTid);
-					return false;
-				}
-			});
-		});
-
-		handleIgnoreWatch(cid);
-	};
-
-	function handleIgnoreWatch(cid) {
-		$('.watch, .ignore').on('click', function() {
-			var $this = $(this);
-			var command = $this.hasClass('watch') ? 'watch' : 'ignore';
-
-			socket.emit('categories.' + command, cid, function(err) {
-				if (err) {
-					return app.alertError(err.message);
-				}
-
-				$('.watch').toggleClass('hidden', command === 'watch');
-				$('.ignore').toggleClass('hidden', command === 'ignore');
-			});
-		});
-	}
-
-	Category.toTop = function() {
-		navigator.scrollTop(0);
-	};
-
-	Category.toBottom = function() {
-		socket.emit('categories.lastTopicIndex', ajaxify.variables.get('category_id'), function(err, index) {
-			navigator.scrollBottom(index);
-		});
-	};
-
-	Category.navigatorCallback = function(element, elementCount) {
-		return parseInt(element.attr('data-index'), 10) + 1;
-	};
-
-	$(window).on('action:popstate', function(ev, data) {
-		if(data.url.indexOf('category/') === 0) {
-			var cid = data.url.match(/^category\/(\d+)/);
-			if (cid && cid[1]) {
-				cid = cid[1];
-			}
-			if (!cid) {
-				return;
-			}
-
-			var bookmark = localStorage.getItem('category:' + cid + ':bookmark');
-			var clicked = localStorage.getItem('category:' + cid + ':bookmark:clicked');
-
-			if (!bookmark) {
-				return;
-			}
-
-			if(config.usePagination) {
-				socket.emit('topics.getTidPage', bookmark, function(err, page) {
-					if (err) {
-						return;
-					}
-					if(parseInt(page, 10) !== pagination.currentPage) {
-						pagination.loadPage(page);
-					} else {
-						Category.scrollToTopic(bookmark, clicked, 400);
-					}
-				});
-			} else {
-				socket.emit('topics.getTidIndex', bookmark, function(err, index) {
-					if (err) {
-						return;
-					}
-
-					if (index === 0) {
-						Category.highlightTopic(clicked);
-						return;
-					}
-
-					if (index < 0) {
-						index = 0;
-					}
-
-					$('#topics-container').empty();
-
-					loadTopicsAfter(index, function() {
-						Category.scrollToTopic(bookmark, clicked, 0);
-					});
-				});
-			}
-		}
-	});
-
-	Category.highlightTopic = function(tid) {
-		var highlight = $('#topics-container li.category-item[data-tid="' + tid + '"]');
-		if(highlight.length && !highlight.hasClass('highlight')) {
-			highlight.addClass('highlight');
-			setTimeout(function() {
-				highlight.removeClass('highlight');
-			}, 5000);
-		}
-	};
-
-	Category.scrollToTopic = function(tid, clickedTid, duration, offset) {
-		if(!tid) {
-			return;
-		}
-
-		if(!offset) {
-			offset = 0;
-		}
-
-		if($('#topics-container li.category-item[data-tid="' + tid + '"]').length) {
-			var	cid = ajaxify.variables.get('category_id');
-			var scrollTo = $('#topics-container li.category-item[data-tid="' + tid + '"]');
-
-			if (cid && scrollTo.length) {
-				$('html, body').animate({
-					scrollTop: (scrollTo.offset().top - $('#header-menu').height() - offset) + 'px'
-				}, duration !== undefined ? duration : 400, function() {
-					Category.highlightTopic(clickedTid);
-					navigator.update();
-				});
-			}
-		}
-	};
-
-	function enableInfiniteLoadingOrPagination() {
-		if (!config.usePagination) {
-			infinitescroll.init(Category.loadMoreTopics);
-		} else {
-			navigator.hide();
-			pagination.init(ajaxify.variables.get('currentPage'), ajaxify.variables.get('pageCount'));
-		}
-	}
-
-	Category.onNewTopic = function(topic) {
-		$(window).trigger('filter:categories.new_topic', topic);
-
-		ajaxify.loadTemplate('category', function(categoryTemplate) {
-			var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), {
-				privileges: {editable: !!$('.thread-tools').length},
-				topics: [topic]
-			});
-
-			translator.translate(html, function(translatedHTML) {
-				var topic = $(translatedHTML),
-					container = $('#topics-container'),
-					topics = $('#topics-container').children('.category-item'),
-					numTopics = topics.length;
-
-				$('#topics-container, .category-sidebar').removeClass('hidden');
-
-				var noTopicsWarning = $('#category-no-topics');
-				if (noTopicsWarning.length) {
-					noTopicsWarning.remove();
-					ajaxify.widgets.render('category', window.location.pathname.slice(1));
-				}
-
-				if (numTopics > 0) {
-					for (var x = 0; x < numTopics; x++) {
-						var pinned = $(topics[x]).hasClass('pinned');
-						if (pinned) {
-							if(x === numTopics - 1) {
-								topic.insertAfter(topics[x]);
-							}
-							continue;
-						}
-						topic.insertBefore(topics[x]);
-						break;
-					}
-				} else {
-					container.append(topic);
-				}
-
-				topic.hide().fadeIn('slow');
-
-				socket.emit('categories.getPageCount', ajaxify.variables.get('category_id'), function(err, newPageCount) {
-					pagination.recreatePaginationLinks(newPageCount);
-				});
-
-				topic.find('span.timeago').timeago();
-				app.createUserTooltips();
-				updateTopicCount();
-
-				$(window).trigger('action:categories.new_topic.loaded');
-			});
-		});
-	};
-
-	function updateTopicCount() {
-		socket.emit('categories.getTopicCount', ajaxify.variables.get('category_id'), function(err, topicCount) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-			navigator.setCount(topicCount);
-		});
-	}
-
-	Category.onTopicsLoaded = function(data, callback) {
-		if(!data || !data.topics.length) {
-			return;
-		}
-
-		function removeAlreadyAddedTopics(topics) {
-			return topics.filter(function(topic) {
-				return $('#topics-container li[data-tid="' + topic.tid +'"]').length === 0;
-			});
-		}
-
-		var after = null,
-			before = null;
-
-		function findInsertionPoint() {
-			if (!$('#topics-container .category-item[data-tid]').length) {
-				return;
-			}
-			var last = $('#topics-container .category-item[data-tid]').last();
-			var lastIndex = last.attr('data-index');
-			var firstIndex = data.topics[data.topics.length - 1].index;
-			if (firstIndex > lastIndex) {
-				after = last;
-			} else {
-				before = $('#topics-container .category-item[data-tid]').first();
-			}
-		}
-
-		data.topics = removeAlreadyAddedTopics(data.topics);
-		if(!data.topics.length) {
-			return;
-		}
-
-		findInsertionPoint();
-
-		ajaxify.loadTemplate('category', function(categoryTemplate) {
-			var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), data);
-
-			translator.translate(html, function(translatedHTML) {
-				var container = $('#topics-container'),
-					html = $(translatedHTML);
-
-				$('#topics-container, .category-sidebar').removeClass('hidden');
-				$('#category-no-topics').remove();
-
-				if(config.usePagination) {
-					container.empty().append(html);
-				} else {
-					if(after) {
-						html.insertAfter(after);
-					} else if(before) {
-						html.insertBefore(before);
-					} else {
-						container.append(html);
-					}
-				}
-
-				if (typeof callback === 'function') {
-					callback();
-				}
-				html.find('span.timeago').timeago();
-				app.createUserTooltips();
-				utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			});
-		});
-	};
-
-	Category.loadMoreTopics = function(direction) {
-		if (!$('#topics-container').length || !$('#topics-container').children().length) {
-			return;
-		}
-
-		infinitescroll.calculateAfter(direction, '#topics-container .category-item[data-tid]', config.topicsPerPage, false, function(after, offset, el) {
-			loadTopicsAfter(after, function() {
-				if (direction < 0 && el) {
-					Category.scrollToTopic(el.attr('data-tid'), null, 0, offset);
-				}
-			});
-		});
-	};
-
-	function loadTopicsAfter(after, callback) {
-		if(!utils.isNumber(after) || (after === 0 && $('#topics-container li.category-item[data-index="0"]').length)) {
-			return;
-		}
-
-		$(window).trigger('action:categories.loading');
-		infinitescroll.loadMore('categories.loadMore', {
-			cid: ajaxify.variables.get('category_id'),
-			after: after
-		}, function (data, done) {
-
-			if (data.topics && data.topics.length) {
-				Category.onTopicsLoaded(data, function() {
-					done();
-					callback();
-				});
-				$('#topics-container').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-
-			$(window).trigger('action:categories.loaded');
-		});
-	}
-
-	return Category;
-});
diff --git a/public/src/forum/categoryTools.js b/public/src/forum/categoryTools.js
deleted file mode 100644
index 620b3af8b0..0000000000
--- a/public/src/forum/categoryTools.js
+++ /dev/null
@@ -1,205 +0,0 @@
-
-'use strict';
-
-/* globals define, app, translator, socket, bootbox, ajaxify */
-
-
-define('forum/categoryTools', ['forum/topic/move', 'topicSelect'], function(move, topicSelect) {
-
-	var CategoryTools = {};
-
-	CategoryTools.init = function(cid) {
-		CategoryTools.cid = cid;
-
-		topicSelect.init(onTopicSelect);
-
-		$('.delete_thread').on('click', function(e) {
-			var tids = topicSelect.getSelectedTids();
-			categoryCommand(isAny(isTopicDeleted, tids) ? 'restore' : 'delete', tids);
-			return false;
-		});
-
-		$('.purge_thread').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-			categoryCommand('purge', tids);
-			return false;
-		});
-
-		$('.lock_thread').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-			if (tids.length) {
-				socket.emit(isAny(isTopicLocked, tids) ? 'topics.unlock' : 'topics.lock', {tids: tids, cid: CategoryTools.cid}, onCommandComplete);
-			}
-			return false;
-		});
-
-		$('.pin_thread').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-			if (tids.length) {
-				socket.emit(isAny(isTopicPinned, tids) ? 'topics.unpin' : 'topics.pin', {tids: tids, cid: CategoryTools.cid}, onCommandComplete);
-			}
-			return false;
-		});
-
-		$('.markAsUnreadForAll').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-			if (tids.length) {
-				socket.emit('topics.markAsUnreadForAll', tids, function(err) {
-					if(err) {
-						return app.alertError(err.message);
-					}
-					app.alertSuccess('[[topic:markAsUnreadForAll.success]]');
-
-					onCommandComplete();
-				});
-			}
-
-			return false;
-		});
-
-		$('.move_thread').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-
-			if (tids.length) {
-				move.init(tids, cid, onCommandComplete);
-			}
-			return false;
-		});
-
-		$('.move_all_threads').on('click', function() {
-			move.init(null, cid, function(err) {
-				ajaxify.refresh();
-			});
-		});
-
-
-		socket.on('event:topic_deleted', setDeleteState);
-		socket.on('event:topic_restored', setDeleteState);
-		socket.on('event:topic_purged', onTopicPurged);
-		socket.on('event:topic_locked', setLockedState);
-		socket.on('event:topic_unlocked', setLockedState);
-		socket.on('event:topic_pinned', setPinnedState);
-		socket.on('event:topic_unpinned', setPinnedState);
-		socket.on('event:topic_moved', onTopicMoved);
-	};
-
-	function categoryCommand(command, tids) {
-		if (!tids.length) {
-			return;
-		}
-
-		translator.translate('[[topic:thread_tools.' + command + '_confirm]]', function(msg) {
-			bootbox.confirm(msg, function(confirm) {
-				if (!confirm) {
-					return;
-				}
-
-				socket.emit('topics.' + command, {tids: tids, cid: CategoryTools.cid}, onCommandComplete);
-			});
-		});
-	}
-
-	CategoryTools.removeListeners = function() {
-		socket.removeListener('event:topic_deleted', setDeleteState);
-		socket.removeListener('event:topic_restored', setDeleteState);
-		socket.removeListener('event:topic_purged', onTopicPurged);
-		socket.removeListener('event:topic_locked', setLockedState);
-		socket.removeListener('event:topic_unlocked', setLockedState);
-		socket.removeListener('event:topic_pinned', setPinnedState);
-		socket.removeListener('event:topic_unpinned', setPinnedState);
-		socket.removeListener('event:topic_moved', onTopicMoved);
-	};
-
-	function closeDropDown() {
-		$('.thread-tools.open').find('.dropdown-toggle').trigger('click');
-	}
-
-	function onCommandComplete(err) {
-		if (err) {
-			return app.alertError(err.message);
-		}
-		closeDropDown();
-		topicSelect.unselectAll();
-	}
-
-	function onTopicSelect() {
-		var tids = topicSelect.getSelectedTids();
-		var isAnyDeleted = isAny(isTopicDeleted, tids);
-		var areAllDeleted = areAll(isTopicDeleted, tids);
-		var isAnyPinned = isAny(isTopicPinned, tids);
-		var isAnyLocked = isAny(isTopicLocked, tids);
-
-		$('.delete_thread span').translateHtml('<i class="fa fa-fw ' + (isAnyDeleted ? 'fa-history' : 'fa-trash-o') + '"></i> [[topic:thread_tools.' + (isAnyDeleted ? 'restore' : 'delete') + ']]');
-		$('.pin_thread').translateHtml('<i class="fa fa-fw fa-thumb-tack"></i> [[topic:thread_tools.' + (isAnyPinned ? 'unpin' : 'pin') + ']]');
-		$('.lock_thread').translateHtml('<i class="fa fa-fw fa-' + (isAnyLocked ? 'un': '') + 'lock"></i> [[topic:thread_tools.' + (isAnyLocked ? 'un': '') + 'lock]]');
-		$('.purge_thread').toggleClass('hidden', !areAllDeleted);
-	}
-
-	function isAny(method, tids) {
-		for(var i=0; i<tids.length; ++i) {
-			if(method(tids[i])) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	function areAll(method, tids) {
-		for(var i=0; i<tids.length; ++i) {
-			if(!method(tids[i])) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	function isTopicDeleted(tid) {
-		return getTopicEl(tid).hasClass('deleted');
-	}
-
-	function isTopicLocked(tid) {
-		return getTopicEl(tid).hasClass('locked');
-	}
-
-	function isTopicPinned(tid) {
-		return getTopicEl(tid).hasClass('pinned');
-	}
-
-	function getTopicEl(tid) {
-		return $('#topics-container li[data-tid="' + tid + '"]');
-	}
-
-	function setDeleteState(data) {
-		var topic = getTopicEl(data.tid);
-		topic.toggleClass('deleted', data.isDeleted);
-		topic.find('.fa-lock').toggleClass('hide', !data.isDeleted);
-	}
-
-	function setPinnedState(data) {
-		var topic = getTopicEl(data.tid);
-		topic.toggleClass('pinned', data.isPinned);
-		topic.find('.fa-thumb-tack').toggleClass('hide', !data.isPinned);
-		ajaxify.refresh();
-	}
-
-	function setLockedState(data) {
-		var topic = getTopicEl(data.tid);
-		topic.toggleClass('locked', data.isLocked);
-		topic.find('.fa-lock').toggleClass('hide', !data.isLocked);
-	}
-
-	function onTopicMoved(data) {
-		getTopicEl(data.tid).remove();
-	}
-
-	function onTopicPurged(tids) {
-		if (!tids) {
-			return;
-		}
-		for(var i=0; i<tids.length; ++i) {
-			getTopicEl(tids[i]).remove();
-		}
-	}
-
-	return CategoryTools;
-});
diff --git a/public/src/forum/chats.js b/public/src/forum/chats.js
deleted file mode 100644
index aa1af729b3..0000000000
--- a/public/src/forum/chats.js
+++ /dev/null
@@ -1,275 +0,0 @@
-'use strict';
-
-/* globals define, app, ajaxify, utils, socket, templates */
-
-define('forum/chats', ['string', 'sounds', 'forum/infinitescroll'], function(S, sounds, infinitescroll) {
-	var Chats = {
-		initialised: false
-	};
-
-	var newMessage = false;
-
-	Chats.init = function() {
-		var containerEl = $('.expanded-chat ul');
-
-		if (!Chats.initialised) {
-			Chats.addSocketListeners();
-			Chats.addGlobalEventListeners();
-		}
-
-		Chats.addEventListeners();
-		Chats.resizeMainWindow();
-		Chats.scrollToBottom(containerEl);
-		Chats.setActive();
-
-		Chats.initialised = true;
-	};
-
-	Chats.getRecipientUid = function() {
-		return parseInt($('.expanded-chat').attr('data-uid'), 10);
-	};
-
-	Chats.isCurrentChat = function(uid) {
-		return Chats.getRecipientUid() === parseInt(uid, 10);
-	};
-
-	Chats.addEventListeners = function() {
-		var inputEl = $('.chat-input'),
-			sendEl = $('.expanded-chat button[data-action="send"]'),
-			popoutEl = $('[data-action="pop-out"]');
-
-		$('.chats-list').on('click', 'li', function(e) {
-			ajaxify.go('chats/' + utils.slugify($(this).attr('data-username')));
-		});
-
-		inputEl.on('keypress', function(e) {
-			if(e.which === 13) {
-				Chats.sendMessage(Chats.getRecipientUid(), inputEl);
-			}
-		});
-
-		inputEl.on('keyup', function() {
-			var val = !!$(this).val();
-			if ((val && $(this).attr('data-typing') === 'true') || (!val && $(this).attr('data-typing') === 'false')) {
-				return;
-			}
-
-			Chats.notifyTyping(Chats.getRecipientUid(), val);
-			$(this).attr('data-typing', val);
-		});
-
-		sendEl.on('click', function(e) {
-			Chats.sendMessage(Chats.getRecipientUid(), inputEl);
-			return false;
-		});
-
-		popoutEl.on('click', function() {
-			var	username = $('.expanded-chat').attr('data-username'),
-				uid = Chats.getRecipientUid();
-
-			if (app.previousUrl && app.previousUrl.match(/chats/)) {
-				ajaxify.go('chats', function() {
-					app.openChat(username, uid);
-				}, true);
-			} else {
-				window.history.go(-1);
-			}
-		});
-
-		$('.recent-chats').on('scroll', function() {
-			var $this = $(this);
-			var bottom = ($this[0].scrollHeight - $this.height()) * 0.9;
-			if ($this.scrollTop() > bottom) {
-				loadMoreRecentChats();
-			}
-		});
-
-		$('.expanded-chat [data-since]').on('click', function() {
-			var since = $(this).attr('data-since');
-			$('.expanded-chat [data-since]').removeClass('selected');
-			$(this).addClass('selected');
-			loadChatSince(since);
-			return false;
-		});
-	};
-
-	function loadChatSince(since) {
-		var uid = Chats.getRecipientUid();
-		if (!uid) {
-			return;
-		}
-		socket.emit('modules.chats.get', {touid: uid, since: since}, function(err, messages) {
-			var chatContent = $('.expanded-chat .chat-content');
-			chatContent.find('.chat-message').remove();
-			Chats.parseMessage(messages, onMessagesParsed);
-		});
-	}
-
-	Chats.addGlobalEventListeners = function() {
-		$(window).on('resize', Chats.resizeMainWindow);
-		$(window).on('mousemove keypress click', function() {
-			if (newMessage) {
-				var recipientUid = Chats.getRecipientUid();
-				if (recipientUid) {
-					socket.emit('modules.chats.markRead', recipientUid);
-					newMessage = false;
-				}
-			}
-		});
-	};
-
-	function onMessagesParsed(html) {
-		var newMessage = $(html);
-		newMessage.insertBefore($('.user-typing'));
-		newMessage.find('span.timeago').timeago();
-		newMessage.find('img:not(".chat-user-image")').addClass('img-responsive');
-		Chats.scrollToBottom($('.expanded-chat .chat-content'));
-	}
-
-	Chats.addSocketListeners = function() {
-		socket.on('event:chats.receive', function(data) {
-			var typingNotifEl = $('.user-typing'),
-				containerEl = $('.expanded-chat ul');
-
-			if (Chats.isCurrentChat(data.withUid)) {
-				newMessage = data.self === 0;
-				data.message.self = data.self;
-				Chats.parseMessage(data.message, onMessagesParsed);
-			} else {
-				$('.chats-list li[data-uid="' + data.withUid + '"]').addClass('unread');
-				app.alternatingTitle('[[modules:chat.user_has_messaged_you, ' + data.message.fromUser.username + ']]');
-			}
-		});
-
-		socket.on('event:chats.userStartTyping', function(withUid) {
-			var typingNotifEl = $('.user-typing');
-
-			if (Chats.isCurrentChat(withUid)) {
-				typingNotifEl.removeClass('hide');
-			}
-
-			$('.chats-list li[data-uid="' + withUid + '"]').addClass('typing');
-		});
-
-		socket.on('event:chats.userStopTyping', function(withUid) {
-			var typingNotifEl = $('.user-typing');
-
-			if (Chats.isCurrentChat(withUid)) {
-				typingNotifEl.addClass('hide');
-			}
-
-			$('.chats-list li[data-uid="' + withUid + '"]').removeClass('typing');
-		});
-
-		socket.on('event:user_status_change', function(data) {
-			var userEl = $('.chats-list li[data-uid="' + data.uid +'"]');
-
-			if (userEl.length) {
-				var statusEl = userEl.find('.status');
-				translator.translate('[[global:' + data.status + ']]', function(translated) {
-					statusEl.attr('class', 'fa fa-circle status ' + data.status)
-						.attr('title', translated)
-						.attr('data-original-title', translated);
-				});
-			}
-		});
-	};
-
-	Chats.resizeMainWindow = function() {
-		var	messagesList = $('.expanded-chat ul');
-
-		if (messagesList.length) {
-			var	margin = $('.expanded-chat ul').outerHeight(true) - $('.expanded-chat ul').height(),
-				inputHeight = $('.chat-input').outerHeight(true),
-				fromTop = messagesList.offset().top;
-
-			messagesList.height($(window).height() - (fromTop + inputHeight + (margin * 4)));
-		}
-	};
-
-	Chats.notifyTyping = function(toUid, typing) {
-		socket.emit('modules.chats.user' + (typing ? 'Start' : 'Stop') + 'Typing', {
-			touid: toUid,
-			fromUid: app.uid
-		});
-	};
-
-	Chats.sendMessage = function(toUid, inputEl) {
-		var msg = S(inputEl.val()).stripTags().s;
-		if (msg.length) {
-			msg = msg +'\n';
-			socket.emit('modules.chats.send', {
-				touid:toUid,
-				message:msg
-			});
-			inputEl.val('');
-			sounds.play('chat-outgoing');
-			Chats.notifyTyping(toUid, false);
-		}
-	};
-
-	Chats.scrollToBottom = function(containerEl) {
-		if (containerEl.length) {
-			containerEl.scrollTop(
-				containerEl[0].scrollHeight - containerEl.height()
-			);
-		}
-	};
-
-	Chats.setActive = function() {
-		var recipientUid = Chats.getRecipientUid();
-		if (recipientUid) {
-			socket.emit('modules.chats.markRead', recipientUid);
-			$('.expanded-chat input').focus();
-		}
-		$('.chats-list li').removeClass('bg-primary');
-		$('.chats-list li[data-uid="' + recipientUid + '"]').addClass('bg-primary');
-	};
-
-	Chats.parseMessage = function(data, callback) {
-		templates.parse('partials/chat_message' + (Array.isArray(data) ? 's' : ''), {
-			messages: data
-		}, callback);
-	};
-
-	function loadMoreRecentChats() {
-		var recentChats = $('.recent-chats');
-		if (recentChats.attr('loading')) {
-			return;
-		}
-		recentChats.attr('loading', 1);
-		socket.emit('modules.chats.getRecentChats', {
-			after: recentChats.attr('data-nextstart')
-		}, function(err, data) {
-			if (err) {
-				return app.alertError(err.message);
-			}
-
-			if (data && data.users.length) {
-				onRecentChatsLoaded(data.users, function() {
-					recentChats.removeAttr('loading');
-					recentChats.attr('data-nextstart', data.nextStart);
-				});
-			} else {
-				recentChats.removeAttr('loading');
-			}
-		});
-	}
-
-	function onRecentChatsLoaded(users, callback) {
-		users = users.filter(function(user) {
-			return !$('.recent-chats li[data-uid=' + user.uid + ']').length;
-		});
-
-		if (!users.length) {
-			return callback();
-		}
-
-		infinitescroll.parseAndTranslate('chats', 'chats', {chats: users}, function(html) {
-			$('.recent-chats').append(html);
-			callback();
-		});
-	}
-
-	return Chats;
-});
diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js
deleted file mode 100644
index 775686aaa2..0000000000
--- a/public/src/forum/footer.js
+++ /dev/null
@@ -1,69 +0,0 @@
-define('forum/footer', ['notifications', 'chat'], function(Notifications, Chat) {
-
-	Notifications.prepareDOM();
-	Chat.prepareDOM();
-	translator.prepareDOM();
-
-	function updateUnreadTopicCount(err, count) {
-		if (err) {
-			return console.warn('Error updating unread count', err);
-		}
-
-		$('#unread-count')
-			.toggleClass('unread-count', count > 0)
-			.attr('data-content', count > 20 ? '20+' : count);
-	}
-
-	function updateUnreadChatCount(err, count) {
-		if (err) {
-			return console.warn('Error updating unread count', err);
-		}
-
-		$('#chat-count')
-			.toggleClass('unread-count', count > 0)
-			.attr('data-content', count > 20 ? '20+' : count);
-	}
-
-	function initUnreadTopics() {
-		var unreadTopics = {};
-
-		function onNewPost(data) {
-			if (data && data.posts && data.posts.length) {
-				var post = data.posts[0];
-
-				if (parseInt(post.uid, 10) !== parseInt(app.uid, 10) && !unreadTopics[post.topic.tid]) {
-					increaseUnreadCount();
-					markTopicsUnread(post.topic.tid);
-					unreadTopics[post.topic.tid] = true;
-				}
-			}
-		}
-
-		function increaseUnreadCount() {
-			var count = parseInt($('#unread-count').attr('data-content'), 10) + 1;
-			updateUnreadTopicCount(null, count);
-		}
-
-		function markTopicsUnread(tid) {
-			$('[data-tid="' + tid + '"]').addClass('unread');
-		}
-
-		$(window).on('action:ajaxify.end', function(ev, data) {
-			var tid = data.url.match(/^topic\/(\d+)/);
-
-			if (tid && tid[1]) {
-				delete unreadTopics[tid[1]];
-			}
-		});
-
-		socket.on('event:new_post', onNewPost);
-	}
-
-	socket.on('event:unread.updateCount', updateUnreadTopicCount);
-	socket.emit('user.getUnreadCount', updateUnreadTopicCount);
-
-	socket.on('event:unread.updateChatCount', updateUnreadChatCount);
-	socket.emit('user.getUnreadChatCount', updateUnreadChatCount);
-
-	initUnreadTopics();
-});
diff --git a/public/src/forum/groups/details.js b/public/src/forum/groups/details.js
deleted file mode 100644
index cbdc3cffa0..0000000000
--- a/public/src/forum/groups/details.js
+++ /dev/null
@@ -1,16 +0,0 @@
-"use strict";
-
-define('forum/groups/details', function() {
-	var Details = {};
-
-	Details.init = function() {
-		var	memberListEl = $('.groups.details .members');
-
-		memberListEl.on('click', '[data-slug]', function() {
-			var	slug = this.getAttribute('data-slug');
-			ajaxify.go('user/' + slug);
-		});
-	};
-
-	return Details;
-});
\ No newline at end of file
diff --git a/public/src/forum/home.js b/public/src/forum/home.js
deleted file mode 100644
index ae52d240c0..0000000000
--- a/public/src/forum/home.js
+++ /dev/null
@@ -1,77 +0,0 @@
-'use strict';
-
-/* globals define, socket, app, templates, translator, ajaxify*/
-
-define('forum/home', function() {
-	var	home = {};
-
-	$(window).on('action:ajaxify.start', function(ev, data) {
-		if (data.url !== '') {
-			socket.removeListener('event:new_post', home.onNewPost);
-		}
-	});
-
-
-	home.init = function() {
-		app.enterRoom('home');
-
-		socket.removeListener('event:new_post', home.onNewPost);
-		socket.on('event:new_post', home.onNewPost);
-
-		$('.home .category-header').tooltip({
-			placement: 'bottom'
-		});
-	};
-
-	home.onNewPost = function(data) {
-		if (data && data.posts && data.posts.length && data.posts[0].topic) {
-			renderNewPost(data.posts[0].topic.cid, data.posts[0]);
-		}
-	};
-
-	function renderNewPost(cid, post) {
-		var category = $('.home .category-item[data-cid="' + cid + '"]');
-		var categoryBox = category.find('.category-box');
-		var numRecentReplies = category.attr('data-numRecentReplies');
-		if (!numRecentReplies || !parseInt(numRecentReplies, 10)) {
-			return;
-		}
-
-		var recentPosts = categoryBox.find('.post-preview');
-		var insertBefore = recentPosts.first();
-
-		parseAndTranslate([post], function(html) {
-			html.hide();
-			if(recentPosts.length === 0) {
-				html.appendTo(categoryBox);
-			} else {
-				html.insertBefore(recentPosts.first());
-			}
-
-			html.fadeIn();
-
-			app.createUserTooltips();
-
-			if (categoryBox.find('.post-preview').length > parseInt(numRecentReplies, 10)) {
-				recentPosts.last().remove();
-			}
-
-			$(window).trigger('action:posts.loaded');
-		});
-	}
-
-	function parseAndTranslate(posts, callback) {
-		ajaxify.loadTemplate('home', function(homeTemplate) {
-			var html = templates.parse(templates.getBlock(homeTemplate, 'posts'), {categories: {posts: posts}});
-
-			translator.translate(html, function(translatedHTML) {
-				translatedHTML = $(translatedHTML);
-				translatedHTML.find('img').addClass('img-responsive');
-				translatedHTML.find('span.timeago').timeago();
-				callback(translatedHTML);
-			});
-		});
-	}
-
-	return home;
-});
diff --git a/public/src/forum/infinitescroll.js b/public/src/forum/infinitescroll.js
deleted file mode 100644
index 6f527f1fa3..0000000000
--- a/public/src/forum/infinitescroll.js
+++ /dev/null
@@ -1,92 +0,0 @@
-'use strict';
-
-/* globals define, socket, ajaxify, translator, templates, app */
-
-define('forum/infinitescroll', function() {
-
-	var scroll = {};
-	var callback;
-	var previousScrollTop = 0;
-	var loadingMore	= false;
-	var topOffset = 0;
-
-	scroll.init = function(cb, _topOffest) {
-		callback = cb;
-		topOffset = _topOffest || 0;
-		$(window).off('scroll', onScroll).on('scroll', onScroll);
-
-		// if ($(document).height() === $(window).height()) {
-		// 	callback(1);
-		// }
-	};
-
-	function onScroll() {
-		var originalPostEl = $('li[data-index="0"]'),
-			top = $(window).height() * 0.15 + topOffset + (originalPostEl ? originalPostEl.outerHeight() : 0),
-			bottom = ($(document).height() - $(window).height()) * 0.85,
-			currentScrollTop = $(window).scrollTop();
-
-		if(currentScrollTop < top && currentScrollTop < previousScrollTop) {
-			callback(-1);
-		} else if (currentScrollTop > bottom && currentScrollTop > previousScrollTop) {
-			callback(1);
-		}
-		previousScrollTop = currentScrollTop;
-	}
-
-	scroll.loadMore = function(method, data, callback) {
-		if (loadingMore) {
-			return;
-		}
-		loadingMore = true;
-		socket.emit(method, data, function(err, data) {
-			if (err) {
-				loadingMore = false;
-				return app.alertError(err.message);
-			}
-			callback(data, function() {
-				loadingMore = false;
-			});
-		});
-	};
-
-	scroll.parseAndTranslate = function(template, blockName, data, callback) {
-		ajaxify.loadTemplate(template, function(templateHtml) {
-			var html = templates.parse(templates.getBlock(templateHtml, blockName), data);
-
-			translator.translate(html, function(translatedHTML) {
-				callback($(translatedHTML));
-			});
-		});
-	};
-
-	scroll.calculateAfter = function(direction, selector, count, reverse, callback) {
-		var after = 0,
-			offset = 0,
-			el = direction > 0 ? $(selector).last() : $(selector).first(),
-			increment;
-
-		count = reverse ? -count : count;
-		increment = reverse ? -1 : 1;
-
-		if (direction > 0) {
-			after = parseInt(el.attr('data-index'), 10) + increment;
-		} else {
-			after = parseInt(el.attr('data-index'), 10);
-			if (isNaN(after)) {
-				after = 0;
-			}
-			after -= count;
-			if (after < 0) {
-				after = 0;
-			}
-			if (el && el.offset()) {
-				offset = el.offset().top - $('#header-menu').offset().top + $('#header-menu').height();
-			}
-		}
-
-		callback(after, offset, el);
-	};
-
-	return scroll;
-});
\ No newline at end of file
diff --git a/public/src/forum/login.js b/public/src/forum/login.js
deleted file mode 100644
index c4600c36ac..0000000000
--- a/public/src/forum/login.js
+++ /dev/null
@@ -1,39 +0,0 @@
-"use strict";
-/* global define, app, RELATIVE_PATH */
-
-define('forum/login', function() {
-	var	Login = {};
-
-	Login.init = function() {
-		var errorEl = $('#login-error-notify'),
-			submitEl = $('#login'),
-			formEl = $('#login-form');
-
-		submitEl.on('click', function(e) {
-			e.preventDefault();
-
-			if (!$('#username').val() || !$('#password').val()) {
-				translator.translate('[[error:invalid-username-or-password]]', function(translated) {
-					errorEl.find('p').text(translated)
-					errorEl.show();
-				});
-			} else {
-				errorEl.hide();
-
-				if (!submitEl.hasClass('disabled')) {
-					submitEl.addClass('disabled');
-					formEl.submit();
-				}
-			}
-		});
-
-		$('#login-error-notify button').on('click', function(e) {
-			e.preventDefault();
-			errorEl.hide();
-		});
-
-		$('#content #username').focus();
-	};
-
-	return Login;
-});
diff --git a/public/src/forum/notifications.js b/public/src/forum/notifications.js
deleted file mode 100644
index aed18cf315..0000000000
--- a/public/src/forum/notifications.js
+++ /dev/null
@@ -1,16 +0,0 @@
-define('forum/notifications', function() {
-	var Notifications = {};
-
-	Notifications.init = function() {
-		var listEl = $('.notifications-list');
-
-		$('span.timeago').timeago();
-
-		// Allow the user to click anywhere in the LI
-		listEl.on('click', 'li', function(e) {
-			this.querySelector('a').click();
-		});
-	}
-
-	return Notifications;
-});
diff --git a/public/src/forum/pagination.js b/public/src/forum/pagination.js
deleted file mode 100644
index 5aab6ada6b..0000000000
--- a/public/src/forum/pagination.js
+++ /dev/null
@@ -1,108 +0,0 @@
-'use strict';
-/*global define, utils, ajaxify, bootbox*/
-
-define('forum/pagination', function() {
-	var pagination = {};
-
-	pagination.currentPage = 0;
-	pagination.pageCount = 0;
-
-	pagination.init = function(currentPage, pageCount) {
-		pagination.currentPage = parseInt(currentPage, 10);
-		pagination.pageCount = parseInt(pageCount, 10);
-
-		pagination.recreatePaginationLinks(pageCount);
-
-		$('.pagination')
-			.on('click', '.previous', function() {
-				return pagination.loadPage(pagination.currentPage - 1);
-			}).on('click', '.next', function() {
-				return pagination.loadPage(pagination.currentPage + 1);
-			}).on('click', '.select_page', function(e) {
-				e.preventDefault();
-				bootbox.prompt('Enter page number:', function(pageNum) {
-					pagination.loadPage(pageNum);
-				});
-			});
-	};
-
-	pagination.recreatePaginationLinks = function(newPageCount) {
-		pagination.pageCount = parseInt(newPageCount, 10);
-
-		var pagesToShow = determinePagesToShow();
-
-		var html = '';
-		for(var i=0; i<pagesToShow.length; ++i) {
-			if(i > 0) {
-				if (pagesToShow[i] - 1 !== pagesToShow[i-1]) {
-					html += '<li><a class="select_page" href="#">|</a></li>';
-				}
-			}
-			html += '<li class="page" data-page="' + pagesToShow[i] + '"><a href="#">' + pagesToShow[i] + '</a></li>';
-		}
-
-		$('.pagination li.page').remove();
-		$('.pagination li .select_page').parent().remove();
-		$(html).insertAfter($('.pagination li.previous'));
-
-		updatePageLinks();
-	};
-
-	function determinePagesToShow() {
-		var pagesToShow = [1];
-		if(pagination.pageCount !== 1) {
-			pagesToShow.push(pagination.pageCount);
-		}
-
-		var previous = pagination.currentPage - 1;
-		var next = pagination.currentPage + 1;
-
-		if(previous > 1 && pagesToShow.indexOf(previous) === -1) {
-			pagesToShow.push(previous);
-		}
-
-		if(next < pagination.pageCount && pagesToShow.indexOf(next) === -1) {
-			pagesToShow.push(next);
-		}
-
-		if(pagesToShow.indexOf(pagination.currentPage) === -1) {
-			pagesToShow.push(pagination.currentPage);
-		}
-
-		pagesToShow.sort(function(a, b) {
-			return parseInt(a, 10) - parseInt(b, 10);
-		});
-		return pagesToShow;
-	}
-
-	pagination.loadPage = function(page, callback) {
-		page = parseInt(page, 10);
-		if(!utils.isNumber(page) || page < 1 || page > pagination.pageCount) {
-			return false;
-		}
-
-		ajaxify.go(window.location.pathname.slice(1) + '?page=' + page, function() {
-			if (typeof callback === 'function') {
-				callback();
-			}
-		});
-		return true;
-	};
-
-	function updatePageLinks() {
-		$('.pagination').toggleClass('hide', pagination.pageCount === 0 || pagination.pageCount === 1);
-
-		$('.pagination .next').toggleClass('disabled', pagination.currentPage === pagination.pageCount);
-		$('.pagination .previous').toggleClass('disabled', pagination.currentPage === 1);
-
-		$('.pagination .page').removeClass('active');
-		$('.pagination .page[data-page="' + pagination.currentPage + '"]').addClass('active');
-		$('.pagination .page').each(function(index, element) {
-			var li = $(this);
-			var page = li.attr('data-page');
-			li.find('a').attr('href', window.location.pathname + '?page=' + page);
-		});
-	}
-
-	return pagination;
-});
diff --git a/public/src/forum/popular.js b/public/src/forum/popular.js
deleted file mode 100644
index 7495f5110d..0000000000
--- a/public/src/forum/popular.js
+++ /dev/null
@@ -1,19 +0,0 @@
-'use strict';
-
-/* globals define, app, socket*/
-
-define('forum/popular', ['forum/recent', 'forum/infinitescroll'], function(recent, infinitescroll) {
-	var Popular = {};
-
-	Popular.init = function() {
-		app.enterRoom('recent_posts');
-
-		$('#new-topics-alert').on('click', function() {
-			$(this).addClass('hide');
-		});
-
-		recent.selectActivePill();
-	};
-
-	return Popular;
-});
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
deleted file mode 100644
index 78cbff6c14..0000000000
--- a/public/src/forum/recent.js
+++ /dev/null
@@ -1,140 +0,0 @@
-'use strict';
-
-/* globals define, app, socket, utils */
-
-define('forum/recent', ['forum/infinitescroll'], function(infinitescroll) {
-	var	Recent = {};
-
-	var newTopicCount = 0,
-		newPostCount = 0;
-
-	var active = '';
-
-	function getActiveSection() {
-		var url = window.location.href,
-		parts = url.split('/'),
-		active = parts[parts.length - 1];
-		return active;
-	}
-
-	$(window).on('action:ajaxify.start', function(ev, data) {
-		if(data.url.indexOf('recent') !== 0) {
-			Recent.removeListeners();
-		}
-	});
-
-	Recent.init = function() {
-		app.enterRoom('recent_posts');
-
-		Recent.watchForNewPosts();
-
-		active = Recent.selectActivePill();
-
-		$('#new-topics-alert').on('click', function() {
-			$(this).addClass('hide');
-		});
-
-
-		infinitescroll.init(Recent.loadMoreTopics);
-	};
-
-	Recent.selectActivePill = function() {
-		var active = getActiveSection();
-
-		$('.nav-pills li').removeClass('active');
-		$('.nav-pills li a').each(function() {
-			var $this = $(this);
-			if ($this.attr('href').match(active)) {
-				$this.parent().addClass('active');
-				return false;
-			}
-		});
-
-		return active;
-	};
-
-	Recent.watchForNewPosts = function () {
-		newPostCount = 0;
-		newTopicCount = 0;
-		Recent.removeListeners();
-		socket.on('event:new_topic', onNewTopic);
-		socket.on('event:new_post', onNewPost);
-	};
-
-	function onNewTopic(data) {
-		++newTopicCount;
-		Recent.updateAlertText();
-	}
-
-	function onNewPost(data) {
-		++newPostCount;
-		Recent.updateAlertText();
-	}
-
-	Recent.removeListeners = function() {
-		socket.removeListener('event:new_topic', onNewTopic);
-		socket.removeListener('event:new_post', onNewPost);
-	};
-
-	Recent.updateAlertText = function() {
-		var text = 'There';
-
-		if (newTopicCount > 1) {
-			text += ' are ' + newTopicCount + ' new topics';
-		} else if (newTopicCount === 1) {
-			text += ' is a new topic';
-		}
-
-		if (newPostCount > 1) {
-			text += (newTopicCount?' and ':' are ') + newPostCount + ' new posts';
-		} else if(newPostCount === 1) {
-			text += (newTopicCount?' and ':' is ') + ' a new post';
-		}
-
-		text += '. Click here to reload.';
-
-		$('#new-topics-alert').html(text).removeClass('hide').fadeIn('slow');
-		$('#category-no-topics').addClass('hide');
-	};
-
-	Recent.loadMoreTopics = function(direction) {
-		if(direction < 0 || !$('#topics-container').length) {
-			return;
-		}
-
-		infinitescroll.loadMore('topics.loadMoreRecentTopics', {
-			after: $('#topics-container').attr('data-nextstart'),
-			term: active
-		}, function(data, done) {
-			if (data.topics && data.topics.length) {
-				Recent.onTopicsLoaded('recent', data.topics, false, done);
-				$('#topics-container').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-		});
-	};
-
-	Recent.onTopicsLoaded = function(templateName, topics, showSelect, callback) {
-
-		topics = topics.filter(function(topic) {
-			return !$('#topics-container li[data-tid=' + topic.tid + ']').length;
-		});
-
-		if (!topics.length) {
-			return callback();
-		}
-
-		infinitescroll.parseAndTranslate(templateName, 'topics', {topics: topics, showSelect: showSelect}, function(html) {
-			$('#category-no-topics').remove();
-
-			$('#topics-container').append(html);
-			html.find('span.timeago').timeago();
-			app.createUserTooltips();
-			utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			callback();
-		});
-	};
-
-	return Recent;
-});
diff --git a/public/src/forum/register.js b/public/src/forum/register.js
deleted file mode 100644
index a332aa7c6f..0000000000
--- a/public/src/forum/register.js
+++ /dev/null
@@ -1,198 +0,0 @@
-'use strict';
-
-/* globals define, app, utils, socket, config */
-
-
-define('forum/register', function() {
-	var Register = {},
-		validationError = false,
-		successIcon = '<i class="fa fa-check"></i>';
-
-	function showError(element, msg) {
-		translator.translate(msg, function(msg) {
-			element.html(msg);
-			element.parent()
-				.removeClass('alert-success')
-				.addClass('alert-danger');
-			element.show();
-		});
-		validationError = true;
-	}
-
-	function showSuccess(element, msg) {
-		translator.translate(msg, function(msg) {
-			element.html(msg);
-			element.parent()
-				.removeClass('alert-danger')
-				.addClass('alert-success');
-			element.show();
-		});
-	}
-
-	function validateEmail(email, callback) {
-		callback = callback || function() {};
-		var email_notify = $('#email-notify');
-
-		if (!email) {
-			validationError = true;
-			return;
-		}
-
-		if (!utils.isEmailValid(email)) {
-			showError(email_notify, '[[error:invalid-email]]');
-			return;
-		}
-
-		socket.emit('user.emailExists', {
-			email: email
-		}, function(err, exists) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			if (exists) {
-				showError(email_notify, '[[error:email-taken]]');
-			} else {
-				showSuccess(email_notify, successIcon);
-			}
-
-			callback();
-		});
-	}
-
-	function validateUsername(username, callback) {
-		callback = callback || function() {};
-
-		var username_notify = $('#username-notify');
-
-		if (!username) {
-			validationError = true;
-			return;
-		}
-
-		if (username.length < config.minimumUsernameLength) {
-			showError(username_notify, '[[error:username-too-short]]');
-		} else if (username.length > config.maximumUsernameLength) {
-			showError(username_notify, '[[error:username-too-long]]');
-		} else if (!utils.isUserNameValid(username) || !utils.slugify(username)) {
-			showError(username_notify, '[[error:invalid-username]]');
-		} else {
-			socket.emit('user.exists', {
-				username: username
-			}, function(err, exists) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-
-				if (exists) {
-					showError(username_notify, '[[error:username-taken]]');
-				} else {
-					showSuccess(username_notify, successIcon);
-				}
-
-				callback();
-			});
-		}
-	}
-
-	function validatePassword(password, password_confirm) {
-		if (!password) {
-			validationError = true;
-			return;
-		}
-		var password_notify = $('#password-notify'),
-			password_confirm_notify = $('#password-confirm-notify');
-
-		if (password.length < config.minimumPasswordLength) {
-			showError(password_notify, '[[user:change_password_error_length]]');
-		} else if (!utils.isPasswordValid(password)) {
-			showError(password_notify, '[[user:change_password_error]]');
-		} else {
-			showSuccess(password_notify, successIcon);
-		}
-
-		if (password !== password_confirm && password_confirm !== '') {
-			showError(password_confirm_notify, '[[user:change_password_error_match]]');
-		}
-	}
-
-	function validatePasswordConfirm(password, password_confirm) {
-		var password_notify = $('#password-notify'),
-			password_confirm_notify = $('#password-confirm-notify');
-
-		if (!password || password_notify.hasClass('alert-error')) {
-			return;
-		}
-
-		if (password !== password_confirm) {
-			showError(password_confirm_notify, '[[user:change_password_error_match]]');
-		} else {
-			showSuccess(password_confirm_notify, successIcon);
-		}
-	}
-
-	Register.init = function() {
-		var email = $('#email'),
-			username = $('#username'),
-			password = $('#password'),
-			password_confirm = $('#password-confirm'),
-			register = $('#register'),
-			agreeTerms = $('#agree-terms');
-
-		$('#referrer').val(app.previousUrl);
-
-		email.on('blur', function() {
-			validateEmail(email.val());
-		});
-
-		username.on('keyup', function() {
-			$('#yourUsername').html(this.value.length > 0 ? this.value : 'username');
-		});
-
-		username.on('blur', function() {
-			validateUsername(username.val());
-		});
-
-		password.on('blur', function() {
-			validatePassword(password.val(), password_confirm.val());
-		});
-
-		password_confirm.on('blur', function() {
-			validatePasswordConfirm(password.val(), password_confirm.val());
-		});
-
-		function validateForm(callback) {
-			validationError = false;
-			validatePassword(password.val(), password_confirm.val());
-			validatePasswordConfirm(password.val(), password_confirm.val());
-
-			validateEmail(email.val(), function() {
-				validateUsername(username.val(), callback);
-			});
-		}
-
-		register.on('click', function(e) {
-			var registerBtn = $(this);
-			e.preventDefault();
-			validateForm(function() {
-				if (!validationError) {
-					registerBtn.parents('form').trigger('submit');
-				}
-			});
-		});
-
-		if(agreeTerms.length) {
-			agreeTerms.on('click', function() {
-				if ($(this).prop('checked')) {
-					register.removeAttr('disabled');
-				} else {
-					register.attr('disabled', 'disabled');
-				}
-			});
-
-			register.attr('disabled', 'disabled');
-		}
-	};
-
-	return Register;
-});
diff --git a/public/src/forum/reset.js b/public/src/forum/reset.js
deleted file mode 100644
index 2cbad172ae..0000000000
--- a/public/src/forum/reset.js
+++ /dev/null
@@ -1,28 +0,0 @@
-define('forum/reset', function() {
-	var	ResetPassword = {};
-
-	ResetPassword.init = function() {
-		var inputEl = $('#email'),
-			errorEl = $('#error'),
-			successEl = $('#success');
-
-		$('#reset').on('click', function() {
-			if (inputEl.val() && inputEl.val().indexOf('@') !== -1) {
-				socket.emit('user.reset.send', inputEl.val(), function(err, data) {
-					if(err) {
-						return app.alertError(err.message);
-					}
-
-					errorEl.addClass('hide').hide();
-					successEl.removeClass('hide').show();
-					inputEl.val('');
-				});
-			} else {
-				successEl.addClass('hide').hide();
-				errorEl.removeClass('hide').show();
-			}
-		});
-	};
-
-	return ResetPassword;
-});
diff --git a/public/src/forum/reset_code.js b/public/src/forum/reset_code.js
deleted file mode 100644
index 9a7fc80075..0000000000
--- a/public/src/forum/reset_code.js
+++ /dev/null
@@ -1,55 +0,0 @@
-define('forum/reset_code', function() {
-	var	ResetCode = {};
-
-	ResetCode.init = function() {
-		var reset_code = ajaxify.variables.get('reset_code');
-
-		var resetEl = $('#reset'),
-			password = $('#password'),
-			repeat = $('#repeat'),
-			noticeEl = $('#notice');
-
-		resetEl.on('click', function() {
-			if (password.val().length < 6) {
-				$('#error').addClass('hide').hide();
-				noticeEl.find('strong').html('Invalid Password');
-				noticeEl.find('p').html('The password entered is too short, please pick a different password.');
-				noticeEl.removeClass('hide').css({display: 'block'});
-			} else if (password.value !== repeat.value) {
-				$('#error').hide();
-				noticeEl.find('strong').html('Invalid Password');
-				noticeEl.find('p').html('The two passwords you\'ve entered do not match.');
-				noticeEl.removeClass('hide').css({display: 'block'});
-			} else {
-				socket.emit('user.reset.commit', {
-					code: reset_code,
-					password: password.val()
-				}, function(err) {
-					if(err) {
-						return app.alertError(err.message);
-					}
-					$('#error').addClass('hide').hide();
-					$('#notice').addClass('hide').hide();
-					$('#success').removeClass('hide').addClass('show').show();
-				});
-			}
-		});
-
-		socket.emit('user.reset.valid', reset_code, function(err, valid) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			if (valid) {
-				resetEl.prop('disabled', false);
-			} else {
-				var formEl = $('#reset-form');
-				// Show error message
-				$('#error').show();
-				formEl.remove();
-			}
-		});
-	};
-
-	return ResetCode;
-});
diff --git a/public/src/forum/search.js b/public/src/forum/search.js
deleted file mode 100644
index 861d8dd441..0000000000
--- a/public/src/forum/search.js
+++ /dev/null
@@ -1,35 +0,0 @@
-define('forum/search', ['search'], function(searchModule) {
-	var	Search = {};
-
-	Search.init = function() {
-		var searchQuery = $('#post-results').attr('data-search-query');
-		var regexes = [];
-		var searchTerms = searchQuery.split(' ');
-		for (var i=0; i<searchTerms.length; ++i) {
-			var regex = new RegExp(searchTerms[i], 'gi');
-			regexes.push({regex: regex, term: searchTerms[i]});
-		}
-
-		$('.search-result-text').each(function() {
-			var result = $(this);
-			var text = result.html();
-			for(var i=0; i<regexes.length; ++i) {
-				text = text.replace(regexes[i].regex, '<strong>' + regexes[i].term + '</strong>');
-			}
-			result.html(text).find('img').addClass('img-responsive');
-		});
-
-		$('#search-form input').val(searchQuery);
-
-		$('#mobile-search-form').off('submit').on('submit', function(e) {
-			e.preventDefault();
-			var input = $(this).find('input');
-
-			searchModule.query(input.val(), function() {
-				input.val('');
-			});
-		});
-	};
-
-	return Search;
-});
diff --git a/public/src/forum/tag.js b/public/src/forum/tag.js
deleted file mode 100644
index f15af62f75..0000000000
--- a/public/src/forum/tag.js
+++ /dev/null
@@ -1,42 +0,0 @@
-'use strict';
-
-/* globals define, app, socket */
-
-define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function(recent, infinitescroll) {
-	var Tag = {};
-
-	Tag.init = function() {
-		app.enterRoom('tags');
-
-		if ($('body').height() <= $(window).height() && $('#topics-container').children().length >= 20) {
-			$('#load-more-btn').show();
-		}
-
-		$('#load-more-btn').on('click', function() {
-			loadMoreTopics();
-		});
-
-		infinitescroll.init(loadMoreTopics);
-
-		function loadMoreTopics(direction) {
-			if(direction < 0 || !$('#topics-container').length) {
-				return;
-			}
-
-			infinitescroll.loadMore('topics.loadMoreFromSet', {
-				set: 'tag:' + ajaxify.variables.get('tag') + ':topics',
-				after: $('#topics-container').attr('data-nextstart')
-			}, function(data, done) {
-				if (data.topics && data.topics.length) {
-					recent.onTopicsLoaded('tag', data.topics, false, done);
-					$('#topics-container').attr('data-nextstart', data.nextStart);
-				} else {
-					done();
-					$('#load-more-btn').hide();
-				}
-			});
-		}
-	};
-
-	return Tag;
-});
diff --git a/public/src/forum/tags.js b/public/src/forum/tags.js
deleted file mode 100644
index bf4395f497..0000000000
--- a/public/src/forum/tags.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict';
-
-/* globals define, app, utils, socket */
-
-define('forum/tags', ['forum/infinitescroll'], function(infinitescroll) {
-	var Tags = {};
-	var timeoutId = 0;
-
-	Tags.init = function() {
-		app.enterRoom('tags');
-
-		$('#tag-search').on('input propertychange', function() {
-			if (timeoutId) {
-				clearTimeout(timeoutId);
-				timeoutId = 0;
-			}
-			timeoutId = setTimeout(function() {
-				socket.emit('topics.searchAndLoadTags', {query: $('#tag-search').val()}, function(err, results) {
-					if (err) {
-						return app.alertError(err.message);
-					}
-					onTagsLoaded(results, true, function() {
-						timeoutId = 0;
-					});
-				});
-			}, 100);
-		});
-
-		infinitescroll.init(Tags.loadMoreTags);
-	};
-
-	Tags.loadMoreTags = function(direction) {
-		if(direction < 0 || !$('.tag-list').length) {
-			return;
-		}
-
-		infinitescroll.loadMore('topics.loadMoreTags', {
-			after: $('.tag-list').attr('data-nextstart')
-		}, function(data, done) {
-			if (data && data.tags && data.tags.length) {
-				onTagsLoaded(data.tags, false, done);
-				$('.tag-list').attr('data-nextstart', data.nextStart);
-			} else {
-				done();
-			}
-		});
-	};
-
-	function onTagsLoaded(tags, replace, callback) {
-		callback = callback || function() {};
-		infinitescroll.parseAndTranslate('tags', 'tags', {tags: tags}, function(html) {
-			$('.tag-list')[replace ? 'html' : 'append'](html);
-			utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
-			callback();
-		});
-	}
-
-	return Tags;
-});
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
deleted file mode 100644
index dcb85f203a..0000000000
--- a/public/src/forum/topic.js
+++ /dev/null
@@ -1,452 +0,0 @@
-'use strict';
-
-
-/* globals define, app, templates, translator, socket, bootbox, config, ajaxify, RELATIVE_PATH, utils */
-
-var dependencies = [
-	'forum/pagination',
-	'forum/infinitescroll',
-	'forum/topic/threadTools',
-	'forum/topic/postTools',
-	'forum/topic/events',
-	'forum/topic/browsing',
-	'navigator'
-];
-
-define('forum/topic', dependencies, function(pagination, infinitescroll, threadTools, postTools, events, browsing, navigator) {
-	var	Topic = {},
-		currentUrl = '';
-
-	$(window).on('action:ajaxify.start', function(ev, data) {
-		if(data.url.indexOf('topic') !== 0) {
-			navigator.hide();
-			$('.header-topic-title').find('span').text('').hide();
-			app.removeAlert('bookmark');
-
-			events.removeListeners();
-
-			socket.removeListener('event:new_post', onNewPost);
-			socket.removeListener('event:new_notification', onNewNotification);
-		}
-	});
-
-	Topic.init = function() {
-		var tid = ajaxify.variables.get('topic_id'),
-			thread_state = {
-				locked: ajaxify.variables.get('locked'),
-				deleted: ajaxify.variables.get('deleted'),
-				pinned: ajaxify.variables.get('pinned')
-			},
-			postCount = ajaxify.variables.get('postcount');
-
-		$(window).trigger('action:topic.loading');
-
-		app.enterRoom('topic_' + tid);
-
-		processPage($('.topic'));
-
-		showBottomPostBar();
-
-		postTools.init(tid, thread_state);
-		threadTools.init(tid, thread_state);
-		events.init();
-
-		handleSorting();
-
-		hidePostToolsForDeletedPosts();
-
-		enableInfiniteLoadingOrPagination();
-
-		addBlockQuoteHandler();
-
-		addBlockquoteEllipses($('.topic .post-content > blockquote'));
-
-		handleBookmark(tid);
-
-		navigator.init('.posts > .post-row', postCount, Topic.toTop, Topic.toBottom, Topic.navigatorCallback, Topic.calculateIndex);
-
-		socket.on('event:new_post', onNewPost);
-		socket.on('event:new_notification', onNewNotification);
-
-		$(window).on('scroll', updateTopicTitle);
-
-		$(window).trigger('action:topic.loaded');
-
-		socket.emit('topics.enter', tid);
-	};
-
-	Topic.toTop = function() {
-		navigator.scrollTop(0);
-	};
-
-	Topic.toBottom = function() {
-		socket.emit('topics.postcount', ajaxify.variables.get('topic_id'), function(err, postCount) {
-			if (config.topicPostSort !== 'oldest_to_newest') {
-				postCount = 1;
-			}
-			navigator.scrollBottom(postCount - 1);
-		});
-	};
-
-	function handleBookmark(tid) {
-		var bookmark = localStorage.getItem('topic:' + tid + ':bookmark');
-		var postIndex = getPostIndex();
-		if (postIndex) {
-			navigator.scrollToPost(postIndex - 1, true);
-		} else if (bookmark && (!config.usePagination || (config.usePagination && pagination.currentPage === 1)) && ajaxify.variables.get('postcount') > 1) {
-			app.alert({
-				alert_id: 'bookmark',
-				message: '[[topic:bookmark_instructions]]',
-				timeout: 0,
-				type: 'info',
-				clickfn : function() {
-					navigator.scrollToPost(parseInt(bookmark, 10), true);
-				},
-				closefn : function() {
-					localStorage.removeItem('topic:' + tid + ':bookmark');
-				}
-			});
-		}
-	}
-
-	function getPostIndex() {
-		var parts = window.location.pathname.split('/');
-		return parts[4] ? parseInt(parts[4], 10) : 0;
-	}
-
-	function handleSorting() {
-		var threadSort = $('.thread-sort');
-		threadSort.find('i').removeClass('fa-check');
-		var currentSetting = threadSort.find('a[data-sort="' + config.topicPostSort + '"]');
-		currentSetting.find('i').addClass('fa-check');
-
-		$('.thread-sort').on('click', 'a', function() {
-			var newSetting = $(this).attr('data-sort');
-			socket.emit('user.setTopicSort', newSetting, function(err) {
-				config.topicPostSort = newSetting;
-				ajaxify.go('topic/' + ajaxify.variables.get('topic_slug'));
-			});
-		});
-	}
-
-	function showBottomPostBar() {
-		if($('#post-container .post-row').length > 1 || !$('#post-container li[data-index="0"]').length) {
-			$('.bottom-post-bar').removeClass('hide');
-		}
-	}
-
-	function onNewPost(data) {
-		var tid = ajaxify.variables.get('topic_id');
-		if(data && data.posts && data.posts.length && data.posts[0].tid !== tid) {
-			return;
-		}
-
-		if(config.usePagination) {
-			return onNewPostPagination(data);
-		}
-
-		for (var i=0; i<data.posts.length; ++i) {
-			var postcount = $('.user_postcount_' + data.posts[i].uid);
-			postcount.html(parseInt(postcount.html(), 10) + 1);
-		}
-		socket.emit('topics.markAsRead', [tid]);
-		createNewPosts(data);
-	}
-
-	function onNewNotification(data) {
-		var tid = ajaxify.variables.get('topic_id');
-		if (data && data.tid && parseInt(data.tid, 10) === parseInt(tid, 10)) {
-			socket.emit('topics.markTopicNotificationsRead', tid);
-		}
-	}
-
-	function addBlockQuoteHandler() {
-		$('#post-container').on('click', 'blockquote .toggle', function() {
-			var blockQuote = $(this).parent('blockquote');
-			var toggle = $(this);
-			blockQuote.toggleClass('uncollapsed');
-			var collapsed = !blockQuote.hasClass('uncollapsed');
-			toggle.toggleClass('fa-angle-down', collapsed).toggleClass('fa-angle-up', !collapsed);
-		});
-	}
-
-	function addBlockquoteEllipses(blockquotes) {
-		blockquotes.each(function() {
-			var $this = $(this);
-			if ($this.find(':hidden:not(br)').length && !$this.find('.toggle').length) {
-				$this.append('<i class="fa fa-angle-down pointer toggle"></i>');
-			}
-		});
-	}
-
-	function enableInfiniteLoadingOrPagination() {
-		if(!config.usePagination) {
-			infinitescroll.init(loadMorePosts, $('#post-container .post-row[data-index="0"]').height());
-		} else {
-			navigator.hide();
-
-			pagination.init(parseInt(ajaxify.variables.get('currentPage'), 10), parseInt(ajaxify.variables.get('pageCount'), 10));
-		}
-	}
-
-	function hidePostToolsForDeletedPosts() {
-		$('#post-container li.deleted').each(function() {
-			postTools.toggle($(this).attr('data-pid'), true);
-		});
-	}
-
-
-	function updateTopicTitle() {
-		if($(window).scrollTop() > 50) {
-			$('.header-topic-title').find('span').text(ajaxify.variables.get('topic_name')).show();
-		} else {
-			$('.header-topic-title').find('span').text('').hide();
-		}
-	}
-
-	Topic.calculateIndex = function(index, elementCount) {
-		if (index !== 1 && config.topicPostSort !== 'oldest_to_newest') {
-			return elementCount - index + 2;
-		}
-		return index;
-	};
-
-	Topic.navigatorCallback = function(element, elementCount) {
-		var path = ajaxify.removeRelativePath(window.location.pathname.slice(1));
-		if (!path.startsWith('topic')) {
-			return 1;
-		}
-		var postIndex = parseInt(element.attr('data-index'), 10);
-		var index = postIndex + 1;
-		if (config.topicPostSort !== 'oldest_to_newest') {
-			if (postIndex === 0) {
-				index = 1;
-			} else  {
-				index = Math.max(elementCount - postIndex + 1, 1);
-			}
-		}
-
-		var currentBookmark = localStorage.getItem('topic:' + ajaxify.variables.get('topic_id') + ':bookmark');
-
-		if (!currentBookmark || parseInt(postIndex, 10) >= parseInt(currentBookmark, 10)) {
-			localStorage.setItem('topic:' + ajaxify.variables.get('topic_id') + ':bookmark', postIndex);
-			app.removeAlert('bookmark');
-		}
-
-		if (!navigator.scrollActive) {
-			var parts = ajaxify.removeRelativePath(window.location.pathname.slice(1)).split('/');
-			var topicId = parts[1],
-				slug = parts[2];
-			var newUrl = 'topic/' + topicId + '/' + (slug ? slug : '');
-			if (postIndex > 0) {
-				 newUrl += '/' + (postIndex + 1);
-			}
-
-			if (newUrl !== currentUrl) {
-				if (history.replaceState) {
-					var search = (window.location.search ? window.location.search : '');
-					history.replaceState({
-						url: newUrl + search
-					}, null, window.location.protocol + '//' + window.location.host + RELATIVE_PATH + '/' + newUrl + search);
-				}
-				currentUrl = newUrl;
-			}
-		}
-		return index;
-	};
-
-	function onNewPostPagination(data) {
-		var posts = data.posts;
-		socket.emit('topics.getPageCount', ajaxify.variables.get('topic_id'), function(err, newPageCount) {
-
-			pagination.recreatePaginationLinks(newPageCount);
-
-			if (pagination.currentPage === pagination.pageCount) {
-				createNewPosts(data);
-			} else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.uid, 10)) {
-				pagination.loadPage(pagination.pageCount);
-			}
-		});
-	}
-
-	function createNewPosts(data, callback) {
-		callback = callback || function() {};
-		if(!data || (data.posts && !data.posts.length)) {
-			return callback(false);
-		}
-
-		function removeAlreadyAddedPosts() {
-			data.posts = data.posts.filter(function(post) {
-				return $('#post-container li[data-pid="' + post.pid +'"]').length === 0;
-			});
-		}
-
-		var after = null,
-			before = null;
-
-		function findInsertionPoint() {
-			var firstPostTimestamp = parseInt(data.posts[0].timestamp, 10);
-			var firstPostVotes = parseInt(data.posts[0].votes, 10);
-			var firstPostPid = data.posts[0].pid;
-
-			var firstReply = $('#post-container li.post-row[data-index!="0"]').first();
-			var lastReply = $('#post-container li.post-row[data-index!="0"]').last();
-
-			if (config.topicPostSort === 'oldest_to_newest') {
-				if (firstPostTimestamp < parseInt(firstReply.attr('data-timestamp'), 10)) {
-					before = firstReply;
-				} else if(firstPostTimestamp >= parseInt(lastReply.attr('data-timestamp'), 10)) {
-					after = lastReply;
-				}
-			} else if(config.topicPostSort === 'newest_to_oldest') {
-				if (firstPostTimestamp > parseInt(firstReply.attr('data-timestamp'), 10)) {
-					before = firstReply;
-				} else if(firstPostTimestamp <= parseInt(lastReply.attr('data-timestamp'), 10)) {
-					after = lastReply;
-				}
-			} else if(config.topicPostSort === 'most_votes') {
-				if (firstPostVotes > parseInt(firstReply.attr('data-votes'), 10)) {
-					before = firstReply;
-				} else if(firstPostVotes < parseInt(firstReply.attr('data-votes'), 10)) {
-					after = lastReply;
-				} else {
-					if (firstPostPid > firstReply.attr('data-pid')) {
-						before = firstReply;
-					} else if(firstPostPid <= firstReply.attr('data-pid')) {
-						after = lastReply;
-					}
-				}
-			}
-		}
-
-		removeAlreadyAddedPosts();
-		if(!data.posts.length) {
-			return callback(false);
-		}
-
-		findInsertionPoint();
-
-		data.title = $('<div></div>').text(ajaxify.variables.get('topic_name')).html();
-		data.viewcount = ajaxify.variables.get('viewcount');
-
-		infinitescroll.parseAndTranslate('topic', 'posts', data, function(html) {
-			if(after) {
-				html.insertAfter(after);
-			} else if(before) {
-				// Save document height and position for future reference (about 5 lines down)
-				var height = $(document).height(),
-					scrollTop = $(document).scrollTop(),
-					originalPostEl = $('li[data-index="0"]');
-
-				// Insert the new post
-				html.insertBefore(before);
-
-				// If the user is not at the top of the page... (or reasonably so...)
-				if (scrollTop > originalPostEl.offset().top) {
-					// Now restore the relative position the user was on prior to new post insertion
-					$(document).scrollTop(scrollTop + ($(document).height() - height));
-				}
-			} else {
-				$('#post-container').append(html);
-			}
-
-			html.hide().fadeIn('slow');
-
-			addBlockquoteEllipses(html.find('.post-content > blockquote'));
-
-			$(window).trigger('action:posts.loaded');
-			onNewPostsLoaded(html, data.posts);
-			callback(true);
-		});
-	}
-
-	function onNewPostsLoaded(html, posts) {
-
-		var pids = [];
-		for(var i=0; i<posts.length; ++i) {
-			pids.push(posts[i].pid);
-		}
-
-		socket.emit('posts.getPrivileges', pids, function(err, privileges) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			for(i=0; i<pids.length; ++i) {
-				toggleModTools(pids[i], privileges[i]);
-			}
-		});
-
-		processPage(html);
-	}
-
-	function processPage(element) {
-		app.createUserTooltips();
-		app.replaceSelfLinks(element.find('a'));
-		utils.addCommasToNumbers(element.find('.formatted-number'));
-		utils.makeNumbersHumanReadable(element.find('.human-readable-number'));
-		element.find('span.timeago').timeago();
-		element.find('.post-content img:not(.emoji)').addClass('img-responsive').each(function() {
-			var $this = $(this);
-			if (!$this.parent().is('a')) {
-				$this.wrap('<a href="' + $this.attr('src') + '" target="_blank">');
-			}
-		});
-		postTools.updatePostCount();
-		showBottomPostBar();
-	}
-
-	function toggleModTools(pid, privileges) {
-		var postEl = $('.post-row[data-pid="' + pid + '"]');
-
-		postEl.find('.edit, .delete').toggleClass('hidden', !privileges.editable);
-		postEl.find('.move').toggleClass('hidden', !privileges.move);
-		postEl.find('.reply, .quote').toggleClass('hidden', !$('.post_reply').length);
-		var isSelfPost = parseInt(postEl.attr('data-uid'), 10) === parseInt(app.uid, 10);
-		postEl.find('.chat, .flag').toggleClass('hidden', isSelfPost || !app.uid);
-	}
-
-	function loadMorePosts(direction) {
-		if (!$('#post-container').length || navigator.scrollActive) {
-			return;
-		}
-
-		var reverse = config.topicPostSort === 'newest_to_oldest' || config.topicPostSort === 'most_votes';
-
-		infinitescroll.calculateAfter(direction, '#post-container .post-row[data-index!="0"]', config.postsPerPage, reverse, function(after, offset, el) {
-			loadPostsAfter(after);
-		});
-	}
-
-	function loadPostsAfter(after) {
-		var tid = ajaxify.variables.get('topic_id');
-		if (!utils.isNumber(tid) || !utils.isNumber(after) || (after === 0 && $('#post-container li.post-row[data-index="1"]').length)) {
-			return;
-		}
-
-		var indicatorEl = $('.loading-indicator');
-		if (!indicatorEl.is(':animated')) {
-			indicatorEl.fadeIn();
-		}
-
-		infinitescroll.loadMore('topics.loadMore', {
-			tid: tid,
-			after: after
-		}, function (data, done) {
-
-			indicatorEl.fadeOut();
-
-			if (data && data.posts && data.posts.length) {
-				createNewPosts(data, function(postsCreated) {
-					done();
-				});
-				hidePostToolsForDeletedPosts();
-			} else {
-				navigator.update();
-				done();
-			}
-		});
-	}
-
-	return Topic;
-});
diff --git a/public/src/forum/topic/browsing.js b/public/src/forum/topic/browsing.js
deleted file mode 100644
index d2cebbcf14..0000000000
--- a/public/src/forum/topic/browsing.js
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-'use strict';
-
-/* globals define, app, translator, config, socket, ajaxify */
-
-define('forum/topic/browsing', function() {
-
-	var Browsing = {};
-
-	Browsing.onUpdateUsersInRoom = function(data) {
-		if(data && data.room.indexOf('topic_' + ajaxify.variables.get('topic_id')) !== -1) {
-			for(var i=0; i<data.users.length; ++i) {
-				addUserIcon(data.users[i]);
-			}
-			getReplyingUsers();
-		}
-	};
-
-	Browsing.onUserEnter = function(data) {
-		var activeEl = $('.thread_active_users');
-		var user = activeEl.find('a[data-uid="' + data.uid + '"]');
-		if (!user.length && activeEl.children().length < 10) {
-			addUserIcon(data);
-		} else {
-			user.attr('data-count', parseInt(user.attr('data-count'), 10) + 1);
-		}
-	};
-
-	Browsing.onUserLeave = function(uid) {
-		var activeEl = $('.thread_active_users');
-		var user = activeEl.find('a[data-uid="' + uid + '"]');
-		if (user.length) {
-			var count = Math.max(0, parseInt(user.attr('data-count'), 10) - 1);
-			user.attr('data-count', count);
-			if (count <= 0) {
-				user.remove();
-			}
-		}
-	};
-
-	Browsing.onUserStatusChange = function(data) {
-		updateOnlineIcon($('.username-field[data-uid="' + data.uid + '"]'), data.status);
-
-		updateBrowsingUsers(data);
-	};
-
-	function updateOnlineIcon(el, status) {
-		translator.translate('[[global:' + status + ']]', function(translated) {
-			el.siblings('i')
-				.attr('class', 'fa fa-circle status ' + status)
-				.attr('title', translated)
-				.attr('data-original-title', translated);
-		});
-	}
-
-	function updateBrowsingUsers(data) {
-		var activeEl = $('.thread_active_users');
-		var user = activeEl.find('a[data-uid="'+ data.uid + '"]');
-		if (user.length && data.status === 'offline') {
-			user.parent().remove();
-		}
-	}
-
-	function addUserIcon(user) {
-		if (!user.userslug) {
-			return;
-		}
-		var activeEl = $('.thread_active_users');
-		var userEl = createUserIcon(user.uid, user.picture, user.userslug, user.username);
-		activeEl.append(userEl);
-		activeEl.find('a[data-uid] img').tooltip({
-			placement: 'top'
-		});
-	}
-
-	function createUserIcon(uid, picture, userslug, username) {
-		if(!$('.thread_active_users').find('[data-uid="' + uid + '"]').length) {
-			return $('<div class="inline-block"><a data-uid="' + uid + '" data-count="1" href="' + config.relative_path + '/user/' + userslug + '"><img title="' + username + '" src="'+ picture +'"/></a></div>');
-		}
-	}
-
-	function getReplyingUsers() {
-		var activeEl = $('.thread_active_users');
-		socket.emit('modules.composer.getUsersByTid', ajaxify.variables.get('topic_id'), function(err, uids) {
-			if (uids && uids.length) {
-				for(var x=0;x<uids.length;x++) {
-					activeEl.find('[data-uid="' + uids[x] + '"]').addClass('replying');
-				}
-			}
-		});
-	}
-
-	return Browsing;
-});
\ No newline at end of file
diff --git a/public/src/forum/topic/events.js b/public/src/forum/topic/events.js
deleted file mode 100644
index bb50f0d556..0000000000
--- a/public/src/forum/topic/events.js
+++ /dev/null
@@ -1,180 +0,0 @@
-
-'use strict';
-
-/* globals app, ajaxify, define, socket, translator, templates */
-
-define('forum/topic/events', ['forum/topic/browsing', 'forum/topic/postTools', 'forum/topic/threadTools'], function(browsing, postTools, threadTools) {
-
-	var Events = {};
-
-	var events = {
-		'event:update_users_in_room': browsing.onUpdateUsersInRoom,
-		'event:user_enter': browsing.onUserEnter,
-		'event:user_leave': browsing.onUserLeave,
-		'event:user_status_change': browsing.onUserStatusChange,
-		'event:voted': updatePostVotesAndUserReputation,
-		'event:favourited': updateFavouriteCount,
-
-		'event:topic_deleted': toggleTopicDeleteState,
-		'event:topic_restored': toggleTopicDeleteState,
-		'event:topic_purged': onTopicPurged,
-
-		'event:topic_locked': threadTools.setLockedState,
-		'event:topic_unlocked': threadTools.setLockedState,
-
-		'event:topic_pinned': threadTools.setPinnedState,
-		'event:topic_unpinned': threadTools.setPinnedState,
-
-		'event:topic_moved': onTopicMoved,
-
-		'event:post_edited': onPostEdited,
-		'event:post_purged': onPostPurged,
-
-		'event:post_deleted': togglePostDeleteState,
-		'event:post_restored': togglePostDeleteState,
-
-		'posts.favourite': togglePostFavourite,
-		'posts.unfavourite': togglePostFavourite,
-
-		'posts.upvote': togglePostVote,
-		'posts.downvote': togglePostVote,
-		'posts.unvote': togglePostVote,
-
-		'event:topic.toggleReply': toggleReply,
-	};
-
-	Events.init = function() {
-		Events.removeListeners();
-		for(var eventName in events) {
-			if (events.hasOwnProperty(eventName)) {
-				socket.on(eventName, events[eventName]);
-			}
-		}
-	};
-
-	Events.removeListeners = function() {
-		for(var eventName in events) {
-			if (events.hasOwnProperty(eventName)) {
-				socket.removeListener(eventName, events[eventName]);
-			}
-		}
-	};
-
-	function updatePostVotesAndUserReputation(data) {
-		var votes = $('li[data-pid="' + data.post.pid + '"] .votes'),
-			reputationElements = $('.reputation[data-uid="' + data.post.uid + '"]');
-
-		votes.html(data.post.votes).attr('data-votes', data.post.votes);
-		reputationElements.html(data.user.reputation).attr('data-reputation', data.user.reputation);
-	}
-
-	function updateFavouriteCount(data) {
-		$('li[data-pid="' + data.post.pid + '"] .favouriteCount').html(data.post.reputation).attr('data-favourites', data.post.reputation);
-	}
-
-	function toggleTopicDeleteState(data) {
-		threadTools.setLockedState(data);
-		threadTools.setDeleteState(data);
-	}
-
-	function onTopicPurged(tid) {
-		ajaxify.go('category/' + ajaxify.variables.get('category_id'));
-	}
-
-	function onTopicMoved(data) {
-		if (data && data.tid > 0) {
-			ajaxify.go('topic/' + data.tid);
-		}
-	}
-
-	function onPostEdited(data) {
-		var editedPostEl = $('#content_' + data.pid),
-			editedPostTitle = $('#topic_title_' + data.pid);
-
-		if (editedPostTitle.length) {
-			editedPostTitle.fadeOut(250, function() {
-				editedPostTitle.html(data.title).fadeIn(250);
-			});
-		}
-
-		editedPostEl.fadeOut(250, function() {
-			editedPostEl.html(data.content);
-			editedPostEl.find('img').addClass('img-responsive');
-			app.replaceSelfLinks(editedPostEl.find('a'));
-			editedPostEl.fadeIn(250);
-
-			$(window).trigger('action:posts.edited');
-		});
-
-		if (data.tags && data.tags.length !== $('.tags').first().children().length) {
-			ajaxify.loadTemplate('partials/post_bar', function(postBarTemplate) {
-				var html = templates.parse(templates.getBlock(postBarTemplate, 'tags'), {
-					tags: data.tags
-				});
-				var tags = $('.tags');
-				tags.fadeOut(250, function() {
-					tags.html(html).fadeIn(250);
-				});
-			});
-		}
-	}
-
-	function onPostPurged(pid) {
-		$('#post-container li[data-pid="' + pid + '"]').fadeOut(500, function() {
-			$(this).remove();
-		});
-	}
-
-	function togglePostDeleteState(data) {
-		var postEl = $('#post-container li[data-pid="' + data.pid + '"]');
-
-		if (!postEl.length) {
-			return;
-		}
-
-		postEl.toggleClass('deleted');
-		var isDeleted = postEl.hasClass('deleted');
-		postTools.toggle(data.pid, isDeleted);
-
-		if (!app.isAdmin && parseInt(data.uid, 10) !== parseInt(app.uid, 10)) {
-			if (isDeleted) {
-				postEl.find('.post-content').translateHtml('[[topic:post_is_deleted]]');
-			} else {
-				postEl.find('.post-content').html(data.content);
-			}
-		}
-
-		postTools.updatePostCount();
-	}
-
-	function togglePostFavourite(data) {
-		var favBtn = $('li[data-pid="' + data.post.pid + '"] .favourite');
-		if (!favBtn.length) {
-			return;
-		}
-
-		favBtn.addClass('btn-warning')
-			.attr('data-favourited', data.isFavourited);
-
-		var icon = favBtn.find('i');
-		var className = icon.attr('class');
-
-		if (data.isFavourited ? className.indexOf('-o') !== -1 : className.indexOf('-o') === -1) {
-			icon.attr('class', data.isFavourited ? className.replace('-o', '') : className + '-o');
-		}
-	}
-
-	function togglePostVote(data) {
-		var post = $('li[data-pid="' + data.post.pid + '"]');
-
-		post.find('.upvote').toggleClass('btn-primary upvoted', data.upvote);
-		post.find('.downvote').toggleClass('btn-primary downvoted', data.downvote);
-	}
-
-	function toggleReply(data) {
-		$('.thread_active_users [data-uid="' + data.uid + '"]').toggleClass('replying', data.isReplying);
-	}
-
-	return Events;
-
-});
diff --git a/public/src/forum/topic/fork.js b/public/src/forum/topic/fork.js
deleted file mode 100644
index 92e9438b24..0000000000
--- a/public/src/forum/topic/fork.js
+++ /dev/null
@@ -1,136 +0,0 @@
-'use strict';
-
-/* globals define, app, translator, socket */
-
-define('forum/topic/fork', function() {
-
-	var Fork = {},
-		forkModal,
-		forkCommit,
-		pids = [];
-
-	Fork.init = function() {
-		$('.fork_thread').on('click', onForkThreadClicked);
-	};
-
-	function disableClicks() {
-		return false;
-	}
-
-	function disableClicksOnPosts() {
-		$('.post-row').on('click', 'button,a', disableClicks);
-	}
-
-	function enableClicksOnPosts() {
-		$('.post-row').off('click', 'button,a', disableClicks);
-	}
-
-	function onForkThreadClicked() {
-		forkModal = $('#fork-thread-modal');
-		forkCommit = forkModal.find('#fork_thread_commit');
-		pids.length = 0;
-
-		showForkModal();
-		showNoPostsSelected();
-
-		forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal);
-		forkModal.find('#fork-title').on('change', checkForkButtonEnable);
-		$('#post-container').on('click', 'li[data-pid]', function() {
-			togglePostSelection($(this));
-		});
-
-		disableClicksOnPosts();
-
-		forkCommit.on('click', createTopicFromPosts);
-	}
-
-	function showForkModal() {
-		forkModal.removeClass('hide')
-			.css('position', 'fixed')
-			.css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px')
-			.css('top', '0px')
-			.css('z-index', '2000');
-	}
-
-	function createTopicFromPosts() {
-		socket.emit('topics.createTopicFromPosts', {
-			title: forkModal.find('#fork-title').val(),
-			pids: pids
-		}, function(err, newTopic) {
-			function fadeOutAndRemove(pid) {
-				$('#post-container li[data-pid="' + pid + '"]').fadeOut(500, function() {
-					$(this).remove();
-				});
-			}
-
-			if (err) {
-				return app.alertError(err.message);
-			}
-
-			app.alert({
-				timeout: 5000,
-				title: '[[global:alert.success]]',
-				message: '[[topic:fork_success]]',
-				type: 'success',
-				clickfn: function() {
-					ajaxify.go('topic/' + newTopic.slug);
-				}
-			});
-
-			for(var i=0; i<pids.length; ++i) {
-				fadeOutAndRemove(pids[i]);
-			}
-			closeForkModal();
-		});
-	}
-
-	function togglePostSelection(post) {
-		var newPid = post.attr('data-pid');
-
-		if(parseInt(post.attr('data-index'), 10) === 0) {
-			return;
-		}
-
-		if(newPid) {
-			var index = pids.indexOf(newPid);
-			if(index === -1) {
-				pids.push(newPid);
-				post.css('opacity', '0.5');
-			} else {
-				pids.splice(index, 1);
-				post.css('opacity', '1.0');
-			}
-
-			if(pids.length) {
-				pids.sort();
-				forkModal.find('#fork-pids').html(pids.toString());
-			} else {
-				showNoPostsSelected();
-			}
-			checkForkButtonEnable();
-		}
-	}
-
-	function showNoPostsSelected() {
-		forkModal.find('#fork-pids').translateHtml('[[topic:fork_no_pids]]');
-	}
-
-	function checkForkButtonEnable() {
-		if(forkModal.find('#fork-title').length && pids.length) {
-			forkCommit.removeAttr('disabled');
-		} else {
-			forkCommit.attr('disabled', true);
-		}
-	}
-
-	function closeForkModal() {
-		for(var i=0; i<pids.length; ++i) {
-			$('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1);
-		}
-		forkModal.addClass('hide');
-		$('#post-container').off('click', 'li[data-pid]');
-		enableClicksOnPosts();
-	}
-
-	return Fork;
-});
diff --git a/public/src/forum/topic/move.js b/public/src/forum/topic/move.js
deleted file mode 100644
index f0dec0e9b7..0000000000
--- a/public/src/forum/topic/move.js
+++ /dev/null
@@ -1,100 +0,0 @@
-'use strict';
-
-/* globals define, app, socket */
-
-define('forum/topic/move', function() {
-
-	var Move = {},
-		modal,
-		targetCid,
-		targetCategoryLabel;
-
-	Move.init = function(tids, currentCid, onComplete) {
-		modal = $('#move_thread_modal');
-
-		Move.tids = tids;
-		Move.currentCid = currentCid;
-		Move.onComplete = onComplete;
-		Move.moveAll = tids ? false : true;
-
-		modal.on('shown.bs.modal', onMoveModalShown);
-		$('#move-confirm').hide();
-
-		if (Move.moveAll || (tids && tids.length > 1)) {
-			modal.find('.modal-header h3').translateText('[[topic:move_topics]]');
-		}
-
-		modal.modal('show');
-	};
-
-	function onMoveModalShown() {
-		var loadingEl = $('#categories-loading');
-		if (!loadingEl.length) {
-			return;
-		}
-
-		socket.emit('categories.get', onCategoriesLoaded);
-	}
-
-	function onCategoriesLoaded(err, categories) {
-		if (err) {
-			return app.alertError(err.message);
-		}
-
-		renderCategories(categories);
-
-		modal.on('click', '.category-list li[data-cid]', function(e) {
-			selectCategory($(this));
-		});
-
-		$('#move_thread_commit').on('click', onCommitClicked);
-	}
-
-	function selectCategory(category) {
-		modal.find('#confirm-category-name').html(category.html());
-		$('#move-confirm').show();
-
-		targetCid = category.attr('data-cid');
-		targetCategoryLabel = category.html();
-		$('#move_thread_commit').prop('disabled', false);
-	}
-
-	function onCommitClicked() {
-		var commitEl = $('#move_thread_commit');
-
-		if (!commitEl.prop('disabled') && targetCid) {
-			commitEl.prop('disabled', true);
-
-			moveTopics();
-		}
-	}
-
-	function moveTopics() {
-		socket.emit(Move.moveAll ? 'topics.moveAll' : 'topics.move', {
-			tids: Move.tids,
-			cid: targetCid,
-			currentCid: Move.currentCid
-		}, function(err) {
-			modal.modal('hide');
-			$('#move_thread_commit').prop('disabled', false);
-
-			if(err) {
-				return app.alertError(err.message);
-			}
-
-			app.alertSuccess('[[topic:topic_move_success, ' + targetCategoryLabel + ']]');
-			if (typeof Move.onComplete === 'function') {
-				Move.onComplete();
-			}
-		});
-	}
-
-	function renderCategories(categories) {
-		templates.parse('partials/category_list', {categories: categories}, function(html) {
-			modal.find('.modal-body').prepend(html);
-			$('#categories-loading').remove();
-		});
-	}
-
-	return Move;
-});
diff --git a/public/src/forum/topic/postTools.js b/public/src/forum/topic/postTools.js
deleted file mode 100644
index 6a26e7120e..0000000000
--- a/public/src/forum/topic/postTools.js
+++ /dev/null
@@ -1,322 +0,0 @@
-'use strict';
-
-/* globals define, app, translator, ajaxify, socket, bootbox */
-
-define('forum/topic/postTools', ['composer', 'share', 'navigator'], function(composer, share, navigator) {
-
-	var PostTools = {},
-		topicName;
-
-	PostTools.init = function(tid, threadState) {
-		topicName = ajaxify.variables.get('topic_name');
-
-		addPostHandlers(tid, threadState);
-
-		share.addShareHandlers(topicName);
-
-		addVoteHandler();
-	};
-
-	PostTools.toggle = function(pid, isDeleted) {
-		var postEl = $('#post-container li[data-pid="' + pid + '"]');
-
-		postEl.find('.quote, .favourite, .post_reply, .chat').toggleClass('hidden', isDeleted);
-		postEl.find('.purge').toggleClass('hidden', !isDeleted);
-		postEl.find('.delete .i').toggleClass('fa-trash-o', !isDeleted).toggleClass('fa-history', isDeleted);
-		postEl.find('.delete span').translateHtml(isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]');
-	};
-
-	PostTools.updatePostCount = function() {
-		socket.emit('topics.postcount', ajaxify.variables.get('topic_id'), function(err, postCount) {
-			if (!err) {
-				$('.topic-post-count').html(postCount);
-				navigator.setCount(postCount);
-			}
-		});
-	};
-
-	function addVoteHandler() {
-		$('#post-container').on('mouseenter', '.post-row .votes', function() {
-			loadDataAndCreateTooltip($(this), 'posts.getUpvoters');
-		});
-	}
-
-	function loadDataAndCreateTooltip(el, method) {
-		var pid = el.parents('.post-row').attr('data-pid');
-		socket.emit(method, pid, function(err, data) {
-			if (!err) {
-				createTooltip(el, data);
-			}
-		});
-	}
-
-	function createTooltip(el, data) {
-		var usernames = data.usernames;
-		if (!usernames.length) {
-			return;
-		}
-		if (usernames.length + data.otherCount > 6) {
-			usernames = usernames.join(', ').replace(/,/g, '|');
-			translator.translate('[[topic:users_and_others, ' + usernames + ', ' + data.otherCount + ']]', function(translated) {
-				translated = translated.replace(/\|/g, ',');
-				el.attr('title', translated).tooltip('destroy').tooltip('show');
-			});
-		} else {
-			usernames = usernames.join(', ');
-			el.attr('title', usernames).tooltip('destroy').tooltip('show');
-		}
-	}
-
-	function addPostHandlers(tid, threadState) {
-		$('.topic').on('click', '.post_reply', function() {
-			if (!threadState.locked) {
-				onReplyClicked($(this), tid, topicName);
-			}
-		});
-
-		var postContainer = $('#post-container');
-
-		postContainer.on('click', '.quote', function() {
-			if (!threadState.locked) {
-				onQuoteClicked($(this), tid, topicName);
-			}
-		});
-
-		postContainer.on('click', '.favourite', function() {
-			favouritePost($(this), getData($(this), 'data-pid'));
-		});
-
-		postContainer.on('click', '.upvote', function() {
-			return toggleVote($(this), '.upvoted', 'posts.upvote');
-		});
-
-		postContainer.on('click', '.downvote', function() {
-			return toggleVote($(this), '.downvoted', 'posts.downvote');
-		});
-
-		postContainer.on('click', '.flag', function() {
-			flagPost(getData($(this), 'data-pid'));
-		});
-
-		postContainer.on('click', '.edit', function(e) {
-			composer.editPost(getData($(this), 'data-pid'));
-		});
-
-		postContainer.on('click', '.delete', function(e) {
-			deletePost($(this), tid);
-		});
-
-		postContainer.on('click', '.purge', function(e) {
-			purgePost($(this), tid);
-		});
-
-		postContainer.on('click', '.move', function(e) {
-			openMovePostModal($(this));
-		});
-
-		postContainer.on('click', '.chat', function(e) {
-			openChat($(this));
-		});
-	}
-
-	function onReplyClicked(button, tid, topicName) {
-		var selectionText = '',
-			selection = window.getSelection ? window.getSelection() : document.selection.createRange();
-
-		if ($(selection.baseNode).parents('.post-content').length > 0) {
-			var snippet = selection.toString();
-			if (snippet.length) {
-				selectionText = '> ' + snippet.replace(/\n/g, '\n> ') + '\n\n';
-			}
-		}
-
-		var username = getUserName(selectionText ? $(selection.baseNode) : button);
-		if (getData(button, 'data-uid') === '0') {
-			username = '';
-		}
-		if (selectionText.length) {
-			composer.addQuote(tid, ajaxify.variables.get('topic_slug'), getData(button, 'data-index'), getData(button, 'data-pid'), topicName, username, selectionText);
-		} else {
-			composer.newReply(tid, getData(button, 'data-pid'), topicName, username ? username + ' ' : '');
-		}
-
-	}
-
-	function onQuoteClicked(button, tid, topicName) {
-		var username = getUserName(button),
-			pid = getData(button, 'data-pid');
-
-		socket.emit('posts.getRawPost', pid, function(err, post) {
-			if(err) {
-				return app.alertError(err.message);
-			}
-			var quoted = '';
-			if(post) {
-				quoted = '> ' + post.replace(/\n/g, '\n> ') + '\n\n';
-			}
-
-			if($('.composer').length) {
-				composer.addQuote(tid, ajaxify.variables.get('topic_slug'), getData(button, 'data-index'), pid, topicName, username, quoted);
-			} else {
-				composer.newReply(tid, pid, topicName, '[[modules:composer.user_said, ' + username + ']]\n' + quoted);
-			}
-		});
-	}
-
-	function favouritePost(button, pid) {
-		var method = button.attr('data-favourited') === 'false' ? 'posts.favourite' : 'posts.unfavourite';
-
-		socket.emit(method, {
-			pid: pid,
-			room_id: app.currentRoom
-		}, function(err) {
-			if (err) {
-				app.alertError(err.message);
-			}
-		});
-
-		return false;
-	}
-
-	function toggleVote(button, className, method) {
-		var post = button.parents('.post-row'),
-			currentState = post.find(className).length;
-
-		socket.emit(currentState ? 'posts.unvote' : method , {
-			pid: post.attr('data-pid'),
-			room_id: app.currentRoom
-		}, function(err) {
-			if (err) {
-				app.alertError(err.message);
-			}
-		});
-
-		return false;
-	}
-
-	function getData(button, data) {
-		return button.parents('.post-row').attr(data);
-	}
-
-	function getUserName(button) {
-		var username = '',
-			post = button.parents('li[data-pid]');
-
-		if (post.length) {
-			username = post.attr('data-username').replace(/\s/g, '-');
-		}
-		if (post.length && post.attr('data-uid') !== '0') {
-			username = '@' + username;
-		}
-
-		return username;
-	}
-
-	function deletePost(button, tid) {
-		var pid = getData(button, 'data-pid'),
-			postEl = $('#post-container li[data-pid="' + pid + '"]'),
-			action = !postEl.hasClass('deleted') ? 'delete' : 'restore';
-
-		postAction(action, pid, tid);
-	}
-
-	function purgePost(button, tid) {
-		postAction('purge', getData(button, 'data-pid'), tid);
-	}
-
-	function postAction(action, pid, tid) {
-		translator.translate('[[topic:post_' + action + '_confirm]]', function(msg) {
-			bootbox.confirm(msg, function(confirm) {
-				if (!confirm) {
-					return;
-				}
-
-				socket.emit('posts.' + action, {
-					pid: pid,
-					tid: tid
-				}, function(err) {
-					if(err) {
-						app.alertError(err.message);
-					}
-				});
-			});
-		});
-	}
-
-	function openMovePostModal(button) {
-		var moveModal = $('#move-post-modal'),
-			moveBtn = moveModal.find('#move_post_commit'),
-			topicId = moveModal.find('#topicId');
-
-		showMoveModal();
-
-		moveModal.find('.close,#move_post_cancel').on('click', function() {
-			moveModal.addClass('hide');
-		});
-
-		topicId.on('change', function() {
-			if(topicId.val().length) {
-				moveBtn.removeAttr('disabled');
-			} else {
-				moveBtn.attr('disabled', true);
-			}
-		});
-
-		moveBtn.on('click', function() {
-			movePost(button.parents('.post-row'), getData(button, 'data-pid'), topicId.val());
-		});
-	}
-
-	function showMoveModal() {
-		$('#move-post-modal').removeClass('hide')
-			.css("position", "fixed")
-			.css("left", Math.max(0, (($(window).width() - $($('#move-post-modal')).outerWidth()) / 2) + $(window).scrollLeft()) + "px")
-			.css("top", "0px")
-			.css("z-index", "2000");
-	}
-
-	function movePost(post, pid, tid) {
-		socket.emit('topics.movePost', {pid: pid, tid: tid}, function(err) {
-			$('#move-post-modal').addClass('hide');
-
-			if(err) {
-				$('#topicId').val('');
-				return app.alertError(err.message);
-			}
-
-			post.fadeOut(500, function() {
-				post.remove();
-			});
-
-			$('#topicId').val('');
-
-			app.alertSuccess('[[topic:post_moved]]');
-		});
-	}
-
-	function flagPost(pid) {
-		translator.translate('[[topic:flag_confirm]]', function(message) {
-			bootbox.confirm(message, function(confirm) {
-				if (confirm) {
-					socket.emit('posts.flag', pid, function(err) {
-						if(err) {
-							return app.alertError(err.message);
-						}
-
-						app.alertSuccess('[[topic:flag_success]]');
-					});
-				}
-			});
-		});
-	}
-
-	function openChat(button) {
-		var post = button.parents('li.post-row');
-
-		app.openChat(post.attr('data-username'), post.attr('data-uid'));
-		button.parents('.btn-group').find('.dropdown-toggle').click();
-		return false;
-	}
-
-	return PostTools;
-});
diff --git a/public/src/forum/topic/threadTools.js b/public/src/forum/topic/threadTools.js
deleted file mode 100644
index 41a3d532bf..0000000000
--- a/public/src/forum/topic/threadTools.js
+++ /dev/null
@@ -1,169 +0,0 @@
-'use strict';
-
-/* globals define, app, translator, ajaxify, socket, bootbox */
-
-define('forum/topic/threadTools', ['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
-
-	var ThreadTools = {};
-
-	ThreadTools.init = function(tid, threadState) {
-		ThreadTools.threadState = threadState;
-
-		if (threadState.locked) {
-			ThreadTools.setLockedState({tid: tid, isLocked: true});
-		}
-
-		if (threadState.deleted) {
-			ThreadTools.setDeleteState({tid: tid, isDelete: true});
-		}
-
-		if (threadState.pinned) {
-			ThreadTools.setPinnedState({tid: tid, isPinned: true});
-		}
-
-		$('.delete_thread').on('click', function() {
-			topicCommand(threadState.deleted ? 'restore' : 'delete', tid);
-			return false;
-		});
-
-		$('.purge_thread').on('click', function() {
-			topicCommand('purge', tid);
-			return false;
-		});
-
-		$('.lock_thread').on('click', function() {
-			socket.emit(threadState.locked ? 'topics.unlock' : 'topics.lock', {tids: [tid], cid: ajaxify.variables.get('category_id')});
-			return false;
-		});
-
-		$('.pin_thread').on('click', function() {
-			socket.emit(threadState.pinned ? 'topics.unpin' : 'topics.pin', {tids: [tid], cid: ajaxify.variables.get('category_id')});
-			return false;
-		});
-
-		$('.markAsUnreadForAll').on('click', function() {
-			var btn = $(this);
-			socket.emit('topics.markAsUnreadForAll', [tid], function(err) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-				app.alertSuccess('[[topic:markAsUnreadForAll.success]]');
-				btn.parents('.thread-tools.open').find('.dropdown-toggle').trigger('click');
-			});
-			return false;
-		});
-
-		$('.move_thread').on('click', function(e) {
-			move.init([tid], ajaxify.variables.get('category_id'));
-			return false;
-		});
-
-		fork.init();
-
-		$('.posts').on('click', '.follow', function() {
-			socket.emit('topics.follow', tid, function(err, state) {
-				if(err) {
-					return app.alert({
-						type: 'danger',
-						alert_id: 'topic_follow',
-						title: '[[global:please_log_in]]',
-						message: '[[topic:login_to_subscribe]]',
-						timeout: 5000
-					});
-				}
-
-				setFollowState(state);
-
-				app.alert({
-					alert_id: 'follow_thread',
-					message: state ? '[[topic:following_topic.message]]' : '[[topic:not_following_topic.message]]',
-					type: 'success',
-					timeout: 5000
-				});
-			});
-
-			return false;
-		});
-	};
-
-	function topicCommand(command, tid) {
-		translator.translate('[[topic:thread_tools.' + command + '_confirm]]', function(msg) {
-			bootbox.confirm(msg, function(confirm) {
-				if (confirm) {
-					socket.emit('topics.' + command, {tids: [tid], cid: ajaxify.variables.get('category_id')});
-				}
-			});
-		});
-	}
-
-	ThreadTools.setLockedState = function(data) {
-		var threadEl = $('#post-container');
-		if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) {
-			var isLocked = data.isLocked && !app.isAdmin;
-
-			$('.lock_thread').translateHtml('<i class="fa fa-fw fa-' + (data.isLocked ? 'un': '') + 'lock"></i> [[topic:thread_tools.' + (data.isLocked ? 'un': '') + 'lock]]');
-
-			translator.translate(isLocked ? '[[topic:locked]]' : '[[topic:reply]]', function(translated) {
-				var className = isLocked ? 'fa-lock' : 'fa-reply';
-				threadEl.find('.post_reply').html('<i class="fa ' + className + '"></i> ' + translated);
-				$('.topic-main-buttons .post_reply').attr('disabled', isLocked).html(isLocked ? '<i class="fa fa-lock"></i> ' + translated : translated);
-			});
-
-			threadEl.find('.quote, .edit, .delete').toggleClass('hidden', isLocked);
-			$('.topic-title i.fa-lock').toggleClass('hide', !data.isLocked);
-			ThreadTools.threadState.locked = data.isLocked;
-		}
-	};
-
-	ThreadTools.setDeleteState = function(data) {
-		var threadEl = $('#post-container');
-		if (parseInt(data.tid, 10) !== parseInt(threadEl.attr('data-tid'), 10)) {
-			return;
-		}
-
-		$('.delete_thread span').translateHtml('<i class="fa fa-fw ' + (data.isDelete ? 'fa-history' : 'fa-trash-o') + '"></i> [[topic:thread_tools.' + (data.isDelete ? 'restore' : 'delete') + ']]');
-
-		threadEl.toggleClass('deleted', data.isDelete);
-		ThreadTools.threadState.deleted = data.isDelete;
-		$('.purge_thread').toggleClass('hidden', !data.isDelete);
-
-		if (data.isDelete) {
-			translator.translate('[[topic:deleted_message]]', function(translated) {
-				$('<div id="thread-deleted" class="alert alert-warning">' + translated + '</div>').insertBefore(threadEl);
-			});
-		} else {
-			$('#thread-deleted').remove();
-		}
-	};
-
-	ThreadTools.setPinnedState = function(data) {
-		var threadEl = $('#post-container');
-		if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) {
-			translator.translate('<i class="fa fa-fw fa-thumb-tack"></i> [[topic:thread_tools.' + (data.isPinned ? 'unpin' : 'pin') + ']]', function(translated) {
-				$('.pin_thread').html(translated);
-				ThreadTools.threadState.pinned = data.isPinned;
-			});
-			$('.topic-title i.fa-thumb-tack').toggleClass('hide', !data.isPinned);
-		}
-	};
-
-	function setFollowState(state) {
-		var title = state ? '[[topic:unwatch.title]]' : '[[topic:watch.title]]';
-		var iconClass = state ? 'fa fa-eye-slash' : 'fa fa-eye';
-		var text = state ? '[[topic:unwatch]]' : '[[topic:watch]]';
-
-		var followEl = $('.posts .follow');
-
-		translator.translate(title, function(titleTranslated) {
-			followEl.attr('title', titleTranslated).find('i').attr('class', iconClass);
-			followEl.find('span').text(text);
-
-			translator.translate(followEl.html(), function(translated) {
-				followEl.html(translated);
-			});
-		});
-	}
-
-
-	return ThreadTools;
-});
diff --git a/public/src/forum/unread.js b/public/src/forum/unread.js
deleted file mode 100644
index 342102f634..0000000000
--- a/public/src/forum/unread.js
+++ /dev/null
@@ -1,151 +0,0 @@
-'use strict';
-
-/* globals define, app, socket */
-
-define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll'], function(recent, topicSelect, infinitescroll) {
-	var Unread = {};
-
-	$(window).on('action:ajaxify.start', function(ev, data) {
-		if(data.url.indexOf('unread') !== 0) {
-			recent.removeListeners();
-		}
-	});
-
-	Unread.init = function() {
-		app.enterRoom('recent_posts');
-
-		$('#new-topics-alert').on('click', function() {
-			$(this).addClass('hide');
-		});
-
-		recent.watchForNewPosts();
-
-		$('#markSelectedRead').on('click', function() {
-			var tids = topicSelect.getSelectedTids();
-			if(!tids.length) {
-				return;
-			}
-			socket.emit('topics.markAsRead', tids, function(err) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-
-				doneRemovingTids(tids);
-			});
-		});
-
-		$('#markAllRead').on('click', function() {
-			socket.emit('topics.markAllRead', function(err) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-
-				app.alertSuccess('[[unread:topics_marked_as_read.success]]');
-
-				$('#topics-container').empty();
-				$('#category-no-topics').removeClass('hidden');
-				$('.markread').addClass('hidden');
-			});
-		});
-
-		$('.markread').on('click', '.category', function() {
-			function getCategoryTids(cid) {
-				var tids = [];
-				$('#topics-container .category-item[data-cid="' + cid + '"]').each(function() {
-					tids.push($(this).attr('data-tid'));
-				});
-				return tids;
-			}
-			var cid = $(this).attr('data-cid');
-			var tids = getCategoryTids(cid);
-
-			socket.emit('topics.markCategoryTopicsRead', cid, function(err) {
-				if(err) {
-					return app.alertError(err.message);
-				}
-
-				doneRemovingTids(tids);
-			});
-		});
-
-		socket.emit('categories.get', onCategoriesLoaded);
-
-		topicSelect.init();
-
-		if ($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20) {
-			$('#load-more-btn').show();
-		}
-
-		$('#load-more-btn').on('click', function() {
-			loadMoreTopics();
-		});
-
-		infinitescroll.init(loadMoreTopics);
-
-		function loadMoreTopics(direction) {
-			if(direction < 0 || !$('#topics-container').length) {
-				return;
-			}
-
-			infinitescroll.loadMore('topics.loadMoreUnreadTopics', {
-				after: $('#topics-container').attr('data-nextstart')
-			}, function(data, done) {
-				if (data.topics && data.topics.length) {
-					recent.onTopicsLoaded('unread', data.topics, true, done);
-					$('#topics-container').attr('data-nextstart', data.nextStart);
-				} else {
-					done();
-					$('#load-more-btn').hide();
-				}
-			});
-		}
-	};
-
-	function doneRemovingTids(tids) {
-		removeTids(tids);
-
-		app.alertSuccess('[[unread:topics_marked_as_read.success]]');
-
-		if (!$('#topics-container').children().length) {
-			$('#category-no-topics').removeClass('hidden');
-			$('.markread').addClass('hidden');
-		}
-	}
-
-	function removeTids(tids) {
-		for(var i=0; i<tids.length; ++i) {
-			$('#topics-container .category-item[data-tid="' + tids[i] + '"]').remove();
-		}
-	}
-
-	function onCategoriesLoaded(err, categories) {
-		createCategoryLinks(categories);
-	}
-
-	function createCategoryLinks(categories) {
-		categories = categories.filter(function(category) {
-			return !category.disabled;
-		});
-
-		for(var i=0; i<categories.length; ++i) {
-			createCategoryLink(categories[i]);
-		}
-	}
-
-	function createCategoryLink(category) {
-
-		var link = $('<a role="menuitem" href="#"></a>');
-		if (category.icon) {
-			link.append('<i class="fa fa-fw ' + category.icon + '"></i> ' + category.name);
-		} else {
-			link.append(category.name);
-		}
-
-
-		$('<li role="presentation" class="category" data-cid="' + category.cid + '"></li>')
-			.append(link)
-			.appendTo($('.markread .dropdown-menu'));
-	}
-
-	return Unread;
-});
diff --git a/public/src/forum/users.js b/public/src/forum/users.js
deleted file mode 100644
index 858b7d70d8..0000000000
--- a/public/src/forum/users.js
+++ /dev/null
@@ -1,186 +0,0 @@
-'use strict';
-
-/* globals define, socket, app, ajaxify, templates, translator*/
-
-define('forum/users', function() {
-	var	Users = {};
-
-	var loadingMoreUsers = false;
-
-	Users.init = function() {
-
-		var active = getActiveSection();
-
-		$('.nav-pills li').removeClass('active');
-		$('.nav-pills li a').each(function() {
-			var $this = $(this);
-			if ($this.attr('href').match(active)) {
-				$this.parent().addClass('active');
-				return false;
-			}
-		});
-
-		handleSearch();
-
-		socket.removeListener('event:user_status_change', onUserStatusChange);
-		socket.on('event:user_status_change', onUserStatusChange);
-
-		$('#load-more-users-btn').on('click', loadMoreUsers);
-
-		$(window).off('scroll').on('scroll', function() {
-			var bottom = ($(document).height() - $(window).height()) * 0.9;
-
-			if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
-				loadMoreUsers();
-			}
-		});
-	};
-
-	function loadMoreUsers() {
-		var set = '';
-		var activeSection = getActiveSection();
-		if (activeSection === 'latest') {
-			set = 'users:joindate';
-		} else if (activeSection === 'sort-posts') {
-			set = 'users:postcount';
-		} else if (activeSection === 'sort-reputation') {
-			set = 'users:reputation';
-		} else if (activeSection === 'online' || activeSection === 'users') {
-			set = 'users:online';
-		}
-
-		if (set) {
-			startLoading(set, $('#users-container').children('.registered-user').length);
-		}
-	}
-
-	function startLoading(set, after) {
-		loadingMoreUsers = true;
-
-		socket.emit('user.loadMore', {
-			set: set,
-			after: after
-		}, function(err, data) {
-			if (data && data.users.length) {
-				onUsersLoaded(data.users);
-				$('#load-more-users-btn').removeClass('disabled');
-			} else {
-				$('#load-more-users-btn').addClass('disabled');
-			}
-			loadingMoreUsers = false;
-		});
-	}
-
-	function onUsersLoaded(users) {
-		users = users.filter(function(user) {
-			return !$('.users-box[data-uid="' + user.uid + '"]').length;
-		});
-
-		ajaxify.loadTemplate('users', function(usersTemplate) {
-			var html = templates.parse(templates.getBlock(usersTemplate, 'users'), {users: users});
-
-			translator.translate(html, function(translated) {
-				$('#users-container').append(translated);
-				$('#users-container .anon-user').appendTo($('#users-container'));
-			});
-		});
-	}
-
-	function handleSearch() {
-		var timeoutId = 0;
-		var lastSearch = null;
-
-		$('#search-user').on('keyup', function() {
-			if (timeoutId !== 0) {
-				clearTimeout(timeoutId);
-				timeoutId = 0;
-			}
-
-			timeoutId = setTimeout(function() {
-				function reset() {
-					notify.html('<i class="fa fa-search"></i>');
-					notify.parent().removeClass('btn-warning label-warning btn-success label-success');
-				}
-				var username = $('#search-user').val();
-				var notify = $('#user-notfound-notify');
-
-				if (username === '') {
-					notify.html('<i class="fa fa-circle-o"></i>');
-					notify.parent().removeClass('btn-warning label-warning btn-success label-success');
-					return;
-				}
-
-				if (lastSearch === username) {
-					return;
-				}
-				lastSearch = username;
-
-				notify.html('<i class="fa fa-spinner fa-spin"></i>');
-
-				socket.emit('user.search', username, function(err, data) {
-					if (err) {
-						reset();
-						return app.alertError(err.message);
-					}
-
-					if (!data) {
-						reset();
-						return;
-					}
-
-					ajaxify.loadTemplate('users', function(usersTemplate) {
-						var html = templates.parse(templates.getBlock(usersTemplate, 'users'), data);
-
-						translator.translate(html, function(translated) {
-							$('#users-container').html(translated);
-							if (!data.users.length) {
-								translator.translate('[[error:no-user]]', function(translated) {
-									notify.html(translated);
-									notify.parent().addClass('btn-warning label-warning');
-								});
-							} else {
-								translator.translate('[[users:users-found-search-took, ' + data.users.length + ', ' + data.timing + ']]', function(translated) {
-									notify.html(translated);
-									notify.parent().addClass('btn-success label-success');
-								});
-							}
-						});
-					});
-				});
-
-			}, 250);
-		});
-	}
-
-	function onUserStatusChange(data) {
-		var section = getActiveSection();
-		if((section.indexOf('online') === 0 || section.indexOf('users') === 0)) {
-			updateUser(data);
-		}
-	}
-
-	function updateUser(data) {
-		if (data.status === 'offline') {
-			return;
-		}
-		var usersContainer = $('#users-container');
-		var userEl = usersContainer.find('li[data-uid="' + data.uid +'"]');
-
-		if (userEl.length) {
-			var statusEl = userEl.find('.status');
-			translator.translate('[[global:' + data.status + ']]', function(translated) {
-				statusEl.attr('class', 'fa fa-circle status ' + data.status)
-					.attr('title', translated)
-					.attr('data-original-title', translated);
-			});
-		}
-	}
-
-	function getActiveSection() {
-		var url = window.location.href,
-			parts = url.split('/');
-		return parts[parts.length - 1];
-	}
-
-	return Users;
-});