From 5c899c765b1478ab69772f8e321b25e2a12e519c Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Sat, 21 Nov 2015 12:27:06 +1100
Subject: [PATCH] Revert "Revert "REFACTOR: support booting discourse with
 DISCOURSE_NO_CONSTANTS""

This reverts commit c21457d6a7a369fb52dfd3cd01b3882055c85d62.
---
 .../admin/components/ip-lookup.js.es6         |  4 +-
 .../admin/components/permalink-form.js.es6    |  6 +-
 ...d_component.js => resumable-upload.js.es6} |  4 +-
 ...screened-ip-address-form-component.js.es6} |  9 ++-
 .../admin/controllers/admin-api.js.es6        |  8 ++-
 .../admin/controllers/admin-dashboard.js.es6  |  3 +-
 .../admin-email-preview-digest.js.es6         |  4 +-
 .../admin/controllers/admin-email-sent.js.es6 |  3 +-
 .../controllers/admin-email-skipped.js.es6    |  6 +-
 .../admin/controllers/admin-flags-list.js.es6 |  4 +-
 .../admin-logs-screened-emails.js.es6         |  3 +-
 .../admin-logs-screened-ip-addresses.js.es6   |  5 +-
 .../admin-logs-screened-urls.js.es6           |  3 +-
 .../admin-logs-staff-action-logs.js.es6       |  3 +-
 .../admin/controllers/admin-permalinks.js.es6 |  3 +-
 .../controllers/admin-users-list-show.js.es6  |  7 +-
 .../modals/admin-start-backup.js.es6          |  3 +-
 ...in_dashboard.js => admin-dashboard.js.es6} | 18 ++---
 .../admin/models/admin-user.js.es6            | 23 ++++---
 .../models/{api_key.js => api-key.js.es6}     | 27 +++-----
 ...eme_color.js => color-scheme-color.js.es6} | 13 +---
 .../{color_scheme.js => color-scheme.js.es6}  | 22 +++---
 .../models/{email_log.js => email-log.js.es6} | 18 ++---
 ...{email_preview.js => email-preview.js.es6} | 16 ++---
 .../admin/models/email-settings.js.es6        | 11 +++
 .../admin/models/email_settings.js            | 17 -----
 .../{flagged_post.js => flagged-post.js.es6}  | 23 +++----
 .../javascripts/admin/models/permalink.js.es6 |  2 +-
 ...creened_email.js => screened-email.js.es6} | 17 ++---
 ..._address.js => screened-ip-address.js.es6} | 12 ++--
 .../{screened_url.js => screened-url.js.es6}  | 16 ++---
 .../admin/models/site-setting.js.es6          |  2 +-
 ..._action_log.js => staff-action-log.js.es6} | 14 ++--
 ...equirements.js => tl3-requirements.js.es6} |  4 +-
 ...{version_check.js => version-check.js.es6} | 16 ++---
 .../javascripts/admin/routes/admin-api.js.es6 |  4 +-
 .../admin/routes/admin-backups-index.js.es6   |  4 +-
 .../admin/routes/admin-backups.js.es6         | 10 +--
 .../routes/admin-customize-colors.js.es6      |  4 +-
 .../admin/routes/admin-dashboard.js.es6       | 13 ++--
 .../admin/routes/admin-email-all.js.es6       |  2 +
 ...ndex_route.js => admin-email-index.js.es6} |  6 +-
 ...logs_routes.js => admin-email-logs.js.es6} | 10 ++-
 .../routes/admin-email-preview-digest.js.es6  |  4 +-
 .../admin/routes/admin-email-sent.js.es6      |  2 +
 .../admin/routes/admin-email-skipped.js.es6   |  2 +
 .../admin/routes/admin-flags-list.js.es6      |  3 +-
 .../admin/routes/admin-groups-type.js.es6     |  4 +-
 .../admin/routes/admin-logs-index.js.es6      |  5 ++
 .../routes/admin-logs-screened-emails.js.es6  |  9 +++
 .../admin-logs-screened-ip-addresses.js.es6   |  9 +++
 .../routes/admin-logs-screened-urls.js.es6    |  9 +++
 .../admin/routes/admin-permalinks.js.es6      |  4 +-
 ..._reports_route.js => admin-reports.js.es6} |  2 +-
 .../admin/routes/admin-user-index.js.es6      |  3 +-
 .../routes/admin-user-tl3-requirements.js.es6 |  5 ++
 .../admin/routes/admin-user.js.es6            |  4 +-
 .../admin/routes/admin-users-list-show.js.es6 |  4 +-
 .../admin/routes/admin-users-list.js.es6      |  3 +-
 .../admin/routes/admin_logs_routes.js         | 67 -------------------
 .../admin_user_tl3_requirements_route.js      | 14 ----
 .../admin/views/admin-customize-colors.js.es6 |  3 +
 .../javascripts/admin/views/admin-user.js.es6 |  1 +
 .../views/admin_customize_colors_view.js      |  3 -
 .../admin/views/admin_user_view.js            |  1 -
 .../controllers/discovery/topics.js.es6       |  3 +-
 .../discourse/controllers/flag.js.es6         |  3 +-
 .../controllers/group/members.js.es6          |  4 +-
 .../discourse/controllers/invite.js.es6       |  8 ++-
 .../discourse/controllers/quote-button.js.es6 |  3 +-
 .../discourse/controllers/topic.js.es6        | 13 ++--
 .../discourse/lib/keyboard-shortcuts.js.es6   |  3 +-
 .../javascripts/discourse/lib/search.js.es6   | 13 ++--
 .../discourse/mixins/open-composer.js.es6     |  6 +-
 .../javascripts/discourse/models/badge.js.es6 | 20 +++---
 .../discourse/models/category-list.js.es6     |  6 +-
 .../javascripts/discourse/models/group.js.es6 |  6 +-
 .../discourse/models/post-stream.js.es6       |  2 +-
 .../javascripts/discourse/models/post.js.es6  |  4 +-
 .../discourse/models/user-badge.js.es6        | 14 ++--
 .../javascripts/discourse/models/user.js.es6  | 19 +++---
 .../routes/build-category-route.js.es6        |  3 +-
 .../discourse/routes/discourse.js.es6         |  4 +-
 .../routes/discovery-categories.js.es6        |  3 +-
 .../javascripts/discourse/routes/group.js.es6 |  6 +-
 .../javascripts/discourse/routes/topic.js.es6 |  4 +-
 .../javascripts/discourse/routes/user.js.es6  |  4 +-
 app/assets/javascripts/main_include_admin.js  |  6 ++
 .../tilt/es6_module_transpiler_template.rb    |  2 +
 .../admin/models/admin-user-test.js.es6       |  8 ++-
 .../admin/models/api-key-test.js.es6          | 11 +--
 .../admin/models/flagged-post-test.js.es6     |  6 +-
 test/javascripts/controllers/flag-test.js.es6 |  3 +-
 test/javascripts/lib/bbcode-test.js.es6       |  3 +-
 test/javascripts/models/composer-test.js.es6  |  2 +-
 test/javascripts/models/email-log-test.js.es6 |  4 +-
 test/javascripts/models/report-test.js.es6    |  5 +-
 .../models/staff-action-log-test.js.es6       |  6 +-
 .../models/version-check-test.js.es6          |  8 ++-
 99 files changed, 394 insertions(+), 384 deletions(-)
 rename app/assets/javascripts/admin/components/{resumable_upload_component.js => resumable-upload.js.es6} (96%)
 rename app/assets/javascripts/admin/components/{screened_ip_address_form_component.js => screened-ip-address-form-component.js.es6} (85%)
 rename app/assets/javascripts/admin/models/{admin_dashboard.js => admin-dashboard.js.es6} (68%)
 rename app/assets/javascripts/admin/models/{api_key.js => api-key.js.es6} (71%)
 rename app/assets/javascripts/admin/models/{color_scheme_color.js => color-scheme-color.js.es6} (88%)
 rename app/assets/javascripts/admin/models/{color_scheme.js => color-scheme.js.es6} (81%)
 rename app/assets/javascripts/admin/models/{email_log.js => email-log.js.es6} (56%)
 rename app/assets/javascripts/admin/models/{email_preview.js => email-preview.js.es6} (59%)
 create mode 100644 app/assets/javascripts/admin/models/email-settings.js.es6
 delete mode 100644 app/assets/javascripts/admin/models/email_settings.js
 rename app/assets/javascripts/admin/models/{flagged_post.js => flagged-post.js.es6} (92%)
 rename app/assets/javascripts/admin/models/{screened_email.js => screened-email.js.es6} (56%)
 rename app/assets/javascripts/admin/models/{screened_ip_address.js => screened-ip-address.js.es6} (79%)
 rename app/assets/javascripts/admin/models/{screened_url.js => screened-url.js.es6} (51%)
 rename app/assets/javascripts/admin/models/{staff_action_log.js => staff-action-log.js.es6} (85%)
 rename app/assets/javascripts/admin/models/{leader_requirements.js => tl3-requirements.js.es6} (96%)
 rename app/assets/javascripts/admin/models/{version_check.js => version-check.js.es6} (80%)
 create mode 100644 app/assets/javascripts/admin/routes/admin-email-all.js.es6
 rename app/assets/javascripts/admin/routes/{admin_email_index_route.js => admin-email-index.js.es6} (51%)
 rename app/assets/javascripts/admin/routes/{admin_email_logs_routes.js => admin-email-logs.js.es6} (55%)
 create mode 100644 app/assets/javascripts/admin/routes/admin-email-sent.js.es6
 create mode 100644 app/assets/javascripts/admin/routes/admin-email-skipped.js.es6
 create mode 100644 app/assets/javascripts/admin/routes/admin-logs-index.js.es6
 create mode 100644 app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
 create mode 100644 app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
 create mode 100644 app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
 rename app/assets/javascripts/admin/routes/{admin_reports_route.js => admin-reports.js.es6} (90%)
 create mode 100644 app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
 delete mode 100644 app/assets/javascripts/admin/routes/admin_logs_routes.js
 delete mode 100644 app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js
 create mode 100644 app/assets/javascripts/admin/views/admin-customize-colors.js.es6
 create mode 100644 app/assets/javascripts/admin/views/admin-user.js.es6
 delete mode 100644 app/assets/javascripts/admin/views/admin_customize_colors_view.js
 delete mode 100644 app/assets/javascripts/admin/views/admin_user_view.js

