diff --git a/.eslintrc.json b/.eslintrc.json
index 3e8b6da35d..ec6dda9982 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -14,7 +14,6 @@
"Handlebars": false,
"XDate": false,
"zxcvbn": false,
- "LazyLoad": false,
"SockJS": false,
"marked": false,
"md5": false,
diff --git a/docs/THIRDPARTY b/docs/THIRDPARTY
index 9a01f2ae04..08e6492c7e 100644
--- a/docs/THIRDPARTY
+++ b/docs/THIRDPARTY
@@ -149,10 +149,6 @@ Files: static/third/jquery-throttle-debounce/*
Copyright: 2010 "Cowboy" Ben Alman
License: Expat or GPL
-Files: src/zulip/static/third/lazyload/*
-Copyright: 2011 Ryan Grove
-License: Expat
-
Files: static/third/marked/*
Copyright: 2011-2013, Christopher Jeffrey
License: Expat
diff --git a/static/third/lazyload/HISTORY b/static/third/lazyload/HISTORY
deleted file mode 100644
index 3d738c5aa7..0000000000
--- a/static/third/lazyload/HISTORY
+++ /dev/null
@@ -1,68 +0,0 @@
-LazyLoad Changelog
-================================================================================
-
-Version 2.0.3 (2011-07-05)
- * Fixed a bug caused by an unwanted Closure Compiler optimization that broke
- CSS load completion detection in Gecko when using the minified version of
- LazyLoad. [Allex Wang]
- * Fixed a race condition in which a URL could be removed from the "pending"
- queue if it finished loading before other URLs in the same batch had been
- added to the queue, resulting in the queue's length changing unexpectedly
- during iteration. [Klaas Neirinck]
-
-Version 2.0.2 (2011-04-17)
- * Added support for reliable detection of CSS load completion in Gecko
- browsers based on a technique described by Zach Leatherman at
- .
- * Fixed a bug that prevented CSS load completion from being detected in WebKit
- when there were no other stylesheets on the page. [Klaas Neirinck]
- * Fixed a bug that could prevent CSS callbacks from being called in IE.
-
-Version 2.0.1 (2011-03-05)
- * Added support for async=false. This ensures that parallel script loading
- still works in Firefox 4 while preserving execution order. For more info,
- see .
- * Stylesheet load completion is now detected reliably in WebKit by polling
- document.styleSheets for changes. Thanks to Jonathan Cook for suggesting
- this solution.
- * Dynamically created script and link nodes are now given a "lazyload" class
- so they can be identified later.
- * The charset for dynamically created script and link nodes is set to "utf-8".
-
-Version 2.0.0 (2009-08-06)
- * Added support for CSS. Caveat: Gecko and WebKit don't support the onload
- event for link nodes, so the CSS callback will fire almost immediately in
- those browsers.
- * When an array of URLs is specified, the resources will be loaded in parallel
- in browsers that support it. Currently, all browsers support loading CSS in
- parallel, but only Gecko and Opera support parallel scripts while preserving
- execution order.
- * The load() method has been replaced by css() and js() methods for loading
- CSS and JS, respectively.
- * The loadOnce() method has been removed, since it wasn't terribly useful.
- * Improved reliability in all supported browsers.
-
-Version 1.0.4 (2008-07-24)
- * Improved reliability with all supported browsers.
- * Reduced the minified size to 1751 bytes (a whopping 67 bytes smaller than
- version 1.0.3).
- * Fixed a bug that caused the load completion callback to fire immediately in
- Safari 3.x.
- * Fixed a bug that caused the load completion callback to fail to fire in
- Internet Explorer if the script was loaded from the cache.
-
-Version 1.0.3 (2007-06-18)
- * Added "force" parameter to the loadOnce() method to force execution of the
- callback even when all specified scripts have already been loaded.
-
-Version 1.0.2 (2007-06-02)
- * Improved browser detection.
- * Switched to NaturalDocs for source documentation.
-
-Version 1.0.1 (2007-05-30)
- * Fixed potential race condition when load() is called multiple times in
- succession.
- * Refactored to reduce complexity.
-
-Version 1.0.0 (2007-05-29)
- * First release.
diff --git a/static/third/lazyload/LICENSE b/static/third/lazyload/LICENSE
deleted file mode 100644
index cf4690b1cb..0000000000
--- a/static/third/lazyload/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Ryan Grove
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the 'Software'), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/static/third/lazyload/README.md b/static/third/lazyload/README.md
deleted file mode 100644
index bc98a61c7c..0000000000
--- a/static/third/lazyload/README.md
+++ /dev/null
@@ -1,97 +0,0 @@
-LazyLoad
-========
-
-LazyLoad is a tiny (only 966 bytes minified and gzipped), dependency-free
-JavaScript utility that makes it super easy to load external JavaScript and CSS
-files on demand.
-
-Whenever possible, LazyLoad will automatically load resources in parallel while
-ensuring execution order when you specify an array of URLs to load. In browsers
-that don't preserve the execution order of asynchronously-loaded scripts,
-LazyLoad will safely load the scripts sequentially.
-
-Use LazyLoad when you need a small, fast, safe dynamic JS or CSS loader, but
-don't need the overhead of dependency management or other extra functionality
-that larger script loaders provide.
-
-Downloads
----------
-
- * [lazyload.js](https://github.com/rgrove/lazyload/raw/master/lazyload.js) (full source)
-
-Usage
------
-
-Using LazyLoad is simple. Just call the appropriate method -- `css()` to load
-CSS, `js()` to load JavaScript -- and pass in a URL or array of URLs to load.
-You can also provide a callback function if you'd like to be notified when the
-resources have finished loading, as well as an argument to pass to the callback
-and a context in which to execute the callback.
-
-```js
-// Load a single JavaScript file and execute a callback when it finishes.
-LazyLoad.js('http://example.com/foo.js', function () {
- alert('foo.js has been loaded');
-});
-
-// Load multiple JS files and execute a callback when they've all finished.
-LazyLoad.js(['foo.js', 'bar.js', 'baz.js'], function () {
- alert('all files have been loaded');
-});
-
-// Load a CSS file and pass an argument to the callback function.
-LazyLoad.css('foo.css', function (arg) {
- alert(arg);
-}, 'foo.css has been loaded');
-
-// Load a CSS file and execute the callback in a different scope.
-LazyLoad.css('foo.css', function () {
- alert(this.foo); // displays 'bar'
-}, null, {foo: 'bar'});
-```
-
-Supported Browsers
-------------------
-
- * Firefox 2+
- * Google Chrome
- * Internet Explorer 6+
- * Opera 9+
- * Safari 3+
- * Mobile Safari
- * Android
-
-Other browsers may work, but haven't been tested. It's a safe bet that anything
-based on a recent version of Gecko or WebKit will probably work.
-
-Caveats
--------
-
-All browsers support parallel loading of CSS. However, only Firefox and Opera
-currently support parallel script loading while preserving execution order. To
-ensure that scripts are always executed in the correct order, LazyLoad will load
-all scripts sequentially in browsers other than Firefox and Opera. Hopefully
-other browsers will improve their parallel script loading behavior soon.
-
-License
--------
-
-Copyright (c) 2011 Ryan Grove (ryan@wonko.com).
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the 'Software'), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/static/third/lazyload/lazyload.js b/static/third/lazyload/lazyload.js
deleted file mode 100644
index 99f7a87662..0000000000
--- a/static/third/lazyload/lazyload.js
+++ /dev/null
@@ -1,393 +0,0 @@
-/*jslint browser: true, eqeqeq: true, bitwise: true, newcap: true, immed: true, regexp: false */
-
-/** @preserve
- Software from "LazyLoad" is Copyright (c) 2011 Ryan Grove
- and is provided under the following license:
- --
- Permission is hereby granted, free of charge, to any person obtaining a copy of
- this software and associated documentation files (the 'Software'), to deal in
- the Software without restriction, including without limitation the rights to
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- the Software, and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- --
-/**
-
-/**
-LazyLoad makes it easy and painless to lazily load one or more external
-JavaScript or CSS files on demand either during or after the rendering of a web
-page.
-
-Supported browsers include Firefox 2+, IE6+, Safari 3+ (including Mobile
-Safari), Google Chrome, and Opera 9+. Other browsers may or may not work and
-are not officially supported.
-
-Visit https://github.com/rgrove/lazyload/ for more info.
-
-@module lazyload
-@class LazyLoad
-@static
-*/
-
-LazyLoad = (function (doc) {
- // -- Private Variables ------------------------------------------------------
-
- // User agent and feature test information.
- var env,
-
- // Reference to the element (populated lazily).
- head,
-
- // Requests currently in progress, if any.
- pending = {},
-
- // Number of times we've polled to check whether a pending stylesheet has
- // finished loading. If this gets too high, we're probably stalled.
- pollCount = 0,
-
- // Queued requests.
- queue = {css: [], js: []},
-
- // Reference to the browser's list of stylesheets.
- styleSheets = doc.styleSheets;
-
- // -- Private Methods --------------------------------------------------------
-
- /**
- Creates and returns an HTML element with the specified name and attributes.
-
- @method createNode
- @param {String} name element name
- @param {Object} attrs name/value mapping of element attributes
- @return {HTMLElement}
- @private
- */
- function createNode(name, attrs) {
- var node = doc.createElement(name), attr;
-
- for (attr in attrs) {
- if (attrs.hasOwnProperty(attr)) {
- node.setAttribute(attr, attrs[attr]);
- }
- }
-
- return node;
- }
-
- /**
- Called when the current pending resource of the specified type has finished
- loading. Executes the associated callback (if any) and loads the next
- resource in the queue.
-
- @method finish
- @param {String} type resource type ('css' or 'js')
- @private
- */
- function finish(type) {
- var p = pending[type],
- callback,
- urls;
-
- if (p) {
- callback = p.callback;
- urls = p.urls;
-
- urls.shift();
- pollCount = 0;
-
- // If this is the last of the pending URLs, execute the callback and
- // start the next request in the queue (if any).
- if (!urls.length) {
- callback && callback.call(p.context, p.obj);
- pending[type] = null;
- queue[type].length && load(type);
- }
- }
- }
-
- /**
- Populates the env variable with user agent and feature test
- information.
-
- @method getEnv
- @private
- */
- function getEnv() {
- var ua = navigator.userAgent;
-
- env = {
- // True if this browser supports disabling async mode on dynamically
- // created script nodes. See
- // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
- async: doc.createElement('script').async === true
- };
-
- (env.webkit = /AppleWebKit\//.test(ua))
- || (env.ie = /MSIE|Trident/.test(ua))
- || (env.opera = /Opera/.test(ua))
- || (env.gecko = /Gecko\//.test(ua))
- || (env.unknown = true);
- }
-
- /**
- Loads the specified resources, or the next resource of the specified type
- in the queue if no resources are specified. If a resource of the specified
- type is already being loaded, the new request will be queued until the
- first request has been finished.
-
- When an array of resource URLs is specified, those URLs will be loaded in
- parallel if it is possible to do so while preserving execution order. All
- browsers support parallel loading of CSS, but only Firefox and Opera
- support parallel loading of scripts. In other browsers, scripts will be
- queued and loaded one at a time to ensure correct execution order.
-
- @method load
- @param {String} type resource type ('css' or 'js')
- @param {String|Array} urls (optional) URL or array of URLs to load
- @param {Function} callback (optional) callback function to execute when the
- resource is loaded
- @param {Object} obj (optional) object to pass to the callback function
- @param {Object} context (optional) if provided, the callback function will
- be executed in this object's context
- @private
- */
- function load(type, urls, callback, obj, context) {
- var _finish = function () { finish(type); },
- isCSS = type === 'css',
- nodes = [],
- i, len, node, p, pendingUrls, url;
-
- env || getEnv();
-
- if (urls) {
- // If urls is a string, wrap it in an array. Otherwise assume it's an
- // array and create a copy of it so modifications won't be made to the
- // original.
- urls = typeof urls === 'string' ? [urls] : urls.concat();
-
- // Create a request object for each URL. If multiple URLs are specified,
- // the callback will only be executed after all URLs have been loaded.
- //
- // Sadly, Firefox and Opera are the only browsers capable of loading
- // scripts in parallel while preserving execution order. In all other
- // browsers, scripts must be loaded sequentially.
- //
- // All browsers respect CSS specificity based on the order of the link
- // elements in the DOM, regardless of the order in which the stylesheets
- // are actually downloaded.
- if (isCSS || env.async || env.gecko || env.opera) {
- // Load in parallel.
- queue[type].push({
- urls : urls,
- callback: callback,
- obj : obj,
- context : context
- });
- } else {
- // Load sequentially.
- for (i = 0, len = urls.length; i < len; ++i) {
- queue[type].push({
- urls : [urls[i]],
- callback: i === len - 1 ? callback : null, // callback is only added to the last URL
- obj : obj,
- context : context
- });
- }
- }
- }
-
- // If a previous load request of this type is currently in progress, we'll
- // wait our turn. Otherwise, grab the next item in the queue.
- if (pending[type] || !(p = pending[type] = queue[type].shift())) {
- return;
- }
-
- head || (head = doc.head || doc.getElementsByTagName('head')[0]);
- pendingUrls = p.urls;
-
- for (i = 0, len = pendingUrls.length; i < len; ++i) {
- url = pendingUrls[i];
-
- if (isCSS) {
- node = env.gecko ? createNode('style') : createNode('link', {
- href: url,
- rel : 'stylesheet'
- });
- } else {
- node = createNode('script', {src: url});
- node.async = false;
- }
-
- node.className = 'lazyload';
- node.setAttribute('charset', 'utf-8');
-
- if (env.ie && !isCSS && 'onreadystatechange' in node && !('draggable' in node)) {
- node.onreadystatechange = function () {
- if (/loaded|complete/.test(node.readyState)) {
- node.onreadystatechange = null;
- _finish();
- }
- };
- } else if (isCSS && (env.gecko || env.webkit)) {
- // Gecko and WebKit don't support the onload event on link nodes.
- if (env.webkit) {
- // In WebKit, we can poll for changes to document.styleSheets to
- // figure out when stylesheets have loaded.
- p.urls[i] = node.href; // resolve relative URLs (or polling won't work)
- pollWebKit();
- } else {
- // In Gecko, we can import the requested URL into a