diff --git a/resources/static/css/common.css b/resources/static/css/common.css
index 6a96e10d20677178cff948c6ddf6cc00131917fe..0a8a061ecd70d2dbf991c3bd1eefdf92af22c4e2 100644
--- a/resources/static/css/common.css
+++ b/resources/static/css/common.css
@@ -195,13 +195,16 @@ button::-moz-focus-inner, .button::-moz-focus-inner {
   border: 0
 }
 
-button[disabled] {
-    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
-    opacity: .5;
+button[disabled], .submit_disabled button, .submit_disabled .button,
+.submit_disabled button:focus, .submit_disabled .button:focus,
+.submit_disabled button:active, .submit_disabled .button:active {
+  background-color: #37A6FF;
+  background-image: -moz-linear-gradient(center top , #76C2FF 0pt, #37A6FF 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #76C2FF), color-stop(100%, #37A6FF));
+  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
+  opacity: .5;
 }
 
-
-
 hr {
   height: 1px;
   border: none;
diff --git a/resources/static/dialog/controllers/authenticate.js b/resources/static/dialog/controllers/authenticate.js
index 997a248b02a9fe02462752dccd5b7feb87d6b00f..b4733b69c5ea18ce5a9e406a9c49b6c69a06446a 100644
--- a/resources/static/dialog/controllers/authenticate.js
+++ b/resources/static/dialog/controllers/authenticate.js
@@ -14,7 +14,7 @@ BrowserID.Modules.Authenticate = (function() {
       tooltip = bid.Tooltip,
       helpers = bid.Helpers,
       dialogHelpers = helpers.Dialog,
-      cancelEvent = dialogHelpers.cancelEvent,
+      cancelEvent = helpers.cancelEvent,
       dom = bid.DOM,
       lastEmail = "";
 
diff --git a/resources/static/dialog/resources/helpers.js b/resources/static/dialog/resources/helpers.js
index 3191825e4e3ea07268e7171ae192087748a6d18c..bcc103b82e079bfc5fb66e988065306f60ddf6ae 100644
--- a/resources/static/dialog/resources/helpers.js
+++ b/resources/static/dialog/resources/helpers.js
@@ -125,13 +125,6 @@
     }
   }
 
-  function cancelEvent(callback) {
-    return function(event) {
-      event && event.preventDefault();
-      callback.call(this);
-    };
-  }
-
   helpers.Dialog = helpers.Dialog || {};
 
   helpers.extend(helpers.Dialog, {
@@ -140,7 +133,7 @@
     createUser: createUser,
     addEmail: addEmail,
     resetPassword: resetPassword,
-    cancelEvent: cancelEvent
+    cancelEvent: helpers.cancelEvent
   });
 
 }());
diff --git a/resources/static/dialog/start.js b/resources/static/dialog/start.js
index 5da6f82361decb6c47c57838282f9050c46c9d37..9566d978bfac61c2b51c2c305b3434902b7ce9bd 100644
--- a/resources/static/dialog/start.js
+++ b/resources/static/dialog/start.js
@@ -32,9 +32,11 @@
         moduleManager.register("primary_user_provisioned", modules.PrimaryUserProvisioned);
         moduleManager.register("email_chosen", modules.EmailChosen);
         moduleManager.register("xhr_delay", modules.XHRDelay);
+        moduleManager.register("xhr_disable_form", modules.XHRDisableForm);
 
 
         moduleManager.start("xhr_delay");
+        moduleManager.start("xhr_disable_form");
         moduleManager.start("dialog");
       }
     }
diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js
index 638778590e6bf9ad5924f32ff7ab5655a9daa7be..b15cf2eb8002c985150dd4f92af6e76628756511 100644
--- a/resources/static/pages/page_helpers.js
+++ b/resources/static/pages/page_helpers.js
@@ -130,13 +130,6 @@ BrowserID.PageHelpers = (function() {
     dom.focus("input:visible:eq(0)");
   }
 
-  function cancelEvent(callback) {
-    return function(event) {
-      event && event.preventDefault();
-      callback && callback();
-    };
-  }
-
   function openPrimaryAuth(winchan, email, baseURL, callback) {
     if(!(email && baseURL)) {
       throw "cannot verify with primary without an email address and URL"
@@ -195,7 +188,7 @@ BrowserID.PageHelpers = (function() {
     emailSent: emailSent,
     cancelEmailSent: cancelEmailSent,
     userValidationComplete: userValidationComplete,
-    cancelEvent: cancelEvent,
+    cancelEvent: helpers.cancelEvent,
     openPrimaryAuth: openPrimaryAuth
   };
 }());
diff --git a/resources/static/pages/start.js b/resources/static/pages/start.js
index 132ce6e894e6b7765b1528ddda4646aee94b6ca2..d64a447b60a46c19eccacc0ee43ba8a4ba624369 100644
--- a/resources/static/pages/start.js
+++ b/resources/static/pages/start.js
@@ -16,11 +16,14 @@ $(function() {
       user = bid.User,
       token = pageHelpers.getParameterByName("token"),
       path = document.location.pathname,
-      XHRDelay = bid.Modules.XHRDelay;
+      XHRDelay = bid.Modules.XHRDelay,
+      XHRDisableForm = bid.Modules.XHRDisableForm;
 
   network.init({ time_until_delay: 10 * 1000 });
   var xhrDelay = XHRDelay.create({});
   xhrDelay.start();
+  var xhrDisableForm = XHRDisableForm.create({});
+  xhrDisableForm.start();
 
   if (!path || path === "/") {
     bid.index();
diff --git a/resources/static/shared/helpers.js b/resources/static/shared/helpers.js
index 1a94fa11ad939d4e3fa5d18a89f8c8ec70ed68f5..edbb0e5b36a2914b2e4a3542baca49fac78cf4e2 100644
--- a/resources/static/shared/helpers.js
+++ b/resources/static/shared/helpers.js
@@ -132,6 +132,12 @@
     return dObj;
   }
 
+  function cancelEvent(callback) {
+    return function(event) {
+      event && event.preventDefault();
+      callback.call(this);
+    };
+  }
 
   extend(helpers, {
     /**
@@ -175,8 +181,14 @@
      * @param {Date} date
      * @returns {string} date relative to now.
      */
-    relativeDate: relativeDate
-
+    relativeDate: relativeDate,
+    /**
+     * Return a function that calls preventDefault on the event and then calls
+     * the callback with the arguments.
+     * @method cancelEvent
+     * @param {function} function to call after the event is cancelled.
+     */
+    cancelEvent: cancelEvent
   });
 
 
diff --git a/resources/static/shared/modules/page_module.js b/resources/static/shared/modules/page_module.js
index b702f6163dbf07d0970ec95d607328eb455876d3..ecefd075190ea4e251e8e438a5e4bb1e2cd1e56a 100644
--- a/resources/static/shared/modules/page_module.js
+++ b/resources/static/shared/modules/page_module.js
@@ -11,13 +11,12 @@ BrowserID.Modules.PageModule = (function() {
       bid = BrowserID,
       dom = bid.DOM,
       screens = bid.Screens,
+      helpers = bid.Helpers,
+      cancelEvent = helpers.cancelEvent,
       mediator = bid.Mediator;
 
-   function onSubmit(event) {
-     event.stopPropagation();
-     event.preventDefault();
-
-     if (this.validate()) {
+   function onSubmit() {
+     if (!dom.hasClass("body", "submit_disabled") && this.validate()) {
        this.submit();
      }
      return false;
@@ -55,8 +54,8 @@ BrowserID.Modules.PageModule = (function() {
 
     start: function(options) {
       var self=this;
-      self.bind("form", "submit", onSubmit);
-      self.bind("#thisIsNotMe", "click", self.close.bind(self, "notme"));
+      self.bind("form", "submit", cancelEvent(onSubmit));
+      self.bind("#thisIsNotMe", "click", cancelEvent(self.close.bind(self, "notme")));
     },
 
     stop: function() {
@@ -69,6 +68,14 @@ BrowserID.Modules.PageModule = (function() {
       this.stop();
     },
 
+    /**
+     * Bind a dom event
+     * @method bind
+     * @param {string} target - css selector
+     * @param {string} type - event type
+     * @param {function} callback
+     * @param {object} [context] - optional context, if not given, use this.
+     */
     bind: function(target, type, callback, context) {
       var self=this,
           cb = callback.bind(context || this);
@@ -123,10 +130,20 @@ BrowserID.Modules.PageModule = (function() {
       screens.error.hide();
     },
 
+    /**
+     * Validate the form, if returns false when called, submit will not be
+     * called on click.
+     * @method validate.
+     */
     validate: function() {
       return true;
     },
 
+    /**
+     * Submit the form.  Can be called to force override the
+     * disableSubmit function.
+     * @method submit
+     */
     submit: function() {
     },
 
@@ -137,12 +154,25 @@ BrowserID.Modules.PageModule = (function() {
       }
     },
 
+    /**
+     * Publish a message to the mediator.
+     * @method publish
+     * @param {string} message
+     * @param {object} data
+     */
     publish: function(message, data) {
       mediator.publish(message, data);
     },
 
-    subscribe: function(message, callback) {
-      mediator.subscribe(message, callback.bind(this));
+    /**
+     * Subscribe to a message on the mediator.
+     * @method subscribe
+     * @param {string} message
+     * @param {function} callback
+     * @param {object} [context] - context, if not given, use this.
+     */
+    subscribe: function(message, callback, context) {
+      mediator.subscribe(message, callback.bind(context || this));
     },
 
     /**
@@ -161,6 +191,11 @@ BrowserID.Modules.PageModule = (function() {
         }, lowLevelInfo), onerror);
       };
     }
+
+    // BEGIN TESTING API
+    ,
+    onSubmit: onSubmit
+    // END TESTING API
   });
 
   return Module;
diff --git a/resources/static/shared/modules/xhr_disable_form.js b/resources/static/shared/modules/xhr_disable_form.js
new file mode 100644
index 0000000000000000000000000000000000000000..23ba3ebed9c47d3b571abb7db95704859163e85f
--- /dev/null
+++ b/resources/static/shared/modules/xhr_disable_form.js
@@ -0,0 +1,30 @@
+/*globals BrowserID: true */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+BrowserID.Modules.XHRDisableForm = (function() {
+  "use strict";
+
+  var bid = BrowserID,
+      dom = bid.DOM,
+      sc;
+
+  var Module = bid.Modules.PageModule.extend({
+    start: function(options) {
+      var self=this;
+
+      self.subscribe("xhr_start",
+        dom.addClass.curry("body", "submit_disabled"));
+      self.subscribe("xhr_complete",
+        dom.removeClass.curry("body", "submit_disabled"));
+
+      sc.start.call(self, options);
+    }
+  });
+
+  sc = Module.sc;
+
+  return Module;
+
+}());
+
diff --git a/resources/static/shared/network.js b/resources/static/shared/network.js
index f0e007d1b988e58d59cd90ebef58e697b631f82e..47f1d9ad3807c4680713c047987f87cfa9da0aed 100644
--- a/resources/static/shared/network.js
+++ b/resources/static/shared/network.js
@@ -84,6 +84,7 @@ BrowserID.Network = (function() {
       delayTimeout = setTimeout(xhrDelay.curry(reqInfo), time_until_delay);
     };
 
+    mediator.publish("xhr_start", reqInfo);
     xhr.ajax(req);
   }
 
diff --git a/resources/static/test/index.html b/resources/static/test/index.html
index ebea44ef7e5798eb844e8219a27523b2c53f0b19..08d998779f3fb06182f0de9e39def60204cfde8e 100644
--- a/resources/static/test/index.html
+++ b/resources/static/test/index.html
@@ -95,6 +95,7 @@
 
     <script src="/shared/modules/page_module.js"></script>
     <script src="/shared/modules/xhr_delay.js"></script>
+    <script src="/shared/modules/xhr_disable_form.js"></script>
 
     <script src="/dialog/resources/internal_api.js"></script>
     <script src="/dialog/resources/helpers.js"></script>
@@ -136,8 +137,10 @@
     <script src="qunit/shared/storage_unit_test.js"></script>
     <script src="qunit/shared/network_unit_test.js"></script>
     <script src="qunit/shared/user_unit_test.js"></script>
-    <script src="qunit/shared/page_module_unit_test.js"></script>
-    <script src="qunit/shared/xhr_delay_unit_test.js"></script>
+
+    <script src="qunit/shared/modules/page_module_unit_test.js"></script>
+    <script src="qunit/shared/modules/xhr_delay_unit_test.js"></script>
+    <script src="qunit/shared/modules/xhr_disable_form_unit_test.js"></script>
 
     <script src="qunit/pages/browserid_unit_test.js"></script>
     <script src="qunit/pages/page_helpers_unit_test.js"></script>
diff --git a/resources/static/test/qunit/pages/forgot_unit_test.js b/resources/static/test/qunit/pages/forgot_unit_test.js
index 621d7ceccb46f188ee0a676f62911762aa928745..22491ef900b829917dda7841d34b89671b0a492f 100644
--- a/resources/static/test/qunit/pages/forgot_unit_test.js
+++ b/resources/static/test/qunit/pages/forgot_unit_test.js
@@ -76,7 +76,7 @@
     $("#email").val("testuser@testuser.com");
 
     testEmailNotSent(function() {
-      equal($("#error").is(":visible"), true, "error is visible");
+      testHelpers.testErrorVisible();
       start();
     });
   });
diff --git a/resources/static/test/qunit/pages/signin_unit_test.js b/resources/static/test/qunit/pages/signin_unit_test.js
index d03a0855648e59e9c7b9edc430155a612ea10f6d..79baa83d22529f7981ad6f6d499ce7cec383d999 100644
--- a/resources/static/test/qunit/pages/signin_unit_test.js
+++ b/resources/static/test/qunit/pages/signin_unit_test.js
@@ -155,9 +155,7 @@
     $("#email").val("registered@testuser.com");
     $("#password").val("password");
 
-    testUserNotSignedIn(function() {
-        equal($("#error").is(":visible"), true, "error is visible");
-    });
+    testUserNotSignedIn(testHelpers.testErrorVisible);
   });
 
   asyncTest("authWithPrimary opens winchan", function() {
diff --git a/resources/static/test/qunit/pages/verify_email_address_test.js b/resources/static/test/qunit/pages/verify_email_address_test.js
index f8af66a957bc7b07e72111f4a6d049d288d519d5..a4c3ef06d7407dd377bcb79b1310da0c59424357 100644
--- a/resources/static/test/qunit/pages/verify_email_address_test.js
+++ b/resources/static/test/qunit/pages/verify_email_address_test.js
@@ -58,7 +58,7 @@
   asyncTest("verifyEmailAddress with emailForVerficationToken XHR failure", function() {
     xhr.useResult("ajaxError");
     bid.verifyEmailAddress("token", function() {
-      ok($("#error").is(":visible"), "cannot communicate box is visible");
+      testHelpers.testErrorVisible();
       start();
     });
   });
diff --git a/resources/static/test/qunit/shared/page_module_unit_test.js b/resources/static/test/qunit/shared/modules/page_module_unit_test.js
similarity index 92%
rename from resources/static/test/qunit/shared/page_module_unit_test.js
rename to resources/static/test/qunit/shared/modules/page_module_unit_test.js
index 82b472d8881e876f170468a38251e16487fc5e2d..5b52f0346e54337e52cb5409ec081dab3f13bcc2 100644
--- a/resources/static/test/qunit/shared/page_module_unit_test.js
+++ b/resources/static/test/qunit/shared/modules/page_module_unit_test.js
@@ -17,7 +17,7 @@
     controller.start();
   }
 
-  module("shared/page_controller", {
+  module("shared/page_module", {
     setup: function() {
       el = $("#controller_head");
       bid.TestHelpers.setup();
@@ -51,11 +51,6 @@
     var html = el.find("#formWrap .contents").html();
     ok(html.length, "with template specified, form text is loaded");
 
-/*
-
-    var input = el.find("input").eq(0);
-    ok(input.is(":focus"), "make sure the first input is focused");
-*/
     html = el.find("#wait .contents").html();
     equal(html, "", "with body template specified, wait text is not loaded");
   });
@@ -233,5 +228,23 @@
     equal(error, "missing config option: requiredField");
   });
 
+  test("form is not submitted when 'submit_disabled' class is added to body", function() {
+    createController();
+
+    var submitCalled = false;
+    controller.submit = function() {
+      submitCalled = true;
+    };
+
+    $("body").addClass("submit_disabled");
+    controller.onSubmit();
+
+    equal(submitCalled, false, "submit was prevented from being called");
+
+
+    $("body").removeClass("submit_disabled");
+    controller.onSubmit();
+    equal(submitCalled, true, "submit permitted to complete");
+  })
 }());
 
diff --git a/resources/static/test/qunit/shared/xhr_delay_unit_test.js b/resources/static/test/qunit/shared/modules/xhr_delay_unit_test.js
similarity index 100%
rename from resources/static/test/qunit/shared/xhr_delay_unit_test.js
rename to resources/static/test/qunit/shared/modules/xhr_delay_unit_test.js
diff --git a/resources/static/test/qunit/shared/modules/xhr_disable_form_unit_test.js b/resources/static/test/qunit/shared/modules/xhr_disable_form_unit_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..61a1d9bb1ac2584dee36dab3f062c6dec7af027a
--- /dev/null
+++ b/resources/static/test/qunit/shared/modules/xhr_disable_form_unit_test.js
@@ -0,0 +1,41 @@
+/*jshint browsers:true, forin: true, laxbreak: true */
+/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+(function() {
+  "use strict";
+
+  var bid = BrowserID,
+      Module = bid.Modules.XHRDisableForm,
+      testHelpers = bid.TestHelpers,
+      mediator = bid.Mediator,
+      mod;
+
+  function createModule(options) {
+    mod = Module.create({});
+    mod.start(options);
+    return mod;
+  }
+
+  module("shared/xhr_disable_form", {
+    setup: function() {
+      testHelpers.setup();
+      createModule();
+    },
+
+    teardown: function() {
+      testHelpers.teardown();
+    }
+  });
+
+  test("xhr_start adds 'submit_disabled' to class, xhr_complete removes it", function() {
+    var body = $("body");
+
+    mediator.publish("xhr_start");
+    equal(body.hasClass("submit_disabled"), true, "xhr_start adds submit_disabled");
+
+    mediator.publish("xhr_complete");
+    equal(body.hasClass("submit_disabled"), false, "xhr_complete removes submit_disabled");
+  });
+}());
diff --git a/resources/static/test/qunit/testHelpers/helpers.js b/resources/static/test/qunit/testHelpers/helpers.js
index 5bfd7148907a71704f864239c28d76e97020e75f..f7703e275999f70d6b2f5c4b5e00a5f064b2d230 100644
--- a/resources/static/test/qunit/testHelpers/helpers.js
+++ b/resources/static/test/qunit/testHelpers/helpers.js
@@ -103,12 +103,15 @@ BrowserID.TestHelpers = (function() {
     isTriggered: function(message) {
       return calls[message];
     },
+
     errorVisible: function() {
       return screens.error.visible;
     },
+
     testErrorVisible: function() {
-      equal(this.errorVisible(), true, "error screen is visible");
+      equal(TestHelpers.errorVisible(), true, "error screen is visible");
     },
+
     checkNetworkError: checkNetworkError,
     unexpectedSuccess: function() {
       ok(false, "unexpected success");
diff --git a/resources/views/dialog_layout.ejs b/resources/views/dialog_layout.ejs
index 18f29c49b688d84877787caf49b5c1a93211c647..4d74033221e550e7ee98d9ae0858d0a456136deb 100644
--- a/resources/views/dialog_layout.ejs
+++ b/resources/views/dialog_layout.ejs
@@ -82,6 +82,7 @@
 
           <script src="/shared/modules/page_module.js"></script>
           <script src="/shared/modules/xhr_delay.js"></script>
+          <script src="/shared/modules/xhr_disable_form.js"></script>
 
           <script src="/dialog/resources/internal_api.js"></script>
           <script src="/dialog/resources/helpers.js"></script>
diff --git a/resources/views/layout.ejs b/resources/views/layout.ejs
index 3e4fbcfb47e48bf39d082dd8768f4a07bd95c508..9b64750678fd890c558f1f634b0a6f7fb64b6635 100644
--- a/resources/views/layout.ejs
+++ b/resources/views/layout.ejs
@@ -47,6 +47,7 @@
 
     <script src="/shared/modules/page_module.js"></script>
     <script src="/shared/modules/xhr_delay.js"></script>
+    <script src="/shared/modules/xhr_disable_form.js"></script>
 
     <script src="/pages/page_helpers.js"></script>
     <script src="/pages/index.js"></script>
diff --git a/scripts/compress.sh b/scripts/compress.sh
index 8c63c4fcd0375cc226c19a62018f684a46753ae8..7a3557f0e0c1df2b1435fb1a7aa9f4e9d0abec13 100755
--- a/scripts/compress.sh
+++ b/scripts/compress.sh
@@ -58,7 +58,7 @@ cp templates.js $BUILD_PATH/templates.js
 cd ../..
 
 # produce the dialog js
-cat lib/jquery-1.7.1.min.js lib/winchan.js lib/underscore-min.js lib/vepbundle.js lib/ejs.js shared/browserid.js lib/hub.js lib/dom-jquery.js lib/module.js lib/jschannel.js shared/javascript-extensions.js shared/mediator.js shared/class.js shared/storage.js $BUILD_PATH/templates.js shared/renderer.js shared/error-display.js shared/screens.js shared/tooltip.js shared/validation.js shared/provisioning.js shared/network.js shared/user.js shared/error-messages.js shared/browser-support.js shared/wait-messages.js shared/helpers.js shared/modules/page_module.js shared/modules/xhr_delay.js dialog/resources/internal_api.js dialog/resources/helpers.js dialog/resources/state_machine.js dialog/controllers/code_check.js dialog/controllers/actions.js dialog/controllers/dialog.js dialog/controllers/authenticate.js dialog/controllers/forgot_password.js dialog/controllers/check_registration.js dialog/controllers/pick_email.js dialog/controllers/add_email.js dialog/controllers/required_email.js dialog/controllers/verify_primary_user.js dialog/controllers/provision_primary_user.js dialog/controllers/primary_user_provisioned.js dialog/controllers/email_chosen.js dialog/start.js > $BUILD_PATH/dialog.uncompressed.js
+cat lib/jquery-1.7.1.min.js lib/winchan.js lib/underscore-min.js lib/vepbundle.js lib/ejs.js shared/browserid.js lib/hub.js lib/dom-jquery.js lib/module.js lib/jschannel.js shared/javascript-extensions.js shared/mediator.js shared/class.js shared/storage.js $BUILD_PATH/templates.js shared/renderer.js shared/error-display.js shared/screens.js shared/tooltip.js shared/validation.js shared/provisioning.js shared/network.js shared/user.js shared/error-messages.js shared/browser-support.js shared/wait-messages.js shared/helpers.js shared/modules/page_module.js shared/modules/xhr_delay.js shared/modules/xhr_disable_form.js dialog/resources/internal_api.js dialog/resources/helpers.js dialog/resources/state_machine.js dialog/controllers/code_check.js dialog/controllers/actions.js dialog/controllers/dialog.js dialog/controllers/authenticate.js dialog/controllers/forgot_password.js dialog/controllers/check_registration.js dialog/controllers/pick_email.js dialog/controllers/add_email.js dialog/controllers/required_email.js dialog/controllers/verify_primary_user.js dialog/controllers/provision_primary_user.js dialog/controllers/primary_user_provisioned.js dialog/controllers/email_chosen.js dialog/start.js > $BUILD_PATH/dialog.uncompressed.js
 
 # produce the dialog css
 cat css/common.css dialog/css/popup.css dialog/css/m.css > $BUILD_PATH/dialog.uncompressed.css
@@ -71,7 +71,7 @@ echo '****Building BrowserID.org HTML, CSS, and JS****'
 echo ''
 
 #produce the main site js
-cat lib/vepbundle.js lib/jquery-1.7.1.min.js lib/underscore-min.js lib/ejs.js shared/javascript-extensions.js shared/browserid.js lib/dom-jquery.js lib/jschannel.js lib/winchan.js lib/hub.js $BUILD_PATH/templates.js shared/renderer.js shared/error-display.js shared/screens.js shared/error-messages.js shared/wait-messages.js shared/mediator.js shared/storage.js shared/network.js shared/provisioning.js shared/user.js shared/tooltip.js shared/validation.js shared/helpers.js shared/class.js shared/modules/page_module.js shared/modules/xhr_delay.js pages/page_helpers.js pages/start.js pages/index.js pages/add_email_address.js pages/verify_email_address.js pages/forgot.js pages/manage_account.js pages/signin.js pages/signup.js > $BUILD_PATH/browserid.uncompressed.js
+cat lib/vepbundle.js lib/jquery-1.7.1.min.js lib/underscore-min.js lib/ejs.js shared/javascript-extensions.js shared/browserid.js lib/dom-jquery.js lib/jschannel.js lib/winchan.js lib/hub.js $BUILD_PATH/templates.js shared/renderer.js shared/error-display.js shared/screens.js shared/error-messages.js shared/wait-messages.js shared/mediator.js shared/storage.js shared/network.js shared/provisioning.js shared/user.js shared/tooltip.js shared/validation.js shared/helpers.js shared/class.js shared/modules/page_module.js shared/modules/xhr_delay.js shared/modules/xhr_disable_form.js pages/page_helpers.js pages/start.js pages/index.js pages/add_email_address.js pages/verify_email_address.js pages/forgot.js pages/manage_account.js pages/signin.js pages/signup.js > $BUILD_PATH/browserid.uncompressed.js
 
 # produce the main site css
 cat css/common.css css/style.css css/m.css > $BUILD_PATH/browserid.uncompressed.css