diff --git a/app/assets/javascripts/admin/components/ip-lookup.js.es6 b/app/assets/javascripts/admin/components/ip-lookup.js.es6
index f1fe7a391c6..63f61dcc98c 100644
--- a/app/assets/javascripts/admin/components/ip-lookup.js.es6
+++ b/app/assets/javascripts/admin/components/ip-lookup.js.es6
@@ -1,3 +1,4 @@
+
 export default Ember.Component.extend({
   classNames: ["ip-lookup"],
 
@@ -42,7 +43,8 @@ export default Ember.Component.extend({
           self.set("totalOthersWithSameIP", result.total);
         });
 
-        Discourse.AdminUser.findAll("active", data).then(function (users) {
+        const AdminUser = require('admin/models/admin-user').default;
+        AdminUser.findAll("active", data).then(function (users) {
           self.setProperties({
             other_accounts: users,
             otherAccountsLoading: false,
diff --git a/app/assets/javascripts/admin/components/permalink-form.js.es6 b/app/assets/javascripts/admin/components/permalink-form.js.es6
index 1bb29e52eb6..2bde845c0c6 100644
--- a/app/assets/javascripts/admin/components/permalink-form.js.es6
+++ b/app/assets/javascripts/admin/components/permalink-form.js.es6
@@ -18,15 +18,17 @@ export default Ember.Component.extend({
 
   actions: {
     submit: function() {
+      const Permalink = require('admin/models/permalink').default;
+
       if (!this.get('formSubmitted')) {
         const self = this;
         self.set('formSubmitted', true);
-        const permalink = Discourse.Permalink.create({url: self.get('url'), permalink_type: self.get('permalinkType'), permalink_type_value: self.get('permalink_type_value')});
+        const permalink = Permalink.create({url: self.get('url'), permalink_type: self.get('permalinkType'), permalink_type_value: self.get('permalink_type_value')});
         permalink.save().then(function(result) {
           self.set('url', '');
           self.set('permalink_type_value', '');
           self.set('formSubmitted', false);
-          self.sendAction('action', Discourse.Permalink.create(result.permalink));
+          self.sendAction('action', Permalink.create(result.permalink));
           Em.run.schedule('afterRender', function() { self.$('.permalink-url').focus(); });
         }, function(e) {
           self.set('formSubmitted', false);
diff --git a/app/assets/javascripts/admin/components/resumable_upload_component.js b/app/assets/javascripts/admin/components/resumable-upload.js.es6
similarity index 96%
rename from app/assets/javascripts/admin/components/resumable_upload_component.js
rename to app/assets/javascripts/admin/components/resumable-upload.js.es6
index dc040464dd2..c71bdb4797c 100644
--- a/app/assets/javascripts/admin/components/resumable_upload_component.js
+++ b/app/assets/javascripts/admin/components/resumable-upload.js.es6
@@ -10,7 +10,7 @@
         uploadText="UPLOAD"
     }}
 **/
-Discourse.ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer, {
+const ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer, {
   tagName: "button",
   classNames: ["btn", "ru"],
   classNameBindings: ["isUploading"],
@@ -118,3 +118,5 @@ Discourse.ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuff
   }.on("willDestroyElement")
 
 });
+
+export default ResumableUploadComponent;
diff --git a/app/assets/javascripts/admin/components/screened_ip_address_form_component.js b/app/assets/javascripts/admin/components/screened-ip-address-form-component.js.es6
similarity index 85%
rename from app/assets/javascripts/admin/components/screened_ip_address_form_component.js
rename to app/assets/javascripts/admin/components/screened-ip-address-form-component.js.es6
index 1bf90b0227b..8702dbb2f9e 100644
--- a/app/assets/javascripts/admin/components/screened_ip_address_form_component.js
+++ b/app/assets/javascripts/admin/components/screened-ip-address-form-component.js.es6
@@ -1,3 +1,4 @@
+import ScreenedIpAddress from 'admin/models/screened-ip-address';
 /**
   A form to create an IP address that will be blocked or whitelisted.
   Example usage:
@@ -13,7 +14,7 @@
   @namespace Discourse
   @module Discourse
 **/
-Discourse.ScreenedIpAddressFormComponent = Ember.Component.extend({
+const ScreenedIpAddressFormComponent = Ember.Component.extend({
   classNames: ['screened-ip-address-form'],
   formSubmitted: false,
   actionName: 'block',
@@ -42,11 +43,11 @@ Discourse.ScreenedIpAddressFormComponent = Ember.Component.extend({
       if (!this.get('formSubmitted')) {
         var self = this;
         this.set('formSubmitted', true);
-        var screenedIpAddress = Discourse.ScreenedIpAddress.create({ip_address: this.get('ip_address'), action_name: this.get('actionName')});
+        var screenedIpAddress = ScreenedIpAddress.create({ip_address: this.get('ip_address'), action_name: this.get('actionName')});
         screenedIpAddress.save().then(function(result) {
           self.set('ip_address', '');
           self.set('formSubmitted', false);
-          self.sendAction('action', Discourse.ScreenedIpAddress.create(result.screened_ip_address));
+          self.sendAction('action', ScreenedIpAddress.create(result.screened_ip_address));
           Em.run.schedule('afterRender', function() { self.$('.ip-address-input').focus(); });
         }, function(e) {
           self.set('formSubmitted', false);
@@ -74,3 +75,5 @@ Discourse.ScreenedIpAddressFormComponent = Ember.Component.extend({
     });
   }
 });
+
+export default ScreenedIpAddressFormComponent;
diff --git a/app/assets/javascripts/admin/controllers/admin-api.js.es6 b/app/assets/javascripts/admin/controllers/admin-api.js.es6
index 6dc3ed9ab1c..1bb0a7dc2ff 100644
--- a/app/assets/javascripts/admin/controllers/admin-api.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-api.js.es6
@@ -1,3 +1,5 @@
+import ApiKey from 'admin/models/api-key';
+
 /**
   This controller supports the interface for dealing with API keys
 
@@ -16,7 +18,7 @@ export default Ember.ArrayController.extend({
     **/
     generateMasterKey: function() {
       var self = this;
-      Discourse.ApiKey.generateMasterKey().then(function (key) {
+      ApiKey.generateMasterKey().then(function (key) {
         self.get('model').pushObject(key);
       });
     },
@@ -25,7 +27,7 @@ export default Ember.ArrayController.extend({
       Creates an API key instance with internal user object
 
       @method regenerateKey
-      @param {Discourse.ApiKey} key the key to regenerate
+      @param {ApiKey} key the key to regenerate
     **/
     regenerateKey: function(key) {
       bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
@@ -39,7 +41,7 @@ export default Ember.ArrayController.extend({
       Revokes an API key
 
       @method revokeKey
-      @param {Discourse.ApiKey} key the key to revoke
+      @param {ApiKey} key the key to revoke
     **/
     revokeKey: function(key) {
       var self = this;
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
index c712a8ac5a4..0e0b33b5130 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
@@ -1,4 +1,5 @@
 import { setting } from 'discourse/lib/computed';
+import AdminDashboard from 'admin/models/admin-dashboard';
 
 // This controller supports the default interface when you enter the admin section.
 export default Ember.Controller.extend({
@@ -26,7 +27,7 @@ export default Ember.Controller.extend({
     this.set('loadingProblems', true);
     this.set('problemsFetchedAt', new Date());
     var c = this;
-    Discourse.AdminDashboard.fetchProblems().then(function(d) {
+    AdminDashboard.fetchProblems().then(function(d) {
       c.set('problems', d.problems);
       c.set('loadingProblems', false);
       if( d.problems && d.problems.length > 0 ) {
diff --git a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6
index 8a3fd0b9609..160f998365b 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6
@@ -1,3 +1,5 @@
+import EmailPreview from 'admin/models/email-preview';
+
 export default Ember.Controller.extend({
 
   actions: {
@@ -5,7 +7,7 @@ export default Ember.Controller.extend({
       const model = this.get('model');
 
       this.set('loading', true);
-      Discourse.EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => {
+      EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => {
         model.setProperties(email.getProperties('html_content', 'text_content'));
         this.set('loading', false);
       });
diff --git a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6
index a03bd8212d7..6ea640672c2 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6
@@ -1,10 +1,11 @@
 import debounce from 'discourse/lib/debounce';
+import EmailLog from 'admin/models/email-log';
 
 export default Ember.Controller.extend({
 
   filterEmailLogs: debounce(function() {
     var self = this;
-    Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) {
+    EmailLog.findAll(this.get("filter")).then(function(logs) {
       self.set("model", logs);
     });
   }, 250).observes("filter.user", "filter.address", "filter.type", "filter.reply_key")
diff --git a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6
index 1d83f14c6d8..b392ea8e987 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6
@@ -2,9 +2,7 @@ import debounce from 'discourse/lib/debounce';
 
 export default Ember.Controller.extend({
   filterEmailLogs: debounce(function() {
-    var self = this;
-    Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) {
-      self.set("model", logs);
-    });
+    const EmailLog = require('admin/models/email-log').default;
+    EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs));
   }, 250).observes("filter.user", "filter.address", "filter.type", "filter.skipped_reason")
 });
diff --git a/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6 b/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6
index 9ef1a432720..94de6841c53 100644
--- a/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6
@@ -1,3 +1,5 @@
+import FlaggedPost from 'admin/models/flagged-post';
+
 export default Ember.ArrayController.extend({
   query: null,
 
@@ -30,7 +32,7 @@ export default Ember.ArrayController.extend({
 
   loadMore(){
     var flags = this.get("model");
-    return Discourse.FlaggedPost.findAll(this.get("query"),flags.length+1).then(function(data){
+    return FlaggedPost.findAll(this.get("query"),flags.length+1).then(function(data){
       if(data.length===0){
         flags.set("allLoaded",true);
       }
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
index 77edccd3b1b..fe158a33aba 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
@@ -1,5 +1,6 @@
 import { exportEntity } from 'discourse/lib/export-csv';
 import { outputExportResult } from 'discourse/lib/export-result';
+import ScreenedEmail from 'admin/models/screened-email';
 
 export default Ember.ArrayController.extend({
   loading: false,
@@ -20,7 +21,7 @@ export default Ember.ArrayController.extend({
   show() {
     var self = this;
     self.set('loading', true);
-    Discourse.ScreenedEmail.findAll().then(function(result) {
+    ScreenedEmail.findAll().then(function(result) {
       self.set('model', result);
       self.set('loading', false);
     });
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
index 987b07a3b66..88bc10f0e77 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
@@ -1,6 +1,7 @@
 import debounce from 'discourse/lib/debounce';
 import { outputExportResult } from 'discourse/lib/export-result';
 import { exportEntity } from 'discourse/lib/export-csv';
+import ScreenedIpAddress from 'admin/models/screened-ip-address';
 
 export default Ember.ArrayController.extend({
   loading: false,
@@ -10,7 +11,7 @@ export default Ember.ArrayController.extend({
   show: debounce(function() {
     var self = this;
     self.set('loading', true);
-    Discourse.ScreenedIpAddress.findAll(this.get("filter")).then(function(result) {
+    ScreenedIpAddress.findAll(this.get("filter")).then(function(result) {
       self.set('model', result);
       self.set('loading', false);
     });
@@ -26,7 +27,7 @@ export default Ember.ArrayController.extend({
       return bootbox.confirm(I18n.t("admin.logs.screened_ips.roll_up_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function (confirmed) {
         if (confirmed) {
           self.set("loading", true);
-          return Discourse.ScreenedIpAddress.rollUp().then(function(results) {
+          return ScreenedIpAddress.rollUp().then(function(results) {
             if (results && results.subnets) {
               if (results.subnets.length > 0) {
                 self.send("show");
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
index d573a738b61..5f5e3339608 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
@@ -1,5 +1,6 @@
 import { exportEntity } from 'discourse/lib/export-csv';
 import { outputExportResult } from 'discourse/lib/export-result';
+import ScreenedUrl from 'admin/models/screened-url';
 
 export default Ember.ArrayController.extend({
   loading: false,
@@ -7,7 +8,7 @@ export default Ember.ArrayController.extend({
   show() {
     const self = this;
     self.set('loading', true);
-    Discourse.ScreenedUrl.findAll().then(function(result) {
+    ScreenedUrl.findAll().then(function(result) {
       self.set('model', result);
       self.set('loading', false);
     });
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
index 58b2583cedc..956a737e578 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
@@ -1,5 +1,6 @@
 import { exportEntity } from 'discourse/lib/export-csv';
 import { outputExportResult } from 'discourse/lib/export-result';
+import StaffActionLog from 'admin/models/staff-action-log';
 
 export default Ember.ArrayController.extend({
   loading: false,
@@ -36,7 +37,7 @@ export default Ember.ArrayController.extend({
     });
     this.set('filterCount', count);
 
-    Discourse.StaffActionLog.findAll(params).then(function(result) {
+    StaffActionLog.findAll(params).then(function(result) {
       self.set('model', result);
     }).finally(function() {
       self.set('loading', false);
diff --git a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
index a0d38e7b8cc..9c5ab4bb3e8 100644
--- a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
@@ -1,4 +1,5 @@
 import debounce from 'discourse/lib/debounce';
+import Permalink from 'admin/models/permalink';
 
 export default Ember.ArrayController.extend({
   loading: false,
@@ -7,7 +8,7 @@ export default Ember.ArrayController.extend({
   show: debounce(function() {
     var self = this;
     self.set('loading', true);
-    Discourse.Permalink.findAll(self.get("filter")).then(function(result) {
+    Permalink.findAll(self.get("filter")).then(function(result) {
       self.set('model', result);
       self.set('loading', false);
     });
diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
index a0eaf6e1622..af4a0297ef6 100644
--- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
@@ -1,5 +1,6 @@
 import debounce from 'discourse/lib/debounce';
 import { i18n } from 'discourse/lib/computed';
+import AdminUser from 'admin/models/admin-user';
 
 export default Ember.ArrayController.extend({
   query: null,
@@ -42,7 +43,7 @@ export default Ember.ArrayController.extend({
     var self = this;
     this.set('refreshing', true);
 
-    Discourse.AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails') }).then(function (result) {
+    AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails') }).then(function (result) {
       self.set('model', result);
     }).finally(function() {
       self.set('refreshing', false);
@@ -51,14 +52,14 @@ export default Ember.ArrayController.extend({
 
   actions: {
     approveUsers: function() {
-      Discourse.AdminUser.bulkApprove(this.get('model').filterProperty('selected'));
+      AdminUser.bulkApprove(this.get('model').filterProperty('selected'));
       this._refreshUsers();
     },
 
     rejectUsers: function() {
       var maxPostAge = this.siteSettings.delete_user_max_post_age;
       var controller = this;
-      Discourse.AdminUser.bulkReject(this.get('model').filterProperty('selected')).then(function(result){
+      AdminUser.bulkReject(this.get('model').filterProperty('selected')).then(function(result){
         var message = I18n.t("admin.users.reject_successful", {count: result.success});
         if (result.failed > 0) {
           message += ' ' + I18n.t("admin.users.reject_failures", {count: result.failed});
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
index 682b1ba25dc..15cd838245b 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
@@ -1,4 +1,5 @@
 import ModalFunctionality from 'discourse/mixins/modal-functionality';
+import Backup from 'admin/models/backup';
 
 export default Ember.Controller.extend(ModalFunctionality, {
   needs: ["adminBackupsLogs"],
@@ -6,7 +7,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
   _startBackup: function (withUploads) {
     var self = this;
     Discourse.User.currentProp("hideReadOnlyAlert", true);
-    Discourse.Backup.start(withUploads).then(function() {
+    Backup.start(withUploads).then(function() {
       self.get("controllers.adminBackupsLogs").clear();
       self.send("backupStarted");
     });
diff --git a/app/assets/javascripts/admin/models/admin_dashboard.js b/app/assets/javascripts/admin/models/admin-dashboard.js.es6
similarity index 68%
rename from app/assets/javascripts/admin/models/admin_dashboard.js
rename to app/assets/javascripts/admin/models/admin-dashboard.js.es6
index 4aaf0984687..866012b9529 100644
--- a/app/assets/javascripts/admin/models/admin_dashboard.js
+++ b/app/assets/javascripts/admin/models/admin-dashboard.js.es6
@@ -1,15 +1,7 @@
-/**
-  A model that stores all or some data that is displayed on the dashboard.
 
-  @class AdminDashboard
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
+const AdminDashboard = Discourse.Model.extend({});
 
-Discourse.AdminDashboard = Discourse.Model.extend({});
-
-Discourse.AdminDashboard.reopenClass({
+AdminDashboard.reopenClass({
 
   /**
     Fetch all dashboard data. This can be an expensive request when the cached data
@@ -20,7 +12,7 @@ Discourse.AdminDashboard.reopenClass({
   **/
   find: function() {
     return Discourse.ajax("/admin/dashboard.json").then(function(json) {
-      var model = Discourse.AdminDashboard.create(json);
+      var model = AdminDashboard.create(json);
       model.set('loaded', true);
       return model;
     });
@@ -38,9 +30,11 @@ Discourse.AdminDashboard.reopenClass({
       type: 'GET',
       dataType: 'json'
     }).then(function(json) {
-      var model = Discourse.AdminDashboard.create(json);
+      var model = AdminDashboard.create(json);
       model.set('loaded', true);
       return model;
     });
   }
 });
+
+export default AdminDashboard;
diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6
index 20a9579bd62..3815111ec23 100644
--- a/app/assets/javascripts/admin/models/admin-user.js.es6
+++ b/app/assets/javascripts/admin/models/admin-user.js.es6
@@ -1,17 +1,20 @@
 import { propertyNotEqual } from 'discourse/lib/computed';
 import { popupAjaxError } from 'discourse/lib/ajax-error';
+import ApiKey from 'admin/models/api-key';
+import Group from 'discourse/models/group';
+import TL3Requirements from 'admin/models/tl3-requirements';
 
 const AdminUser = Discourse.User.extend({
 
-  customGroups: Em.computed.filter("groups", (g) => !g.automatic && Discourse.Group.create(g)),
-  automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Discourse.Group.create(g)),
+  customGroups: Em.computed.filter("groups", (g) => !g.automatic && Group.create(g)),
+  automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Group.create(g)),
 
   generateApiKey() {
     const self = this;
     return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", {
       type: 'POST'
     }).then(function (result) {
-      const apiKey = Discourse.ApiKey.create(result.api_key);
+      const apiKey = ApiKey.create(result.api_key);
       self.set('api_key', apiKey);
       return apiKey;
     });
@@ -377,7 +380,7 @@ const AdminUser = Discourse.User.extend({
           }
         }
       }).catch(function() {
-        Discourse.AdminUser.find( user.get('username') ).then(function(u){ user.setProperties(u); });
+        AdminUser.find( user.get('username') ).then(function(u){ user.setProperties(u); });
         bootbox.alert(I18n.t("admin.user.delete_failed"));
       });
     };
@@ -450,7 +453,7 @@ const AdminUser = Discourse.User.extend({
 
     if (user.get('loadedDetails')) { return Ember.RSVP.resolve(user); }
 
-    return Discourse.AdminUser.find(user.get('username_lower')).then(function (result) {
+    return AdminUser.find(user.get('username_lower')).then(function (result) {
       user.setProperties(result);
       user.set('loadedDetails', true);
     });
@@ -458,19 +461,19 @@ const AdminUser = Discourse.User.extend({
 
   tl3Requirements: function() {
     if (this.get('tl3_requirements')) {
-      return Discourse.TL3Requirements.create(this.get('tl3_requirements'));
+      return TL3Requirements.create(this.get('tl3_requirements'));
     }
   }.property('tl3_requirements'),
 
   suspendedBy: function() {
     if (this.get('suspended_by')) {
-      return Discourse.AdminUser.create(this.get('suspended_by'));
+      return AdminUser.create(this.get('suspended_by'));
     }
   }.property('suspended_by'),
 
   approvedBy: function() {
     if (this.get('approved_by')) {
-      return Discourse.AdminUser.create(this.get('approved_by'));
+      return AdminUser.create(this.get('approved_by'));
     }
   }.property('approved_by')
 
@@ -511,7 +514,7 @@ AdminUser.reopenClass({
   find(username) {
     return Discourse.ajax("/admin/users/" + username + ".json").then(function (result) {
       result.loadedDetails = true;
-      return Discourse.AdminUser.create(result);
+      return AdminUser.create(result);
     });
   },
 
@@ -519,7 +522,7 @@ AdminUser.reopenClass({
     return Discourse.ajax("/admin/users/list/" + query + ".json", {
       data: filter
     }).then(function(users) {
-      return users.map((u) => Discourse.AdminUser.create(u));
+      return users.map((u) => AdminUser.create(u));
     });
   }
 });
diff --git a/app/assets/javascripts/admin/models/api_key.js b/app/assets/javascripts/admin/models/api-key.js.es6
similarity index 71%
rename from app/assets/javascripts/admin/models/api_key.js
rename to app/assets/javascripts/admin/models/api-key.js.es6
index 40968855841..7ef77195437 100644
--- a/app/assets/javascripts/admin/models/api_key.js
+++ b/app/assets/javascripts/admin/models/api-key.js.es6
@@ -1,12 +1,4 @@
-/**
-  Our data model for representing an API key in the system
-
-  @class ApiKey
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.ApiKey = Discourse.Model.extend({
+const ApiKey = Discourse.Model.extend({
 
   /**
     Regenerates the api key
@@ -34,19 +26,20 @@ Discourse.ApiKey = Discourse.Model.extend({
 
 });
 
-Discourse.ApiKey.reopenClass({
+ApiKey.reopenClass({
 
   /**
     Creates an API key instance with internal user object
 
     @method create
     @param {...} var_args the properties to initialize this with
-    @returns {Discourse.ApiKey} the ApiKey instance
+    @returns {ApiKey} the ApiKey instance
   **/
   create: function() {
+    const AdminUser = require('admin/models/admin-user').default;
     var result = this._super.apply(this, arguments);
     if (result.user) {
-      result.user = Discourse.AdminUser.create(result.user);
+      result.user = AdminUser.create(result.user);
     }
     return result;
   },
@@ -55,12 +48,12 @@ Discourse.ApiKey.reopenClass({
     Finds a list of API keys
 
     @method find
-    @returns {Promise} a promise that resolves to the array of `Discourse.ApiKey` instances
+    @returns {Promise} a promise that resolves to the array of `ApiKey` instances
   **/
   find: function() {
     return Discourse.ajax("/admin/api").then(function(keys) {
       return keys.map(function (key) {
-        return Discourse.ApiKey.create(key);
+        return ApiKey.create(key);
       });
     });
   },
@@ -69,12 +62,14 @@ Discourse.ApiKey.reopenClass({
     Generates a master api key and returns it.
 
     @method generateMasterKey
-    @returns {Promise} a promise that resolves to a master `Discourse.ApiKey`
+    @returns {Promise} a promise that resolves to a master `ApiKey`
   **/
   generateMasterKey: function() {
     return Discourse.ajax("/admin/api/key", {type: 'POST'}).then(function (result) {
-      return Discourse.ApiKey.create(result.api_key);
+      return ApiKey.create(result.api_key);
     });
   }
 
 });
+
+export default ApiKey;
diff --git a/app/assets/javascripts/admin/models/color_scheme_color.js b/app/assets/javascripts/admin/models/color-scheme-color.js.es6
similarity index 88%
rename from app/assets/javascripts/admin/models/color_scheme_color.js
rename to app/assets/javascripts/admin/models/color-scheme-color.js.es6
index 9b598961fcf..07e2bb95f83 100644
--- a/app/assets/javascripts/admin/models/color_scheme_color.js
+++ b/app/assets/javascripts/admin/models/color-scheme-color.js.es6
@@ -1,13 +1,4 @@
-/**
-  Our data model for a color within a color scheme.
-  (It's a funny name for a class, but Color seemed too generic for what this class is.)
-
-  @class ColorSchemeColor
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.ColorSchemeColor = Discourse.Model.extend({
+const ColorSchemeColor = Discourse.Model.extend({
 
   init: function() {
     this._super();
@@ -78,3 +69,5 @@ Discourse.ColorSchemeColor = Discourse.Model.extend({
     return this.get('hex').match(/^([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/) !== null;
   }.property('hex')
 });
+
+export default ColorSchemeColor;
diff --git a/app/assets/javascripts/admin/models/color_scheme.js b/app/assets/javascripts/admin/models/color-scheme.js.es6
similarity index 81%
rename from app/assets/javascripts/admin/models/color_scheme.js
rename to app/assets/javascripts/admin/models/color-scheme.js.es6
index e55cad1999c..512672230d4 100644
--- a/app/assets/javascripts/admin/models/color_scheme.js
+++ b/app/assets/javascripts/admin/models/color-scheme.js.es6
@@ -1,12 +1,6 @@
-/**
-  Our data model for a color scheme.
+import ColorSchemeColor from 'admin/models/color-scheme-color';
 
-  @class ColorScheme
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.ColorScheme = Discourse.Model.extend(Ember.Copyable, {
+const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
 
   init: function() {
     this._super();
@@ -25,9 +19,9 @@ Discourse.ColorScheme = Discourse.Model.extend(Ember.Copyable, {
   },
 
   copy: function() {
-    var newScheme = Discourse.ColorScheme.create({name: this.get('name'), enabled: false, can_edit: true, colors: Em.A()});
+    var newScheme = ColorScheme.create({name: this.get('name'), enabled: false, can_edit: true, colors: Em.A()});
     _.each(this.get('colors'), function(c){
-      newScheme.colors.pushObject(Discourse.ColorSchemeColor.create({name: c.get('name'), hex: c.get('hex'), default_hex: c.get('default_hex')}));
+      newScheme.colors.pushObject(ColorSchemeColor.create({name: c.get('name'), hex: c.get('hex'), default_hex: c.get('default_hex')}));
     });
     return newScheme;
   },
@@ -109,17 +103,17 @@ var ColorSchemes = Ember.ArrayProxy.extend({
   }.observes('selectedItem')
 });
 
-Discourse.ColorScheme.reopenClass({
+ColorScheme.reopenClass({
   findAll: function() {
     var colorSchemes = ColorSchemes.create({ content: [], loading: true });
     Discourse.ajax('/admin/color_schemes').then(function(all) {
       _.each(all, function(colorScheme){
-        colorSchemes.pushObject(Discourse.ColorScheme.create({
+        colorSchemes.pushObject(ColorScheme.create({
           id: colorScheme.id,
           name: colorScheme.name,
           enabled: colorScheme.enabled,
           is_base: colorScheme.is_base,
-          colors: colorScheme.colors.map(function(c) { return Discourse.ColorSchemeColor.create({name: c.name, hex: c.hex, default_hex: c.default_hex}); })
+          colors: colorScheme.colors.map(function(c) { return ColorSchemeColor.create({name: c.name, hex: c.hex, default_hex: c.default_hex}); })
         }));
       });
       colorSchemes.set('loading', false);
@@ -127,3 +121,5 @@ Discourse.ColorScheme.reopenClass({
     return colorSchemes;
   }
 });
+
+export default ColorScheme;
diff --git a/app/assets/javascripts/admin/models/email_log.js b/app/assets/javascripts/admin/models/email-log.js.es6
similarity index 56%
rename from app/assets/javascripts/admin/models/email_log.js
rename to app/assets/javascripts/admin/models/email-log.js.es6
index fe824866997..ce7d8a2420d 100644
--- a/app/assets/javascripts/admin/models/email_log.js
+++ b/app/assets/javascripts/admin/models/email-log.js.es6
@@ -1,20 +1,14 @@
-/**
-  Our data model for representing an email log.
+import AdminUser from 'admin/models/admin-user';
 
-  @class EmailLog
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.EmailLog = Discourse.Model.extend({});
+const EmailLog = Discourse.Model.extend({});
 
-Discourse.EmailLog.reopenClass({
+EmailLog.reopenClass({
 
   create: function(attrs) {
     attrs = attrs || {};
 
     if (attrs.user) {
-      attrs.user = Discourse.AdminUser.create(attrs.user);
+      attrs.user = AdminUser.create(attrs.user);
     }
 
     return this._super(attrs);
@@ -27,10 +21,10 @@ Discourse.EmailLog.reopenClass({
 
     return Discourse.ajax("/admin/email/" + status + ".json", { data: filter }).then(function(logs) {
       return _.map(logs, function (log) {
-        return Discourse.EmailLog.create(log);
+        return EmailLog.create(log);
       });
     });
   }
 });
 
-
+export default EmailLog;
diff --git a/app/assets/javascripts/admin/models/email_preview.js b/app/assets/javascripts/admin/models/email-preview.js.es6
similarity index 59%
rename from app/assets/javascripts/admin/models/email_preview.js
rename to app/assets/javascripts/admin/models/email-preview.js.es6
index 8ae9bdfcd4f..12826f98ed0 100644
--- a/app/assets/javascripts/admin/models/email_preview.js
+++ b/app/assets/javascripts/admin/models/email-preview.js.es6
@@ -1,14 +1,6 @@
-/**
-  Our data model for showing a preview of an email
+const EmailPreview = Discourse.Model.extend({});
 
-  @class EmailPreview
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.EmailPreview = Discourse.Model.extend({});
-
-Discourse.EmailPreview.reopenClass({
+EmailPreview.reopenClass({
   findDigest: function(lastSeenAt, username) {
 
     if (Em.isEmpty(lastSeenAt)) {
@@ -22,7 +14,9 @@ Discourse.EmailPreview.reopenClass({
     return Discourse.ajax("/admin/email/preview-digest.json", {
       data: { last_seen_at: lastSeenAt, username: username }
     }).then(function (result) {
-      return Discourse.EmailPreview.create(result);
+      return EmailPreview.create(result);
     });
   }
 });
+
+export default EmailPreview;
diff --git a/app/assets/javascripts/admin/models/email-settings.js.es6 b/app/assets/javascripts/admin/models/email-settings.js.es6
new file mode 100644
index 00000000000..1b8f791f268
--- /dev/null
+++ b/app/assets/javascripts/admin/models/email-settings.js.es6
@@ -0,0 +1,11 @@
+const EmailSettings = Discourse.Model.extend({});
+
+EmailSettings.reopenClass({
+  find: function() {
+    return Discourse.ajax("/admin/email.json").then(function (settings) {
+      return EmailSettings.create(settings);
+    });
+  }
+});
+
+export default EmailSettings;
diff --git a/app/assets/javascripts/admin/models/email_settings.js b/app/assets/javascripts/admin/models/email_settings.js
deleted file mode 100644
index d061635515d..00000000000
--- a/app/assets/javascripts/admin/models/email_settings.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
-  Our data model for representing the current email settings
-
-  @class EmailSettings
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.EmailSettings = Discourse.Model.extend({});
-
-Discourse.EmailSettings.reopenClass({
-  find: function() {
-    return Discourse.ajax("/admin/email.json").then(function (settings) {
-      return Discourse.EmailSettings.create(settings);
-    });
-  }
-});
diff --git a/app/assets/javascripts/admin/models/flagged_post.js b/app/assets/javascripts/admin/models/flagged-post.js.es6
similarity index 92%
rename from app/assets/javascripts/admin/models/flagged_post.js
rename to app/assets/javascripts/admin/models/flagged-post.js.es6
index e3a01948ca0..8492c4f8b7e 100644
--- a/app/assets/javascripts/admin/models/flagged_post.js
+++ b/app/assets/javascripts/admin/models/flagged-post.js.es6
@@ -1,12 +1,9 @@
-/**
-  Our data model for interacting with flagged posts.
+import AdminUser from 'admin/models/admin-user';
+import Topic from 'discourse/models/topic';
+import Post from 'discourse/models/post';
 
-  @class FlaggedPost
-  @extends Discourse.Post
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.FlaggedPost = Discourse.Post.extend({
+
+const FlaggedPost = Post.extend({
 
   summary: function () {
     return _(this.post_actions)
@@ -140,7 +137,7 @@ Discourse.FlaggedPost = Discourse.Post.extend({
 
 });
 
-Discourse.FlaggedPost.reopenClass({
+FlaggedPost.reopenClass({
   findAll: function (filter, offset) {
     offset = offset || 0;
 
@@ -151,18 +148,18 @@ Discourse.FlaggedPost.reopenClass({
       // users
       var userLookup = {};
       _.each(data.users, function (user) {
-        userLookup[user.id] = Discourse.AdminUser.create(user);
+        userLookup[user.id] = AdminUser.create(user);
       });
 
       // topics
       var topicLookup = {};
       _.each(data.topics, function (topic) {
-        topicLookup[topic.id] = Discourse.Topic.create(topic);
+        topicLookup[topic.id] = Topic.create(topic);
       });
 
       // posts
       _.each(data.posts, function (post) {
-        var f = Discourse.FlaggedPost.create(post);
+        var f = FlaggedPost.create(post);
         f.userLookup = userLookup;
         f.topicLookup = topicLookup;
         result.pushObject(f);
@@ -174,3 +171,5 @@ Discourse.FlaggedPost.reopenClass({
     });
   }
 });
+
+export default FlaggedPost;
diff --git a/app/assets/javascripts/admin/models/permalink.js.es6 b/app/assets/javascripts/admin/models/permalink.js.es6
index 761cd4ab51f..eb867adb315 100644
--- a/app/assets/javascripts/admin/models/permalink.js.es6
+++ b/app/assets/javascripts/admin/models/permalink.js.es6
@@ -14,7 +14,7 @@ const Permalink = Discourse.Model.extend({
 Permalink.reopenClass({
   findAll: function(filter) {
     return Discourse.ajax("/admin/permalinks.json", { data: { filter: filter } }).then(function(permalinks) {
-      return permalinks.map(p => Discourse.Permalink.create(p));
+      return permalinks.map(p => Permalink.create(p));
     });
   }
 });
diff --git a/app/assets/javascripts/admin/models/screened_email.js b/app/assets/javascripts/admin/models/screened-email.js.es6
similarity index 56%
rename from app/assets/javascripts/admin/models/screened_email.js
rename to app/assets/javascripts/admin/models/screened-email.js.es6
index 5e6a8ddf832..71c74d0ad0c 100644
--- a/app/assets/javascripts/admin/models/screened_email.js
+++ b/app/assets/javascripts/admin/models/screened-email.js.es6
@@ -1,13 +1,4 @@
-/**
-  Represents an email address that is watched for during account registration,
-  and an action is taken.
-
-  @class ScreenedEmail
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.ScreenedEmail = Discourse.Model.extend({
+const ScreenedEmail = Discourse.Model.extend({
   actionName: function() {
     return I18n.t("admin.logs.screened_actions." + this.get('action'));
   }.property('action'),
@@ -17,12 +8,14 @@ Discourse.ScreenedEmail = Discourse.Model.extend({
   }
 });
 
-Discourse.ScreenedEmail.reopenClass({
+ScreenedEmail.reopenClass({
   findAll: function() {
     return Discourse.ajax("/admin/logs/screened_emails.json").then(function(screened_emails) {
       return screened_emails.map(function(b) {
-        return Discourse.ScreenedEmail.create(b);
+        return ScreenedEmail.create(b);
       });
     });
   }
 });
+
+export default ScreenedEmail;
diff --git a/app/assets/javascripts/admin/models/screened_ip_address.js b/app/assets/javascripts/admin/models/screened-ip-address.js.es6
similarity index 79%
rename from app/assets/javascripts/admin/models/screened_ip_address.js
rename to app/assets/javascripts/admin/models/screened-ip-address.js.es6
index f487896206b..51f8ff5021a 100644
--- a/app/assets/javascripts/admin/models/screened_ip_address.js
+++ b/app/assets/javascripts/admin/models/screened-ip-address.js.es6
@@ -1,8 +1,4 @@
-/**
-  Represents an IP address that is watched for during account registration
-  (and possibly other times), and an action is taken.
-**/
-Discourse.ScreenedIpAddress = Discourse.Model.extend({
+const ScreenedIpAddress = Discourse.Model.extend({
   actionName: function() {
     return I18n.t("admin.logs.screened_ips.actions." + this.get('action_name'));
   }.property('action_name'),
@@ -27,11 +23,11 @@ Discourse.ScreenedIpAddress = Discourse.Model.extend({
   }
 });
 
-Discourse.ScreenedIpAddress.reopenClass({
+ScreenedIpAddress.reopenClass({
   findAll: function(filter) {
     return Discourse.ajax("/admin/logs/screened_ip_addresses.json", { data: { filter: filter } }).then(function(screened_ips) {
       return screened_ips.map(function(b) {
-        return Discourse.ScreenedIpAddress.create(b);
+        return ScreenedIpAddress.create(b);
       });
     });
   },
@@ -40,3 +36,5 @@ Discourse.ScreenedIpAddress.reopenClass({
     return Discourse.ajax("/admin/logs/screened_ip_addresses/roll_up", { type: "POST" });
   }
 });
+
+export default ScreenedIpAddress;
diff --git a/app/assets/javascripts/admin/models/screened_url.js b/app/assets/javascripts/admin/models/screened-url.js.es6
similarity index 51%
rename from app/assets/javascripts/admin/models/screened_url.js
rename to app/assets/javascripts/admin/models/screened-url.js.es6
index 60c4f984b4f..9b16c7faecb 100644
--- a/app/assets/javascripts/admin/models/screened_url.js
+++ b/app/assets/javascripts/admin/models/screened-url.js.es6
@@ -1,23 +1,17 @@
-/**
-  Represents a URL that is watched for, and an action may be taken.
-
-  @class ScreenedUrl
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.ScreenedUrl = Discourse.Model.extend({
+const ScreenedUrl = Discourse.Model.extend({
   actionName: function() {
     return I18n.t("admin.logs.screened_actions." + this.get('action'));
   }.property('action')
 });
 
-Discourse.ScreenedUrl.reopenClass({
+ScreenedUrl.reopenClass({
   findAll: function() {
     return Discourse.ajax("/admin/logs/screened_urls.json").then(function(screened_urls) {
       return screened_urls.map(function(b) {
-        return Discourse.ScreenedUrl.create(b);
+        return ScreenedUrl.create(b);
       });
     });
   }
 });
+
+export default ScreenedUrl;
diff --git a/app/assets/javascripts/admin/models/site-setting.js.es6 b/app/assets/javascripts/admin/models/site-setting.js.es6
index 1d769369cab..98b3ab896ee 100644
--- a/app/assets/javascripts/admin/models/site-setting.js.es6
+++ b/app/assets/javascripts/admin/models/site-setting.js.es6
@@ -35,7 +35,7 @@ SiteSetting.reopenClass({
         if (!categories[s.category]) {
           categories[s.category] = [];
         }
-        categories[s.category].pushObject(Discourse.SiteSetting.create(s));
+        categories[s.category].pushObject(SiteSetting.create(s));
       });
 
       return Object.keys(categories).map(function(n) {
diff --git a/app/assets/javascripts/admin/models/staff_action_log.js b/app/assets/javascripts/admin/models/staff-action-log.js.es6
similarity index 85%
rename from app/assets/javascripts/admin/models/staff_action_log.js
rename to app/assets/javascripts/admin/models/staff-action-log.js.es6
index 0dde7736616..bc3ff520a0c 100644
--- a/app/assets/javascripts/admin/models/staff_action_log.js
+++ b/app/assets/javascripts/admin/models/staff-action-log.js.es6
@@ -1,4 +1,6 @@
-Discourse.StaffActionLog = Discourse.Model.extend({
+import AdminUser from 'admin/models/admin-user';
+
+const StaffActionLog = Discourse.Model.extend({
   showFullDetails: false,
 
   actionName: function() {
@@ -39,15 +41,15 @@ Discourse.StaffActionLog = Discourse.Model.extend({
   }.property('action_name')
 });
 
-Discourse.StaffActionLog.reopenClass({
+StaffActionLog.reopenClass({
   create: function(attrs) {
     attrs = attrs || {};
 
     if (attrs.acting_user) {
-      attrs.acting_user = Discourse.AdminUser.create(attrs.acting_user);
+      attrs.acting_user = AdminUser.create(attrs.acting_user);
     }
     if (attrs.target_user) {
-      attrs.target_user = Discourse.AdminUser.create(attrs.target_user);
+      attrs.target_user = AdminUser.create(attrs.target_user);
     }
     return this._super(attrs);
   },
@@ -55,8 +57,10 @@ Discourse.StaffActionLog.reopenClass({
   findAll: function(filters) {
     return Discourse.ajax("/admin/logs/staff_action_logs.json", { data: filters }).then(function(staff_actions) {
       return staff_actions.map(function(s) {
-        return Discourse.StaffActionLog.create(s);
+        return StaffActionLog.create(s);
       });
     });
   }
 });
+
+export default StaffActionLog;
diff --git a/app/assets/javascripts/admin/models/leader_requirements.js b/app/assets/javascripts/admin/models/tl3-requirements.js.es6
similarity index 96%
rename from app/assets/javascripts/admin/models/leader_requirements.js
rename to app/assets/javascripts/admin/models/tl3-requirements.js.es6
index 9b42d122449..1bb9e42811c 100644
--- a/app/assets/javascripts/admin/models/leader_requirements.js
+++ b/app/assets/javascripts/admin/models/tl3-requirements.js.es6
@@ -1,4 +1,4 @@
-Discourse.TL3Requirements = Discourse.Model.extend({
+const TL3Requirements = Discourse.Model.extend({
   days_visited_percent: function() {
     return ((this.get('days_visited') * 100) / this.get('time_period'));
   }.property('days_visited', 'time_period'),
@@ -38,3 +38,5 @@ Discourse.TL3Requirements = Discourse.Model.extend({
              'num_likes_received_users', 'min_likes_received_users',
              'trust_level_locked')
 });
+
+export default TL3Requirements;
diff --git a/app/assets/javascripts/admin/models/version_check.js b/app/assets/javascripts/admin/models/version-check.js.es6
similarity index 80%
rename from app/assets/javascripts/admin/models/version_check.js
rename to app/assets/javascripts/admin/models/version-check.js.es6
index 2add3b7b2f0..4f9b2c4c660 100644
--- a/app/assets/javascripts/admin/models/version_check.js
+++ b/app/assets/javascripts/admin/models/version-check.js.es6
@@ -1,12 +1,4 @@
-/**
-  Our data model for determining whether there's a new version of Discourse
-
-  @class VersionCheck
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.VersionCheck = Discourse.Model.extend({
+const VersionCheck = Discourse.Model.extend({
 
   noCheckPerformed: function() {
     return this.get('updated_at') === null;
@@ -39,10 +31,12 @@ Discourse.VersionCheck = Discourse.Model.extend({
   }.property('installed_sha')
 });
 
-Discourse.VersionCheck.reopenClass({
+VersionCheck.reopenClass({
   find: function() {
     return Discourse.ajax('/admin/version_check').then(function(json) {
-      return Discourse.VersionCheck.create(json);
+      return VersionCheck.create(json);
     });
   }
 });
+
+export default VersionCheck;
diff --git a/app/assets/javascripts/admin/routes/admin-api.js.es6 b/app/assets/javascripts/admin/routes/admin-api.js.es6
index 82212c96577..6142e2a2968 100644
--- a/app/assets/javascripts/admin/routes/admin-api.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-api.js.es6
@@ -1,5 +1,7 @@
+import ApiKey from 'admin/models/api-key';
+
 export default Ember.Route.extend({
   model() {
-    return Discourse.ApiKey.find();
+    return ApiKey.find();
   }
 });
diff --git a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
index 651551f857e..fce0b126d36 100644
--- a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
@@ -1,5 +1,7 @@
+import Backup from 'admin/models/backup';
+
 export default Ember.Route.extend({
   model() {
-    return Discourse.Backup.find();
+    return Backup.find();
   }
 });
diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6
index ac7f963cd44..f97d86f9318 100644
--- a/app/assets/javascripts/admin/routes/admin-backups.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6
@@ -1,4 +1,6 @@
 import showModal from 'discourse/lib/show-modal';
+import BackupStatus from 'admin/models/backup-status';
+import Backup from 'admin/models/backup';
 
 const LOG_CHANNEL = "/admin/backups/logs";
 
@@ -31,7 +33,7 @@ export default Discourse.Route.extend({
     return PreloadStore.getAndRemove("operations_status", function() {
       return Discourse.ajax("/admin/backups/status.json");
     }).then(status => {
-      return Discourse.BackupStatus.create({
+      return BackupStatus.create({
         isOperationRunning: status.is_operation_running,
         canRollback: status.can_rollback,
         allowRestore: status.allow_restore
@@ -98,7 +100,7 @@ export default Discourse.Route.extend({
         I18n.t("yes_value"),
         function(confirmed) {
           if (confirmed) {
-            Discourse.Backup.cancel().then(function() {
+            Backup.cancel().then(function() {
               self.controllerFor("adminBackups").set("model.isOperationRunning", false);
             });
           }
@@ -112,7 +114,7 @@ export default Discourse.Route.extend({
         I18n.t("no_value"),
         I18n.t("yes_value"),
         function(confirmed) {
-          if (confirmed) { Discourse.Backup.rollback(); }
+          if (confirmed) { Backup.rollback(); }
         }
       );
     },
@@ -120,7 +122,7 @@ export default Discourse.Route.extend({
     uploadSuccess(filename) {
       const self = this;
       bootbox.alert(I18n.t("admin.backups.upload.success", { filename: filename }), function() {
-        Discourse.Backup.find().then(function (backups) {
+        Backup.find().then(function (backups) {
           self.controllerFor("adminBackupsIndex").set("model", backups);
         });
       });
diff --git a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
index b0f4745a381..8a47f1ba212 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
@@ -1,7 +1,9 @@
+import ColorScheme from 'admin/models/color-scheme';
+
 export default Ember.Route.extend({
 
   model() {
-    return Discourse.ColorScheme.findAll();
+    return ColorScheme.findAll();
   },
 
   deactivate() {
diff --git a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
index 7bdb274e438..b080834d0bf 100644
--- a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
@@ -1,3 +1,8 @@
+import AdminDashboard from 'admin/models/admin-dashboard';
+import VersionCheck from 'admin/models/version-check';
+import Report from 'admin/models/report';
+import AdminUser from 'admin/models/admin-user';
+
 export default Discourse.Route.extend({
 
   setupController: function(c) {
@@ -8,19 +13,19 @@ export default Discourse.Route.extend({
     if( !c.get('dashboardFetchedAt') || moment().subtract(30, 'minutes').toDate() > c.get('dashboardFetchedAt') ) {
       c.set('dashboardFetchedAt', new Date());
       var versionChecks = this.siteSettings.version_checks;
-      Discourse.AdminDashboard.find().then(function(d) {
+      AdminDashboard.find().then(function(d) {
         if (versionChecks) {
-          c.set('versionCheck', Discourse.VersionCheck.create(d.version_check));
+          c.set('versionCheck', VersionCheck.create(d.version_check));
         }
 
         ['global_reports', 'page_view_reports', 'private_message_reports', 'http_reports', 'user_reports', 'mobile_reports'].forEach(name => {
-          c.set(name, d[name].map(r => Discourse.Report.create(r)));
+          c.set(name, d[name].map(r => Report.create(r)));
         });
 
         var topReferrers = d.top_referrers;
         if (topReferrers && topReferrers.data) {
           d.top_referrers.data = topReferrers.data.map(function (user) {
-            return Discourse.AdminUser.create(user);
+            return AdminUser.create(user);
           });
           c.set('top_referrers', topReferrers);
         }
diff --git a/app/assets/javascripts/admin/routes/admin-email-all.js.es6 b/app/assets/javascripts/admin/routes/admin-email-all.js.es6
new file mode 100644
index 00000000000..be310b9c385
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-email-all.js.es6
@@ -0,0 +1,2 @@
+import AdminEmailLogs from 'admin/routes/admin-email-logs';
+export default AdminEmailLogs.extend({ status: "all" });
diff --git a/app/assets/javascripts/admin/routes/admin_email_index_route.js b/app/assets/javascripts/admin/routes/admin-email-index.js.es6
similarity index 51%
rename from app/assets/javascripts/admin/routes/admin_email_index_route.js
rename to app/assets/javascripts/admin/routes/admin-email-index.js.es6
index 479d5911711..9e8aa7d8990 100644
--- a/app/assets/javascripts/admin/routes/admin_email_index_route.js
+++ b/app/assets/javascripts/admin/routes/admin-email-index.js.es6
@@ -1,6 +1,8 @@
-Discourse.AdminEmailIndexRoute = Discourse.Route.extend({
+import EmailSettings from 'admin/models/email-settings';
+
+export default Discourse.Route.extend({
   model: function() {
-    return Discourse.EmailSettings.find();
+    return EmailSettings.find();
   },
 
   renderTemplate: function() {
diff --git a/app/assets/javascripts/admin/routes/admin_email_logs_routes.js b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6
similarity index 55%
rename from app/assets/javascripts/admin/routes/admin_email_logs_routes.js
rename to app/assets/javascripts/admin/routes/admin-email-logs.js.es6
index 757cded71d4..f6cbd90eae4 100644
--- a/app/assets/javascripts/admin/routes/admin_email_logs_routes.js
+++ b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6
@@ -1,3 +1,5 @@
+import EmailLog from 'admin/models/email-log';
+
 /**
   Handles routes related to viewing email logs.
 
@@ -6,10 +8,10 @@
   @namespace Discourse
   @module Discourse
 **/
-Discourse.AdminEmailLogsRoute = Discourse.Route.extend({
+export default Discourse.Route.extend({
 
   model: function() {
-    return Discourse.EmailLog.findAll({ status: this.get("status") });
+    return EmailLog.findAll({ status: this.get("status") });
   },
 
   setupController: function(controller, model) {
@@ -23,7 +25,3 @@ Discourse.AdminEmailLogsRoute = Discourse.Route.extend({
   }
 
 });
-
-Discourse.AdminEmailAllRoute = Discourse.AdminEmailLogsRoute.extend({ status: "all" });
-Discourse.AdminEmailSentRoute = Discourse.AdminEmailLogsRoute.extend({ status: "sent" });
-Discourse.AdminEmailSkippedRoute = Discourse.AdminEmailLogsRoute.extend({ status: "skipped" });
diff --git a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
index 94d48e400df..7ca2f727722 100644
--- a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
@@ -1,7 +1,9 @@
+import EmailPreview from 'admin/models/email-preview';
+
 export default Discourse.Route.extend({
 
   model() {
-    return Discourse.EmailPreview.findDigest();
+    return EmailPreview.findDigest();
   },
 
   afterModel(model) {
diff --git a/app/assets/javascripts/admin/routes/admin-email-sent.js.es6 b/app/assets/javascripts/admin/routes/admin-email-sent.js.es6
new file mode 100644
index 00000000000..cf445973718
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-email-sent.js.es6
@@ -0,0 +1,2 @@
+import AdminEmailLogs from 'admin/routes/admin-email-logs';
+export default AdminEmailLogs.extend({ status: "sent" });
diff --git a/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6 b/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6
new file mode 100644
index 00000000000..90afc8bc381
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6
@@ -0,0 +1,2 @@
+import AdminEmailLogs from 'admin/routes/admin-email-logs';
+export default AdminEmailLogs.extend({ status: "skipped" });
diff --git a/app/assets/javascripts/admin/routes/admin-flags-list.js.es6 b/app/assets/javascripts/admin/routes/admin-flags-list.js.es6
index e277ef4417a..ebbc3e6d2bc 100644
--- a/app/assets/javascripts/admin/routes/admin-flags-list.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-flags-list.js.es6
@@ -1,9 +1,10 @@
 import showModal from 'discourse/lib/show-modal';
+import FlaggedPost from 'admin/models/flagged-post';
 
 export default Discourse.Route.extend({
   model(params) {
     this.filter = params.filter;
-    return Discourse.FlaggedPost.findAll(params.filter);
+    return FlaggedPost.findAll(params.filter);
   },
 
   setupController(controller, model) {
diff --git a/app/assets/javascripts/admin/routes/admin-groups-type.js.es6 b/app/assets/javascripts/admin/routes/admin-groups-type.js.es6
index def99aa7c15..52e383bf9a0 100644
--- a/app/assets/javascripts/admin/routes/admin-groups-type.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-groups-type.js.es6
@@ -1,7 +1,9 @@
+import Group from 'discourse/models/group';
+
 export default Discourse.Route.extend({
   model(params) {
     this.set("type", params.type);
-    return Discourse.Group.findAll().then(function(groups) {
+    return Group.findAll().then(function(groups) {
       return groups.filterBy("type", params.type);
     });
   },
diff --git a/app/assets/javascripts/admin/routes/admin-logs-index.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6
new file mode 100644
index 00000000000..c3ee93bb012
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6
@@ -0,0 +1,5 @@
+export default Discourse.Route.extend({
+  redirect: function() {
+    this.transitionTo('adminLogs.staffActionLogs');
+  }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
new file mode 100644
index 00000000000..1008dc1c1db
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
@@ -0,0 +1,9 @@
+export default Discourse.Route.extend({
+  renderTemplate: function() {
+    this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'});
+  },
+
+  setupController: function() {
+    return this.controllerFor('adminLogsScreenedEmails').show();
+  }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
new file mode 100644
index 00000000000..4aa57c17e21
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
@@ -0,0 +1,9 @@
+export default Discourse.Route.extend({
+  renderTemplate: function() {
+    this.render('admin/templates/logs/screened_ip_addresses', {into: 'adminLogs'});
+  },
+
+  setupController: function() {
+    return this.controllerFor('adminLogsScreenedIpAddresses').show();
+  }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
new file mode 100644
index 00000000000..093dd263319
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
@@ -0,0 +1,9 @@
+export default Discourse.Route.extend({
+  renderTemplate: function() {
+    this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'});
+  },
+
+  setupController: function() {
+    return this.controllerFor('adminLogsScreenedUrls').show();
+  }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
index 72b7f444d2f..cd9c79cffcb 100644
--- a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
@@ -1,6 +1,8 @@
+import Permalink from 'admin/models/permalink';
+
 export default Discourse.Route.extend({
   model() {
-    return Discourse.Permalink.findAll();
+    return Permalink.findAll();
   },
 
   setupController(controller, model) {
diff --git a/app/assets/javascripts/admin/routes/admin_reports_route.js b/app/assets/javascripts/admin/routes/admin-reports.js.es6
similarity index 90%
rename from app/assets/javascripts/admin/routes/admin_reports_route.js
rename to app/assets/javascripts/admin/routes/admin-reports.js.es6
index 2e11a0d39e0..829799d794d 100644
--- a/app/assets/javascripts/admin/routes/admin_reports_route.js
+++ b/app/assets/javascripts/admin/routes/admin-reports.js.es6
@@ -6,7 +6,7 @@
   @namespace Discourse
   @module Discourse
 **/
-Discourse.AdminReportsRoute = Discourse.Route.extend({
+export default Discourse.Route.extend({
   model: function(params) {
     return Discourse.Report.find(params.type);
   },
diff --git a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 b/app/assets/javascripts/admin/routes/admin-user-index.js.es6
index fdcf844abd8..5a3afa10caa 100644
--- a/app/assets/javascripts/admin/routes/admin-user-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user-index.js.es6
@@ -1,4 +1,5 @@
 import showModal from 'discourse/lib/show-modal';
+import Group from 'discourse/models/group';
 
 export default Discourse.Route.extend({
   model() {
@@ -8,7 +9,7 @@ export default Discourse.Route.extend({
   afterModel(model) {
     if (this.currentUser.get('admin')) {
       const self = this;
-      return Discourse.Group.findAll().then(function(groups){
+      return Group.findAll().then(function(groups){
         self._availableGroups = groups.filterBy('automatic', false);
         return model;
       });
diff --git a/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6 b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
new file mode 100644
index 00000000000..40c874eaaa1
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
@@ -0,0 +1,5 @@
+export default Discourse.Route.extend({
+  model: function() {
+    return this.modelFor('adminUser');
+  }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-user.js.es6 b/app/assets/javascripts/admin/routes/admin-user.js.es6
index 03c236ab9be..af3171a8570 100644
--- a/app/assets/javascripts/admin/routes/admin-user.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user.js.es6
@@ -1,10 +1,12 @@
+import AdminUser from 'admin/models/admin-user';
+
 export default Discourse.Route.extend({
   serialize(model) {
     return { username: model.get('username').toLowerCase() };
   },
 
   model(params) {
-    return Discourse.AdminUser.find(Em.get(params, 'username').toLowerCase());
+    return AdminUser.find(Em.get(params, 'username').toLowerCase());
   },
 
   renderTemplate() {
diff --git a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
index 87d5fce68c9..eacefeb15a6 100644
--- a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
@@ -1,7 +1,9 @@
+import AdminUser from 'admin/models/admin-user';
+
 export default Discourse.Route.extend({
   model: function(params) {
     this.userFilter = params.filter;
-    return Discourse.AdminUser.findAll(params.filter);
+    return AdminUser.findAll(params.filter);
   },
 
   setupController: function(controller, model) {
diff --git a/app/assets/javascripts/admin/routes/admin-users-list.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list.js.es6
index e76040b098e..cb7cfdd9bdb 100644
--- a/app/assets/javascripts/admin/routes/admin-users-list.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-list.js.es6
@@ -1,5 +1,6 @@
 import { exportEntity } from 'discourse/lib/export-csv';
 import { outputExportResult } from 'discourse/lib/export-result';
+import AdminUser from 'admin/models/admin-user';
 
 export default Discourse.Route.extend({
 
@@ -13,7 +14,7 @@ export default Discourse.Route.extend({
     },
 
     deleteUser(user) {
-      Discourse.AdminUser.create(user).destroy({ deletePosts: true });
+      AdminUser.create(user).destroy({ deletePosts: true });
     }
   }
 
diff --git a/app/assets/javascripts/admin/routes/admin_logs_routes.js b/app/assets/javascripts/admin/routes/admin_logs_routes.js
deleted file mode 100644
index ad54a895d4e..00000000000
--- a/app/assets/javascripts/admin/routes/admin_logs_routes.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
-  Index redirects to a default logs index.
-
-  @class AdminLogsIndexRoute
-  @extends Discourse.Route
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.AdminLogsIndexRoute = Discourse.Route.extend({
-  redirect: function() {
-    this.transitionTo('adminLogs.staffActionLogs');
-  }
-});
-
-/**
-  The route that lists blocked email addresses.
-
-  @class AdminLogsScreenedEmailsRoute
-  @extends Discourse.Route
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.AdminLogsScreenedEmailsRoute = Discourse.Route.extend({
-  renderTemplate: function() {
-    this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'});
-  },
-
-  setupController: function() {
-    return this.controllerFor('adminLogsScreenedEmails').show();
-  }
-});
-
-/**
-  The route that lists screened IP addresses.
-
-  @class AdminLogsScreenedIpAddresses
-  @extends Discourse.Route
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.AdminLogsScreenedIpAddressesRoute = Discourse.Route.extend({
-  renderTemplate: function() {
-    this.render('admin/templates/logs/screened_ip_addresses', {into: 'adminLogs'});
-  },
-
-  setupController: function() {
-    return this.controllerFor('adminLogsScreenedIpAddresses').show();
-  }
-});
-
-/**
-  The route that lists screened URLs.
-
-  @class AdminLogsScreenedUrlsRoute
-  @extends Discourse.Route
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.AdminLogsScreenedUrlsRoute = Discourse.Route.extend({
-  renderTemplate: function() {
-    this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'});
-  },
-
-  setupController: function() {
-    return this.controllerFor('adminLogsScreenedUrls').show();
-  }
-});
diff --git a/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js b/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js
deleted file mode 100644
index 934ccbb556c..00000000000
--- a/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
-  Shows all the requirements for being at trust level 3 and if the
-  given user is meeting them.
-
-  @class AdminUserLeaderRequirementsRoute
-  @extends Discourse.Route
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.AdminUserTl3RequirementsRoute = Discourse.Route.extend({
-  model: function() {
-    return this.modelFor('adminUser');
-  }
-});
diff --git a/app/assets/javascripts/admin/views/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/views/admin-customize-colors.js.es6
new file mode 100644
index 00000000000..ac5df78af58
--- /dev/null
+++ b/app/assets/javascripts/admin/views/admin-customize-colors.js.es6
@@ -0,0 +1,3 @@
+export default Ember.View.extend({
+  templateName: 'admin/templates/customize_colors'
+});
diff --git a/app/assets/javascripts/admin/views/admin-user.js.es6 b/app/assets/javascripts/admin/views/admin-user.js.es6
new file mode 100644
index 00000000000..2bd2497f157
--- /dev/null
+++ b/app/assets/javascripts/admin/views/admin-user.js.es6
@@ -0,0 +1 @@
+export default Ember.View.extend(Discourse.ScrollTop);
diff --git a/app/assets/javascripts/admin/views/admin_customize_colors_view.js b/app/assets/javascripts/admin/views/admin_customize_colors_view.js
deleted file mode 100644
index b03e8eb767b..00000000000
--- a/app/assets/javascripts/admin/views/admin_customize_colors_view.js
+++ /dev/null
@@ -1,3 +0,0 @@
-Discourse.AdminCustomizeColorsView = Ember.View.extend({
-  templateName: 'admin/templates/customize_colors'
-});
diff --git a/app/assets/javascripts/admin/views/admin_user_view.js b/app/assets/javascripts/admin/views/admin_user_view.js
deleted file mode 100644
index 997eaf3b2c3..00000000000
--- a/app/assets/javascripts/admin/views/admin_user_view.js
+++ /dev/null
@@ -1 +0,0 @@
-Discourse.AdminUserView = Ember.View.extend(Discourse.ScrollTop);
diff --git a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
index 6426f75524f..071e710398d 100644
--- a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
@@ -54,7 +54,8 @@ const controllerOpts = {
       this.set('controllers.discovery.loading', true);
 
       this.store.findFiltered('topicList', {filter}).then(list => {
-        Discourse.TopicList.hideUniformCategory(list, this.get('category'));
+        const TopicList = require('discourse/models/topic-list');
+        TopicList.hideUniformCategory(list, this.get('category'));
 
         this.setProperties({ model: list });
         this.resetSelected();
diff --git a/app/assets/javascripts/discourse/controllers/flag.js.es6 b/app/assets/javascripts/discourse/controllers/flag.js.es6
index 5250059d9f6..bc0a311e5d3 100644
--- a/app/assets/javascripts/discourse/controllers/flag.js.es6
+++ b/app/assets/javascripts/discourse/controllers/flag.js.es6
@@ -139,7 +139,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
 
   fetchUserDetails() {
     if (Discourse.User.currentProp('staff') && this.get('model.username')) {
-      Discourse.AdminUser.find(this.get('model.username').toLowerCase())
+      const AdminUser = require('admin/models/admin-user').default;
+      AdminUser.find(this.get('model.username').toLowerCase())
                          .then(user => this.set('userDetails', user));
     }
   }
diff --git a/app/assets/javascripts/discourse/controllers/group/members.js.es6 b/app/assets/javascripts/discourse/controllers/group/members.js.es6
index 3234c1c2135..0391cc47649 100644
--- a/app/assets/javascripts/discourse/controllers/group/members.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group/members.js.es6
@@ -29,13 +29,15 @@ export default Ember.Controller.extend({
     },
 
     loadMore() {
+      const Group = require('discourse/models/group').default;
+
       if (this.get("loading")) { return; }
       // we've reached the end
       if (this.get("model.members.length") >= this.get("model.user_count")) { return; }
 
       this.set("loading", true);
 
-      Discourse.Group.loadMembers(this.get("model.name"), this.get("model.members.length"), this.get("limit")).then(result => {
+      Group.loadMembers(this.get("model.name"), this.get("model.members.length"), this.get("limit")).then(result => {
         this.get("model.members").addObjects(result.members.map(member => Discourse.User.create(member)));
         this.setProperties({
           loading: false,
diff --git a/app/assets/javascripts/discourse/controllers/invite.js.es6 b/app/assets/javascripts/discourse/controllers/invite.js.es6
index ffaaab94d1d..bb94adae25c 100644
--- a/app/assets/javascripts/discourse/controllers/invite.js.es6
+++ b/app/assets/javascripts/discourse/controllers/invite.js.es6
@@ -1,5 +1,4 @@
 import ModalFunctionality from 'discourse/mixins/modal-functionality';
-import Invite from 'discourse/models/invite';
 
 export default Ember.Controller.extend(ModalFunctionality, {
   needs: ['user-invited-show'],
@@ -108,7 +107,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
   }.property('isPrivateTopic'),
 
   groupFinder(term) {
-    return Discourse.Group.findAll({search: term, ignore_automatic: true});
+    const Group = require('discourse/models/group').default;
+    return Group.findAll({search: term, ignore_automatic: true});
   },
 
   successMessage: function() {
@@ -148,6 +148,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
   actions: {
 
     createInvite() {
+      const Invite = require('discourse/models/invite').default;
+
       if (this.get('disabled')) { return; }
 
       const groupNames = this.get('model.groupNames'),
@@ -170,6 +172,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
     },
 
     generateInvitelink() {
+      const Invite = require('discourse/models/invite').default;
+
       if (this.get('disabled')) { return; }
 
       const groupNames = this.get('model.groupNames'),
diff --git a/app/assets/javascripts/discourse/controllers/quote-button.js.es6 b/app/assets/javascripts/discourse/controllers/quote-button.js.es6
index 2ad413846dd..cfff408844d 100644
--- a/app/assets/javascripts/discourse/controllers/quote-button.js.es6
+++ b/app/assets/javascripts/discourse/controllers/quote-button.js.es6
@@ -95,6 +95,7 @@ export default Ember.Controller.extend({
   },
 
   quoteText() {
+    const Composer = require('discourse/models/composer').default;
     const postId = this.get('postId');
     const post = this.get('post');
 
@@ -115,7 +116,7 @@ export default Ember.Controller.extend({
 
     const composerController = this.get('controllers.composer');
     const composerOpts = {
-      action: Discourse.Composer.REPLY,
+      action: Composer.REPLY,
       draftKey: post.get('topic.draft_key')
     };
 
diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6
index bb2115ad92e..8f27f093d6d 100644
--- a/app/assets/javascripts/discourse/controllers/topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic.js.es6
@@ -5,6 +5,7 @@ import Topic from 'discourse/models/topic';
 import Quote from 'discourse/lib/quote';
 import { popupAjaxError } from 'discourse/lib/ajax-error';
 import computed from 'ember-addons/ember-computed-decorators';
+import Composer from 'discourse/models/composer';
 
 export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
   needs: ['header', 'modal', 'composer', 'quote-button', 'topic-progress', 'application'],
@@ -100,14 +101,14 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
       quoteController.set('buffer', '');
 
       if (composerController.get('content.topic.id') === topic.get('id') &&
-          composerController.get('content.action') === Discourse.Composer.REPLY) {
+          composerController.get('content.action') === Composer.REPLY) {
         composerController.set('content.post', post);
-        composerController.set('content.composeState', Discourse.Composer.OPEN);
+        composerController.set('content.composeState', Composer.OPEN);
         this.appEvents.trigger('composer:insert-text', quotedText.trim());
       } else {
 
         const opts = {
-          action: Discourse.Composer.REPLY,
+          action: Composer.REPLY,
           draftKey: topic.get('draft_key'),
           draftSequence: topic.get('draft_sequence')
         };
@@ -185,7 +186,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
             composerModel = composer.get('model'),
             opts = {
               post: post,
-              action: Discourse.Composer.EDIT,
+              action: Composer.EDIT,
               draftKey: post.get('topic.draft_key'),
               draftSequence: post.get('topic.draft_sequence')
             };
@@ -389,8 +390,8 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
       quoteController.deselectText();
 
       composerController.open({
-        action: Discourse.Composer.CREATE_TOPIC,
-        draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY,
+        action: Composer.CREATE_TOPIC,
+        draftKey: Composer.REPLY_AS_NEW_TOPIC_KEY,
         categoryId: this.get('category.id')
       }).then(() => {
         return Em.isEmpty(quotedText) ? Discourse.Post.loadQuote(post.get('id')) : quotedText;
diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
index 499a6d1bf6a..1330239f151 100644
--- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
+++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
@@ -1,4 +1,5 @@
 import DiscourseURL from 'discourse/lib/url';
+import Composer from 'discourse/models/composer';
 
 const bindings = {
   '!':               {postAction: 'showFlags'},
@@ -170,7 +171,7 @@ export default {
   },
 
   createTopic() {
-    this.container.lookup('controller:composer').open({action: Discourse.Composer.CREATE_TOPIC, draftKey: Discourse.Composer.CREATE_TOPIC});
+    this.container.lookup('controller:composer').open({action: Composer.CREATE_TOPIC, draftKey: Composer.CREATE_TOPIC});
   },
 
   pinUnpinTopic() {
diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6
index 4b4c083d61b..2675f103118 100644
--- a/app/assets/javascripts/discourse/lib/search.js.es6
+++ b/app/assets/javascripts/discourse/lib/search.js.es6
@@ -1,6 +1,11 @@
-import Topic from 'discourse/models/topic';
 
 export function translateResults(results, opts) {
+
+  const User = require('discourse/models/user').default;
+  const Category = require('discourse/models/category').default;
+  const Post = require('discourse/models/post').default;
+  const Topic = require('discourse/models/topic').default;
+
   if (!opts) opts = {};
 
   // Topics might not be included
@@ -17,18 +22,18 @@ export function translateResults(results, opts) {
   });
 
   results.posts = results.posts.map(function(post){
-    post = Discourse.Post.create(post);
+    post = Post.create(post);
     post.set('topic', topicMap[post.topic_id]);
     return post;
   });
 
   results.users = results.users.map(function(user){
-    user = Discourse.User.create(user);
+    user = User.create(user);
     return user;
   });
 
   results.categories = results.categories.map(function(category){
-    return Discourse.Category.list().findProperty('id', category.id);
+    return Category.list().findProperty('id', category.id);
   }).compact();
 
   const r = results.grouped_search_result;
diff --git a/app/assets/javascripts/discourse/mixins/open-composer.js.es6 b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
index 8717d21a5c8..3341fa3dd01 100644
--- a/app/assets/javascripts/discourse/mixins/open-composer.js.es6
+++ b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
@@ -3,17 +3,19 @@
 export default Ember.Mixin.create({
 
   openComposer(controller) {
+    const Composer = require('discourse/models/composer').default;
     this.controllerFor('composer').open({
       categoryId: controller.get('category.id'),
-      action: Discourse.Composer.CREATE_TOPIC,
+      action: Composer.CREATE_TOPIC,
       draftKey: controller.get('model.draft_key'),
       draftSequence: controller.get('model.draft_sequence')
     });
   },
 
   openComposerWithParams(controller, topicTitle, topicBody, topicCategoryId, topicCategory) {
+    const Composer = require('discourse/models/composer').default;
     this.controllerFor('composer').open({
-      action: Discourse.Composer.CREATE_TOPIC,
+      action: Composer.CREATE_TOPIC,
       topicTitle,
       topicBody,
       topicCategoryId,
diff --git a/app/assets/javascripts/discourse/models/badge.js.es6 b/app/assets/javascripts/discourse/models/badge.js.es6
index fbda32fba50..1e4d79433a8 100644
--- a/app/assets/javascripts/discourse/models/badge.js.es6
+++ b/app/assets/javascripts/discourse/models/badge.js.es6
@@ -93,7 +93,7 @@ const Badge = RestModel.extend({
     Save and update the badge from the server's response.
 
     @method save
-    @returns {Promise} A promise that resolves to the updated `Discourse.Badge`
+    @returns {Promise} A promise that resolves to the updated `Badge`
   **/
   save: function(data) {
     let url = "/admin/badges",
@@ -133,11 +133,11 @@ const Badge = RestModel.extend({
 
 Badge.reopenClass({
   /**
-    Create `Discourse.Badge` instances from the server JSON response.
+    Create `Badge` instances from the server JSON response.
 
     @method createFromJson
     @param {Object} json The JSON returned by the server
-    @returns Array or instance of `Discourse.Badge` depending on the input JSON
+    @returns Array or instance of `Badge` depending on the input JSON
   **/
   createFromJson: function(json) {
     // Create BadgeType objects.
@@ -163,7 +163,7 @@ Badge.reopenClass({
       badges = json.badges;
     }
     badges = badges.map(function(badgeJson) {
-      const badge = Discourse.Badge.create(badgeJson);
+      const badge = Badge.create(badgeJson);
       badge.set('badge_type', badgeTypes[badge.get('badge_type_id')]);
       badge.set('badge_grouping', badgeGroupings[badge.get('badge_grouping_id')]);
       return badge;
@@ -177,10 +177,10 @@ Badge.reopenClass({
   },
 
   /**
-    Find all `Discourse.Badge` instances that have been defined.
+    Find all `Badge` instances that have been defined.
 
     @method findAll
-    @returns {Promise} a promise that resolves to an array of `Discourse.Badge`
+    @returns {Promise} a promise that resolves to an array of `Badge`
   **/
   findAll: function(opts) {
     let listable = "";
@@ -188,20 +188,20 @@ Badge.reopenClass({
       listable = "?only_listable=true";
     }
     return Discourse.ajax('/badges.json' + listable).then(function(badgesJson) {
-      return Discourse.Badge.createFromJson(badgesJson);
+      return Badge.createFromJson(badgesJson);
     });
   },
 
   /**
-    Returns a `Discourse.Badge` that has the given ID.
+    Returns a `Badge` that has the given ID.
 
     @method findById
     @param {Number} id ID of the badge
-    @returns {Promise} a promise that resolves to a `Discourse.Badge`
+    @returns {Promise} a promise that resolves to a `Badge`
   **/
   findById: function(id) {
     return Discourse.ajax("/badges/" + id).then(function(badgeJson) {
-      return Discourse.Badge.createFromJson(badgeJson);
+      return Badge.createFromJson(badgeJson);
     });
   }
 });
diff --git a/app/assets/javascripts/discourse/models/category-list.js.es6 b/app/assets/javascripts/discourse/models/category-list.js.es6
index b5e70970540..810a3e49022 100644
--- a/app/assets/javascripts/discourse/models/category-list.js.es6
+++ b/app/assets/javascripts/discourse/models/category-list.js.es6
@@ -7,7 +7,7 @@ const CategoryList = Ember.ArrayProxy.extend({
 
 CategoryList.reopenClass({
   categoriesFrom(store, result) {
-    const categories = Discourse.CategoryList.create();
+    const categories = CategoryList.create();
     const users = Discourse.Model.extractByKey(result.featured_users, Discourse.User);
     const list = Discourse.Category.list();
 
@@ -35,7 +35,7 @@ CategoryList.reopenClass({
 
   listForParent(store, category) {
     return Discourse.ajax(`/categories.json?parent_category_id=${category.get("id")}`).then(result => {
-      return Discourse.CategoryList.create({
+      return CategoryList.create({
         categories: this.categoriesFrom(store, result),
         parentCategory: category
       });
@@ -45,7 +45,7 @@ CategoryList.reopenClass({
   list(store) {
     const getCategories = () => Discourse.ajax("/categories.json");
     return PreloadStore.getAndRemove("categories_list", getCategories).then(result => {
-      return Discourse.CategoryList.create({
+      return CategoryList.create({
         categories: this.categoriesFrom(store, result),
         can_create_category: result.category_list.can_create_category,
         can_create_topic: result.category_list.can_create_topic,
diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6
index 55e3b29b7e1..49f0e4ae0d6 100644
--- a/app/assets/javascripts/discourse/models/group.js.es6
+++ b/app/assets/javascripts/discourse/models/group.js.es6
@@ -28,7 +28,7 @@ const Group = Discourse.Model.extend({
 
     const self = this, offset = Math.min(this.get("user_count"), Math.max(this.get("offset"), 0));
 
-    return Discourse.Group.loadMembers(this.get("name"), offset, this.get("limit")).then(function (result) {
+    return Group.loadMembers(this.get("name"), offset, this.get("limit")).then(function (result) {
       var ownerIds = {};
       result.owners.forEach(owner => ownerIds[owner.id] = true);
 
@@ -136,7 +136,7 @@ const Group = Discourse.Model.extend({
 Group.reopenClass({
   findAll(opts) {
     return Discourse.ajax("/admin/groups.json", { data: opts }).then(function (groups){
-      return groups.map(g => Discourse.Group.create(g));
+      return groups.map(g => Group.create(g));
     });
   },
 
@@ -145,7 +145,7 @@ Group.reopenClass({
   },
 
   find(name) {
-    return Discourse.ajax("/groups/" + name + ".json").then(result => Discourse.Group.create(result.basic_group));
+    return Discourse.ajax("/groups/" + name + ".json").then(result => Group.create(result.basic_group));
   },
 
   loadMembers(name, offset, limit) {
diff --git a/app/assets/javascripts/discourse/models/post-stream.js.es6 b/app/assets/javascripts/discourse/models/post-stream.js.es6
index 4ea6646f035..0368b2c2ec1 100644
--- a/app/assets/javascripts/discourse/models/post-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/post-stream.js.es6
@@ -205,7 +205,7 @@ const PostStream = RestModel.extend({
     opts = _.merge(opts, self.get('streamFilters'));
 
     // Request a topicView
-    return Discourse.PostStream.loadTopicView(topic.get('id'), opts).then(function (json) {
+    return PostStream.loadTopicView(topic.get('id'), opts).then(function (json) {
       topic.updateFromJson(json);
       self.updateFromJson(json.post_stream);
       self.setProperties({ loadingFilter: false, loaded: true });
diff --git a/app/assets/javascripts/discourse/models/post.js.es6 b/app/assets/javascripts/discourse/models/post.js.es6
index 3de88eb2efe..d55075d060e 100644
--- a/app/assets/javascripts/discourse/models/post.js.es6
+++ b/app/assets/javascripts/discourse/models/post.js.es6
@@ -132,7 +132,9 @@ const Post = RestModel.extend({
   },
 
   createProperties() {
-    const data = this.getProperties(Discourse.Composer.serializedFieldsForCreate());
+    // composer only used once, defer the dependency
+    const Composer = require('discourse/models/composer').default;
+    const data = this.getProperties(Composer.serializedFieldsForCreate());
     data.reply_to_post_number = this.get('reply_to_post_number');
     data.image_sizes = this.get('imageSizes');
 
diff --git a/app/assets/javascripts/discourse/models/user-badge.js.es6 b/app/assets/javascripts/discourse/models/user-badge.js.es6
index f5e2209f95a..8f938298dba 100644
--- a/app/assets/javascripts/discourse/models/user-badge.js.es6
+++ b/app/assets/javascripts/discourse/models/user-badge.js.es6
@@ -52,7 +52,7 @@ UserBadge.reopenClass({
     }
 
     userBadges = userBadges.map(function(userBadgeJson) {
-      var userBadge = Discourse.UserBadge.create(userBadgeJson);
+      var userBadge = UserBadge.create(userBadgeJson);
 
       var grantedAtDate = Date.parse(userBadge.get('granted_at'));
       userBadge.set('grantedAt', grantedAtDate);
@@ -83,7 +83,7 @@ UserBadge.reopenClass({
     @method findByUsername
     @param {String} username
     @param {Object} options
-    @returns {Promise} a promise that resolves to an array of `Discourse.UserBadge`.
+    @returns {Promise} a promise that resolves to an array of `UserBadge`.
   **/
   findByUsername: function(username, options) {
     var url = "/user-badges/" + username + ".json";
@@ -91,7 +91,7 @@ UserBadge.reopenClass({
       url += "?grouped=true";
     }
     return Discourse.ajax(url).then(function(json) {
-      return Discourse.UserBadge.createFromJson(json);
+      return UserBadge.createFromJson(json);
     });
   },
 
@@ -100,7 +100,7 @@ UserBadge.reopenClass({
 
     @method findById
     @param {String} badgeId
-    @returns {Promise} a promise that resolves to an array of `Discourse.UserBadge`.
+    @returns {Promise} a promise that resolves to an array of `UserBadge`.
   **/
   findByBadgeId: function(badgeId, options) {
     if (!options) { options = {}; }
@@ -109,7 +109,7 @@ UserBadge.reopenClass({
     return Discourse.ajax("/user_badges.json", {
       data: options
     }).then(function(json) {
-      return Discourse.UserBadge.createFromJson(json);
+      return UserBadge.createFromJson(json);
     });
   },
 
@@ -119,7 +119,7 @@ UserBadge.reopenClass({
     @method grant
     @param {Integer} badgeId id of the badge to be granted.
     @param {String} username username of the user to be granted the badge.
-    @returns {Promise} a promise that resolves to an instance of `Discourse.UserBadge`.
+    @returns {Promise} a promise that resolves to an instance of `UserBadge`.
   **/
   grant: function(badgeId, username, reason) {
     return Discourse.ajax("/user_badges", {
@@ -130,7 +130,7 @@ UserBadge.reopenClass({
         reason: reason
       }
     }).then(function(json) {
-      return Discourse.UserBadge.createFromJson(json);
+      return UserBadge.createFromJson(json);
     });
   }
 });
diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6
index f220436afc7..97c611ab89e 100644
--- a/app/assets/javascripts/discourse/models/user.js.es6
+++ b/app/assets/javascripts/discourse/models/user.js.es6
@@ -7,6 +7,9 @@ import { longDate } from 'discourse/lib/formatter';
 import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
 import Badge from 'discourse/models/badge';
 import UserBadge from 'discourse/models/user-badge';
+import UserActionStat from 'discourse/models/user-action-stat';
+import UserAction from 'discourse/models/user-action';
+import Group from 'discourse/models/group';
 
 const User = RestModel.extend({
 
@@ -184,7 +187,7 @@ const User = RestModel.extend({
         if ((this.get('stream.filter') || ua.action_type) !== ua.action_type) return;
         if (!this.get('stream.filter') && !this.inAllStream(ua)) return;
 
-        const action = Discourse.UserAction.collapseStream([Discourse.UserAction.create(ua)]);
+        const action = UserAction.collapseStream([UserAction.create(ua)]);
         stream.set('itemsLoaded', stream.get('itemsLoaded') + 1);
         stream.get('content').insertAt(0, action[0]);
       }
@@ -192,8 +195,8 @@ const User = RestModel.extend({
   },
 
   inAllStream(ua) {
-    return ua.action_type === Discourse.UserAction.TYPES.posts ||
-           ua.action_type === Discourse.UserAction.TYPES.topics;
+    return ua.action_type === UserAction.TYPES.posts ||
+           ua.action_type === UserAction.TYPES.topics;
   },
 
   // The user's stat count, excluding PMs.
@@ -226,12 +229,12 @@ const User = RestModel.extend({
       if (!Em.isEmpty(json.user.stats)) {
         json.user.stats = Discourse.User.groupStats(_.map(json.user.stats, s => {
           if (s.count) s.count = parseInt(s.count, 10);
-          return Discourse.UserActionStat.create(s);
+          return UserActionStat.create(s);
         }));
       }
 
       if (!Em.isEmpty(json.user.custom_groups)) {
-        json.user.custom_groups = json.user.custom_groups.map(g => Discourse.Group.create(g));
+        json.user.custom_groups = json.user.custom_groups.map(g => Group.create(g));
       }
 
       if (json.user.invited_by) {
@@ -372,9 +375,9 @@ User.reopenClass(Singleton, {
   },
 
   groupStats(stats) {
-    const responses = Discourse.UserActionStat.create({
+    const responses = UserActionStat.create({
       count: 0,
-      action_type: Discourse.UserAction.TYPES.replies
+      action_type: UserAction.TYPES.replies
     });
 
     stats.filterProperty('isResponse').forEach(stat => {
@@ -386,7 +389,7 @@ User.reopenClass(Singleton, {
 
     let insertAt = 0;
     result.forEach((item, index) => {
-     if (item.action_type === Discourse.UserAction.TYPES.topics || item.action_type === Discourse.UserAction.TYPES.posts) {
+     if (item.action_type === UserAction.TYPES.topics || item.action_type === UserAction.TYPES.posts) {
        insertAt = index + 1;
      }
     });
diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
index 219ae7d3276..18c959979f0 100644
--- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
@@ -1,5 +1,6 @@
 import { filterQueryParams, findTopicList } from 'discourse/routes/build-topic-route';
 import { queryParams } from 'discourse/controllers/discovery-sortable';
+import TopicList from 'discourse/models/topic-list';
 
 // A helper function to create a category route with parameters
 export default (filter, params) => {
@@ -50,7 +51,7 @@ export default (filter, params) => {
              extras = { cached: this.isPoppedState(transition) };
 
       return findTopicList(this.store, this.topicTrackingState, listFilter, findOpts, extras).then(list => {
-        Discourse.TopicList.hideUniformCategory(list, category);
+        TopicList.hideUniformCategory(list, category);
         this.set('topics', list);
         return list;
       });
diff --git a/app/assets/javascripts/discourse/routes/discourse.js.es6 b/app/assets/javascripts/discourse/routes/discourse.js.es6
index cf7a7c27a43..4969c0872f3 100644
--- a/app/assets/javascripts/discourse/routes/discourse.js.es6
+++ b/app/assets/javascripts/discourse/routes/discourse.js.es6
@@ -1,3 +1,5 @@
+import Composer from 'discourse/models/composer';
+
 const DiscourseRoute = Ember.Route.extend({
 
   // Set to true to refresh a model without a transition if a query param
@@ -58,7 +60,7 @@ const DiscourseRoute = Ember.Route.extend({
       const composer = this.controllerFor('composer');
       if (!composer.get('model.viewOpen')) {
         composer.open({
-          action: Discourse.Composer.CREATE_TOPIC,
+          action: Composer.CREATE_TOPIC,
           draft: model.draft,
           draftKey: model.draft_key,
           draftSequence: model.draft_sequence
diff --git a/app/assets/javascripts/discourse/routes/discovery-categories.js.es6 b/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
index 072f33e47d7..1d9d34e7e74 100644
--- a/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
+++ b/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
@@ -1,5 +1,6 @@
 import showModal from "discourse/lib/show-modal";
 import OpenComposer from "discourse/mixins/open-composer";
+import CategoryList from "discourse/models/category-list";
 
 const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
   renderTemplate() {
@@ -16,7 +17,7 @@ const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
     // if default page is categories
     PreloadStore.remove("topic_list");
 
-    return Discourse.CategoryList.list(this.store, 'categories').then(list => {
+    return CategoryList.list(this.store, 'categories').then(list => {
       const tracking = this.topicTrackingState;
       if (tracking) {
         tracking.sync(list, "categories");
diff --git a/app/assets/javascripts/discourse/routes/group.js.es6 b/app/assets/javascripts/discourse/routes/group.js.es6
index a33a4f63760..21b5aad57fa 100644
--- a/app/assets/javascripts/discourse/routes/group.js.es6
+++ b/app/assets/javascripts/discourse/routes/group.js.es6
@@ -1,7 +1,9 @@
+import Group from 'discourse/models/group';
+
 export default Discourse.Route.extend({
 
   model: function(params) {
-    return Discourse.Group.find(params.name);
+    return Group.find(params.name);
   },
 
   serialize: function(model) {
@@ -10,7 +12,7 @@ export default Discourse.Route.extend({
 
   afterModel: function(model) {
     var self = this;
-    return Discourse.Group.findGroupCounts(model.get('name')).then(function (counts) {
+    return Group.findGroupCounts(model.get('name')).then(function (counts) {
       self.set('counts', counts);
     });
   },
diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6
index 976de121666..a4a6fa58cc5 100644
--- a/app/assets/javascripts/discourse/routes/topic.js.es6
+++ b/app/assets/javascripts/discourse/routes/topic.js.es6
@@ -97,7 +97,7 @@ const TopicRoute = Discourse.Route.extend({
     // Use replaceState to update the URL once it changes
     postChangedRoute(currentPost) {
       // do nothing if we are transitioning to another route
-      if (isTransitioning || Discourse.TopicRoute.disableReplaceState) { return; }
+      if (isTransitioning || TopicRoute.disableReplaceState) { return; }
 
       const topic = this.modelFor('topic');
       if (topic && currentPost) {
@@ -205,7 +205,7 @@ const TopicRoute = Discourse.Route.extend({
       firstPostExpanded: false
     });
 
-    Discourse.TopicRoute.trigger('setupTopicController', this);
+    TopicRoute.trigger('setupTopicController', this);
 
     this.controllerFor('header').setProperties({ topic: model, showExtraInfo: false });
     this.searchService.set('searchContext', model.get('searchContext'));
diff --git a/app/assets/javascripts/discourse/routes/user.js.es6 b/app/assets/javascripts/discourse/routes/user.js.es6
index 040f949b5a7..71e803300d0 100644
--- a/app/assets/javascripts/discourse/routes/user.js.es6
+++ b/app/assets/javascripts/discourse/routes/user.js.es6
@@ -15,8 +15,10 @@ export default Discourse.Route.extend({
       const recipient = user ? user.get('username') : '',
           reply = post ? window.location.protocol + "//" + window.location.host + post.get("url") : null;
 
+      // used only once, one less dependency
+      const Composer = require('discourse/models/composer').default;
       return this.controllerFor('composer').open({
-        action: Discourse.Composer.PRIVATE_MESSAGE,
+        action: Composer.PRIVATE_MESSAGE,
         usernames: recipient,
         archetypeId: 'private_message',
         draftKey: 'new_private_message',
diff --git a/app/assets/javascripts/main_include_admin.js b/app/assets/javascripts/main_include_admin.js
index 72d94e54d46..7816da8382a 100644
--- a/app/assets/javascripts/main_include_admin.js
+++ b/app/assets/javascripts/main_include_admin.js
@@ -1,6 +1,12 @@
 //= require_tree ./ember-addons
 //= require admin/models/user-field
 //= require admin/models/site-setting
+//= require admin/models/screened-ip-address
+//= require admin/models/api-key
+//= require admin/models/tl3-requirements
+//= require admin/models/admin-user
+//= require_tree ./admin/models
+//= require admin/routes/admin-email-logs
 //= require admin/controllers/admin-email-skipped
 //= require discourse/lib/export-result
 //= require_tree ./admin
diff --git a/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb b/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb
index 435c45a26a1..c920afc1307 100644
--- a/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb
+++ b/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb
@@ -86,6 +86,8 @@ module Tilt
          "discourse/models/user",
          "discourse/models/session",
          "discourse/models/model",
+         "discourse/models/topic",
+         "discourse/models/post",
          "discourse/views/grouped"]
       )
 
diff --git a/test/javascripts/admin/models/admin-user-test.js.es6 b/test/javascripts/admin/models/admin-user-test.js.es6
index 5d0b231857d..16e3cf0dde9 100644
--- a/test/javascripts/admin/models/admin-user-test.js.es6
+++ b/test/javascripts/admin/models/admin-user-test.js.es6
@@ -1,11 +1,13 @@
 import { blank, present } from 'helpers/qunit-helpers';
+import AdminUser from 'admin/models/admin-user';
+import ApiKey from 'admin/models/api-key';
 
 module("Discourse.AdminUser");
 
 asyncTestDiscourse('generate key', function() {
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 1234, key: 'asdfasdf'}}));
 
-  var adminUser = Discourse.AdminUser.create({id: 333});
+  var adminUser = AdminUser.create({id: 333});
 
   blank(adminUser.get('api_key'), 'it has no api key by default');
   adminUser.generateApiKey().then(function() {
@@ -17,8 +19,8 @@ asyncTestDiscourse('generate key', function() {
 
 asyncTestDiscourse('revoke key', function() {
 
-  var apiKey = Discourse.ApiKey.create({id: 1234, key: 'asdfasdf'}),
-      adminUser = Discourse.AdminUser.create({id: 333, api_key: apiKey});
+  var apiKey = ApiKey.create({id: 1234, key: 'asdfasdf'}),
+      adminUser = AdminUser.create({id: 333, api_key: apiKey});
 
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve());
 
diff --git a/test/javascripts/admin/models/api-key-test.js.es6 b/test/javascripts/admin/models/api-key-test.js.es6
index 07121c9e164..640845ff802 100644
--- a/test/javascripts/admin/models/api-key-test.js.es6
+++ b/test/javascripts/admin/models/api-key-test.js.es6
@@ -1,9 +1,10 @@
 import { present } from 'helpers/qunit-helpers';
+import ApiKey from 'admin/models/api-key';
 
 module("Discourse.ApiKey");
 
 test('create', function() {
-  var apiKey = Discourse.ApiKey.create({id: 123, user: {id: 345}});
+  var apiKey = ApiKey.create({id: 123, user: {id: 345}});
 
   present(apiKey, 'it creates the api key');
   present(apiKey.get('user'), 'it creates the user inside');
@@ -12,7 +13,7 @@ test('create', function() {
 
 asyncTestDiscourse('find', function() {
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([]));
-  Discourse.ApiKey.find().then(function() {
+  ApiKey.find().then(function() {
     start();
     ok(Discourse.ajax.calledWith("/admin/api"), "it GETs the keys");
   });
@@ -20,14 +21,14 @@ asyncTestDiscourse('find', function() {
 
 asyncTestDiscourse('generateMasterKey', function() {
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {}}));
-  Discourse.ApiKey.generateMasterKey().then(function() {
+  ApiKey.generateMasterKey().then(function() {
     start();
     ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'POST'}), "it POSTs to create a master key");
   });
 });
 
 asyncTestDiscourse('regenerate', function() {
-  var apiKey = Discourse.ApiKey.create({id: 3456});
+  var apiKey = ApiKey.create({id: 3456});
 
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 3456}}));
   apiKey.regenerate().then(function() {
@@ -37,7 +38,7 @@ asyncTestDiscourse('regenerate', function() {
 });
 
 asyncTestDiscourse('revoke', function() {
-  var apiKey = Discourse.ApiKey.create({id: 3456});
+  var apiKey = ApiKey.create({id: 3456});
 
   sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([]));
   apiKey.revoke().then(function() {
diff --git a/test/javascripts/admin/models/flagged-post-test.js.es6 b/test/javascripts/admin/models/flagged-post-test.js.es6
index bf26a06648f..3b5587e041b 100644
--- a/test/javascripts/admin/models/flagged-post-test.js.es6
+++ b/test/javascripts/admin/models/flagged-post-test.js.es6
@@ -1,9 +1,11 @@
+import FlaggedPost from 'admin/models/flagged-post';
+
 module("Discourse.FlaggedPost");
 
 test('delete first post', function() {
   sandbox.stub(Discourse, 'ajax');
 
-  Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 })
+  FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 })
            .deletePost();
 
   ok(Discourse.ajax.calledWith("/t/2", { type: 'DELETE', cache: false }), "it deleted the topic");
@@ -12,7 +14,7 @@ test('delete first post', function() {
 test('delete second post', function() {
   sandbox.stub(Discourse, 'ajax');
 
-  Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 })
+  FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 })
            .deletePost();
 
   ok(Discourse.ajax.calledWith("/posts/1", { type: 'DELETE', cache: false }), "it deleted the post");
diff --git a/test/javascripts/controllers/flag-test.js.es6 b/test/javascripts/controllers/flag-test.js.es6
index beb5dd9af6e..ebff4fd1d7b 100644
--- a/test/javascripts/controllers/flag-test.js.es6
+++ b/test/javascripts/controllers/flag-test.js.es6
@@ -1,4 +1,5 @@
 import createStore from 'helpers/create-store';
+import AdminUser from 'admin/models/admin-user';
 
 var buildPost = function(args) {
   return Discourse.Post.create(_.merge({
@@ -9,7 +10,7 @@ var buildPost = function(args) {
 };
 
 var buildAdminUser = function(args) {
-  return Discourse.AdminUser.create(_.merge({
+  return AdminUser.create(_.merge({
     id: 11,
     username: 'urist'
   }, args || {}));
diff --git a/test/javascripts/lib/bbcode-test.js.es6 b/test/javascripts/lib/bbcode-test.js.es6
index ad26cc6c70a..34b3992b843 100644
--- a/test/javascripts/lib/bbcode-test.js.es6
+++ b/test/javascripts/lib/bbcode-test.js.es6
@@ -1,4 +1,5 @@
 import Quote from 'discourse/lib/quote';
+import Post from 'discourse/models/post';
 
 module("Discourse.BBCode");
 
@@ -78,7 +79,7 @@ test("size tags", function() {
 
 test("quotes", function() {
 
-  var post = Discourse.Post.create({
+  var post = Post.create({
     cooked: "<p><b>lorem</b> ipsum</p>",
     username: "eviltrout",
     post_number: 1,
diff --git a/test/javascripts/models/composer-test.js.es6 b/test/javascripts/models/composer-test.js.es6
index a6c419cf0cb..c156c92306e 100644
--- a/test/javascripts/models/composer-test.js.es6
+++ b/test/javascripts/models/composer-test.js.es6
@@ -185,7 +185,7 @@ test('initial category when uncategorized is not allowed', function() {
 test('open with a quote', function() {
   const quote = '[quote="neil, post:5, topic:413"]\nSimmer down you two.\n[/quote]';
   const newComposer = function() {
-    return openComposer({action: Discourse.Composer.REPLY, draftKey: 'asfd', draftSequence: 1, quote: quote});
+    return openComposer({action: Composer.REPLY, draftKey: 'asfd', draftSequence: 1, quote: quote});
   };
 
   equal(newComposer().get('originalText'), quote, "originalText is the quote" );
diff --git a/test/javascripts/models/email-log-test.js.es6 b/test/javascripts/models/email-log-test.js.es6
index bce4017fb1a..98d4b714f9c 100644
--- a/test/javascripts/models/email-log-test.js.es6
+++ b/test/javascripts/models/email-log-test.js.es6
@@ -1,5 +1,7 @@
+import EmailLog from 'admin/models/email-log';
+
 module("Discourse.EmailLog");
 
 test("create", function() {
-  ok(Discourse.EmailLog.create(), "it can be created without arguments");
+  ok(EmailLog.create(), "it can be created without arguments");
 });
diff --git a/test/javascripts/models/report-test.js.es6 b/test/javascripts/models/report-test.js.es6
index 9ae550d1570..3fcdd9d037c 100644
--- a/test/javascripts/models/report-test.js.es6
+++ b/test/javascripts/models/report-test.js.es6
@@ -1,9 +1,10 @@
 import { blank } from 'helpers/qunit-helpers';
+import Report from 'admin/models/report';
 
-module("Discourse.Report");
+module("Report");
 
 function reportWithData(data) {
-  return Discourse.Report.create({
+  return Report.create({
     type: 'topics',
     data: _.map(data, function(val, index) {
       return { x: moment().subtract(index, "days").format('YYYY-MM-DD'), y: val };
diff --git a/test/javascripts/models/staff-action-log-test.js.es6 b/test/javascripts/models/staff-action-log-test.js.es6
index 9dbac57d0c3..933dd6271d8 100644
--- a/test/javascripts/models/staff-action-log-test.js.es6
+++ b/test/javascripts/models/staff-action-log-test.js.es6
@@ -1,5 +1,7 @@
-module("Discourse.StaffActionLog");
+import StaffActionLog from 'admin/models/staff-action-log';
+
+module("StaffActionLog");
 
 test("create", function() {
-  ok(Discourse.StaffActionLog.create(), "it can be created without arguments");
+  ok(StaffActionLog.create(), "it can be created without arguments");
 });
diff --git a/test/javascripts/models/version-check-test.js.es6 b/test/javascripts/models/version-check-test.js.es6
index c0e6d3e8b25..4b8b6bc94f1 100644
--- a/test/javascripts/models/version-check-test.js.es6
+++ b/test/javascripts/models/version-check-test.js.es6
@@ -1,8 +1,10 @@
-module("Discourse.VersionCheck");
+import VersionCheck from 'admin/models/version-check';
+
+module("VersionCheck");
 
 test('dataIsOld', function() {
   var dataIsOld = function(args, expected, message) {
-    equal(Discourse.VersionCheck.create(args).get('dataIsOld'), expected, message);
+    equal(VersionCheck.create(args).get('dataIsOld'), expected, message);
   };
 
   dataIsOld({updated_at: moment().subtract(2, 'hours').toJSON()},  false, '2 hours ago');
@@ -15,7 +17,7 @@ test('staleData', function() {
     return moment().subtract(hoursAgo, 'hours').toJSON();
   };
   var staleData = function(args, expected, message) {
-    equal(Discourse.VersionCheck.create(args).get('staleData'), expected, message);
+    equal(VersionCheck.create(args).get('staleData'), expected, message);
   };
 
   staleData({missing_versions_count: 0, installed_version: '0.9.3', latest_version: '0.9.3', updated_at: updatedAt(2)}, false, 'up to date');