Repository: ckan/ckan

Issue:
Remove Bootstrap 2 templates from master
They have been around (and will be) for the whole 2.8 release cycle, which should give users plenty of time to upgrade.


Discussion:

Resolving patch:
diff --git a/ckan/config/environment.py b/ckan/config/environment.py
--- a/ckan/config/environment.py
+++ b/ckan/config/environment.py
@@ -76,14 +76,14 @@ def find_controller(self, controller):
     # Pylons paths
     root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
-    valid_base_public_folder_names = ['public', 'public-bs2']
+    valid_base_public_folder_names = ['public']
     static_files = app_conf.get('ckan.base_public_folder', 'public')
     app_conf['ckan.base_public_folder'] = static_files
 
     if static_files not in valid_base_public_folder_names:
         raise CkanConfigurationException(
             'You provided an invalid value for ckan.base_public_folder. '
-            'Possible values are: "public" and "public-bs2".'
+            'Possible values are: "public".'
         )
 
     log.info('Loading static files from %s' % static_files)
@@ -248,14 +248,14 @@ def update_config():
     config['pylons.h'] = helpers.helper_functions
 
     # Templates and CSS loading from configuration
-    valid_base_templates_folder_names = ['templates', 'templates-bs2']
+    valid_base_templates_folder_names = ['templates']
     templates = config.get('ckan.base_templates_folder', 'templates')
     config['ckan.base_templates_folder'] = templates
 
     if templates not in valid_base_templates_folder_names:
         raise CkanConfigurationException(
             'You provided an invalid value for ckan.base_templates_folder. '
-            'Possible values are: "templates" and "templates-bs2".'
+            'Possible values are: "templates".'
         )
 
     jinja2_templates_path = os.path.join(root, templates)
diff --git a/ckan/templates-bs2/revision/__init__.py b/ckan/templates-bs2/revision/__init__.py
deleted file mode 100644
--- a/ckan/templates-bs2/revision/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# encoding: utf-8
-
-# empty file needed for pylons to find templates in this directory


Test patch:
diff --git a/ckan/public-bs2/base/test/index.html b/ckan/public-bs2/base/test/index.html
deleted file mode 100644
--- a/ckan/public-bs2/base/test/index.html
+++ /dev/null
@@ -1,169 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <title>Mocha Tests</title>
-    <link rel="stylesheet" href="vendor/mocha.css" />
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <div id="fixture" style="position: absolute; top: -9999px; left: -9999px"></div>
-
-    <!-- Test Runner -->
-    <script src="./vendor/sinon.js"></script>
-    <script src="./vendor/mocha.js"></script>
-    <script src="./vendor/chai.js"></script>
-    <script>
-      mocha.setup('bdd');
-      var assert = chai.assert;
-
-      // Export sinon.assert methods onto assert.
-      sinon.assert.expose(assert, {prefix: ''});
-
-      var ckan = {ENV: 'testing'};
-    </script>
-
-    <!-- Source -->
-    <script src="../vendor/jed.js"></script>
-    <script src="../vendor/jquery.js"></script>
-    <script src="../vendor/bootstrap/js/bootstrap.js"></script>
-    <script src="../javascript/plugins/jquery.inherit.js"></script>
-    <script src="../javascript/plugins/jquery.proxy-all.js"></script>
-    <script src="../javascript/plugins/jquery.url-helpers.js"></script>
-    <script src="../javascript/plugins/jquery.date-helpers.js"></script>
-    <script src="../javascript/plugins/jquery.slug.js"></script>
-    <script src="../javascript/plugins/jquery.slug-preview.js"></script>
-    <script src="../javascript/plugins/jquery.form-warning.js"></script>
-    <script src="../javascript/sandbox.js"></script>
-    <script src="../javascript/module.js"></script>
-    <script src="../javascript/pubsub.js"></script>
-    <script src="../javascript/client.js"></script>
-    <script src="../javascript/notify.js"></script>
-    <script src="../javascript/i18n.js"></script>
-    <script src="../javascript/main.js"></script>
-    <script src="../javascript/view-filters.js"></script>
-    <script src="../javascript/modules/basic-form.js"></script>
-    <script src="../javascript/modules/autocomplete.js"></script>
-    <script src="../javascript/modules/resource-form.js"></script>
-    <script src="../javascript/modules/resource-upload-field.js"></script>
-    <script src="../javascript/modules/image-upload.js"></script>
-    <script src="../javascript/modules/confirm-action.js"></script>
-    <script src="../javascript/modules/custom-fields.js"></script>
-    <script src="../javascript/modules/followers-counter.js"></script>
-
-    <!-- Suite -->
-    <script src="./spec/ckan.spec.js"></script>
-    <script src="./spec/i18n.spec.js"></script>
-    <script src="./spec/module.spec.js"></script>
-    <script src="./spec/sandbox.spec.js"></script>
-    <script src="./spec/client.spec.js"></script>
-    <script src="./spec/pubsub.spec.js"></script>
-    <script src="./spec/notify.spec.js"></script>
-    <script src="./spec/view-filters.spec.js"></script>
-    <script src="./spec/modules/resource-form.spec.js"></script>
-    <script src="./spec/modules/resource-upload-field.spec.js"></script>
-    <script src="./spec/modules/image-upload.spec.js"></script>
-    <script src="./spec/modules/confirm-action.spec.js"></script>
-    <script src="./spec/modules/basic-form.spec.js"></script>
-    <script src="./spec/modules/autocomplete.spec.js"></script>
-    <script src="./spec/modules/custom-fields.spec.js"></script>
-    <script src="./spec/modules/followers-counter.spec.js"></script>
-    <script src="./spec/plugins/jquery.inherit.spec.js"></script>
-    <script src="./spec/plugins/jquery.proxy-all.spec.js"></script>
-    <script src="./spec/plugins/jquery.url-helpers.spec.js"></script>
-    <script src="./spec/plugins/jquery.date-helpers.spec.js"></script>
-    <script src="./spec/plugins/jquery.slug.spec.js"></script>
-    <script src="./spec/plugins/jquery.slug-preview.spec.js"></script>
-    <script src="./spec/plugins/jquery.form-warning.spec.js"></script>
-
-    <script>
-      /* Helper function for loading snippets from the ajax_snippets directory.
-       * The filename should be provided and an optional object of query
-       * string parameters. The returned snippet will be loaded into the
-       * fixture and passed to any callback.
-       *
-       * The callback shares the same scope as the rest of the suite so you
-       * can assign test variables easily. It is passed the loaded HTML string
-       * and the fixture element.
-       *
-       * filename - The snippet filename to load.
-       * params   - An optional object of query string params.
-       * callback - An optional callback to call when loaded.
-       *
-       * Example:
-       *
-       *   // To simply load a fixture.
-       *   beforeEach(function (done) {
-       *     this.loadFixture('my-snippet', done);
-       *   });
-       *
-       *   // To get the html itself.
-       *   beforeEach(function (done) {
-       *     this.loadFixture('my-snippet', function (html) {
-       *       this.template = html;
-       *       done();
-       *     });
-       *   });
-       *
-       */
-      function loadFixture(filename, params, callback) {
-        var context = this;
-
-        // Allow function to be called without params.
-        if (typeof params === 'function') {
-          callback = params;
-          params = {};
-        }
-
-        return  (new ckan.Client()).getTemplate(filename, params).fail(function () {
-          throw new Error('Unable to load fixture: ' + filename);
-        }).pipe(function (template) {
-          var fixture = jQuery('#fixture').html(template);
-          callback && callback.call(context, template, fixture);
-          return template;
-        });
-      }
-
-      before(function () {
-        // Assign the loadFixture helper. Callbacks will have the same scope
-        // as the before() functions.
-        this.loadFixture = jQuery.proxy(loadFixture, this);
-      });
-
-      beforeEach(function () {
-        this.fixture = jQuery('#fixture').empty();
-      });
-
-      afterEach(function () {
-        this.fixture.empty();
-      });
-
-
-      // Add dummy translations for testing i18n
-      ckan.i18n.load({
-        '': {
-          "domain": "ckan",
-          "lang": "en",
-          "plural_forms": "nplurals=2; plural=(n != 1);"
-        },
-        'foo': [null, 'FOO'],
-        'hello %(name)s!': [null, 'HELLO %(name)s!'],
-        'bar': ['bars', 'BAR', 'BARS'],
-        '%(color)s shirt': [
-          '%(color)s shirts',
-          '%(color)s SHIRT',
-          '%(color)s SHIRTS'
-        ],
-        '%(num)d item': ['%(num)d items', '%(num)d ITEM', '%(num)d ITEMS']
-      });
-
-
-      if (window.mochaPhantomJS) {
-        mochaPhantomJS.run();
-      } else {
-        mocha.run();
-      }
-
-    </script>
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/test/primer/index.html b/ckan/public-bs2/base/test/primer/index.html
deleted file mode 100644
--- a/ckan/public-bs2/base/test/primer/index.html
+++ /dev/null
@@ -1,647 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <title>CKAN Primer</title>
-    <link rel="stylesheet/less" href="../../less/main.less">
-    <script src="../vendor/less.js"></script>
-    <style>
-      .primer-wrapper {
-        padding: 20px;
-      }
-
-      .primer-heading {
-        margin-bottom: 20px;
-      }
-
-      .primer-spacer {
-        height: 20px;
-      }
-    </style>
-  </head>
-  <body>
-    <div class="primer-wrapper">
-      <h1 class="primer-heading">CKAN CSS Primer</h1>
-      <section class="module">
-        <p class="content">This is an empty module</p>
-      </section>
-      <section class="module">
-        <h2 class="heading">Module Heading</h2>
-        <div class="content">
-          <p>This is an example module with a heading and stuff</p>
-        </div>
-      </section>
-      <section class="module">
-        <h2 class="heading">Module Heading</h2>
-        <ul class="nav nav-simple">
-          <li><a href="#">Navigation Item 1</a></li>
-          <li><a href="#">Navigation Item 2</a></li>
-          <li><a href="#">Navigation Item 3</a></li>
-        </ul>
-      </section>
-      <section class="module">
-        <h2 class="heading">Module Heading</h2>
-        <ul class="nav nav-simple">
-          <li><a href="#">Navigation Item 1</a></li>
-          <li class="selected"><a href="#">Selected Item 2</a></li>
-          <li><a href="#">Navigation Item 3</a></li>
-        </ul>
-        <p class="footer"><a href="#">View all</a></p>
-      </section>
-      <section class="module">
-        <h2 class="heading">General Prose</h2>
-        <div class="content">
-        <h2>Sections <a href="#">Linked</a></h2>
-        <p>The main page header of this guide is an <code>h1</code> element. Any header elements may include links, as depicted in the example.</p>
-        <p>The secondary header above is an <code>h2</code> element, which may be used for any form of important page-level header. More than one may be used per page. Consider using an <code>h2</code> unless you need a header level of less importance, or as a sub-header to an existing <code>h2</code> element.</p>
-        <h3>Third-Level Header <a href="#">Linked</a></h3>
-        <p>The header above is an <code>h3</code> element, which may be used for any form of page-level header which falls below the <code>h2</code> header in a document hierarchy.</p>
-        <h4>Fourth-Level Header <a href="#">Linked</a></h4>
-        <p>The header above is an <code>h4</code> element, which may be used for any form of page-level header which falls below the <code>h3</code> header in a document hierarchy.</p>
-        <h5>Fifth-Level Header <a href="#">Linked</a></h5>
-        <p>The header above is an <code>h5</code> element, which may be used for any form of page-level header which falls below the <code>h4</code> header in a document hierarchy.</p>
-        <h6>Sixth-Level Header <a href="#">Linked</a></h6>
-        <p>The header above is an <code>h6</code> element, which may be used for any form of page-level header which falls below the <code>h5</code> header in a document hierarchy.</p>
-
-        <h2 id="grouping" class="heading">Grouping content</h2>
-        <h3>Paragraphs</h3>
-        <p>All paragraphs are wrapped in <code>p</code> tags. Additionally, <code>p</code> elements can be wrapped with a <code>blockquote</code> element <em>if the <code>p</code> element is indeed a quote</em>. Historically, <code>blockquote</code> has been used purely to force indents, but this is now achieved using CSS. Reserve <code>blockquote</code> for quotes.</p>
-
-        <h3>Horizontal rule</h3>
-        <p>The <code>hr</code> element represents a paragraph-level thematic break, e.g. a scene change in a story, or a transition to another topic within a section of a reference book. The following extract from <cite>Pandora&#8217;s Star</cite> by Peter F. Hamilton shows two paragraphs that precede a scene change and the paragraph that follows it:</p>
-        <div class="example">
-            <p>Dudley was ninety-two, in his second life, and fast approaching time for another rejuvenation. Despite his body having the physical age of a standard fifty-year-old, the prospect of a long degrading campaign within academia was one he regarded with dread. For a supposedly advanced civilization, the Intersolar Commonwearth could be appallingly backward at times, not to mention cruel.</p>
-            <p><i>Maybe it won&#8217;t be that bad</i>, he told himself. The lie was comforting enough to get him through the rest of the night&#8217;s shift.</p>
-            <hr/>
-            <p>The Carlton AllLander drove Dudley home just after dawn. Like the astronomer, the vehicle was old and worn, but perfectly capable of doing its job. It had a cheap diesel engine, common enough on a semi-frontier world like Gralmond, although its drive array was a thoroughly modern photoneural processor. With its high suspension and deep-tread tyres it could plough along the dirt track to the observatory in all weather and seasons, including the metre-deep snow of Gralmond&#8217;s winters.</p>
-        </div>
-
-        <h3>Pre-formatted text</h3>
-        <p>The <code>pre</code> element represents a block of pre-formatted text, in which structure is represented by typographic conventions rather than by elements. Such examples are an e-mail (with paragraphs indicated by blank lines, lists indicated by lines prefixed with a bullet), fragments of computer code (with structure indicated according to the conventions of that language) or displaying <abbr title="American Standard Code for Information Interchange">ASCII</abbr> art. Here&#8217;s an example showing the printable characters of <abbr>ASCII</abbr>:</p>
-        <div class="example">
-<pre><samp>  ! " # $ % &amp; ' ( ) * + , - . /
-    0 1 2 3 4 5 6 7 8 9 : ; &lt; = &gt; ?
-    @ A B C D E F G H I J K L M N O
-    P Q R S T U V W X Y Z [ \ ] ^ _
-    ` a b c d e f g h i j k l m n o
-    p q r s t u v w x y z { | } ~ </samp></pre>
-        </div>
-
-        <h3>Blockquotes</h3>
-        <p>The <code>blockquote</code> element represents a section that is being quoted from another source.</p>
-        <div class="example">
-            <blockquote cite="http://hansard.millbanksystems.com/commons/1947/nov/11/parliament-bill#column_206">
-                <p>Many forms of Government have been tried, and will be tried in this world of sin and woe. No one pretends that democracy is perfect or all-wise. Indeed, it has been said that democracy is the worst form of government except all those other forms that have been tried from time to time.</p>
-            </blockquote>
-            <p>Winston Churchill, in <cite><a href="http://hansard.millbanksystems.com/commons/1947/nov/11/parliament-bill#column_206">a speech to the House of Commons</a></cite>. 11th November 1947</p>
-        </div>
-        <p>Additionally, you might wish to cite the source, as in the above example. The correct method involves including the <code>cite</code> attribute on the <code>blockquote</code> element, but since no browser makes any use of that information, it&#8217;s useful to link to the source also.</p>
-
-        <h3>Ordered list</h3>
-        <p>The <code>ol</code> element denotes an ordered list, and various numbering schemes are available through the CSS (including 1,2,3&#8230; a,b,c&#8230; i,ii,iii&#8230; and so on). Each item requires a surrounding <code>&lt;li&gt;</code> and <code>&lt;/li&gt;</code> tag, to denote individual items within the list (as you may have guessed, <code>li</code> stands for list item).</p>
-        <div class="example">
-            <ol>
-                <li>This is an ordered list.</li>
-                <li>
-                    This is the second item, which contains a sub list
-                    <ol>
-                        <li>This is the sub list, which is also ordered.</li>
-                        <li>It has two items.</li>
-                    </ol>
-                </li>
-                <li>This is the final item on this list.</li>
-            </ol>
-        </div>
-
-        <h3>Unordered list</h3>
-        <p>The <code>ul</code> element denotes an unordered list (ie. a list of loose items that don&#8217;t require numbering, or a bulleted list). Again, each item requires a surrounding <code>&lt;li&gt;</code> and <code>&lt;/li&gt;</code> tag, to denote individual items. Here is an example list showing the constituent parts of the British Isles:</p>
-        <div class="example">
-            <ul>
-                <li>
-                    United Kingdom of Great Britain and Northern Ireland:
-                    <ul>
-                        <li>England</li>
-                        <li>Scotland</li>
-                        <li>Wales</li>
-                        <li>Northern Ireland</li>
-                    </ul>
-                </li>
-                <li>Republic of Ireland</li>
-                <li>Isle of Man</li>
-                <li>
-                    Channel Islands:
-                    <ul>
-                        <li>Bailiwick of Guernsey</li>
-                        <li>Bailiwick of Jersey</li>
-                    </ul>
-                </li>
-            </ul>
-        </div>
-        <p>Sometimes we may want each list item to contain block elements, typically a paragraph or two.</p>
-        <div class="example">
-            <ul>
-                <li>
-                    <p>The British Isles is an archipelago consisting of the two large islands of Great Britain and Ireland, and many smaller surrounding islands.</p>
-                </li>
-                <li>
-                    <p>Great Britain is the largest island of the archipelago. Ireland is the second largest island of the archipelago and lies directly to the west of Great Britain.</p>
-                </li>
-                <li>
-                    <p>The full list of islands in the British Isles includes over 1,000 islands, of which 51 have an area larger than 20 km<sup>2</sup>.</p>
-                </li>
-            </ul>
-        </div>
-
-        <h3>Definition list</h3>
-        <p>The <code>dl</code> element is for another type of list called a definition list. Instead of list items, the content of a <code>dl</code> consists of <code>dt</code> (Definition Term) and <code>dd</code> (Definition description) pairs. Though it may be called a &#8220;definition list&#8221;, <code>dl</code> can apply to other scenarios where a parent/child relationship is applicable. For example, it may be used for marking up dialogues, with each <code>dt</code> naming a speaker, and each <code>dd</code> containing his or her words.</p>
-        <div class="example">
-            <dl>
-                <dt>This is a term.</dt>
-                <dd>This is the definition of that term, which both live in a <code>dl</code>.</dd>
-                <dt>Here is another term.</dt>
-                <dd>And it gets a definition too, which is this line.</dd>
-                <dt>Here is term that shares a definition with the term below.</dt>
-                <dt>Here is a defined term.</dt>
-                <dd><code>dt</code> terms may stand on their own without an accompanying <code>dd</code>, but in that case they <em>share</em> descriptions with the next available <code>dt</code>. You may not have a <code>dd</code> without a parent <code>dt</code>.</dd>
-            </dl>
-        </div>
-
-        <h3>Figures</h3>
-        <p>Figures are usually used to refer to images:</p>
-        <div class="example">
-            <figure>
-                <img src="http://lorempixum.com/680/400/abstract/?r" alt="Example image"/>
-                <figcaption>
-                    <p>This is a placeholder image, with supporting caption.</p>
-                </figcaption>
-            </figure>
-        </div>
-        <p>Here, a part of a poem is marked up using figure:</p>
-        <div class="example">
-            <figure>
-                <p>&#8216;Twas brillig, and the slithy toves<br/>
-                Did gyre and gimble in the wabe;<br/>
-                All mimsy were the borogoves,<br/>
-                And the mome raths outgrabe.</p>
-                <figcaption>
-                    <p><cite>Jabberwocky</cite> (first verse). Lewis Carroll, 1832-98</p>
-                </figcaption>
-            </figure>
-        </div>
-
-        <h2 id="text" class="heading">Text-level Semantics</h2>
-        <p>There are a number of inline <abbr title="HyperText Markup Language">HTML</abbr> elements you may use anywhere within other elements.</p>
-
-        <h3>Links and anchors</h3>
-        <p>The <code>a</code> element is used to hyperlink text, be that to another page, a named fragment on the current page or any other location on the web. Example:</p>
-        <div class="example">
-            <p><a href="/">Go to the home page</a> or <a href="#banner">return to the top of this page</a>.</p>
-        </div>
-
-        <h3>Stressed emphasis</h3>
-        <p>The <code>em</code> element is used to denote text with stressed emphasis, i.e., something you&#8217;d pronounce differently. Where italicizing is required for stylistic differentiation, the <code>i</code> element may be preferable. Example:</p>
-        <div class="example">
-            <p>You simply <em>must</em> try the negitoro maki!</p>
-        </div>
-
-        <h3>Strong importance</h3>
-        <p>The <code>strong</code> element is used to denote text with strong importance. Where bolding is used for stylistic differentiation, the <code>b</code> element may be preferable. Example:</p>
-        <div class="example">
-            <p><strong>Don&#8217;t</strong> stick nails in the electrical outlet.</p>
-        </div>
-
-        <h3>Small print</h3>
-        <p>The <small>small</small> element is used to represent disclaimers, caveats, legal restrictions, or copyrights (commonly referred to as &#8216;small print&#8217;). It can also be used for attributions or satisfying licensing requirements. Example:</p>
-        <div class="example">
-            <p><small>Copyright &#169; 1922-2011 Acme Corporation. All Rights Reserved.</small></p>
-        </div>
-
-        <h3>Strikethrough</h3>
-        <p>The <code>s</code> element is used to represent content that is no longer accurate or relevant. When indicating document edits i.e., marking a span of text as having been removed from a document, use the <code>del</code> element instead. Example:</p>
-        <div class="example">
-            <p>
Recommended retail price: &#163;3.99 per bottle
<br/><strong>Now selling for just &#163;2.99 a bottle!</strong></p>
-        </div>
-
-        <h3>Citations</h3>
-        <p>The <code>cite</code> element is used to represent the title of a work (e.g. a book, essay, poem, song, film, TV show, sculpture, painting, musical, exhibition, etc). This can be a work that is being quoted or referenced in detail (i.e. a citation), or it can just be a work that is mentioned in passing. Example:</p>
-        <div class="example">
-            <p><cite>Universal Declaration of Human Rights</cite>, United Nations, December 1948. Adopted by General Assembly resolution 217 A (III).</p>
-        </div>
-
-        <h3>Inline quotes</h3>
-        <p>The <code>q</code> element is used for quoting text inline. Example showing nested quotations:</p>
-        <div class="example">
-            <p>John said, <q>I saw Lucy at lunch, she told me <q>Mary wants you to get some ice cream on your way home</q>. I think I will get some at Ben and Jerry&#8217;s, on Gloucester Road.</q></p>
-        </div>
-
-        <h3>Definition</h3>
-        <p>The <code>dfn</code> element is used to highlight the first use of a term. The <code>title</code> attribute can be used to describe the term. Example:</p>
-        <div class="example">
-            <p>Bob&#8217;s <dfn title="Dog">canine</dfn> mother and <dfn title="Horse">equine</dfn> father sat him down and carefully explained that he was an <dfn title="A mutation that combines two or more sets of chromosomes from different species">allopolyploid</dfn> organism.</p>
-        </div>
-
-        <h3>Abbreviation</h3>
-        <p>The <code>abbr</code> element is used for any abbreviated text, whether it be acronym, initialism, or otherwise. Generally, it&#8217;s less work and useful (enough) to mark up only the first occurrence of any particular abbreviation on a page, and ignore the rest. Any text in the <code>title</code> attribute will appear when the user&#8217;s mouse hovers the abbreviation (although notably, this does not work in Internet Explorer for Windows). Example abbreviations:</p>
-        <div class="example">
-            <p><abbr title="British Broadcasting Corportation">BBC</abbr>, <abbr title="HyperText Markup Language">HTML</abbr>, and <abbr title="Staffordshire">Staffs.</abbr></p>
-        </div>
-
-        <h3>Time</h3>
-        <p>The <code>time</code> element is used to represent either a time on a 24 hour clock, or a precise date in the proleptic Gregorian calendar, optionally with a time and a time-zone offset. Example:</p>
-        <div class="example">
-            <p>Queen Elizabeth II was proclaimed sovereign of each of the Commonwealth realms on <time datetime="1952-02-6">6</time> and <time datetime="1952-02-7">7 February 1952</time>, after the death of her father, King George VI.</p>
-        </div>
-
-        <h3>Code</h3>
-        <p>The <code>code</code> element is used to represent fragments of computer code. Useful for technology-oriented sites, not so useful otherwise. Example:</p>
-        <div class="example">
-            <p>When you call the <code>activate()</code> method on the <code>robotSnowman</code> object, the eyes glow.</p>
-        </div>
-        <p>Used in conjunction with the <code>pre</code> element:</p>
-        <div class="example">
-    <pre><code>function getJelly() {
-    &#160;&#160;&#160;&#160;echo $aDeliciousSnack;
-    }</code></pre>
-        </div>
-
-        <h3>Variable</h3>
-        <p>The <code>var</code> element is used to denote a variable in a mathematical expression or programming context, but can also be used to indicate a placeholder where the contents should be replaced with your own value. Example:</p>
-        <div class="example">
-            <p>If there are <var>n</var> pipes leading to the ice cream factory then I expect at <em>least</em> <var>n</var> flavours of ice cream to be available for purchase!</p>
-        </div>
-
-        <h3>Sample output</h3>
-        <p>The <code>samp</code> element is used to represent (sample) output from a program or computing system. Useful for technology-oriented sites, not so useful otherwise. Example:</p>
-        <div class="example">
-            <p>The computer said <samp>Too much cheese in tray two</samp> but I didn&#8217;t know what that meant.</p>
-        </div>
-
-        <h3>Keyboard entry</h3>
-        <p>The <code>kbd</code> element is used to denote user input (typically via a keyboard, although it may also be used to represent other input methods, such as voice commands). Example:<p>
-        <div class="example">
-            <p>To take a screenshot on your Mac, press <kbd>&#8984; Cmd</kbd> + <kbd>&#8679; Shift</kbd> + <kbd>3</kbd>.</p>
-        </div>
-
-        <h3>Superscript and subscript text</h3>
-        <p>The <code>sup</code> element represents a superscript and the sub element represents a <code>sub</code>. These elements must be used only to mark up typographical conventions with specific meanings, not for typographical presentation. As a guide, only use these elements if their absence would change the meaning of the content. Example:</p>
-        <div class="example">
-            <p>The coordinate of the <var>i</var>th point is (<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>). For example, the 10th point has coordinate (<var>x<sub>10</sub></var>, <var>y<sub>10</sub></var>).</p>
-            <p>f(<var>x</var>, <var>n</var>) = log<sub>4</sub><var>x</var><sup><var>n</var></sup></p>
-        </div>
-
-        <h3>Italicised</h3>
-        <p>The <code>i</code> element is used for text in an alternate voice or mood, or otherwise offset from the normal prose. Examples include taxonomic designations, technical terms, idiomatic phrases from another language, the name of a ship or other spans of text whose typographic presentation is typically italicised. Example:</p>
-        <div class="example">
-            <p>There is a certain <i lang="fr">je ne sais quoi</i> in the air.</p>
-        </div>
-
-        <h3>Emboldened</h3>
-        <p>The <code>b</code> element is used for text stylistically offset from normal prose without conveying extra importance, such as key words in a document abstract, product names in a review, or other spans of text whose typographic presentation is typically emboldened. Example:</p>
-        <div class="example">
-            <p>You enter a small room. Your <b>sword</b> glows brighter. A <b>rat</b> scurries past the corner wall.</p>
-        </div>
-
-        <h3>Marked or highlighted text</h3>
-        <p>The <code>mark</code> element is used to represent a run of text marked or highlighted for reference purposes. When used in a quotation it indicates a highlight not originally present but added to bring the reader&#8217;s attention to that part of the text. When used in the main prose of a document, it indicates a part of the document that has been highlighted due to its relevance to the user&#8217;s current activity. Example:</p>
-        <div class="example">
-            <p>I also have some <mark>kitten</mark>s who are visiting me these days. They&#8217;re really cute. I think they like my garden! Maybe I should adopt a <mark>kitten</mark>.</p>
-        </div>
-
-        <h3 id="edits">Edits</h3>
-        <p>The <code>del</code> element is used to represent deleted or retracted text which still must remain on the page for some reason. Meanwhile its counterpart, the <code>ins</code> element, is used to represent inserted text. Both <code>del</code> and <code>ins</code> have a <code>datetime</code> attribute which allows you to include a timestamp directly in the element. Example inserted text and usage:</p>
-        <div class="example">
-            <p>She bought <del datetime="2005-05-30T13:00:00">two</del> <ins datetime="2005-05-30T13:00:00">five</ins> pairs of shoes.</p>
-        </div>
-
-        <h2 id="tables" class="heading">Tabular data</h2>
-        <p>Tables should be used when displaying tabular data. The <code>thead</code>, <code>tfoot</code> and <code>tbody</code> elements enable you to group rows within each a table.</p>
-        <p>If you use these elements, you must use every element. They should appear in this order: <code>thead</code>, <code>tfoot</code> and <code>tbody</code>, so that browsers can render the foot before receiving all the data. You must use these tags within the table element.</p>
-        <div class="example">
-            <table>
-                <caption>The Very Best Eggnog</caption>
-                <colgroup>
-                    <col style="width:50%" />
-                    <col style="width:25%" />
-                    <col style="width:25%" />
-                </colgroup>
-                <thead>
-                    <tr>
-                        <th scope="col">Ingredients</th>
-                        <th scope="col">Serves 12</th>
-                        <th scope="col">Serves 24</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <tr>
-                        <td>Milk</td>
-                        <td>1 quart</td>
-                        <td>2 quart</td>
-                    </tr>
-                    <tr>
-                        <td>Cinnamon Sticks</td>
-                        <td>2</td>
-                        <td>1</td>
-                    </tr>
-                    <tr>
-                        <td>Vanilla Bean, Split</td>
-                        <td>1</td>
-                        <td>2</td>
-                    </tr>
-                    <tr>
-                        <td>Cloves</td>
-                        <td>5</td>
-                        <td>10</td>
-                    </tr>
-                    <tr>
-                        <td>Mace</td>
-                        <td>10 blades</td>
-                        <td>20 blades</td>
-                    </tr>
-                    <tr>
-                        <td>Egg Yolks</td>
-                        <td>12</td>
-                        <td>24</td>
-                    </tr>
-                    <tr>
-                        <td>Cups Sugar</td>
-                        <td>1 &frac12; cups</td>
-                        <td>3 cups</td>
-                    </tr>
-                    <tr>
-                        <td>Dark Rum</td>
-                        <td>1 &frac12; cups</td>
-                        <td>3 cups</td>
-                    </tr>
-                    <tr>
-                        <td>Brandy</td>
-                        <td>1 &frac12; cups</td>
-                        <td>3 cups</td>
-                    </tr>
-                    <tr>
-                        <td>Vanilla</td>
-                        <td>1 tbsp</td>
-                        <td>2 tbsp</td>
-                    </tr>
-                    <tr>
-                        <td>Half-and-half or Light Cream</td>
-                        <td>1 quart</td>
-                        <td>2 quart</td>
-                    </tr>
-                    <tr>
-                        <td>Freshly grated nutmeg to taste</td>
-                        <td></td>
-                        <td></td>
-                    </tr>
-                </tbody>
-            </table>
-        </div>
-
-        <h2 id="forms" class="heading">Forms</h2>
-        <p>Forms can be used when you wish to collect data from users. The <code>fieldset</code> element enables you to group related fields within a form, and each one should contain a corresponding <code>legend</code>. The <code>label</code> element ensures field descriptions are associated with their corresponding form widgets.</p>
-        <div class="example">
-            <form action="#">
-                <fieldset>
-                    <legend>Legend</legend>
-                    <div class="control-group">
-                        <label for="text">Text Input <abbr title="Required">*</abbr></label>
-                        <input id="text" class="text" type="text"/>
-                        <span class="help-inline">Note about this field</span>
-                    </div class="control-group">
-                    <div>
-                        <label for="password">Password</label>
-                        <input id="password" class="text" type="password"/>
-                        <span class="help-inline">Note about this field</span>
-                    </div class="control-group">
-                    <div>
-                        <label for="password">Web Address</label>
-                        <input id="password" class="text" type="url"/>
-                        <span class="help-inline">Note about this field</span>
-                    </div class="control-group">
-                    <div class="control-group">
-                        <label for="password">Email Address</label>
-                        <input id="password" class="text" type="email"/>
-                        <span class="help-inline">Note about this field</span>
-                    </div>
-                    <div class="control-group">
-                        <label for="textarea">Textarea</label>
-                        <textarea id="textarea" class="text" rows="8" cols="48"></textarea>
-                        <span class="help-inline">Note about this field</span>
-                    </div>
-                    <div class="control-group">
-                        <label for="checkbox">Single Checkbox</label>
-                        <label for="checkbox" class="checkbox"><input id="checkbox" type="checkbox" class="checkbox"/> Label</label>
-                    </div>
-                    <div class="control-group">
-                        <label for="select">Select</label>
-                        <select id="select">
-                            <optgroup label="Option Group">
-                                <option>Option One</option>
-                                <option>Option Two</option>
-                                <option>Option Three</option>
-                            </optgroup>
-                        </select>
-                        <span class="help-inline">Note about this selection</span>
-                    </div>
-                    <fieldset class="control-group">
-                        <legend>Checkbox <abbr title="Required">*</abbr></legend>
-                        <div class="control-group">
-                          <label for="checkbox1" class="checkbox"><input id="checkbox1" name="checkbox" type="checkbox" checked="checked" /> Choice A</label>
-                          <label for="checkbox2" class="checkbox"><input id="checkbox2" name="checkbox" type="checkbox" /> Choice B</label>
-                          <label for="checkbox3" class="checkbox"><input id="checkbox3" name="checkbox" type="checkbox" /> Choice C</label>
-                        </div>
-                    </fieldset>
-                    <fieldset class="control-group">
-                      <div class="control-group">
-                        <legend>Radio</legend>
-                        <label for="radio1" class="radio"><input id="radio1" name="radio" type="radio" class="radio" checked="checked" /> Option 1</label>
-                      </div>
-                    </fieldset>
-                    <div class="form-actions">
-                      <input type="submit" class="btn btn-primary" value="Post Comment" />
-                      <input type="button" class="btn" value="Preview" />
-                    </div>
-                </fieldset>
-            </form>
-        </div>
-
-        <p><small>This block is copyright &#169; 2012 Paul Robert Lloyd. Code covered by the <a rel="license" href="http://paulrobertlloyd.mit-license.org/">MIT license</a>.</small></p>
-      </div>
-      </section>
-      <h1>Dataset Results</h1>
-      <section class="module">
-        <div class="content">
-          <ul class="dataset-list unstyled">
-            <li class="dataset-item">
-              <h2 class="heading"><a href="#">Counselling in London Central, Camden</a></h2>
-              <ul class="dataset-resources unstyled">
-                <li><a href="#" class="label">HTML</a></li>
-                <li><a href="#" class="label">XML</a></li>
-                <li><a href="#" class="label">CSV</a></li>
-              </ul>
-              <div class="content">
-                <p>This is an application programming interface (API) that opens up
-                core EU legislative data for further use. The interface uses JSON,
-                meaning that you have easy to use machine-readable access to
-                metadata on European Union legislation.</p>
-                <p>It will be useful if you
-                want to use or analyze European Union legislative data in a way
-                that the official databases are not originally build for. The API
-                extracts, organize and connects data from various official
-                sources.</p>
-              </div>
-            </li>
-          </ul>
-        </div>
-      </section>
-      <section class="module">
-        <div class="content">
-          <ul class="dataset-list unstyled">
-            <li class="dataset-item">
-              <h2 class="heading"><a href="#">Counselling in London Central, Camden</a></h2>
-              <ul class="dataset-resources unstyled">
-                <li><a href="#" class="label">HTML</a></li>
-                <li><a href="#" class="label">XML</a></li>
-                <li><a href="#" class="label">CSV</a></li>
-              </ul>
-              <div class="content">
-                <p>This is an application programming interface (API) that opens up
-                core EU legislative data for further use. The interface uses JSON,
-                meaning that you have easy to use machine-readable access to
-                metadata on European Union legislation.</p>
-                <p>It will be useful if you
-                want to use or analyze European Union legislative data in a way
-                that the official databases are not originally build for. The API
-                extracts, organize and connects data from various official
-                sources.</p>
-              </div>
-            </li>
-            <li class="dataset-item">
-              <h2 class="heading"><a href="#">Counselling in London Central, Camden</a></h2>
-              <ul class="dataset-resources unstyled">
-                <li><a href="#" class="label">HTML</a></li>
-                <li><a href="#" class="label">XML</a></li>
-                <li><a href="#" class="label">CSV</a></li>
-              </ul>
-              <div class="content">
-                <p>This is an application programming interface (API) that opens up
-                core EU legislative data for further use. The interface uses JSON,
-                meaning that you have easy to use machine-readable access to
-                metadata on European Union legislation.</p>
-                <p>It will be useful if you
-                want to use or analyze European Union legislative data in a way
-                that the official databases are not originally build for. The API
-                extracts, organize and connects data from various official
-                sources.</p>
-              </div>
-            </li>
-            <li class="dataset-item">
-              <h2 class="heading"><a href="#">Counselling in London Central, Camden</a></h2>
-              <ul class="dataset-resources unstyled">
-                <li><a href="#" class="label">HTML</a></li>
-                <li><a href="#" class="label">XML</a></li>
-                <li><a href="#" class="label">CSV</a></li>
-              </ul>
-              <div class="content">
-                <p>This is an application programming interface (API) that opens up
-                core EU legislative data for further use. The interface uses JSON,
-                meaning that you have easy to use machine-readable access to
-                metadata on European Union legislation.</p>
-                <p>It will be useful if you
-                want to use or analyze European Union legislative data in a way
-                that the official databases are not originally build for. The API
-                extracts, organize and connects data from various official
-                sources.</p>
-              </div>
-            </li>
-          </ul>
-        </div>
-        <div class="pagination pagination-centered">
-          <ul>
-            <li><a href="#">Prev</a></li>
-            <li class="active"><a href="#">1</a></li>
-            <li><a href="#">2</a></li>
-            <li><a href="#">3</a></li>
-            <li><a href="#">4</a></li>
-            <li><a href="#">Next</a></li>
-          </ul>
-        </div>
-      </section>
-      <section class="module dataset-filters">
-        <p class="content">
-          <strong class="results">4 datasets found for &quot;London&quot;</strong>
-          +
-          <span>Tags:</span>
-          <span class="filtered"><a href="#">camden</a> <a href="#">[remove]</a></span>
-          <span>Format:</span>
-          <span class="filtered"><a href="#">HTML</a> <a href="#">[remove]</a></span>
-          <span class="filtered"><a href="#">CSV</a> <a href="#">[remove]</a></span>
-        </p>
-      </section>
-      <section class="module">
-        <form class="form-search">
-          <input class="search-giant" placeholder="Search" />
-          <button>Search</button>
-        </form>
-      </section>
-      <h1 id="masthead" class="primer-heading">Masthead (Site Header)</h1>
-      <header class="masthead">
-        <hgroup>
-          <h1><a href="">My Site Title</a></h1>
-          <h2>My Site Tagline</h2>
-        </hgroup>
-        <nav>
-          <ul class="unstyled">
-            <li><a href="#">Find</a></li>
-            <li><a class="active" href="#">Groups</a></li>
-            <li><a href="#">Share</a></li>
-            <li><a href="#">About</a></li>
-            <li class="section"><a href="#">Login</a></li>
-          </ul>
-        </nav>
-      </header>
-      <div class="primer-spacer"></div>
-      <header class="masthead">
-        <hgroup>
-          <h1><a href="">My Site Title</a></h1>
-          <h2>My Site Tagline</h2>
-        </hgroup>
-        <div class="account">
-          <a href="#home" class="image">
-            <img src="" width="25" height="25" />
-          </a>
-          <span class="links">
-            <a href="#home">username</a>
-            <a class="logout" href="#logout">Log out</a>
-          </span>
-        </div>
-        <nav>
-          <ul class="unstyled">
-            <li><a href="#">Find</a></li>
-            <li><a class="active" href="#">Groups</a></li>
-            <li><a href="#">Share</a></li>
-            <li><a href="#">About</a></li>
-          </ul>
-        </nav>
-      </header>
-      <div class="primer-spacer"></div>
-      <footer class="site-footer">
-        <nav class="footer-links row-fluid">
-          <ul class="unstyled row-fluid">
-            <li><a href="#">Terms and Conditions</a></li>
-            <li><a href="#">Accessibility</a></li>
-            <li><a href="#">Code of conduct</a></li>
-            <li><a href="#">Moderation policy</a></li>
-            <li><a href="#">FAQ</a></li>
-            <li><a href="#">Privacy</a></li>
-            <li><a href="#">Contact us</a></li>
-            <li><a href="#">Consultation</a></li>
-          </ul>
-        </nav>
-        <div class="attribution">
-          <p><strong>Powered by</strong> <a href="">CityData</a> from <a href="">CKAN</a></p>
-          <p><small>Maps powered by Leaflet, map data &copy; OpenStreetMap contributors, CC-BY-SA, map imagery &copy; CloudMade</small></p>
-        </div>
-      </footer>
-    </div>
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/test/spec/ckan.spec.js b/ckan/public-bs2/base/test/spec/ckan.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/ckan.spec.js
+++ /dev/null
@@ -1,70 +0,0 @@
-describe('ckan.initialize()', function () {
-  beforeEach(function () {
-    this.promise = jQuery.Deferred();
-    this.target = sinon.stub(ckan.Client.prototype, 'getLocaleData').returns(this.promise);
-  });
-
-  afterEach(function () {
-    this.target.restore();
-  });
-
-  it('should load the localisations for the current page', function () {
-    ckan.initialize()
-    assert.called(this.target);
-  });
-
-  it('should load the localisations into the i18n library', function () {
-    var target = sinon.stub(ckan.i18n, 'load');
-    var data = {lang: {}};
-
-    ckan.initialize();
-    this.promise.resolve(data);
-
-    assert.called(target);
-    assert.calledWith(target, data);
-
-    target.restore();
-  });
-
-  it('should initialize the module on the page', function () {
-    var target = sinon.stub(ckan.module, 'initialize');
-
-    ckan.initialize();
-    this.promise.resolve();
-
-    assert.called(target);
-    target.restore();
-  });
-});
-
-describe('ckan.url()', function () {
-  beforeEach(function () {
-    ckan.SITE_ROOT = 'http://example.com';
-    ckan.LOCALE_ROOT = ckan.SITE_ROOT + '/en';
-  });
-
-  it('should return the ckan.SITE_ROOT', function () {
-    var target = ckan.url();
-    assert.equal(target, ckan.SITE_ROOT);
-  });
-
-  it('should return the ckan.LOCALE_ROOT if true is passed', function () {
-    var target = ckan.url(true);
-    assert.equal(target, ckan.LOCALE_ROOT);
-  });
-
-  it('should append the path provided', function () {
-    var target = ckan.url('/test.html');
-    assert.equal(target, ckan.SITE_ROOT + '/test.html');
-  });
-
-  it('should append the path to the locale provided', function () {
-    var target = ckan.url('/test.html', true);
-    assert.equal(target, ckan.LOCALE_ROOT + '/test.html');
-  });
-
-  it('should handle missing preceding slashes', function () {
-    var target = ckan.url('test.html');
-    assert.equal(target, ckan.SITE_ROOT + '/test.html');
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/client.spec.js b/ckan/public-bs2/base/test/spec/client.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/client.spec.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.Client()', function () {
-  var Client = ckan.Client;
-
-  beforeEach(function () {
-    this.client = new Client();
-  });
-
-  it('should add a new instance to each client', function () {
-    var target = ckan.sandbox().client;
-
-    assert.instanceOf(target, Client);
-  });
-
-  it('should set the .endpoint property to options.endpoint', function () {
-    var client = new Client({endpoint: 'http://example.com'});
-    assert.equal(client.endpoint, 'http://example.com');
-  });
-
-  it('should default the endpoint to a blank string', function () {
-    assert.equal(this.client.endpoint, '');
-  });
-
-  describe('.url(path)', function () {
-    beforeEach(function () {
-      this.client.endpoint = 'http://api.example.com';
-    });
-
-    it('should return the path with the enpoint prepended', function () {
-      assert.equal(this.client.url('/api/endpoint'), 'http://api.example.com/api/endpoint');
-    });
-
-    it('should normalise preceding slashes in the path', function () {
-      assert.equal(this.client.url('api/endpoint'), 'http://api.example.com/api/endpoint');
-    });
-
-    it('should return the string if it already has a protocol', function () {
-      assert.equal(this.client.url('http://example.com/my/endpoint'), 'http://example.com/my/endpoint');
-    });
-  });
-
-  describe('.getTemplate(filename, params, success, error)', function () {
-    beforeEach(function () {
-      this.fakePromise = sinon.stub(jQuery.Deferred());
-      this.fakePromise.then.returns(this.fakePromise);
-      sinon.stub(jQuery, 'get').returns(this.fakePromise);
-    });
-
-    afterEach(function () {
-      jQuery.get.restore();
-    });
-
-    it('should return a jQuery promise', function () {
-      var target = this.client.getTemplate('test.html');
-      assert.ok(target === this.fakePromise, 'target === this.fakePromise'); 
-    });
-
-    it('should request the template file', function () {
-      var target = this.client.getTemplate('test.html');
-      assert.called(jQuery.get);
-      assert.calledWith(jQuery.get, '/api/1/util/snippet/test.html', {});
-    });
-
-    it('should request the template file with any provided params', function () {
-      var options = {limit: 5, page: 2};
-      var target = this.client.getTemplate('test.html', options);
-      assert.called(jQuery.get);
-      assert.calledWith(jQuery.get, '/api/1/util/snippet/test.html', options);
-    });
-  });
-
-  describe('.getLocaleData(locale, success, error)', function () {
-    beforeEach(function () {
-      this.fakePromise = sinon.stub(jQuery.Deferred());
-      this.fakePromise.then.returns(this.fakePromise);
-      sinon.stub(jQuery, 'getJSON').returns(this.fakePromise);
-    });
-
-    afterEach(function () {
-      jQuery.getJSON.restore();
-    });
-
-    it('should return a jQuery promise', function () {
-      var target = this.client.getLocaleData('en');
-      assert.ok(target === this.fakePromise, 'target === this.fakePromise'); 
-    });
-
-    it('should request the locale provided', function () {
-      var target = this.client.getLocaleData('en');
-      assert.called(jQuery.getJSON);
-      assert.calledWith(jQuery.getJSON, '/api/i18n/en');
-    });
-  });
-
-  describe('.getCompletions(url, options, success, error)', function () {
-    beforeEach(function () {
-      this.fakePiped  = sinon.stub(jQuery.Deferred());
-      this.fakePiped.then.returns(this.fakePiped);
-      this.fakePiped.promise.returns(this.fakePiped);
-
-      this.fakePromise = sinon.stub(jQuery.Deferred());
-      this.fakePromise.pipe.returns(this.fakePiped);
-
-      sinon.stub(jQuery, 'ajax').returns(this.fakePromise);
-    });
-
-    afterEach(function () {
-      jQuery.ajax.restore();
-    });
-
-    it('should return a jQuery promise', function () {
-      var target = this.client.getCompletions('url');
-      assert.ok(target === this.fakePiped, 'target === this.fakePiped');
-    });
-
-    it('should make an ajax request for the url provided', function () {
-      function success() {}
-      function error() {}
-
-      var target = this.client.getCompletions('url', success, error);
-
-      assert.called(jQuery.ajax);
-      assert.calledWith(jQuery.ajax, {url: '/url'});
-
-      assert.called(this.fakePiped.then);
-      assert.calledWith(this.fakePiped.then, success, error);
-    });
-
-    it('should pipe the result through .parseCompletions()', function () {
-      var target = this.client.getCompletions('url');
-
-      assert.called(this.fakePromise.pipe);
-      assert.calledWith(this.fakePromise.pipe, this.client.parseCompletions);
-    });
-
-    it('should allow a custom format option to be provided', function () {
-      function format() {}
-
-      var target = this.client.getCompletions('url', {format: format});
-
-      assert.called(this.fakePromise.pipe);
-      assert.calledWith(this.fakePromise.pipe, format);
-    });
-
-  });
-
-  describe('.parseCompletions(data, options)', function () {
-    it('should return a string of tags for a ResultSet collection', function () {
-      var data = {
-        ResultSet: {
-          Result: [
-            {"Name": "1 percent"}, {"Name": "18thc"}, {"Name": "19thcentury"}
-          ]
-        }
-      };
-
-      var target = this.client.parseCompletions(data, {});
-
-      assert.deepEqual(target, ["1 percent", "18thc", "19thcentury"]);
-    });
-
-    it('should return a string of formats for a ResultSet collection', function () {
-      var data = {
-        ResultSet: {
-          Result: [
-            {"Format": "json"}, {"Format": "csv"}, {"Format": "text"}
-          ]
-        }
-      };
-
-      var target = this.client.parseCompletions(data, {});
-
-      assert.deepEqual(target, ["json", "csv", "text"]);
-    });
-
-    it('should strip out duplicates with a case insensitive comparison', function () {
-      var data = {
-        ResultSet: {
-          Result: [
-            {"Name": " Test"}, {"Name": "test"}, {"Name": "TEST"}
-          ]
-        }
-      };
-
-      var target = this.client.parseCompletions(data, {});
-
-      assert.deepEqual(target, ["Test"]);
-    });
-
-    it('should return an array of objects if options.objects is true', function () {
-      var data = {
-        ResultSet: {
-          Result: [
-            {"Format": "json"}, {"Format": "csv"}, {"Format": "text"}
-          ]
-        }
-      };
-
-      var target = this.client.parseCompletions(data, {objects: true});
-
-      assert.deepEqual(target, [
-        {id: "json", text: "json"},
-        {id: "csv", text: "csv"},
-        {id: "text", text: "text"}
-      ]);
-    });
-
-    it('should call .parsePackageCompletions() id data is a string', function () {
-      var data = 'Name|id';
-      var target = sinon.stub(this.client, 'parsePackageCompletions');
-
-      this.client.parseCompletions(data, {objects: true});
-
-      assert.called(target);
-      assert.calledWith(target, data);
-    });
-  });
-
-  describe('.parseCompletionsForPlugin(data)', function () {
-    it('should return a string of tags for a ResultSet collection', function () {
-      var data = {
-        ResultSet: {
-          Result: [
-            {"Name": "1 percent"}, {"Name": "18thc"}, {"Name": "19thcentury"}
-          ]
-        }
-      };
-
-      var target = this.client.parseCompletionsForPlugin(data);
-
-      assert.deepEqual(target, {
-        results: [
-          {id: "1 percent", text: "1 percent"},
-          {id: "18thc", text:  "18thc"},
-          {id: "19thcentury", text: "19thcentury"}
-        ]
-      });
-    });
-  });
-
-  describe('.parsePackageCompletions(string, options)', function () {
-    it('should parse the package completions string', function () {
-      var data = 'Package 1|package-1\nPackage 2|package-2\nPackage 3|package-3\n';
-      var target = this.client.parsePackageCompletions(data);
-
-      assert.deepEqual(target, ['package-1', 'package-2', 'package-3']);
-    });
-
-    it('should return an object if options.object is true', function () {
-      var data = 'Package 1|package-1\nPackage 2|package-2\nPackage 3|package-3\n';
-      var target = this.client.parsePackageCompletions(data, {objects: true});
-
-      assert.deepEqual(target, [
-        {id: 'package-1', text: 'Package 1'},
-        {id: 'package-2', text: 'Package 2'},
-        {id: 'package-3', text: 'Package 3'}
-      ]);
-    });
-  });
-
-  describe('.getStorageAuth()', function () {
-    beforeEach(function () {
-      this.fakePromise = sinon.mock(jQuery.Deferred());
-      sinon.stub(jQuery, 'ajax').returns(this.fakePromise);
-    });
-
-    afterEach(function () {
-      jQuery.ajax.restore();
-    });
-
-    it('should return a jQuery promise', function () {
-      var target = this.client.getStorageAuth('filename');
-      assert.equal(target, this.fakePromise);
-    });
-
-    it('should call request a new auth token', function () {
-      function success() {}
-      function error() {}
-
-      var target = this.client.getStorageAuth('filename', success, error);
-
-      assert.called(jQuery.ajax);
-      assert.calledWith(jQuery.ajax, {
-        url: '/api/storage/auth/form/filename',
-        success: success,
-        error: error
-      });
-    });
-  });
-
-  describe('.getStorageMetadata()', function () {
-    beforeEach(function () {
-      this.fakePromise = sinon.mock(jQuery.Deferred());
-      sinon.stub(jQuery, 'ajax').returns(this.fakePromise);
-    });
-
-    afterEach(function () {
-      jQuery.ajax.restore();
-    });
-
-    it('should return a jQuery promise', function () {
-      var target = this.client.getStorageMetadata('filename');
-      assert.equal(target, this.fakePromise);
-    });
-
-    it('should call request a new auth token', function () {
-      function success() {}
-      function error() {}
-
-      var target = this.client.getStorageMetadata('filename', success, error);
-
-      assert.called(jQuery.ajax);
-      assert.calledWith(jQuery.ajax, {
-        url: '/api/storage/metadata/filename',
-        success: success,
-        error: error
-      });
-    });
-
-    it('should throw an error if no filename is provided', function () {
-      var client = this.client;
-      assert.throws(function () {
-        client.getStorageMetadata();
-      });
-    });
-  });
-
-  describe('.convertStorageMetadataToResource(meta)', function () {
-    beforeEach(function () {
-      this.meta = {
-        "_checksum": "md5:527c97d2aa3ed1b40aea4b7ddf98692e",
-        "_content_length": 122632,
-        "_creation_date": "2012-07-17T14:35:35",
-        "_label": "2012-07-17T13:35:35.540Z/cat.jpg",
-        "_last_modified": "2012-07-17T14:35:35",
-        "_location": "http://example.com/storage/f/2012-07-17T13%3A35%3A35.540Z/cat.jpg",
-        "filename-original": "cat.jpg",
-        "key": "2012-07-17T13:35:35.540Z/cat.jpg",
-        "uploaded-by": "user"
-      };
-    });
-
-    it('should return a representation for a resource', function () {
-      var target = this.client.convertStorageMetadataToResource(this.meta);
-
-      assert.deepEqual(target, {
-        url: 'http://example.com/storage/f/2012-07-17T13%3A35%3A35.540Z/cat.jpg',
-        key: '2012-07-17T13:35:35.540Z/cat.jpg',
-        name: 'cat.jpg',
-        size: 122632,
-        created: "2012-07-17T14:35:35",
-        last_modified: "2012-07-17T14:35:35",
-        format: 'jpg',
-        mimetype: null,
-        resource_type: 'file.upload', // Is this standard?
-        owner: 'user',
-        hash: 'md5:527c97d2aa3ed1b40aea4b7ddf98692e',
-        cache_url: 'http://example.com/storage/f/2012-07-17T13%3A35%3A35.540Z/cat.jpg',
-        cache_url_updated: '2012-07-17T14:35:35'
-      });
-    });
-
-    it('should provide a full url', function () {
-      ckan.SITE_ROOT = 'http://example.com';
-
-      this.meta._location = "/storage/f/2012-07-17T13%3A35%3A35.540Z/cat.jpg";
-      var target = this.client.convertStorageMetadataToResource(this.meta);
-      assert.equal(target.url, 'http://example.com/storage/f/2012-07-17T13%3A35%3A35.540Z/cat.jpg');
-    });
-
-    it('should not include microseconds or timezone in timestamps', function () {
-      ckan.SITE_ROOT = 'http://example.com';
-
-      var target = this.client.convertStorageMetadataToResource(this.meta);
-      assert.ok(!(/\.\d\d\d/).test(target.last_modified), 'no microseconds');
-      assert.ok(!(/((\+|\-)\d{4}|Z)$/).test(target.last_modified), 'no timezone');
-    });
-
-    it('should use the mime type for the format if found', function () {
-      this.meta._format = 'image/jpeg';
-      var target = this.client.convertStorageMetadataToResource(this.meta);
-
-      assert.equal(target.format, 'image/jpeg', 'format');
-      assert.equal(target.mimetype, 'image/jpeg', 'mimetype');
-    });
-  });
-
-  describe('.normalizeTimestamp(timestamp)', function () {
-    it('should add a timezone to a timestamp without one', function () {
-      var target = this.client.normalizeTimestamp("2012-07-17T14:35:35");
-      assert.equal(target, "2012-07-17T14:35:35Z");
-    });
-
-    it('should not add a timezone to a timestamp with one already', function () {
-      var target = this.client.normalizeTimestamp("2012-07-17T14:35:35Z");
-      assert.equal(target, "2012-07-17T14:35:35Z", 'timestamp with Z');
-
-      target = this.client.normalizeTimestamp("2012-07-17T14:35:35+0100");
-      assert.equal(target, "2012-07-17T14:35:35+0100", 'timestamp with +0100');
-
-      target = this.client.normalizeTimestamp("2012-07-17T14:35:35-0400");
-      assert.equal(target, "2012-07-17T14:35:35-0400", 'timestamp with -0400');
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/i18n.spec.js b/ckan/public-bs2/base/test/spec/i18n.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/i18n.spec.js
+++ /dev/null
@@ -1,116 +0,0 @@
-describe('ckan.i18n', function () {
-  describe('ckan.i18n.translate', function () {
-    it('should work while being deprecated', function () {
-      var x = ckan.i18n.translate('foo');
-      assert.deepProperty(x, 'fetch');
-      assert.equal(x.fetch(), 'FOO');
-      assert.deepProperty(x, 'ifPlural');
-    });
-  });
-
-  describe('._(string, [values])', function () {
-    it('should return the translated string', function () {
-      assert.equal(ckan.i18n._('foo'), 'FOO');
-    });
-
-    it('should return the key when no translation exists', function () {
-      assert.equal(ckan.i18n._('no translation'), 'no translation');
-    });
-
-    it('should fill in placeholders', function () {
-      assert.equal(
-        ckan.i18n._('hello %(name)s!', {name: 'Julia'}),
-        'HELLO Julia!'
-      );
-    });
-
-    it('should fill in placeholders when no translation exists', function () {
-      assert.equal(
-        ckan.i18n._('no %(attr)s translation', {attr: 'good'}),
-        'no good translation'
-      );
-    });
-  });
-
-  describe('.ngettext(singular, plural, number, [values])', function () {
-    var ngettext = ckan.i18n.ngettext;
-
-    it('should return the translated strings', function () {
-      assert.equal(ngettext('bar', 'bars', 1), 'BAR');
-      assert.equal(ngettext('bar', 'bars', 0), 'BARS');
-      assert.equal(ngettext('bar', 'bars', 2), 'BARS');
-    });
-
-    it('should return the key when no translation exists', function () {
-      assert.equal(
-        ngettext('no translation', 'no translations', 1),
-        'no translation'
-      );
-      assert.equal(
-        ngettext('no translation', 'no translations', 0),
-        'no translations'
-      );
-      assert.equal(
-        ngettext('no translation', 'no translations', 2),
-        'no translations'
-      );
-    });
-
-    it('should fill in placeholders', function () {
-      assert.equal(
-        ngettext('%(color)s shirt', '%(color)s shirts', 1, {color: 'RED'}),
-        'RED SHIRT'
-      );
-      assert.equal(
-        ngettext('%(color)s shirt', '%(color)s shirts', 0, {color: 'RED'}),
-        'RED SHIRTS'
-      );
-      assert.equal(
-        ngettext('%(color)s shirt', '%(color)s shirts', 2, {color: 'RED'}),
-        'RED SHIRTS'
-      );
-    });
-
-    it('should fill in placeholders when no translation exists', function () {
-      assert.equal(
-        ngettext('no %(attr)s translation', 'no %(attr)s translations',
-                 1, {attr: 'good'}),
-        'no good translation'
-      );
-      assert.equal(
-        ngettext('no %(attr)s translation', 'no %(attr)s translations',
-                 0, {attr: 'good'}),
-        'no good translations'
-      );
-      assert.equal(
-        ngettext('no %(attr)s translation', 'no %(attr)s translations',
-                 2, {attr: 'good'}),
-        'no good translations'
-      );
-    });
-
-    it('should provide a magic `num` placeholder', function () {
-      assert.equal(ngettext('%(num)d item', '%(num)d items', 1), '1 ITEM');
-      assert.equal(ngettext('%(num)d item', '%(num)d items', 0), '0 ITEMS');
-      assert.equal(ngettext('%(num)d item', '%(num)d items', 2), '2 ITEMS');
-    });
-
-    it('should provide `num` when no translation exists', function () {
-      assert.equal(
-        ngettext('%(num)d missing translation',
-                 '%(num)d missing translations', 1),
-        '1 missing translation'
-      );
-      assert.equal(
-        ngettext('%(num)d missing translation',
-                 '%(num)d missing translations', 0),
-        '0 missing translations'
-      );
-      assert.equal(
-        ngettext('%(num)d missing translation',
-                 '%(num)d missing translations', 2),
-        '2 missing translations'
-      );
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/module.spec.js b/ckan/public-bs2/base/test/spec/module.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/module.spec.js
+++ /dev/null
@@ -1,418 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.module(id, properties|callback)', function () {
-  beforeEach(function () {
-    ckan.module.registry = {};
-    ckan.module.instances = {};
-    this.factory = {};
-  });
-
-  it('should add a new item to the registry', function () {
-    ckan.module('test', this.factory);
-
-    assert.instanceOf(new ckan.module.registry.test(), ckan.module.BaseModule);
-  });
-
-  it('should allow a function to be provided', function () {
-    var target = sinon.stub().returns({});
-    ckan.module('test', target);
-
-    assert.called(target);
-  });
-
-  it('should pass jQuery, i18n.translate() and i18n into the function', function () {
-    // Note: This behavior is deprecated but kept for backwards-compatibility
-    var target = sinon.stub().returns({});
-    ckan.module('test', target);
-
-    assert.calledWith(target, jQuery, ckan.i18n.translate, ckan.i18n);
-  });
-
-  it('should throw an exception if the module is already defined', function () {
-    ckan.module('name', this.factory);
-    assert.throws(function () {
-      ckan.module('name', this.factory);
-    });
-  });
-
-  it('should return the ckan object', function () {
-    assert.equal(ckan.module('name', this.factory), ckan);
-  });
-
-  describe('.initialize()', function () {
-    beforeEach(function () {
-      this.element1 = jQuery('<div data-module="test1">').appendTo(this.fixture);
-      this.element2 = jQuery('<div data-module="test1">').appendTo(this.fixture);
-      this.element3 = jQuery('<div data-module="test2">').appendTo(this.fixture);
-
-      this.test1 = sinon.spy();
-
-      // Add test1 to the registry.
-      ckan.module.registry = {
-        test1: this.test1
-      };
-
-      this.target = sinon.stub(ckan.module, 'createInstance');
-    });
-
-    afterEach(function () {
-      this.target.restore();
-    });
-
-    it('should find all elements with the "data-module" attribute', function () {
-      ckan.module.initialize();
-      assert.called(this.target);
-    });
-
-    it('should skip modules that are not functions', function () {
-      ckan.module.initialize();
-      assert.calledTwice(this.target);
-    });
-
-    it('should call module.createInstance() with the element and factory', function () {
-      ckan.module.initialize();
-      assert.calledWith(this.target, this.test1, this.element1[0]);
-      assert.calledWith(this.target, this.test1, this.element2[0]);
-    });
-
-    it('should return the module object', function () {
-      assert.equal(ckan.module.initialize(), ckan.module);
-    });
-
-    it('should initialize more than one module sepearted by a space', function () {
-      this.fixture.empty();
-      this.element4 = jQuery('<div data-module="test1 test2">').appendTo(this.fixture);
-      this.test2 = ckan.module.registry.test2 = sinon.spy();
-
-      ckan.module.initialize();
-
-      assert.calledWith(this.target, this.test1, this.element4[0]);
-      assert.calledWith(this.target, this.test2, this.element4[0]);
-    });
-
-    it('should defer all published events untill all modules have loaded', function () {
-      var pubsub    = ckan.pubsub;
-      var callbacks = [];
-
-      // Ensure each module is loaded. Three in total.
-      ckan.module.registry = {
-        test1: function () {},
-        test2: function () {}
-      };
-
-      // Call a function to publish and subscribe to an event on each instance.
-      this.target.restore();
-      this.target = sinon.stub(ckan.module, 'createInstance', function () {
-        var callback = sinon.spy();
-
-        pubsub.publish('test');
-        pubsub.subscribe('test', callback);
-
-        callbacks.push(callback);
-      });
-
-      ckan.module.initialize();
-
-      // Ensure that all subscriptions received all messages.
-      assert.ok(callbacks.length, 'no callbacks were created');
-      jQuery.each(callbacks, function () {
-        assert.calledThrice(this);
-      });
-    });
-  });
-
-  describe('.createInstance(Module, element)', function () {
-    beforeEach(function () {
-      this.element = document.createElement('div');
-      this.factory = ckan.module.BaseModule;
-      this.factory.options = this.defaults = {test1: 'a', test2: 'b', test3: 'c'};
-
-      this.sandbox = {
-        i18n: {
-          translate: sinon.spy()
-        }
-      };
-      sinon.stub(ckan, 'sandbox').returns(this.sandbox);
-
-      this.extractedOptions = {test1: 1, test2: 2};
-      sinon.stub(ckan.module, 'extractOptions').returns(this.extractedOptions);
-    });
-
-    afterEach(function () {
-      ckan.sandbox.restore();
-      ckan.module.extractOptions.restore();
-    });
-
-    it('should extract the options from the element', function () {
-      ckan.module.createInstance(this.factory, this.element);
-
-      assert.called(ckan.module.extractOptions);
-      assert.calledWith(ckan.module.extractOptions, this.element);
-    });
-
-    it('should not modify the defaults object', function () {
-      var clone = jQuery.extend({}, this.defaults);
-      ckan.module.createInstance(this.factory, this.element);
-
-      assert.deepEqual(this.defaults, clone);
-    });
-
-    it('should create a sandbox object', function () {
-      ckan.module.createInstance(this.factory, this.element);
-      assert.called(ckan.sandbox);
-      assert.calledWith(ckan.sandbox, this.element);
-    });
-
-    it('should initialize the module factory with the sandbox, options and translate function', function () {
-      var target = sinon.spy();
-      ckan.module.createInstance(target, this.element);
-
-      assert.called(target);
-      assert.calledWith(target, this.element, this.extractedOptions, this.sandbox);
-    });
-
-    it('should initialize the module as a constructor', function () {
-      var target = sinon.spy();
-      ckan.module.createInstance(target, this.element);
-
-      assert.calledWithNew(target);
-
-    });
-
-    it('should call the .initialize() method if one exists', function () {
-      var init = sinon.spy();
-      var target = sinon.stub().returns({
-        initialize: init
-      });
-
-      ckan.module.createInstance(target, this.element);
-
-      assert.called(init);
-    });
-
-    it('should push the new instance into an array under ckan.module.instances', function () {
-      var target = function MyModule() { return {'mock': 'instance'}; };
-      target.namespace = 'test';
-
-      ckan.module.createInstance(target, this.element);
-
-      assert.deepEqual(ckan.module.instances.test, [{'mock': 'instance'}]);
-    });
-
-    it('should push further instances into the existing array under ckan.module.instances', function () {
-      var target = function MyModule() { return {'mock': 'instance3'}; };
-      target.namespace = 'test';
-
-      ckan.module.instances.test = [{'mock': 'instance1'}, {'mock': 'instance2'}];
-      ckan.module.createInstance(target, this.element);
-
-      assert.deepEqual(ckan.module.instances.test, [
-        {'mock': 'instance1'}, {'mock': 'instance2'}, {'mock': 'instance3'}
-      ]);
-    });
-
-  });
-
-  describe('.extractOptions(element)', function () {
-    it('should extract the data keys from the element', function () {
-      var element = jQuery('<div>', {
-        'data-not-module': 'skip',
-        'data-module': 'skip',
-        'data-module-a': 'capture',
-        'data-module-b': 'capture',
-        'data-module-c': 'capture'
-      })[0];
-
-      var target = ckan.module.extractOptions(element);
-
-      assert.deepEqual(target, {a: 'capture', b: 'capture', c: 'capture'});
-    });
-
-    it('should convert JSON contents of keys into JS primitives', function () {
-      var element = jQuery('<div>', {
-        'data-module-null': 'null',
-        'data-module-int': '100',
-        'data-module-arr': '[1, 2, 3]',
-        'data-module-obj': '{"a": 1, "b":2, "c": 3}',
-        'data-module-str': 'hello'
-      })[0];
-
-      var target = ckan.module.extractOptions(element);
-
-      assert.deepEqual(target, {
-        'null': null,
-        'int': 100,
-        'arr': [1, 2, 3],
-        'obj': {"a": 1, "b": 2, "c": 3},
-        'str': 'hello'
-      });
-    });
-
-    it('should simply use strings for content that it cannot parse as JSON', function () {
-      var element = jQuery('<div>', {
-        'data-module-url': 'http://example.com/path/to.html',
-        'data-module-bad': '{oh: 1, no'
-      })[0];
-
-      var target = ckan.module.extractOptions(element);
-
-      assert.deepEqual(target, {
-        'url': 'http://example.com/path/to.html',
-        'bad': '{oh: 1, no'
-      });
-    });
-
-    it('should convert keys with hyphens into camelCase', function () {
-      var element = jQuery('<div>', {
-        'data-module-long-property': 'long',
-        'data-module-really-very-long-property': 'longer'
-      })[0];
-
-      var target = ckan.module.extractOptions(element);
-
-      assert.deepEqual(target, {
-        'longProperty': 'long',
-        'reallyVeryLongProperty': 'longer'
-      });
-    });
-
-    it('should set boolean attributes to true', function () {
-      var element = jQuery('<div>', {
-        'data-module-long-property': ''
-      })[0];
-
-      var target = ckan.module.extractOptions(element);
-
-      assert.deepEqual(target, {'longProperty': true});
-    });
-  });
-
-  describe('BaseModule(element, options, sandbox)', function () {
-    var BaseModule = ckan.module.BaseModule;
-
-    beforeEach(function () {
-      this.el = jQuery('<div />');
-      this.options = {};
-      this.sandbox = ckan.sandbox();
-      this.module = new BaseModule(this.el, this.options, this.sandbox);
-    });
-
-    it('should assign .el as the element option', function () {
-      assert.ok(this.module.el === this.el);
-    });
-
-    it('should wrap .el in jQuery if not already wrapped', function () {
-      var element = document.createElement('div');
-      var target = new BaseModule(element, this.options, this.sandbox);
-
-      assert.ok(target.el instanceof jQuery);
-    });
-
-    it('should deep extend the options object', function () {
-      // Lazy check :/
-      var target = sinon.stub(jQuery, 'extend');
-      new BaseModule(this.el, this.options, this.sandbox);
-
-      assert.called(target);
-      assert.calledWith(target, true, {}, BaseModule.prototype.options, this.options);
-
-      target.restore();
-    });
-
-    it('should assign the sandbox property', function () {
-      assert.equal(this.module.sandbox, this.sandbox);
-    });
-
-    describe('.$(selector)', function () {
-      it('should find children within the module element', function () {
-        this.module.el.append(jQuery('<input /><input />'));
-        assert.equal(this.module.$('input').length, 2);
-      });
-    });
-
-    describe('.i18n()', function () {
-      // Note: This function is deprecated but kept for backwards-compatibility
-      beforeEach(function () {
-        this.i18n = {
-          first: 'first string',
-          second: {fetch: sinon.stub().returns('second string')},
-          third: sinon.stub().returns('third string')
-        };
-
-        this.module.options.i18n = this.i18n;
-      });
-
-      it('should return the translation string', function () {
-        var target = this.module.i18n('first');
-        assert.equal(target, 'first string');
-      });
-
-      it('should call fetch on the translation string if it exists', function () {
-        var target = this.module.i18n('second');
-        assert.equal(target, 'second string');
-      });
-
-      it('should return just the key if no translation exists', function () {
-        var target = this.module.i18n('missing');
-        assert.equal(target, 'missing');
-      });
-
-      it('should call the translation function if one is provided', function () {
-        var target = this.module.i18n('third');
-        assert.equal(target, 'third string');
-      });
-
-      it('should pass the argments after the key into trans.fetch()', function () {
-        var target = this.module.options.i18n.second.fetch;
-        this.module.i18n('second', 1, 2, 3);
-        assert.called(target);
-        assert.calledWith(target, 1, 2, 3);
-      });
-
-      it('should pass the argments after the key into the translation function', function () {
-        var target = this.module.options.i18n.third;
-        this.module.i18n('third', 1, 2, 3);
-        assert.called(target);
-        assert.calledWith(target, 1, 2, 3);
-      });
-    });
-
-    describe('._()', function () {
-      it('should be a shortcut for ckan.i18n._', function () {
-        /*
-         * In a module, this._ is a shortcut for ckan.i18n._,
-         * but it's not a direct reference.
-         */
-        assert.equal(this.module._('foo'), 'FOO');
-      });
-    });
-
-    describe('.ngettext()', function () {
-      it('should be a shortcut for ckan.i18n.ngettext', function () {
-        /*
-         * In a module, this.ngettext is a shortcut for ckan.i18n.ngettext,
-         * but it's not a direct reference.
-         */
-        assert.equal(this.module.ngettext('bar', 'bars', 1), 'BAR');
-        assert.equal(this.module.ngettext('bar', 'bars', 0), 'BARS');
-        assert.equal(this.module.ngettext('bar', 'bars', 2), 'BARS');
-      });
-    });
-
-    describe('.remove()', function () {
-      it('should teardown the module', function () {
-        var target = sinon.stub(this.module, 'teardown');
-
-        this.module.remove();
-
-        assert.called(target);
-      });
-
-      it('should remove the element from the page', function () {
-        this.fixture.append(this.module.el);
-        this.module.remove();
-
-        assert.equal(this.fixture.children().length, 0);
-      });
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/autocomplete.spec.js b/ckan/public-bs2/base/test/spec/modules/autocomplete.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/autocomplete.spec.js
+++ /dev/null
@@ -1,315 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.modules.AutocompleteModule()', function () {
-  var Autocomplete = ckan.module.registry['autocomplete'];
-
-  beforeEach(function () {
-    // Stub select2 plugin if loaded.
-    if (jQuery.fn.select2) {
-      this.select2 = sinon.stub(jQuery.fn, 'select2');
-    } else {
-      this.select2 = jQuery.fn.select2 = sinon.stub().returns({
-        data: sinon.stub().returns({
-          on: sinon.stub()
-        })
-      });
-    }
-
-    this.el = document.createElement('input');
-    this.sandbox = ckan.sandbox();
-    this.sandbox.body = this.fixture;
-    this.module = new Autocomplete(this.el, {}, this.sandbox);
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-
-    if (this.select2.restore) {
-      this.select2.restore();
-    } else {
-      delete jQuery.fn.select2;
-    }
-  });
-
-  describe('.initialize()', function () {
-    it('should bind callback methods to the module', function () {
-      var target = sinon.stub(jQuery, 'proxyAll');
-
-      this.module.initialize();
-
-      assert.called(target);
-      assert.calledWith(target, this.module, /_on/, /format/);
-
-      target.restore();
-    });
-
-    it('should setup the autocomplete plugin', function () {
-      var target = sinon.stub(this.module, 'setupAutoComplete');
-
-      this.module.initialize();
-
-      assert.called(target);
-    });
-  });
-
-  describe('.setupAutoComplete()', function () {
-    it('should initialize the autocomplete plugin', function () {
-      this.module.setupAutoComplete();
-
-      assert.called(this.select2);
-      assert.calledWith(this.select2, {
-        width: 'resolve',
-        query: this.module._onQuery,
-        dropdownCssClass: '',
-        containerCssClass: '',
-        formatResult: this.module.formatResult,
-        formatNoMatches: this.module.formatNoMatches,
-        formatInputTooShort: this.module.formatInputTooShort,
-        createSearchChoice: this.module.formatTerm, // Not used by tags.
-        initSelection: this.module.formatInitialValue
-      });
-    });
-
-    it('should initialize the autocomplete plugin with a tags callback if options.tags is true', function () {
-      this.module.options.tags = true;
-      this.module.setupAutoComplete();
-
-      assert.called(this.select2);
-      assert.calledWith(this.select2, {
-        width: 'resolve',
-        tags: this.module._onQuery,
-        dropdownCssClass: '',
-        containerCssClass: '',
-        formatResult: this.module.formatResult,
-        formatNoMatches: this.module.formatNoMatches,
-        formatInputTooShort: this.module.formatInputTooShort,
-        initSelection: this.module.formatInitialValue
-      });
-
-      it('should watch the keydown event on the select2 input');
-
-      it('should allow a custom css class to be added to the dropdown', function () {
-        this.module.options.dropdownClass = 'tags';
-        this.module.setupAutoComplete();
-
-        assert.called(this.select2);
-        assert.calledWith(this.select2, {
-          width: 'resolve',
-          tags: this.module._onQuery,
-          dropdownCssClass: 'tags',
-          containerCssClass: '',
-          formatResult: this.module.formatResult,
-          formatNoMatches: this.module.formatNoMatches,
-          formatInputTooShort: this.module.formatInputTooShort,
-          initSelection: this.module.formatInitialValue
-        });
-      });
-
-      it('should allow a custom css class to be added to the container', function () {
-        this.module.options.containerClass = 'tags';
-        this.module.setupAutoComplete();
-
-        assert.called(this.select2);
-        assert.calledWith(this.select2, {
-          width: 'resolve',
-          tags: this.module._onQuery,
-          dropdownCssClass: '',
-          containerCssClass: 'tags',
-          formatResult: this.module.formatResult,
-          formatNoMatches: this.module.formatNoMatches,
-          formatInputTooShort: this.module.formatInputTooShort,
-          initSelection: this.module.formatInitialValue
-        });
-      });
-
-    });
-  });
-
-  describe('.getCompletions(term, fn)', function () {
-    beforeEach(function () {
-      this.term = 'term';
-      this.module.options.source = 'http://example.com?term=?';
-
-      this.target = sinon.stub(this.sandbox.client, 'getCompletions');
-    });
-
-    it('should get the completions from the client', function () {
-      this.module.getCompletions(this.term);
-      assert.called(this.target);
-    });
-
-    it('should replace the last ? in the source url with the term', function () {
-      this.module.getCompletions(this.term);
-      assert.calledWith(this.target, 'http://example.com?term=term');
-    });
-
-    it('should escape special characters in the term', function () {
-      this.module.getCompletions('term with spaces');
-      assert.calledWith(this.target, 'http://example.com?term=term%20with%20spaces');
-    });
-  });
-
-  describe('.lookup(term, fn)', function () {
-    beforeEach(function () {
-      sinon.stub(this.module, 'getCompletions');
-      this.target = sinon.spy();
-      this.module.setupAutoComplete();
-    });
-
-    it('should set the _lastTerm property', function () {
-      this.module.lookup('term', this.target);
-      assert.equal(this.module._lastTerm, 'term');
-    });
-
-    it('should call the fn immediately if there is no term', function () {
-      this.module.lookup('', this.target);
-      assert.called(this.target);
-      assert.calledWith(this.target, {results: []});
-    });
-
-    it('should debounce the request if there is a term');
-    it('should cancel the last request');
-  });
-
-  describe('.formatResult(state)', function () {
-    beforeEach(function () {
-      this.module._lastTerm = 'term';
-    });
-
-    it('should return the string with the last term wrapped in bold tags', function () {
-      var target = this.module.formatResult({id: 'we have termites', text: 'we have termites'});
-      assert.equal(target, 'we have <b>term</b>ites');
-    });
-
-    it('should return the string with each instance of the term wrapped in bold tags', function () {
-      var target = this.module.formatResult({id: 'we have a termite terminology', text: 'we have a termite terminology'});
-      assert.equal(target, 'we have a <b>term</b>ite <b>term</b>inology');
-    });
-
-    it('should return the term if there is no last term saved', function () {
-      delete this.module._lastTerm;
-      var target = this.module.formatResult({id: 'we have a termite terminology', text: 'we have a termite terminology'});
-      assert.equal(target, 'we have a termite terminology');
-    });
-  });
-
-  describe('.formatNoMatches(term)', function () {
-    it('should return the no matches string if there is a term', function () {
-      var target = this.module.formatNoMatches('term');
-      assert.equal(target, 'No matches found');
-    });
-
-    it('should return the empty string if there is no term', function () {
-      var target = this.module.formatNoMatches('');
-      assert.equal(target, 'Start typing…');
-    });
-  });
-
-  describe('.formatInputTooShort(term, min)', function () {
-    it('should return the plural input too short string', function () {
-      var target = this.module.formatInputTooShort('term', 2);
-      assert.equal(target, 'Input is too short, must be at least 2 characters');
-    });
-
-    it('should return the singular input too short string', function () {
-      var target = this.module.formatInputTooShort('term', 1);
-      assert.equal(target, 'Input is too short, must be at least one character');
-    });
-  });
-
-  describe('.formatTerm()', function () {
-    it('should return an item object with id and text properties', function () {
-      assert.deepEqual(this.module.formatTerm('test'), {id: 'test', text: 'test'});
-    });
-
-    it('should trim whitespace from the value', function () {
-      assert.deepEqual(this.module.formatTerm(' test  '), {id: 'test', text: 'test'});
-    });
-
-    it('should convert commas in ids into unicode characters', function () {
-      assert.deepEqual(this.module.formatTerm('test, test'), {id: 'test\u002C test', text: 'test, test'});
-    });
-  });
-
-  describe('.formatInitialValue(element, callback)', function () {
-    beforeEach(function () {
-      this.callback = sinon.spy();
-    });
-
-    it('should pass an item object with id and text properties into the callback', function () {
-      var target = jQuery('<input value="test"/>');
-
-      this.module.formatInitialValue(target, this.callback);
-      assert.calledWith(this.callback, {id: 'test', text: 'test'});
-    });
-
-    it('should pass an array of properties into the callback if options.tags is true', function () {
-      this.module.options.tags = true;
-      var target = jQuery('<input />', {value: "test, test"});
-
-      this.module.formatInitialValue(target, this.callback);
-      assert.calledWith(this.callback, [{id: 'test', text: 'test'}, {id: 'test', text: 'test'}]);
-    });
-
-    it('should return the value if no callback is provided (to support select2 v2.1)', function () {
-      var target = jQuery('<input value="test"/>');
-
-      assert.deepEqual(this.module.formatInitialValue(target), {id: 'test', text: 'test'});
-    });
-  });
-
-  describe('._onQuery(options)', function () {
-    it('should lookup the current term with the callback', function () {
-      var target = sinon.stub(this.module, 'lookup');
-
-      this.module._onQuery({term: 'term', callback: 'callback'});
-
-      assert.called(target);
-      assert.calledWith(target, 'term', 'callback');
-    });
-
-    it('should do nothing if there is no options object', function () {
-      var target = sinon.stub(this.module, 'lookup');
-      this.module._onQuery();
-      assert.notCalled(target);
-    });
-  });
-
-  describe('._onKeydown(event)', function () {
-    beforeEach(function () {
-      this.keyDownEvent = jQuery.Event("keydown", { which: 188 });
-      this.fakeEvent = {};
-      this.clock = sinon.useFakeTimers();
-      this.jQuery = sinon.stub(jQuery.fn, 'init', jQuery.fn.init);
-      this.Event  = sinon.stub(jQuery, 'Event').returns(this.fakeEvent);
-      this.trigger  = sinon.stub(jQuery.fn, 'trigger');
-    });
-
-    afterEach(function () {
-      this.clock.restore();
-      this.jQuery.restore();
-      this.Event.restore();
-      this.trigger.restore();
-    });
-  
-    it('should trigger fake "return" keypress if a comma is pressed', function () {
-      this.module._onKeydown(this.keyDownEvent);
-
-      this.clock.tick(100);
-
-      assert.called(this.jQuery);
-      assert.called(this.Event);
-      assert.called(this.trigger);
-      assert.calledWith(this.trigger, this.fakeEvent);
-    });
-
-    it('should do nothing if another key is pressed', function () {
-      this.keyDownEvent.which = 200;
-
-      this.module._onKeydown(this.keyDownEvent);
-
-      this.clock.tick(100);
-
-      assert.notCalled(this.Event);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/basic-form.spec.js b/ckan/public-bs2/base/test/spec/modules/basic-form.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/basic-form.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.module.BasicFormModule()', function () {
-  var BasicFormModule = ckan.module.registry['basic-form'];
-
-  beforeEach(function () {
-    sinon.stub(jQuery.fn, 'incompleteFormWarning');
-
-    this.el = document.createElement('form');
-    this.el.innerHTML = '<button name="save" type="submit">Save</button>'
-    this.sandbox = ckan.sandbox();
-    this.sandbox.body = this.fixture;
-    this.sandbox.body.append(this.el)
-    this.module = new BasicFormModule(this.el, {}, this.sandbox);
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-    jQuery.fn.incompleteFormWarning.restore();
-  });
-
-  describe('.initialize()', function () {
-    it('should attach the jQuery.fn.incompleteFormWarning() to the form', function () {
-      this.module.initialize();
-      assert.called(jQuery.fn.incompleteFormWarning);
-    });
-
-    it('should disable the submit button on form submit', function(done) {
-      this.module.initialize();
-      this.module._onSubmit();
-
-      setTimeout(function() {
-        var buttonAttrDisabled = this.el.querySelector('button').getAttribute('disabled');
-
-        assert.ok(buttonAttrDisabled === 'disabled')
-        done();
-      }.bind(this), 0);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/confirm-action.spec.js b/ckan/public-bs2/base/test/spec/modules/confirm-action.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/confirm-action.spec.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.module.ConfirmActionModule()', function () {
-  var ConfirmActionModule = ckan.module.registry['confirm-action'];
-
-  beforeEach(function () {
-    jQuery.fn.modal = sinon.spy();
-
-    this.el = document.createElement('button');
-    this.sandbox = ckan.sandbox();
-    this.sandbox.body = this.fixture;
-    this.module = new ConfirmActionModule(this.el, {}, this.sandbox);
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-  });
-
-  describe('.initialize()', function () {
-    it('should watch for clicks on the module element', function () {
-      var target = sinon.stub(this.module.el, 'on');
-      this.module.initialize();
-      assert.called(target);
-      assert.calledWith(target, 'click', this.module._onClick);
-    });
-  });
-
-  describe('.confirm()', function () {
-    it('should append the modal to the document body', function () {
-      this.module.confirm();
-      assert.equal(this.fixture.children().length, 1);
-      assert.equal(this.fixture.find('.modal').length, 1);
-    });
-
-    it('should show the modal dialog', function () {
-      this.module.confirm();
-      assert.called(jQuery.fn.modal);
-      assert.calledWith(jQuery.fn.modal, 'show');
-    });
-  });
-
-  describe('.performAction()', function () {
-    it('should submit the action');
-  });
-
-  describe('.createModal()', function () {
-    it('should create the modal element', function () {
-      var target = this.module.createModal();
-
-      assert.ok(target.hasClass('modal'));
-    });
-
-    it('should set the module.modal property', function () {
-      var target = this.module.createModal();
-
-      assert.ok(target === this.module.modal);
-    });
-
-    it('should bind the success/cancel listeners', function () {
-      var target = sinon.stub(jQuery.fn, 'on');
-
-      this.module.createModal();
-
-      // Not an ideal check as this implementation could be done in many ways.
-      assert.calledTwice(target);
-      assert.calledWith(target, 'click', '.btn-primary', this.module._onConfirmSuccess);
-      assert.calledWith(target, 'click', '.btn-cancel', this.module._onConfirmCancel);
-
-      target.restore();
-    });
-
-    it('should initialise the modal plugin', function () {
-      this.module.createModal();
-      assert.called(jQuery.fn.modal);
-      assert.calledWith(jQuery.fn.modal, {show: false});
-    });
-
-    it('should allow to customize the content', function () {
-      this.module.options.content = 'some custom content';
-      var target = this.module.createModal();
-
-      assert.equal(target.find('.modal-body').text(), 'some custom content');
-    });
-  });
-
-  describe('._onClick()', function () {
-    it('should prevent the default action', function () {
-      var target = {preventDefault: sinon.spy()};
-      this.module._onClick(target);
-
-      assert.called(target.preventDefault);
-    });
-
-    it('should display the confirmation dialog', function () {
-      var target = sinon.stub(this.module, 'confirm');
-      this.module._onClick({preventDefault: sinon.spy()});
-      assert.called(target);
-    });
-  });
-
-  describe('._onConfirmSuccess()', function () {
-    it('should perform the action', function () {
-      var target = sinon.stub(this.module, 'performAction');
-      this.module._onConfirmSuccess(jQuery.Event('click'));
-      assert.called(target);
-    });
-  });
-
-  describe('._onConfirmCancel()', function () {
-    it('should hide the modal', function () {
-      this.module.modal = jQuery('<div/>');
-      this.module._onConfirmCancel(jQuery.Event('click'));
-
-      assert.called(jQuery.fn.modal);
-      assert.calledWith(jQuery.fn.modal, 'hide');
-    });
-  });
-
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/custom-fields.spec.js b/ckan/public-bs2/base/test/spec/modules/custom-fields.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/custom-fields.spec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/*globals describe before beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.module.CustomFieldsModule()', function () {
-  var CustomFieldsModule = ckan.module.registry['custom-fields'];
-
-  before(function (done) {
-    this.loadFixture('custom_fields.html', function (template) {
-      this.template = template;
-      done();
-    });
-  });
-
-  beforeEach(function () {
-    this.fixture.html(this.template);
-    this.el = this.fixture.find('[data-module]');
-    this.sandbox = ckan.sandbox();
-    this.sandbox.body = this.fixture;
-    this.module = new CustomFieldsModule(this.el, {}, this.sandbox);
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-  });
-
-  describe('.initialize()', function () {
-    it('should bind all functions beginning with _on to the module scope', function () {
-      var target = sinon.stub(jQuery, 'proxyAll');
-
-      this.module.initialize();
-
-      assert.called(target);
-      assert.calledWith(target, this.module, /_on/);
-
-      target.restore();
-    });
-
-    it('should listen for changes to the last "key" input', function () {
-      var target = sinon.stub(this.module, '_onChange');
-
-      this.module.initialize();
-      this.module.$('input[name*=key]').change();
-
-      assert.calledOnce(target);
-    });
-
-    it('should listen for changes to all checkboxes', function () {
-      var target = sinon.stub(this.module, '_onRemove');
-
-      this.module.initialize();
-      this.module.$(':checkbox').trigger('change');
-
-      assert.calledOnce(target);
-    });
-
-    it('should add "button" classes to the remove input', function () {
-      this.module.initialize();
-
-      assert.equal(this.module.$('.checkbox.btn').length, 1, 'each item should have the .btn class');
-      assert.equal(this.module.$('.checkbox.fa-times').length, 1, 'each item shoud have the .fa-times class');
-    });
-  });
-
-  describe('.newField(element)', function () {
-    it('should append a new field to the element', function () {
-      var element = document.createElement('div');
-      sinon.stub(this.module, 'cloneField').returns(element);
-
-      this.module.newField();
-
-      assert.ok(jQuery.contains(this.module.el[0], element));
-    });
-  });
-
-  describe('.cloneField(element)', function () {
-    it('should clone the provided field', function () {
-      var element = document.createElement('div');
-      var init  = sinon.stub(jQuery.fn, 'init', jQuery.fn.init);
-      var clone = sinon.stub(jQuery.fn, 'clone', jQuery.fn.clone);
-
-      this.module.cloneField(element);
-
-      assert.called(init);
-      assert.calledWith(init, element);
-      assert.called(clone);
-
-      init.restore();
-      clone.restore();
-    });
-
-    it('should return the cloned element', function () {
-      var element = document.createElement('div');
-      var cloned  = document.createElement('div');
-      var init  = sinon.stub(jQuery.fn, 'init', jQuery.fn.init);
-      var clone = sinon.stub(jQuery.fn, 'clone').returns(jQuery(cloned));
-
-      assert.ok(this.module.cloneField(element)[0] === cloned);
-
-      init.restore();
-      clone.restore();
-    });
-  });
-
-  describe('.resetField(element)', function () {
-    beforeEach(function () {
-      this.field = jQuery('<div><label for="field-1">Field 1</label><input name="field-1" value="value" /></div>');
-    });
-
-    it('should empty all input values', function () {
-      var target = this.module.resetField(this.field);
-      assert.equal(target.find(':input').val(), '');
-    });
-
-    it('should increment any integers in the input names by one', function () {
-      var target = this.module.resetField(this.field);
-      assert.equal(target.find(':input').attr('name'), 'field-2');
-    });
-
-    it('should increment any numbers in the label text by one', function () {
-      var target = this.module.resetField(this.field);
-      assert.equal(target.find('label').text(), 'Field 2');
-    });
-
-    it('should increment any numbers in the label for by one', function () {
-      var target = this.module.resetField(this.field);
-      assert.equal(target.find('label').attr('for'), 'field-2');
-    });
-  });
-
-  describe('.disableField(field, disable)', function () {
-    beforeEach(function () {
-      this.target = this.module.$('.control-custom:first');
-    });
-
-    it('should add a .disable class to the element', function () {
-      this.module.disableField(this.target);
-      assert.isTrue(this.target.hasClass('disabled'));
-    });
-
-    it('should remove a .disable class to the element if disable is false', function () {
-      this.target.addClass('disable');
-
-      this.module.disableField(this.target, false);
-      assert.isFalse(this.target.hasClass('disabled'));
-    });
-
-  });
-
-  describe('._onChange(event)', function () {
-    it('should call .newField() with the custom control', function () {
-      var target = sinon.stub(this.module, 'newField');
-      var field  = this.module.$('[name*=key]:last').val('test');
-
-      this.module._onChange(jQuery.Event('change', {target: field[0]}));
-
-      assert.called(target);
-    });
-
-    it('should not call .newField() if the target field is empty', function () {
-      var target = sinon.stub(this.module, 'newField');
-      var field  = this.module.$('[name*=key]:last').val('');
-
-      this.module._onChange(jQuery.Event('change', {target: field[0]}));
-
-      assert.notCalled(target);
-    });
-  });
-
-  describe('._onRemove(event)', function () {
-    it('should call .disableField() with the custom control', function () {
-      var target = sinon.stub(this.module, 'disableField');
-      this.module._onRemove(jQuery.Event('change', {target: this.module.$(':checkbox')[0]}));
-
-      assert.called(target);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/followers-counter.spec.js b/ckan/public-bs2/base/test/spec/modules/followers-counter.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/followers-counter.spec.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.module.FollowersCounterModule()', function() {
-    var FollowersCounterModule = ckan.module.registry['followers-counter'];
-
-    beforeEach(function() {
-      this.initialCounter = 10;
-      this.el = jQuery('<dd><span>' + this.initialCounter + '</span></dd>');
-      this.sandbox = ckan.sandbox();
-      this.module = new FollowersCounterModule(this.el, {}, this.sandbox);
-      this.module.options.num_followers = this.initialCounter;
-    });
-
-    afterEach(function() {
-      this.module.teardown();
-    });
-
-    describe('.initialize()', function() {
-      it('should bind callback methods to the module', function() {
-        var target = sinon.stub(jQuery, 'proxyAll');
-
-        this.module.initialize();
-
-        assert.called(target);
-        assert.calledWith(target, this.module, /_on/);
-
-        target.restore();
-      });
-
-      it('should subscribe to the "follow-follow-some-id" event', function() {
-        var target = sinon.stub(this.sandbox, 'subscribe');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        assert.called(target);
-        assert.calledWith(target, 'follow-follow-some-id', this.module._onFollow);
-
-        target.restore();
-      });
-
-      it('should subscribe to the "follow-unfollow-some-id" event', function() {
-        var target = sinon.stub(this.sandbox, 'subscribe');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        assert.called(target);
-        assert.calledWith(target, 'follow-unfollow-some-id', this.module._onUnfollow);
-
-        target.restore();
-      });
-    });
-
-    describe('.teardown()', function() {
-      it('should unsubscribe to the "follow-follow-some-id" event', function() {
-        var target = sinon.stub(this.sandbox, 'unsubscribe');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-        this.module.teardown();
-
-        assert.called(target);
-        assert.calledWith(target, 'follow-follow-some-id', this.module._onFollow);
-
-        target.restore();
-      });
-
-      it('should unsubscribe to the "follow-unfollow-some-id" event', function() {
-        var target = sinon.stub(this.sandbox, 'unsubscribe');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-        this.module.teardown();
-
-        assert.called(target);
-        assert.calledWith(target, 'follow-unfollow-some-id', this.module._onUnfollow);
-
-        target.restore();
-      });
-    });
-
-    describe('._onFollow', function() {
-      it('should call _onFollow on "follow-follow-some-id" event', function() {
-        var target = sinon.stub(this.module, '_onFollow');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        this.sandbox.publish('follow-follow-some-id');
-
-        assert.called(target);
-      });
-
-      it('should call _updateCounter when ._onFollow is called', function() {
-        var target = sinon.stub(this.module, '_updateCounter');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        this.module._onFollow();
-
-        assert.called(target);
-        assert.calledWith(target, {action: 'follow'});
-      });
-    });
-
-    describe('._onUnfollow', function() {
-      it('should call _onUnfollow on "follow-unfollow-some-id" event', function() {
-        var target = sinon.stub(this.module, '_onUnfollow');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        this.sandbox.publish('follow-unfollow-some-id');
-
-        assert.called(target);
-      });
-
-      it('should call _updateCounter when ._onUnfollow is called', function() {
-        var target = sinon.stub(this.module, '_updateCounter');
-
-        this.module.options = {id: 'some-id'};
-        this.module.initialize();
-
-        this.module._onUnfollow();
-
-        assert.called(target);
-        assert.calledWith(target, {action: 'unfollow'});
-      });
-    });
-
-    describe('._updateCounter', function() {
-      it('should increment this.options.num_followers on calling _onFollow', function() {
-        this.module.initialize();
-        this.module._onFollow();
-
-        assert.equal(this.module.options.num_followers, ++this.initialCounter);
-      });
-
-      it('should increment the counter value in the DOM on calling _onFollow', function() {
-        var counterVal;
-
-        this.module.initialize();
-        this.module._onFollow();
-
-        counterVal = this.module.counterEl.text();
-        counterVal = parseInt(counterVal, 10);
-
-        assert.equal(counterVal, ++this.initialCounter);
-      });
-
-      it('should decrement this.options.num_followers on calling _onUnfollow', function() {
-        this.module.initialize();
-        this.module._onUnfollow();
-
-        assert.equal(this.module.options.num_followers, --this.initialCounter);
-      });
-
-      it('should decrement the counter value in the DOM on calling _onUnfollow', function() {
-        var counterVal;
-
-        this.module.initialize();
-        this.module._onUnfollow();
-
-        counterVal = this.module.counterEl.text();
-        counterVal = parseInt(counterVal, 10);
-
-        assert.equal(counterVal, --this.initialCounter);
-      });
-
-      it('should not change the counter value in the DOM when the value is greater than 1000', function() {
-        var beforeCounterVal = 1536;
-        var afterCounterVal;
-
-        this.module.options = {num_followers: beforeCounterVal};
-        this.module.initialize();
-        this.module.counterEl.text(this.module.options.num_followers);
-        this.module._onFollow();
-
-        afterCounterVal = this.module.counterEl.text();
-        afterCounterVal = parseInt(afterCounterVal, 10);
-
-        assert.equal(beforeCounterVal, afterCounterVal);
-      });
-    });
-  });
diff --git a/ckan/public-bs2/base/test/spec/modules/image-upload.spec.js b/ckan/public-bs2/base/test/spec/modules/image-upload.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/image-upload.spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.modules.ImageUploadModule()', function () {
-  var ImageUploadModule = ckan.module.registry['image-upload'];
-
-  beforeEach(function () {
-    this.el = document.createElement('div');
-    this.sandbox = ckan.sandbox();
-    this.module = new ImageUploadModule(this.el, {}, this.sandbox);
-    this.module.el.html([
-      '<div class="control-group"><input name="image_url" /></div>',
-      '<input name="image_upload" />',
-    ]);
-    this.module.initialize();
-    this.module.field_name = jQuery('<input>', {type: 'text'})
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-  });
-
-  describe('._onFromWeb()', function () {
-
-    it('should change name when url changed', function () {
-      this.module.field_url_input.val('http://example.com/some_image.png');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'some_image.png');
-
-      this.module.field_url_input.val('http://example.com/undefined_file');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'undefined_file');
-    });
-
-    it('should ignore url changes if name was manualy changed', function () {
-      this.module.field_url_input.val('http://example.com/some_image.png');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'some_image.png');
-
-      this.module._onModifyName();
-
-      this.module.field_url_input.val('http://example.com/undefined_file');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'some_image.png');
-    });
-
-    it('should ignore url changes if name was filled before', function () {
-      this.module._nameIsDirty = true;
-      this.module.field_name.val('prefilled');
-
-      this.module.field_url_input.val('http://example.com/some_image.png');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'prefilled');
-
-      this.module.field_url_input.val('http://example.com/second_some_image.png');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'prefilled');
-
-      this.module._onModifyName()
-
-      this.module.field_url_input.val('http://example.com/undefined_file');
-      this.module._onFromWebBlur();
-      assert.equal(this.module.field_name.val(), 'prefilled');
-    });
-  });
-
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/resource-form.spec.js b/ckan/public-bs2/base/test/spec/modules/resource-form.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/resource-form.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.modules.ResourceFormModule()', function () {
-  var ResourceFormModule = ckan.module.registry['resource-form'];
-
-  beforeEach(function () {
-    this.el = document.createElement('form');
-    this.sandbox = ckan.sandbox();
-    this.module = new ResourceFormModule(this.el, {}, this.sandbox);
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-  });
-
-  describe('.initialize()', function () {
-    it('should subscribe to the "resource:uploaded" event', function () {
-      var target = sinon.stub(this.sandbox, 'subscribe');
-
-      this.module.initialize();
-
-      assert.called(target);
-      assert.calledWith(target, 'resource:uploaded', this.module._onResourceUploaded);
-
-      target.restore();
-    });
-  });
-
-  describe('.teardown()', function () {
-    it('should unsubscribe from the "resource:uploaded" event', function () {
-      var target = sinon.stub(this.sandbox, 'unsubscribe');
-
-      this.module.teardown();
-
-      assert.called(target);
-      assert.calledWith(target, 'resource:uploaded', this.module._onResourceUploaded);
-
-      target.restore(); 
-    });
-  });
-
-  describe('._onResourceUploaded()', function () {
-    beforeEach(function () {
-      this.module.el.html([
-        '<input type="text" name="text" />',
-        '<input type="checkbox" name="checkbox" value="check" />',
-        '<input type="radio" name="radio" value="radio1" />',
-        '<input type="radio" name="radio" value="radio2" />',
-        '<input type="hidden" name="hidden" />',
-        '<select name="select">',
-        '<option value="option1" />',
-        '<option value="option2" />',
-        '</select>'
-      ].join(''));
-
-      this.resource = {
-        text: 'text',
-        checkbox: "check",
-        radio: "radio2",
-        hidden: "hidden",
-        select: "option1"
-      };
-    });
-
-    it('should set the values on appropriate fields', function () {
-      var res = this.resource;
-
-      this.module._onResourceUploaded(res);
-
-      jQuery.each(this.module.el.serializeArray(), function (idx, field) {
-        assert.equal(field.value, res[field.name]);
-      });
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/modules/resource-upload-field.spec.js b/ckan/public-bs2/base/test/spec/modules/resource-upload-field.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/modules/resource-upload-field.spec.js
+++ /dev/null
@@ -1,290 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.modules.ResourceUploadFieldModule()', function () {
-  var ResourceFileUploadModule = ckan.module.registry['resource-upload-field'];
-
-  beforeEach(function () {
-    jQuery.fn.fileupload = sinon.spy();
-
-    this.el = jQuery('<form />');
-    this.sandbox = ckan.sandbox();
-    this.module = new ResourceFileUploadModule(this.el, {}, this.sandbox);
-    this.module.initialize();
-  });
-
-  afterEach(function () {
-    this.module.teardown();
-  });
-
-  describe('.initialize()', function () {
-    beforeEach(function () {
-      // Create un-initialised module.
-      this.module.teardown();
-      this.module = new ResourceFileUploadModule(this.el, {}, this.sandbox);
-    });
-
-    it('should create the #upload field', function () {
-      this.module.initialize();
-      assert.ok(typeof this.module.upload === 'object');
-    });
-
-    it('should append the upload field to the module element', function () {
-      this.module.initialize();
-
-      assert.ok(jQuery.contains(this.el[0], this.module.upload[0]));
-    });
-
-    it('should call .setupFileUpload()', function () {
-      var target = sinon.stub(this.module, 'setupFileUpload');
-
-      this.module.initialize();
-
-      assert.called(target);
-    });
-  });
-
-  describe('.setupFileUpload()', function () {
-    it('should set the label text on the form input', function () {
-      this.module.initialize();
-      this.module.setupFileUpload();
-
-      assert.equal(this.module.upload.find('label').text(), 'Upload a file');
-    });
-
-    it('should setup the file upload with relevant options', function () {
-      this.module.initialize();
-      this.module.setupFileUpload();
-
-      assert.called(jQuery.fn.fileupload);
-      assert.calledWith(jQuery.fn.fileupload, {
-        type: 'POST',
-        paramName: 'file',
-        forceIframeTransport: true, // Required for XDomain request. 
-        replaceFileInput: true,
-        autoUpload: false,
-        add:  this.module._onUploadAdd,
-        send: this.module._onUploadSend,
-        done: this.module._onUploadDone,
-        fail: this.module._onUploadFail,
-        always: this.module._onUploadComplete 
-      });
-    });
-  });
-
-  describe('.loading(show)', function () {
-    it('should add a loading class to the upload element', function () {
-      this.module.loading();
-
-      assert.ok(this.module.upload.hasClass('loading'));
-    });
-
-    it('should remove the loading class if false is passed as an argument', function () {
-      this.module.upload.addClass('loading');
-      this.module.loading();
-
-      assert.ok(!this.module.upload.hasClass('loading'));
-    });
-  });
-
-  describe('.authenticate(key, data)', function () {
-    beforeEach(function () {
-      this.fakeThen = sinon.spy();
-      this.fakeProxy = sinon.stub(jQuery, 'proxy').returns('onsuccess');
-
-      this.target = sinon.stub(this.sandbox.client, 'getStorageAuth');
-      this.target.returns({
-        then: this.fakeThen
-      });
-    });
-
-    afterEach(function () {
-      jQuery.proxy.restore();
-    });
-
-    it('should request authentication for the upload', function () {
-      this.module.authenticate('test', {});
-      assert.called(this.target);
-      assert.calledWith(this.target, 'test'); 
-    });
-
-    it('should register success and error callbacks', function () {
-      this.module.authenticate('test', {});
-      assert.called(this.fakeThen);
-      assert.calledWith(this.fakeThen, 'onsuccess', this.module._onAuthError);
-    });
-
-    it('should save the key on the data object', function () {
-      var data = {};
-
-      this.module.authenticate('test', data);
-
-      assert.equal(data.key, 'test');
-    });
-  });
-
-  describe('.lookupMetadata(key, data)', function () {
-    beforeEach(function () {
-      this.fakeThen = sinon.spy();
-      this.fakeProxy = sinon.stub(jQuery, 'proxy').returns('onsuccess');
-
-      this.target = sinon.stub(this.sandbox.client, 'getStorageMetadata');
-      this.target.returns({
-        then: this.fakeThen
-      });
-    });
-
-    afterEach(function () {
-      jQuery.proxy.restore();
-    });
-
-    it('should request metadata for the upload key', function () {
-      this.module.lookupMetadata('test', {});
-      assert.called(this.target);
-      assert.calledWith(this.target, 'test'); 
-    });
-
-    it('should register success and error callbacks', function () {
-      this.module.lookupMetadata('test', {});
-      assert.called(this.fakeThen);
-      assert.calledWith(this.fakeThen, 'onsuccess', this.module._onMetadataError);
-    });
-  });
-
-  describe('.notify(message, type)', function () {
-    it('should call the sandbox.notify() method', function () {
-      var target = sinon.stub(this.sandbox, 'notify');
-
-      this.module.notify('this is an example message', 'info');
-
-      assert.called(target);
-      assert.calledWith(target, 'An Error Occurred', 'this is an example message', 'info');
-    });
-  });
-
-  describe('.generateKey(file)', function () {
-    it('should generate a unique filename prefixed with a timestamp', function () {
-      var now   = new Date();
-      var date  = jQuery.date.toISOString(now);
-      var clock = sinon.useFakeTimers(now.getTime());
-      var target = this.module.generateKey('this is my file.png');
-
-      assert.equal(target, date + '/this-is-my-file.png');
-
-      clock.restore();
-    });
-  });
-
-  describe('._onUploadAdd(event, data)', function () {
-    beforeEach(function () {
-      this.target = sinon.stub(this.module, 'authenticate');
-      sinon.stub(this.module, 'generateKey').returns('stubbed');
-    });
-
-    it('should authenticate the upload if a file is provided', function () {
-      var data = {files: [{name: 'my_file.jpg'}]};
-      this.module._onUploadAdd({}, data);
-
-      assert.called(this.target);
-      assert.calledWith(this.target, 'stubbed', data);
-    });
-
-    it('should not authenticate the upload if no file is provided', function () {
-      var data = {files: []};
-      this.module._onUploadAdd({}, data);
-
-      assert.notCalled(this.target);
-    });
-  });
-
-  describe('._onUploadSend()', function () {
-    it('should display the loading spinner', function () {
-      var target = sinon.stub(this.module, 'loading');
-      this.module._onUploadSend({}, {});
-
-      assert.called(target);
-    });
-  });
-
-  describe('._onUploadDone()', function () {
-    it('should request the metadata for the file', function () {
-      var target = sinon.stub(this.module, 'lookupMetadata');
-      this.module._onUploadDone({}, {result: {}});
-
-      assert.called(target);
-    });
-
-    it('should call the fail handler if the "result" key in the data is undefined', function () {
-      var target = sinon.stub(this.module, '_onUploadFail');
-      this.module._onUploadDone({}, {result: undefined});
-
-      assert.called(target);
-    });
-
-    it('should call the fail handler if the "result" object has an "error" key', function () {
-      var target = sinon.stub(this.module, '_onUploadFail');
-      this.module._onUploadDone({}, {result: {error: 'failed'}});
-
-      assert.called(target);
-    });
-  });
-
-  describe('._onUploadComplete()', function () {
-    it('should hide the loading spinner', function () {
-      var target = sinon.stub(this.module, 'loading');
-      this.module._onUploadComplete({}, {});
-
-      assert.called(target);
-      assert.calledWith(target, false);
-    });
-  });
-
-  describe('._onAuthSuccess()', function () {
-    beforeEach(function () {
-      this.target = {
-        submit: sinon.spy()
-      };
-
-      this.response = {
-        action: 'action',
-        fields: [{name: 'name', value: 'value'}]
-      };
-    });
-
-    it('should set the data url', function () {
-      this.module._onAuthSuccess(this.target, this.response);
-
-      assert.equal(this.target.url, this.response.action);
-    });
-
-    it('should set the additional form data', function () {
-      this.module._onAuthSuccess(this.target, this.response);
-
-      assert.deepEqual(this.target.formData, this.response.fields);
-    });
-
-    it('should merge the form data with the options', function () {
-      this.module.options.form.params = [{name: 'option', value: 'option'}];
-      this.module._onAuthSuccess(this.target, this.response);
-
-      assert.deepEqual(this.target.formData, [{name: 'option', value: 'option'}, {name: 'name', value: 'value'}]);
-    });
-
-    it('should call data.submit()', function () {
-      this.module._onAuthSuccess(this.target, this.response);
-      assert.called(this.target.submit);
-    });
-  });
-
-  describe('._onMetadataSuccess()', function () {
-    it('should publish the "resource:uploaded" event', function () {
-      var resource = {url: 'http://', name: 'My File'};
-      var target = sinon.stub(this.sandbox, 'publish');
-
-      sinon.stub(this.sandbox.client, 'convertStorageMetadataToResource').returns(resource);
-
-      this.module._onMetadataSuccess();
-
-      assert.called(target);
-      assert.calledWith(target, "resource:uploaded", resource);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/notify.spec.js b/ckan/public-bs2/base/test/spec/notify.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/notify.spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.notify()', function () {
-  beforeEach(function () {
-    this.element = jQuery('<div />');
-    this.fixture.append(this.element);
-
-    ckan.notify.el = this.element;
-  });
-
-  it('should append a notification to the element', function () {
-    ckan.notify('test');
-    assert.equal(this.element.children().length, 1, 'should be one child');
-    ckan.notify('test');
-    assert.equal(this.element.children().length, 2, 'should be two children');
-  });
-
-  it('should append a notification title', function () {
-    ckan.notify('test');
-    assert.equal(this.element.find('strong').text(), 'test');
-  });
-
-  it('should append a notification body', function () {
-    ckan.notify('test', 'this is a message');
-    assert.equal(this.element.find('span').text(), 'this is a message');
-  });
-
-  it('should escape all content', function () {
-    ckan.notify('<script>', '<script>');
-    assert.equal(this.element.find('strong').html(), '&lt;script&gt;');
-    assert.equal(this.element.find('span').html(), '&lt;script&gt;');
-  });
-
-  it('should default the class to "alert-error"', function () {
-    ckan.notify('test');
-    assert.ok(this.element.find('.alert').hasClass('alert-error'));
-  });
-
-  it('should allow a type to be provided', function () {
-    ckan.notify('test', '', 'info');
-    assert.ok(this.element.find('.alert').hasClass('alert-info'));
-  });
-
-  it('should add itself to the ckan.sandbox()', function () {
-    assert.equal(ckan.sandbox().notify, ckan.notify);
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.date-helpers.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.date-helpers.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.date-helpers.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('jQuery.date', function () {
-  beforeEach(function () {
-    this.now = new Date();
-    this.now.setTime(0);
-
-    this.clock = sinon.useFakeTimers(this.now.getTime());
-  });
-
-  afterEach(function () {
-    this.clock.restore();
-  });
-
-  describe('jQuery.date.format()', function () {
-    it('should format the date based on the string provided', function () {
-      var target = jQuery.date.format('yyyy-MM-dd', this.now);
-      assert.equal(target, '1970-01-01');
-    });
-
-    it('should use the current time if none provided', function () {
-      var target = jQuery.date.format('yyyy/MM/dd');
-      assert.equal(target, '1970/01/01');
-    });
-  });
-
-  describe('jQuery.date.toISOString()', function () {
-    it('should output an ISO8601 compatible string', function () {
-      var target = jQuery.date.toISOString(this.now);
-      assert.equal(target, '1970-01-01T00:00:00.000Z');
-    });
-
-    it('should use the current time if none provided', function () {
-      var target = jQuery.date.toISOString();
-      assert.equal(target, '1970-01-01T00:00:00.000Z');
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.form-warning.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.form-warning.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.form-warning.spec.js
+++ /dev/null
@@ -1,42 +0,0 @@
-describe('jQuery.incompleteFormWarning()', function () {
-  beforeEach(function () {
-    this.el = jQuery('<form />').appendTo(this.fixture);
-    this.el.on('submit', false);
-
-    this.input1 = jQuery('<input name="input1" value="a" />').appendTo(this.el);
-    this.input2 = jQuery('<input name="input2" value="b" />').appendTo(this.el);
-
-    this.el.incompleteFormWarning('my message');
-
-    this.on = sinon.stub(jQuery.fn, 'on');
-    this.off = sinon.stub(jQuery.fn, 'off');
-  });
-
-  afterEach(function () {
-    this.on.restore();
-    this.off.restore();
-  });
-
-  it('should bind a beforeunload event when the form changes', function () {
-    this.input1.val('c');
-    this.el.change();
-
-    assert.called(this.on);
-  });
-
-  it('should unbind a beforeunload event when a form returns to the original state', function () {
-    this.input1.val('c');
-    this.el.change();
-
-    this.input1.val('a');
-    this.el.change();
-
-    assert.called(this.off); 
-  });
-
-  it('should unbind the beforeunload event when the form is submitted', function () {
-    this.el.submit();
-
-    assert.called(this.off); 
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.inherit.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.inherit.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.inherit.spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('jQuery.inherit()', function () {
-  beforeEach(function () {
-    this.MyClass = function MyClass() {};
-    this.MyClass.static = function () {};
-    this.MyClass.prototype.method = function () {};
-  });
-
-  it('should create a subclass of the constructor provided', function () {
-    var target = new (jQuery.inherit(this.MyClass))();
-    assert.isTrue(target instanceof this.MyClass);
-  });
-
-  it('should set the childs prototype object', function () {
-    var target = new (jQuery.inherit(this.MyClass))();
-    assert.isFunction(target.method);
-  });
-
-  it('should copy over the childs static properties', function () {
-    var Target = jQuery.inherit(this.MyClass);
-    assert.isFunction(Target.static);
-  });
-
-  it('should allow instance properties to be overridden', function () {
-    function method() {}
-
-    var target = new (jQuery.inherit(this.MyClass, {method: method}))();
-    assert.equal(target.method, method);
-  });
-
-  it('should allow static properties to be overridden', function () {
-    function staticmethod() {}
-
-    var Target = jQuery.inherit(this.MyClass, {}, {static: staticmethod});
-    assert.equal(Target.static, staticmethod);
-  });
-
-  it('should allow a custom constructor to be provided', function () {
-    var MyConstructor = sinon.spy();
-    var Target = jQuery.inherit(this.MyClass, {constructor: MyConstructor});
-
-    new Target();
-
-    sinon.assert.called(MyConstructor);
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.proxy-all.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.proxy-all.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.proxy-all.spec.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*globals describe it beforeEach afterEach jQuery sinon assert */
-describe('jQuery.proxyAll(obj, args...)', function () {
-  beforeEach(function () {
-    this.proxy = sinon.stub(jQuery, 'proxy').returns(function proxied() {});
-    this.target = {
-      prop1: '',
-      method1: function method1() {},
-      method2: function method2() {},
-      method3: function method3() {}
-    };
-
-    this.cloned = jQuery.extend({}, this.target);
-  });
-
-  afterEach(function () {
-    this.proxy.restore();
-  });
-
-  it('should bind the methods provided to the object', function () {
-    jQuery.proxyAll(this.target, 'method1', 'method2');
-
-    assert.called(this.proxy);
-
-    assert.calledWith(this.proxy, this.cloned.method1, this.target);
-    assert.calledWith(this.proxy, this.cloned.method2, this.target);
-    assert.neverCalledWith(this.proxy, this.cloned.method3, this.target);
-  });
-
-  it('should allow regular expressions to be provided', function () {
-    jQuery.proxyAll(this.target, /method[1-2]/);
-
-    assert.called(this.proxy);
-
-    assert.calledWith(this.proxy, this.cloned.method1, this.target);
-    assert.calledWith(this.proxy, this.cloned.method2, this.target);
-    assert.neverCalledWith(this.proxy, this.cloned.method3, this.target);
-  });
-
-  it('should skip properties that are not functions', function () {
-    jQuery.proxyAll(this.target, 'prop1');
-    assert.notCalled(this.proxy);
-  });
-
-  it('should not bind function more than once', function () {
-    jQuery.proxyAll(this.target, 'method1');
-    jQuery.proxyAll(this.target, 'method1');
-
-    assert.calledOnce(this.proxy);
-  });
-
-  it('should not bind function more than once if the method name is passed twice', function () {
-    jQuery.proxyAll(this.target, 'method1', 'method1');
-
-    assert.calledOnce(this.proxy);
-  });
-
-  it('should return the first argument', function () {
-    assert.equal(jQuery.proxyAll(this.target), this.target);
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.slug-preview.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.slug-preview.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.slug-preview.spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*globals describe it assert jQuery*/
-describe('jQuery.fn.slugPreview()', function () {
-  beforeEach(function () {
-    this.element = jQuery('<div><input /></div>');
-  });
-
-  it('should return the preview element', function () {
-    var target = this.element.slugPreview();
-    assert.ok(target.hasClass('slug-preview'));
-  });
-
-  it('should restore the stack when .end() is called', function () {
-    var target = this.element.slugPreview();
-    assert.ok(target.end() === this.element);
-  });
-
-  it('should allow a prefix to be provided', function () {
-    var target = this.element.slugPreview({prefix: 'prefix'});
-    assert.equal(target.find('.slug-preview-prefix').text(), 'prefix');
-  });
-
-  it('should allow a placeholder to be provided', function () {
-    var target = this.element.slugPreview({placeholder: 'placeholder'});
-    assert.equal(target.find('.slug-preview-value').text(), 'placeholder');
-  });
-
-  it('should allow translations for strings to be provided', function () {
-    var target = this.element.slugPreview({
-      i18n: {'Edit': 'translated'}
-    });
-    assert.equal(target.find('button').text(), 'translated');
-  });
-
-  it('should set preview value to the initial value of the input', function () {
-    var input = this.element.find('input').val('initial');
-    var target = this.element.slugPreview();
-
-    assert.equal(target.find('.slug-preview-value').text(), 'initial');
-  });
-
-  it('should update the preview value when the target input changes', function () {
-    var target = this.element.slugPreview();
-    var input = this.element.find('input').val('initial');
-
-    input.val('updated').change();
-    assert.equal(target.find('.slug-preview-value').text(), 'updated');
-  });
-
-  it('should hide the original element', function () {
-    var target = this.element.slugPreview();
-    assert.ok(this.element.css('display') === 'none');
-  });
-
-  it('should show the original element when Edit is clicked', function () {
-    var target = this.element.slugPreview();
-    target.find('button').click();
-    assert.ok(this.element.css('display') === '');
-  });
-
-  it('should hide the preview element when Edit is clicked', function () {
-    var target = this.element.slugPreview();
-    target.find('button').click();
-    assert.ok(target.css('display') === 'none');
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.slug.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.slug.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.slug.spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*globals beforeEach describe it assert jQuery*/
-describe('jQuery.fn.slug()', function () {
-  beforeEach(function () {
-    this.input = jQuery('<input />').slug();
-    this.fixture.append(this.input);
-  });
-
-  it('should slugify and append the pressed key', function () {
-    var e = jQuery.Event('keypress', {charCode: 97 /* a */});
-    this.input.trigger(e);
-
-    assert.equal(this.input.val(), 'a', 'append an "a"');
-
-    e = jQuery.Event('keypress', {charCode: 38 /* & */});
-    this.input.trigger(e);
-
-    assert.equal(this.input.val(), 'a-', 'append an "-"');
-  });
-
-  it('should do nothing if a non character key is pressed', function () {
-    var e = jQuery.Event('keypress', {charCode: 0});
-    this.input.val('some other string').trigger(e);
-
-    assert.equal(this.input.val(), 'some other string');
-  });
-
-  it('should slugify the input contents on "blur" and "change" events', function () {
-    this.input.val('apples & pears').trigger(jQuery.Event('blur'));
-    assert.equal(this.input.val(), 'apples-pears', 'on blur');
-
-    this.input.val('apples & pears').trigger(jQuery.Event('change'));
-    assert.equal(this.input.val(), 'apples-pears', 'on change');
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/plugins/jquery.url-helpers.spec.js b/ckan/public-bs2/base/test/spec/plugins/jquery.url-helpers.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/plugins/jquery.url-helpers.spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*globals describe it assert jQuery*/
-describe('jQuery.url', function () {
-  describe('.escape()', function () {
-    it('should escape special characters', function () {
-      var target = jQuery.url.escape('&<>=?#/');
-      assert.equal(target, '%26%3C%3E%3D%3F%23%2F');
-    });
-
-    it('should convert spaces to + rather than %20', function () {
-      var target = jQuery.url.escape(' ');
-      assert.equal(target, '+');
-    });
-  });
-
-  describe('.slugify()', function () {
-    it('should replace spaces with hyphens', function () {
-      var target = jQuery.url.slugify('apples and pears');
-      assert.equal(target, 'apples-and-pears');
-    });
-
-    it('should lowecase all characters', function () {
-      var target = jQuery.url.slugify('APPLES AND PEARS');
-      assert.equal(target, 'apples-and-pears');
-    });
-
-    it('should convert unknown characters to hyphens', function () {
-      var target = jQuery.url.slugify('apples & pears');
-      assert.equal(target, 'apples-pears');
-    });
-
-    it('should nomalise hyphens', function () {
-      var target = jQuery.url.slugify('apples---pears');
-      assert.equal(target, 'apples-pears', 'remove duplicate hyphens');
-
-      target = jQuery.url.slugify('--apples-pears');
-      assert.equal(target, 'apples-pears', 'strip preceding hyphens');
-
-      target = jQuery.url.slugify('apples-pears--');
-      assert.equal(target, 'apples-pears', 'strip trailing hyphens');
-    });
-
-    it('should try and asciify unicode characters', function () {
-      var target = jQuery.url.slugify('éåøç');
-      assert.equal(target, 'eaoc');
-    });
-
-    it('should allow underscore characters', function() {
-      var target = jQuery.url.slugify('apples_pears');
-      assert.equal(target, 'apples_pears');
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/pubsub.spec.js b/ckan/public-bs2/base/test/spec/pubsub.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/pubsub.spec.js
+++ /dev/null
@@ -1,92 +0,0 @@
-describe('ckan.pubsub', function () {
-  beforeEach(function () {
-    ckan.pubsub.events = jQuery({});
-    ckan.pubsub.queue = [];
-  });
-
-  describe('.enqueue()', function () {
-    beforeEach(function () {
-      this.target = sinon.spy();
-    });
-
-    it('should defer callbacks for published events until later', function () {
-      ckan.pubsub.subscribe('change', this.target);
-      ckan.pubsub.enqueue();
-      ckan.pubsub.publish('change');
-
-      assert.notCalled(this.target);
-    });
-
-    it('should add the published calls to the .queue', function () {
-      var queue = ckan.pubsub.queue;
-
-      ckan.pubsub.enqueue();
-
-      ckan.pubsub.publish('change');
-      assert.equal(queue.length, 1);
-
-      ckan.pubsub.publish('change');
-      assert.equal(queue.length, 2);
-
-      ckan.pubsub.publish('change');
-      assert.equal(queue.length, 3);
-    });
-  });
-
-  describe('.dequeue()', function () {
-    beforeEach(function () {
-      ckan.pubsub.queue = [
-        ['change'],
-        ['change', 'arg1', 'arg2'],
-        ['update', 'arg1']
-      ];
-
-      this.target1 = sinon.spy();
-      this.target2 = sinon.spy();
-      this.target3 = sinon.spy();
-
-      ckan.pubsub.subscribe('change', this.target1);
-      ckan.pubsub.subscribe('change', this.target2);
-      ckan.pubsub.subscribe('update', this.target3);
-    });
-
-    it('should publish all queued callbacks', function () {
-      ckan.pubsub.dequeue();
-
-      assert.calledTwice(this.target1);
-      assert.calledWith(this.target1, 'arg1', 'arg2');
-
-      assert.calledTwice(this.target2);
-      assert.calledWith(this.target2, 'arg1', 'arg2');
-
-      assert.calledOnce(this.target3);
-    });
-
-    it('should set the queue to null to allow new events to be published', function () {
-      ckan.pubsub.dequeue();
-      assert.isNull(ckan.pubsub.queue);
-    });
-
-    it('should not block new events from being published', function () {
-      var pubsub = ckan.pubsub;
-
-      var second = sinon.spy();
-      var third  = sinon.spy();
-
-      pubsub.enqueue();
-      pubsub.subscribe('first', function () {
-        pubsub.publish('third');
-      });
-      pubsub.subscribe('second', second);
-      pubsub.subscribe('third', third);
-
-      pubsub.publish('first');
-      pubsub.publish('second');
-
-      pubsub.dequeue();
-
-      assert.called(second);
-      assert.called(third);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/spec/sandbox.spec.js b/ckan/public-bs2/base/test/spec/sandbox.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/sandbox.spec.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
-describe('ckan.sandbox()', function () {
-  it('should create an instance of Sandbox', function () {
-    var target = sinon.stub(ckan.sandbox, 'Sandbox');
-    ckan.sandbox();
-    sinon.assert.called(target);
-    target.restore();
-  });
-
-  it('should pass in sandbox.callbacks', function () {
-    var target = sinon.stub(ckan.sandbox, 'Sandbox');
-    ckan.sandbox();
-    sinon.assert.calledWith(target, ckan.sandbox.callbacks);
-    target.restore();
-  });
-
-  describe('Sandbox()', function () {
-    var Sandbox = ckan.sandbox.Sandbox;
-
-    beforeEach(function () {
-    });
-
-    it('should call each callback provided with itself', function () {
-      var callbacks = [sinon.spy(), sinon.spy(), sinon.spy()];
-
-      var target = new Sandbox(callbacks);
-
-      jQuery.each(callbacks, function () {
-        sinon.assert.called(this);
-        sinon.assert.calledWith(this, target);
-      });
-    });
-
-    describe('.ajax()', function () {
-      it('should be an alias for the jQuery.ajax() method', function () {
-        var target = new Sandbox();
-        assert.strictEqual(target.ajax, jQuery.ajax);
-      });
-    });
-
-    describe('.jQuery()', function () {
-      it('should be a reference to jQuery', function () {
-        var target = new Sandbox();
-        assert.ok(target.jQuery === jQuery);
-      });
-    });
-
-    describe('.body', function () {
-      it('should be a jQuery wrapped body object', function () {
-        var target = new Sandbox();
-        assert.ok(target.body instanceof jQuery);
-        assert.ok(target.body[0] === window.document.body);
-      });
-    });
-
-    describe('.location', function () {
-      it('should be a reference to window.location', function () {
-        var target = new Sandbox();
-        assert.ok(target.location === window.location);
-      });
-    });
-
-    describe('.window', function () {
-      it('should be a reference to window', function () {
-        var target = new Sandbox();
-        assert.ok(target.window === window);
-      });
-    });
-
-    describe('.i18n', function () {
-      it('should be available while being deprecated', function () {
-        var target = new Sandbox();
-        assert.equal(target.i18n, ckan.i18n);
-      });
-    });
-
-    describe('.translate', function () {
-      it('should be available while being deprecated', function () {
-        var target = new Sandbox();
-        assert.equal(target.translate, ckan.i18n.translate);
-      });
-    });
-  });
-
-  describe('sandbox.extend()', function () {
-    it('should extend the Sandbox.prototype with properties', function () {
-      var method = sinon.spy();
-
-      ckan.sandbox.extend({method: method});
-
-      assert.equal(ckan.sandbox().method, method);
-    });
-  });
-
-  describe('sandbox.setup()', function () {
-    it('should register a function to be called when the sandbox is initialized', function () {
-      var target = sinon.spy();
-
-      ckan.sandbox.setup(target);
-      ckan.sandbox();
-
-      sinon.assert.called(target);
-    });
-
-    it('should throw an error if a non function is provided', function () {
-      assert.throws(function () {
-        ckan.sandbox.setup('not a function');
-      });
-    });
-  });
-
-});
diff --git a/ckan/public-bs2/base/test/spec/view-filters.spec.js b/ckan/public-bs2/base/test/spec/view-filters.spec.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/spec/view-filters.spec.js
+++ /dev/null
@@ -1,233 +0,0 @@
-describe('ckan.views.filters', function(){
-  var filters = ckan.views.filters,
-      setLocationHrefSpy;
-
-  function _currentHref() {
-    return setLocationHrefSpy.args[setLocationHrefSpy.args.length-1][0];
-  }
-
-  beforeEach(function() {
-    filters._initialize('');
-    setLocationHrefSpy = sinon.spy();
-    filters._setLocationHref = setLocationHrefSpy;
-  });
-
-  describe('#initialization', function() {
-    it('should clear the filters on subsequent calls', function() {
-      filters._initialize('?filters=country:Brazil');
-      assert.deepEqual(['Brazil'], filters.get('country'));
-      filters._initialize('');
-      assert.equal(undefined, filters.get('country'));
-    });
-
-    it('should work with multiple filters', function() {
-      var expectedFilters = {
-        country: ['Brazil'],
-        state: ['Paraiba']
-      };
-
-      filters._initialize('?filters=country:Brazil|state:Paraiba');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should work with multiple values for the same filter', function() {
-      var expectedFilters = {
-        country: ['Brazil', 'Argentina'],
-        state: ['Paraiba']
-      };
-
-      filters._initialize('?filters=country:Brazil|state:Paraiba|country:Argentina');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should keep the order defined in the query string', function() {
-      var expectedFiltersSorted = {
-            country: ['Argentina', 'Brazil']
-          },
-          expectedFiltersReverse = {
-            country: ['Brazil', 'Argentina']
-          };
-
-      filters._initialize('?filters=country:Argentina|country:Brazil');
-      assert.deepEqual(expectedFiltersSorted, filters.get());
-
-      filters._initialize('?filters=country:Brazil|country:Argentina');
-      assert.deepEqual(expectedFiltersReverse, filters.get());
-    });
-
-    it('should work with a single numeric filter', function() {
-      var expectedFilters = {
-            year: ['2014']
-          };
-
-      filters._initialize('?filters=year:2014');
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should work with quoted filters', function() {
-      var expectedFilters = {
-            country: ['"Brazil"']
-          };
-
-      filters._initialize('?filters=country:"Brazil"');
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should work with filters with colons', function() {
-      var expectedFilters = {
-            time: ['11:00', '']
-          };
-
-      filters._initialize('?filters=time:11:00|time:');
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-  });
-
-  describe('#get', function(){
-    it('should return all filters if called without params', function(){
-      var expectedFilters = {
-        country: ['Brazil']
-      };
-
-      filters._initialize('?filters=country:Brazil');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should return the requested filter field', function(){
-      var countryFilter;
-
-      filters._initialize('?filters=country:Brazil');
-
-      countryFilter = filters.get('country');
-
-      assert.equal(1, countryFilter.length);
-      assert.equal('Brazil', countryFilter[0]);
-    });
-
-    it('should return an empty object if there\'re no filters', function(){
-      filters._initialize('');
-
-      assert.deepEqual({}, filters.get());
-    });
-
-    it('should return undefined if there\'s no filter with the requested field', function(){
-      var cityFilter;
-      filters._initialize('?filters=country:Brazil');
-
-      cityFilter = filters.get('city');
-
-      assert.equal(undefined, cityFilter);
-    });
-  });
-
-  describe('#set', function(){
-    it('should set the filters', function(){
-      var expectedFilters = {
-        country: 'Brazil'
-      };
-
-      filters.set('country', 'Brazil');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should update the url', function(){
-      var expectedSearch = '?filters=country%3ABrazil%7Ccountry%3AArgentina' +
-                           '%7Cindicator%3Ahappiness';
-
-      filters.set('country', ['Brazil', 'Argentina']);
-      filters.set('indicator', 'happiness');
-
-      assert.include(_currentHref(), expectedSearch);
-    });
-  });
-
-  describe('#setAndRedirectTo', function(){
-    it('should set the filters', function(){
-      var url = 'http://www.ckan.org',
-          expectedFilters = {
-            country: 'Brazil'
-          };
-
-      filters.setAndRedirectTo('country', 'Brazil', 'http://www.ckan.org');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should update the url', function(){
-      var url = 'http://www.ckan.org',
-          expectedSearch = '?filters=country%3ABrazil%7Ccountry%3AArgentina' +
-                           '%7Cindicator%3Ahappiness';
-
-      filters.setAndRedirectTo('country', ['Brazil', 'Argentina'], url);
-      filters.setAndRedirectTo('indicator', 'happiness', url);
-
-      assert.include(_currentHref(), expectedSearch);
-    });
-
-    it('should keep the original url\'s query params', function(){
-      var url = 'http://www.ckan.org/?id=42',
-          expectedSearch = '?id=42&filters=country%3ABrazil%7Ccountry%3AArgentina' +
-                           '%7Cindicator%3Ahappiness';
-
-      filters.setAndRedirectTo('country', ['Brazil', 'Argentina'], url);
-      filters.setAndRedirectTo('indicator', 'happiness', url);
-
-      assert.include(_currentHref(), expectedSearch);
-    });
-
-    it('should override the original url\'s filters', function(){
-      var url = 'http://www.ckan.org/?filters=country%3AEngland%7Cyear%3A2014',
-          expectedSearch = '?filters=country%3ABrazil%7Ccountry%3AArgentina' +
-                           '%7Cindicator%3Ahappiness';
-
-      filters.setAndRedirectTo('country', ['Brazil', 'Argentina'], url);
-      filters.setAndRedirectTo('indicator', 'happiness', url);
-
-      assert.include(_currentHref(), expectedSearch);
-    });
-  });
-
-  describe('#unset', function(){
-    it('should unset the filters', function(){
-      var expectedFilters = {};
-      filters.set('country', 'Brazil');
-
-      filters.unset('country', 'Brazil');
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should unset the filters when we unset every filter activated', function(){
-      var expectedFilters = {};
-      filters.set('country', ['Brazil', 'Argentina']);
-
-      filters.unset('country', ['Brazil', 'Argentina']);
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should work with arrays', function(){
-      var expectedFilters = {
-        country: ['Argentina']
-      };
-      filters.set('country', ['Brazil', 'Argentina', 'Uruguay']);
-
-      filters.unset('country', ['Brazil', 'Uruguay']);
-
-      assert.deepEqual(expectedFilters, filters.get());
-    });
-
-    it('should update the url', function(){
-      var expectedSearch = '?filters=country%3AArgentina';
-      filters.set('country', ['Brazil', 'Argentina']);
-
-      filters.unset('country', 'Brazil');
-
-      assert.include(_currentHref(), expectedSearch);
-    });
-  });
-});
diff --git a/ckan/public-bs2/base/test/vendor/chai.js b/ckan/public-bs2/base/test/vendor/chai.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/vendor/chai.js
+++ /dev/null
@@ -1,3464 +0,0 @@
-!function (name, definition) {
-  if (typeof define == 'function' && typeof define.amd  == 'object') define(definition);
-  else this[name] = definition();
-}('chai', function () {
-
-// CommonJS require()
-
-function require(p){
-    var path = require.resolve(p)
-      , mod = require.modules[path];
-    if (!mod) throw new Error('failed to require "' + p + '"');
-    if (!mod.exports) {
-      mod.exports = {};
-      mod.call(mod.exports, mod, mod.exports, require.relative(path));
-    }
-    return mod.exports;
-  }
-
-require.modules = {};
-
-require.resolve = function (path){
-    var orig = path
-      , reg = path + '.js'
-      , index = path + '/index.js';
-    return require.modules[reg] && reg
-      || require.modules[index] && index
-      || orig;
-  };
-
-require.register = function (path, fn){
-    require.modules[path] = fn;
-  };
-
-require.relative = function (parent) {
-    return function(p){
-      if ('.' != p[0]) return require(p);
-
-      var path = parent.split('/')
-        , segs = p.split('/');
-      path.pop();
-
-      for (var i = 0; i < segs.length; i++) {
-        var seg = segs[i];
-        if ('..' == seg) path.pop();
-        else if ('.' != seg) path.push(seg);
-      }
-
-      return require(path.join('/'));
-    };
-  };
-
-
-require.register("chai.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-var used = []
-  , exports = module.exports = {};
-
-/*!
- * Chai version
- */
-
-exports.version = '1.1.0';
-
-/*!
- * Primary `Assertion` prototype
- */
-
-exports.Assertion = require('./chai/assertion');
-
-/*!
- * Assertion Error
- */
-
-exports.AssertionError = require('./chai/browser/error');
-
-/*!
- * Utils for plugins (not exported)
- */
-
-var util = require('./chai/utils');
-
-/**
- * # .use(function)
- *
- * Provides a way to extend the internals of Chai
- *
- * @param {Function}
- * @returns {this} for chaining
- * @api public
- */
-
-exports.use = function (fn) {
-  if (!~used.indexOf(fn)) {
-    fn(this, util);
-    used.push(fn);
-  }
-
-  return this;
-};
-
-/*!
- * Core Assertions
- */
-
-var core = require('./chai/core/assertions');
-exports.use(core);
-
-/*!
- * Expect interface
- */
-
-var expect = require('./chai/interface/expect');
-exports.use(expect);
-
-/*!
- * Should interface
- */
-
-var should = require('./chai/interface/should');
-exports.use(should);
-
-/*!
- * Assert interface
- */
-
-var assert = require('./chai/interface/assert');
-exports.use(assert);
-
-}); // module: chai.js
-
-require.register("chai/assertion.js", function(module, exports, require){
-/*!
- * chai
- * http://chaijs.com
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/*!
- * Module dependencies.
- */
-
-var AssertionError = require('./browser/error')
-  , util = require('./utils')
-  , flag = util.flag;
-
-/*!
- * Module export.
- */
-
-module.exports = Assertion;
-
-
-/*!
- * Assertion Constructor
- *
- * Creates object for chaining.
- *
- * @api private
- */
-
-function Assertion (obj, msg, stack) {
-  flag(this, 'ssfi', stack || arguments.callee);
-  flag(this, 'object', obj);
-  flag(this, 'message', msg);
-}
-
-/*!
-  * ### Assertion.includeStack
-  *
-  * User configurable property, influences whether stack trace
-  * is included in Assertion error message. Default of false
-  * suppresses stack trace in the error message
-  *
-  *     Assertion.includeStack = true;  // enable stack on error
-  *
-  * @api public
-  */
-
-Assertion.includeStack = false;
-
-Assertion.addProperty = function (name, fn) {
-  util.addProperty(this.prototype, name, fn);
-};
-
-Assertion.addMethod = function (name, fn) {
-  util.addMethod(this.prototype, name, fn);
-};
-
-Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
-  util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
-};
-
-Assertion.overwriteProperty = function (name, fn) {
-  util.overwriteProperty(this.prototype, name, fn);
-};
-
-Assertion.overwriteMethod = function (name, fn) {
-  util.overwriteMethod(this.prototype, name, fn);
-};
-
-/*!
- * ### .assert(expression, message, negateMessage, expected, actual)
- *
- * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
- *
- * @name assert
- * @param {Philosophical} expression to be tested
- * @param {String} message to display if fails
- * @param {String} negatedMessage to display if negated expression fails
- * @param {Mixed} expected value (remember to check for negation)
- * @param {Mixed} actual (optional) will default to `this.obj`
- * @api private
- */
-
-Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual) {
-  var msg = util.getMessage(this, arguments)
-    , actual = util.getActual(this, arguments)
-    , ok = util.test(this, arguments);
-
-  if (!ok) {
-    throw new AssertionError({
-        message: msg
-      , actual: actual
-      , expected: expected
-      , stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi')
-    });
-  }
-};
-
-/*!
- * ### ._obj
- *
- * Quick reference to stored `actual` value for plugin developers.
- *
- * @api private
- */
-
-Object.defineProperty(Assertion.prototype, '_obj',
-  { get: function () {
-      return flag(this, 'object');
-    }
-  , set: function (val) {
-      flag(this, 'object', val);
-    }
-});
-
-}); // module: chai/assertion.js
-
-require.register("chai/browser/error.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-module.exports = AssertionError;
-
-function AssertionError (options) {
-  options = options || {};
-  this.message = options.message;
-  this.actual = options.actual;
-  this.expected = options.expected;
-  this.operator = options.operator;
-
-  if (options.stackStartFunction && Error.captureStackTrace) {
-    var stackStartFunction = options.stackStartFunction;
-    Error.captureStackTrace(this, stackStartFunction);
-  }
-}
-
-AssertionError.prototype = Object.create(Error.prototype);
-AssertionError.prototype.name = 'AssertionError';
-AssertionError.prototype.constructor = AssertionError;
-
-AssertionError.prototype.toString = function() {
-  return this.message;
-};
-
-}); // module: chai/browser/error.js
-
-require.register("chai/core/assertions.js", function(module, exports, require){
-/*!
- * chai
- * http://chaijs.com
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-module.exports = function (chai, _) {
-  var Assertion = chai.Assertion
-    , toString = Object.prototype.toString
-    , flag = _.flag;
-
-  /**
-   * ### Language Chains
-   *
-   * The following are provide as chainable getters to
-   * improve the readability of your assertions. They
-   * do not provide an testing capability unless they
-   * have been overwritten by a plugin.
-   *
-   * **Chains**
-   *
-   * - to
-   * - be
-   * - been
-   * - is
-   * - that
-   * - and
-   * - have
-   * - with
-   *
-   * @name language chains
-   * @api public
-   */
-
-  [ 'to', 'be', 'been'
-  , 'is', 'and', 'have'
-  , 'with', 'that' ].forEach(function (chain) {
-    Assertion.addProperty(chain, function () {
-      return this;
-    });
-  });
-
-  /**
-   * ### .not
-   *
-   * Negates any of assertions following in the chain.
-   *
-   *     expect(foo).to.not.equal('bar');
-   *     expect(goodFn).to.not.throw(Error);
-   *     expect({ foo: 'baz' }).to.have.property('foo')
-   *       .and.not.equal('bar');
-   *
-   * @name not
-   * @api public
-   */
-
-  Assertion.addProperty('not', function () {
-    flag(this, 'negate', true);
-  });
-
-  /**
-   * ### .deep
-   *
-   * Sets the `deep` flag, later used by the `equal` and
-   * `property` assertions.
-   *
-   *     expect(foo).to.deep.equal({ bar: 'baz' });
-   *     expect({ foo: { bar: { baz: 'quux' } } })
-   *       .to.have.deep.property('foo.bar.baz', 'quux');
-   *
-   * @name deep
-   * @api public
-   */
-
-  Assertion.addProperty('deep', function () {
-    flag(this, 'deep', true);
-  });
-
-  /**
-   * ### .a(type)
-   *
-   * The `a` and `an` assertions are aliases that can be
-   * used either as language chains or to assert a value's
-   * type (as revealed by `Object.prototype.toString`).
-   *
-   *     // typeof
-   *     expect('test').to.be.a('string');
-   *     expect({ foo: 'bar' }).to.be.an('object');
-   *     expect(null).to.be.a('null');
-   *     expect(undefined).to.be.an('undefined');
-   *
-   *     // language chain
-   *     expect(foo).to.be.an.instanceof(Foo);
-   *
-   * @name a
-   * @alias an
-   * @param {String} type
-   * @api public
-   */
-
-  function an(type) {
-    var obj = flag(this, 'object')
-      , klassStart = type.charAt(0).toUpperCase()
-      , klass = klassStart + type.slice(1)
-      , article = ~[ 'A', 'E', 'I', 'O', 'U' ].indexOf(klassStart) ? 'an ' : 'a ';
-
-    this.assert(
-        '[object ' + klass + ']' === toString.call(obj)
-      , 'expected #{this} to be ' + article + type
-      , 'expected #{this} not to be ' + article + type
-    );
-  }
-
-  Assertion.addChainableMethod('an', an);
-  Assertion.addChainableMethod('a', an);
-
-  /**
-   * ### .include(value)
-   *
-   * The `include` and `contain` assertions can be used as either property
-   * based language chains or as methods to assert the inclusion of an object
-   * in an array or a substring in a string. When used as language chains,
-   * they toggle the `contain` flag for the `keys` assertion.
-   *
-   *     expect([1,2,3]).to.include(2);
-   *     expect('foobar').to.contain('foo');
-   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
-   *
-   * @name include
-   * @alias contain
-   * @param {Object|String|Number} obj
-   * @api public
-   */
-
-  function includeChainingBehavior () {
-    flag(this, 'contains', true);
-  }
-
-  function include (val) {
-    var obj = flag(this, 'object')
-    this.assert(
-        ~obj.indexOf(val)
-      , 'expected #{this} to include ' + _.inspect(val)
-      , 'expected #{this} to not include ' + _.inspect(val));
-  }
-
-  Assertion.addChainableMethod('include', include, includeChainingBehavior);
-  Assertion.addChainableMethod('contain', include, includeChainingBehavior);
-
-  /**
-   * ### .ok
-   *
-   * Asserts that the target is truthy.
-   *
-   *     expect('everthing').to.be.ok;
-   *     expect(1).to.be.ok;
-   *     expect(false).to.not.be.ok;
-   *     expect(undefined).to.not.be.ok;
-   *     expect(null).to.not.be.ok;
-   *
-   * @name ok
-   * @api public
-   */
-
-  Assertion.addProperty('ok', function () {
-    this.assert(
-        flag(this, 'object')
-      , 'expected #{this} to be truthy'
-      , 'expected #{this} to be falsy');
-  });
-
-  /**
-   * ### .true
-   *
-   * Asserts that the target is `true`.
-   *
-   *     expect(true).to.be.true;
-   *     expect(1).to.not.be.true;
-   *
-   * @name true
-   * @api public
-   */
-
-  Assertion.addProperty('true', function () {
-    this.assert(
-        true === flag(this, 'object')
-      , 'expected #{this} to be true'
-      , 'expected #{this} to be false'
-      , this.negate ? false : true
-    );
-  });
-
-  /**
-   * ### .false
-   *
-   * Asserts that the target is `false`.
-   *
-   *     expect(false).to.be.false;
-   *     expect(0).to.not.be.false;
-   *
-   * @name false
-   * @api public
-   */
-
-  Assertion.addProperty('false', function () {
-    this.assert(
-        false === flag(this, 'object')
-      , 'expected #{this} to be false'
-      , 'expected #{this} to be true'
-      , this.negate ? true : false
-    );
-  });
-
-  /**
-   * ### .null
-   *
-   * Asserts that the target is `null`.
-   *
-   *     expect(null).to.be.null;
-   *     expect(undefined).not.to.be.null;
-   *
-   * @name null
-   * @api public
-   */
-
-  Assertion.addProperty('null', function () {
-    this.assert(
-        null === flag(this, 'object')
-      , 'expected #{this} to be null'
-      , 'expected #{this} not to be null'
-    );
-  });
-
-  /**
-   * ### .undefined
-   *
-   * Asserts that the target is `undefined`.
-   *
-   *      expect(undefined).to.be.undefined;
-   *      expect(null).to.not.be.undefined;
-   *
-   * @name undefined
-   * @api public
-   */
-
-  Assertion.addProperty('undefined', function () {
-    this.assert(
-        undefined === flag(this, 'object')
-      , 'expected #{this} to be undefined'
-      , 'expected #{this} not to be undefined'
-    );
-  });
-
-  /**
-   * ### .exist
-   *
-   * Asserts that the target is neither `null` nor `undefined`.
-   *
-   *     var foo = 'hi'
-   *       , bar = null
-   *       , baz;
-   *
-   *     expect(foo).to.exist;
-   *     expect(bar).to.not.exist;
-   *     expect(baz).to.not.exist;
-   *
-   * @name exist
-   * @api public
-   */
-
-  Assertion.addProperty('exist', function () {
-    this.assert(
-        null != flag(this, 'object')
-      , 'expected #{this} to exist'
-      , 'expected #{this} to not exist'
-    );
-  });
-
-
-  /**
-   * ### .empty
-   *
-   * Asserts that the target's length is `0`. For arrays, it checks
-   * the `length` property. For objects, it gets the count of
-   * enumerable keys.
-   *
-   *     expect([]).to.be.empty;
-   *     expect('').to.be.empty;
-   *     expect({}).to.be.empty;
-   *
-   * @name empty
-   * @api public
-   */
-
-  Assertion.addProperty('empty', function () {
-    var obj = flag(this, 'object')
-      , expected = obj;
-
-    if (Array.isArray(obj) || 'string' === typeof object) {
-      expected = obj.length;
-    } else if (typeof obj === 'object') {
-      expected = Object.keys(obj).length;
-    }
-
-    this.assert(
-        !expected
-      , 'expected #{this} to be empty'
-      , 'expected #{this} not to be empty'
-    );
-  });
-
-  /**
-   * ### .arguments
-   *
-   * Asserts that the target is an arguments object.
-   *
-   *     function test () {
-   *       expect(arguments).to.be.arguments;
-   *     }
-   *
-   * @name arguments
-   * @alias Arguments
-   * @api public
-   */
-
-  function checkArguments () {
-    var obj = flag(this, 'object')
-      , type = Object.prototype.toString.call(obj);
-    this.assert(
-        '[object Arguments]' === type
-      , 'expected #{this} to be arguments but got ' + type
-      , 'expected #{this} to not be arguments'
-    );
-  }
-
-  Assertion.addProperty('arguments', checkArguments);
-  Assertion.addProperty('Arguments', checkArguments);
-
-  /**
-   * ### .equal(value)
-   *
-   * Asserts that the target is strictly equal (`===`) to `value`.
-   * Alternately, if the `deep` flag is set, asserts that
-   * the target is deeply equal to `value`.
-   *
-   *     expect('hello').to.equal('hello');
-   *     expect(42).to.equal(42);
-   *     expect(1).to.not.equal(true);
-   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
-   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
-   *
-   * @name equal
-   * @alias eq
-   * @alias deep.equal
-   * @param {Mixed} value
-   * @api public
-   */
-
-  function assertEqual (val) {
-    var obj = flag(this, 'object');
-    if (flag(this, 'deep')) {
-      return this.eql(val);
-    } else {
-      this.assert(
-          val === obj
-        , 'expected #{this} to equal #{exp}'
-        , 'expected #{this} to not equal #{exp}'
-        , val
-      );
-    }
-  }
-
-  Assertion.addMethod('equal', assertEqual);
-  Assertion.addMethod('eq', assertEqual);
-
-  /**
-   * ### .eql(value)
-   *
-   * Asserts that the target is deeply equal to `value`.
-   *
-   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
-   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
-   *
-   * @name eql
-   * @param {Mixed} value
-   * @api public
-   */
-
-  Assertion.addMethod('eql', function (obj) {
-    this.assert(
-        _.eql(obj, flag(this, 'object'))
-      , 'expected #{this} to deeply equal #{exp}'
-      , 'expected #{this} to not deeply equal #{exp}'
-      , obj
-    );
-  });
-
-  /**
-   * ### .above(value)
-   *
-   * Asserts that the target is greater than `value`.
-   *
-   *     expect(10).to.be.above(5);
-   *
-   * Can also be used in conjunction with `length` to
-   * assert a minimum length. The benefit being a
-   * more informative error message than if the length
-   * was supplied directly.
-   *
-   *     expect('foo').to.have.length.above(2);
-   *     expect([ 1, 2, 3 ]).to.have.length.above(2);
-   *
-   * @name above
-   * @alias gt
-   * @alias greaterThan
-   * @param {Number} value
-   * @api public
-   */
-
-  function assertAbove (n) {
-    var obj = flag(this, 'object');
-    if (flag(this, 'doLength')) {
-      new Assertion(obj).to.have.property('length');
-      var len = obj.length;
-      this.assert(
-          len > n
-        , 'expected #{this} to have a length above #{exp} but got #{act}'
-        , 'expected #{this} to not have a length above #{exp}'
-        , n
-        , len
-      );
-    } else {
-      this.assert(
-          obj > n
-        , 'expected #{this} to be above ' + n
-        , 'expected #{this} to be below ' + n
-      );
-    }
-  }
-
-  Assertion.addMethod('above', assertAbove);
-  Assertion.addMethod('gt', assertAbove);
-  Assertion.addMethod('greaterThan', assertAbove);
-
-  /**
-   * ### .below(value)
-   *
-   * Asserts that the target is less than `value`.
-   *
-   *     expect(5).to.be.below(10);
-   *
-   * Can also be used in conjunction with `length` to
-   * assert a maximum length. The benefit being a
-   * more informative error message than if the length
-   * was supplied directly.
-   *
-   *     expect('foo').to.have.length.below(4);
-   *     expect([ 1, 2, 3 ]).to.have.length.below(4);
-   *
-   * @name below
-   * @alias lt
-   * @alias lessThan
-   * @param {Number} value
-   * @api public
-   */
-
-  function assertBelow (n) {
-    var obj = flag(this, 'object');
-    if (flag(this, 'doLength')) {
-      new Assertion(obj).to.have.property('length');
-      var len = obj.length;
-      this.assert(
-          len < n
-        , 'expected #{this} to have a length below #{exp} but got #{act}'
-        , 'expected #{this} to not have a length below #{exp}'
-        , n
-        , len
-      );
-    } else {
-      this.assert(
-          obj < n
-        , 'expected #{this} to be below ' + n
-        , 'expected #{this} to be above ' + n
-      );
-    }
-  }
-
-  Assertion.addMethod('below', assertBelow);
-  Assertion.addMethod('lt', assertBelow);
-  Assertion.addMethod('lessThan', assertBelow);
-
-  /**
-   * ### .within(start, finish)
-   *
-   * Asserts that the target is within a range.
-   *
-   *     expect(7).to.be.within(5,10);
-   *
-   * Can also be used in conjunction with `length` to
-   * assert a length range. The benefit being a
-   * more informative error message than if the length
-   * was supplied directly.
-   *
-   *     expect('foo').to.have.length.within(2,4);
-   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
-   *
-   * @name within
-   * @param {Number} start lowerbound inclusive
-   * @param {Number} finish upperbound inclusive
-   * @api public
-   */
-
-  Assertion.addMethod('within', function (start, finish) {
-    var obj = flag(this, 'object')
-      , range = start + '..' + finish;
-    if (flag(this, 'doLength')) {
-      new Assertion(obj).to.have.property('length');
-      var len = obj.length;
-      this.assert(
-          len >= start && len <= finish
-        , 'expected #{this} to have a length within ' + range
-        , 'expected #{this} to not have a length within ' + range
-      );
-    } else {
-      this.assert(
-          obj >= start && obj <= finish
-        , 'expected #{this} to be within ' + range
-        , 'expected #{this} to not be within ' + range
-      );
-    }
-  });
-
-  /**
-   * ### .instanceof(constructor)
-   *
-   * Asserts that the target is an instance of `constructor`.
-   *
-   *     var Tea = function (name) { this.name = name; }
-   *       , Chai = new Tea('chai');
-   *
-   *     expect(Chai).to.be.an.instanceof(Tea);
-   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);
-   *
-   * @name instanceof
-   * @param {Constructor} constructor
-   * @alias instanceOf
-   * @api public
-   */
-
-  function assertInstanceOf (constructor) {
-    var name = _.getName(constructor);
-    this.assert(
-        flag(this, 'object') instanceof constructor
-      , 'expected #{this} to be an instance of ' + name
-      , 'expected #{this} to not be an instance of ' + name
-    );
-  };
-
-  Assertion.addMethod('instanceof', assertInstanceOf);
-  Assertion.addMethod('instanceOf', assertInstanceOf);
-
-  /**
-   * ### .property(name, [value])
-   *
-   * Asserts that the target has a property `name`, optionally asserting that
-   * the value of that property is strictly equal to  `value`.
-   * If the `deep` flag is set, you can use dot- and bracket-notation for deep
-   * references into objects and arrays.
-   *
-   *     // simple referencing
-   *     var obj = { foo: 'bar' };
-   *     expect(obj).to.have.property('foo');
-   *     expect(obj).to.have.property('foo', 'bar');
-   *
-   *     // deep referencing
-   *     var deepObj = {
-   *         green: { tea: 'matcha' }
-   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
-   *     };
-
-   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');
-   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
-   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
-   *
-   * You can also use an array as the starting point of a `deep.property`
-   * assertion, or traverse nested arrays.
-   *
-   *     var arr = [
-   *         [ 'chai', 'matcha', 'konacha' ]
-   *       , [ { tea: 'chai' }
-   *         , { tea: 'matcha' }
-   *         , { tea: 'konacha' } ]
-   *     ];
-   *
-   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');
-   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
-   *
-   * Furthermore, `property` changes the subject of the assertion
-   * to be the value of that property from the original object. This
-   * permits for further chainable assertions on that property.
-   *
-   *     expect(obj).to.have.property('foo')
-   *       .that.is.a('string');
-   *     expect(deepObj).to.have.property('green')
-   *       .that.is.an('object')
-   *       .that.deep.equals({ tea: 'matcha' });
-   *     expect(deepObj).to.have.property('teas')
-   *       .that.is.an('array')
-   *       .with.deep.property('[2]')
-   *         .that.deep.equals({ tea: 'konacha' });
-   *
-   * @name property
-   * @alias deep.property
-   * @param {String} name
-   * @param {Mixed} value (optional)
-   * @returns value of property for chaining
-   * @api public
-   */
-
-  Assertion.addMethod('property', function (name, val) {
-    var obj = flag(this, 'object')
-      , value = flag(this, 'deep') ? _.getPathValue(name, obj) : obj[name]
-      , descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
-      , negate = flag(this, 'negate');
-
-    if (negate && undefined !== val) {
-      if (undefined === value) {
-        throw new Error(_.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
-      }
-    } else {
-      this.assert(
-          undefined !== value
-        , 'expected #{this} to have a ' + descriptor + _.inspect(name)
-        , 'expected #{this} to not have ' + descriptor + _.inspect(name));
-    }
-
-    if (undefined !== val) {
-      this.assert(
-          val === value
-        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
-        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
-        , val
-        , value
-      );
-    }
-
-    flag(this, 'object', value);
-  });
-
-
-  /**
-   * ### .ownProperty(name)
-   *
-   * Asserts that the target has an own property `name`.
-   *
-   *     expect('test').to.have.ownProperty('length');
-   *
-   * @name ownProperty
-   * @alias haveOwnProperty
-   * @param {String} name
-   * @api public
-   */
-
-  function assertOwnProperty (name) {
-    var obj = flag(this, 'object');
-    this.assert(
-        obj.hasOwnProperty(name)
-      , 'expected #{this} to have own property ' + _.inspect(name)
-      , 'expected #{this} to not have own property ' + _.inspect(name)
-    );
-  }
-
-  Assertion.addMethod('ownProperty', assertOwnProperty);
-  Assertion.addMethod('haveOwnProperty', assertOwnProperty);
-
-  /**
-   * ### .length(value)
-   *
-   * Asserts that the target's `length` property has
-   * the expected value.
-   *
-   *     expect([ 1, 2, 3]).to.have.length(3);
-   *     expect('foobar').to.have.length(6);
-   *
-   * Can also be used as a chain precursor to a value
-   * comparison for the length property.
-   *
-   *     expect('foo').to.have.length.above(2);
-   *     expect([ 1, 2, 3 ]).to.have.length.above(2);
-   *     expect('foo').to.have.length.below(4);
-   *     expect([ 1, 2, 3 ]).to.have.length.below(4);
-   *     expect('foo').to.have.length.within(2,4);
-   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
-   *
-   * @name length
-   * @alias lengthOf
-   * @param {Number} length
-   * @api public
-   */
-
-  function assertLengthChain () {
-    flag(this, 'doLength', true);
-  }
-
-  function assertLength (n) {
-    var obj = flag(this, 'object');
-    new Assertion(obj).to.have.property('length');
-    var len = obj.length;
-
-    this.assert(
-        len == n
-      , 'expected #{this} to have a length of #{exp} but got #{act}'
-      , 'expected #{this} to not have a length of #{act}'
-      , n
-      , len
-    );
-  }
-
-  Assertion.addChainableMethod('length', assertLength, assertLengthChain);
-  Assertion.addMethod('lengthOf', assertLength, assertLengthChain);
-
-  /**
-   * ### .match(regexp)
-   *
-   * Asserts that the target matches a regular expression.
-   *
-   *     expect('foobar').to.match(/^foo/);
-   *
-   * @name match
-   * @param {RegExp} RegularExpression
-   * @api public
-   */
-
-  Assertion.addMethod('match', function (re) {
-    var obj = flag(this, 'object');
-    this.assert(
-        re.exec(obj)
-      , 'expected #{this} to match ' + re
-      , 'expected #{this} not to match ' + re
-    );
-  });
-
-  /**
-   * ### .string(string)
-   *
-   * Asserts that the string target contains another string.
-   *
-   *     expect('foobar').to.have.string('bar');
-   *
-   * @name string
-   * @param {String} string
-   * @api public
-   */
-
-  Assertion.addMethod('string', function (str) {
-    var obj = flag(this, 'object');
-    new Assertion(obj).is.a('string');
-
-    this.assert(
-        ~obj.indexOf(str)
-      , 'expected #{this} to contain ' + _.inspect(str)
-      , 'expected #{this} to not contain ' + _.inspect(str)
-    );
-  });
-
-
-  /**
-   * ### .keys(key1, [key2], [...])
-   *
-   * Asserts that the target has exactly the given keys, or
-   * asserts the inclusion of some keys when using the
-   * `include` or `contain` modifiers.
-   *
-   *     expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
-   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
-   *
-   * @name keys
-   * @alias key
-   * @param {String...|Array} keys
-   * @api public
-   */
-
-  function assertKeys (keys) {
-    var obj = flag(this, 'object')
-      , str
-      , ok = true;
-
-    keys = keys instanceof Array
-      ? keys
-      : Array.prototype.slice.call(arguments);
-
-    if (!keys.length) throw new Error('keys required');
-
-    var actual = Object.keys(obj)
-      , len = keys.length;
-
-    // Inclusion
-    ok = keys.every(function(key){
-      return ~actual.indexOf(key);
-    });
-
-    // Strict
-    if (!flag(this, 'negate') && !flag(this, 'contains')) {
-      ok = ok && keys.length == actual.length;
-    }
-
-    // Key string
-    if (len > 1) {
-      keys = keys.map(function(key){
-        return _.inspect(key);
-      });
-      var last = keys.pop();
-      str = keys.join(', ') + ', and ' + last;
-    } else {
-      str = _.inspect(keys[0]);
-    }
-
-    // Form
-    str = (len > 1 ? 'keys ' : 'key ') + str;
-
-    // Have / include
-    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
-
-    // Assertion
-    this.assert(
-        ok
-      , 'expected #{this} to ' + str
-      , 'expected #{this} to not ' + str
-    );
-  }
-
-  Assertion.addMethod('keys', assertKeys);
-  Assertion.addMethod('key', assertKeys);
-
-  /**
-   * ### .throw(constructor)
-   *
-   * Asserts that the function target will throw a specific error, or specific type of error
-   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
-   * for the error's message.
-   *
-   *     var err = new ReferenceError('This is a bad function.');
-   *     var fn = function () { throw err; }
-   *     expect(fn).to.throw(ReferenceError);
-   *     expect(fn).to.throw(Error);
-   *     expect(fn).to.throw(/bad function/);
-   *     expect(fn).to.not.throw('good function');
-   *     expect(fn).to.throw(ReferenceError, /bad function/);
-   *     expect(fn).to.throw(err);
-   *     expect(fn).to.not.throw(new RangeError('Out of range.'));
-   *
-   * Please note that when a throw expectation is negated, it will check each
-   * parameter independently, starting with error constructor type. The appropriate way
-   * to check for the existence of a type of error but for a message that does not match
-   * is to use `and`.
-   *
-   *     expect(fn).to.throw(ReferenceError)
-   *        .and.not.throw(/good function/);
-   *
-   * @name throw
-   * @alias throws
-   * @alias Throw
-   * @param {ErrorConstructor} constructor
-   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
-   * @api public
-   */
-
-  function assertThrows (constructor, msg) {
-    var obj = flag(this, 'object');
-    new Assertion(obj).is.a('function');
-
-    var thrown = false
-      , desiredError = null
-      , name = null;
-
-    if (arguments.length === 0) {
-      msg = null;
-      constructor = null;
-    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
-      msg = constructor;
-      constructor = null;
-    } else if (constructor && constructor instanceof Error) {
-      desiredError = constructor;
-      constructor = null;
-      msg = null;
-    } else if (typeof constructor === 'function') {
-      name = (new constructor()).name;
-    } else {
-      constructor = null;
-    }
-
-    try {
-      obj();
-    } catch (err) {
-      // first, check desired error
-      if (desiredError) {
-        this.assert(
-            err === desiredError
-          , 'expected #{this} to throw ' + _.inspect(desiredError) + ' but ' + _.inspect(err) + ' was thrown'
-          , 'expected #{this} to not throw ' + _.inspect(desiredError)
-        );
-        return this;
-      }
-      // next, check constructor
-      if (constructor) {
-        this.assert(
-            err instanceof constructor
-          , 'expected #{this} to throw ' + name + ' but a ' + err.name + ' was thrown'
-          , 'expected #{this} to not throw ' + name );
-        if (!msg) return this;
-      }
-      // next, check message
-      if (err.message && msg && msg instanceof RegExp) {
-        this.assert(
-            msg.exec(err.message)
-          , 'expected #{this} to throw error matching ' + msg + ' but got ' + _.inspect(err.message)
-          , 'expected #{this} to throw error not matching ' + msg
-        );
-        return this;
-      } else if (err.message && msg && 'string' === typeof msg) {
-        this.assert(
-            ~err.message.indexOf(msg)
-          , 'expected #{this} to throw error including #{exp} but got #{act}'
-          , 'expected #{this} to throw error not including #{act}'
-          , msg
-          , err.message
-        );
-        return this;
-      } else {
-        thrown = true;
-      }
-    }
-
-    var expectedThrown = name ? name : desiredError ? _.inspect(desiredError) : 'an error';
-
-    this.assert(
-        thrown === true
-      , 'expected #{this} to throw ' + expectedThrown
-      , 'expected #{this} to not throw ' + expectedThrown
-    );
-  };
-
-  Assertion.addMethod('throw', assertThrows);
-  Assertion.addMethod('throws', assertThrows);
-  Assertion.addMethod('Throw', assertThrows);
-
-  /**
-   * ### .respondTo(method)
-   *
-   * Asserts that the object or class target will respond to a method.
-   *
-   *     Klass.prototype.bar = function(){};
-   *     expect(Klass).to.respondTo('bar');
-   *     expect(obj).to.respondTo('bar');
-   *
-   * To check if a constructor will respond to a static function,
-   * set the `itself` flag.
-   *
-   *    Klass.baz = function(){};
-   *    expect(Klass).itself.to.respondTo('baz');
-   *
-   * @name respondTo
-   * @param {String} method
-   * @api public
-   */
-
-  Assertion.addMethod('respondTo', function (method) {
-    var obj = flag(this, 'object')
-      , itself = flag(this, 'itself')
-      , context = ('function' === typeof obj && !itself)
-        ? obj.prototype[method]
-        : obj[method];
-
-    this.assert(
-        'function' === typeof context
-      , 'expected #{this} to respond to ' + _.inspect(method)
-      , 'expected #{this} to not respond to ' + _.inspect(method)
-    );
-  });
-
-  /**
-   * ### .itself
-   *
-   * Sets the `itself` flag, later used by the `respondTo` assertion.
-   *
-   *    function Foo() {}
-   *    Foo.bar = function() {}
-   *    Foo.prototype.baz = function() {}
-   *
-   *    expect(Foo).itself.to.respondTo('bar');
-   *    expect(Foo).itself.not.to.respondTo('baz');
-   *
-   * @name itself
-   * @api public
-   */
-
-  Assertion.addProperty('itself', function () {
-    flag(this, 'itself', true);
-  });
-
-  /**
-   * ### .satisfy(method)
-   *
-   * Asserts that the target passes a given truth test.
-   *
-   *     expect(1).to.satisfy(function(num) { return num > 0; });
-   *
-   * @name satisfy
-   * @param {Function} matcher
-   * @api public
-   */
-
-  Assertion.addMethod('satisfy', function (matcher) {
-    var obj = flag(this, 'object');
-    this.assert(
-        matcher(obj)
-      , 'expected #{this} to satisfy ' + _.inspect(matcher)
-      , 'expected #{this} to not satisfy' + _.inspect(matcher)
-      , this.negate ? false : true
-      , matcher(obj)
-    );
-  });
-
-  /**
-   * ### .closeTo(expected, delta)
-   *
-   * Asserts that the target is equal `expected`, to within a +/- `delta` range.
-   *
-   *     expect(1.5).to.be.closeTo(1, 0.5);
-   *
-   * @name closeTo
-   * @param {Number} expected
-   * @param {Number} delta
-   * @api public
-   */
-
-  Assertion.addMethod('closeTo', function (expected, delta) {
-    var obj = flag(this, 'object');
-    this.assert(
-        Math.abs(obj - expected) <= delta
-      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
-      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
-    );
-  });
-
-};
-
-}); // module: chai/core/assertions.js
-
-require.register("chai/interface/assert.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-
-module.exports = function (chai, util) {
-
-  /*!
-   * Chai dependencies.
-   */
-
-  var Assertion = chai.Assertion
-    , flag = util.flag;
-
-  /*!
-   * Module export.
-   */
-
-  /**
-   * ### assert(expression, message)
-   *
-   * Write your own test expressions.
-   *
-   *     assert('foo' !== 'bar', 'foo is not bar');
-   *     assert(Array.isArray([]), 'empty arrays are arrays');
-   *
-   * @param {Mixed} expression to test for truthiness
-   * @param {String} message to display on error
-   * @name assert
-   * @api public
-   */
-
-  var assert = chai.assert = function (express, errmsg) {
-    var test = new Assertion(null);
-    test.assert(
-        express
-      , errmsg
-      , '[ negation message unavailable ]'
-    );
-  };
-
-  /**
-   * ### .fail(actual, expected, [message], [operator])
-   *
-   * Throw a failure. Node.js `assert` module-compatible.
-   *
-   * @name fail
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @param {String} operator
-   * @api public
-   */
-
-  assert.fail = function (actual, expected, message, operator) {
-    throw new chai.AssertionError({
-        actual: actual
-      , expected: expected
-      , message: message
-      , operator: operator
-      , stackStartFunction: assert.fail
-    });
-  };
-
-  /**
-   * ### .ok(object, [message])
-   *
-   * Asserts that `object` is truthy.
-   *
-   *     assert.ok('everything', 'everything is ok');
-   *     assert.ok(false, 'this will fail');
-   *
-   * @name ok
-   * @param {Mixed} object to test
-   * @param {String} message
-   * @api public
-   */
-
-  assert.ok = function (val, msg) {
-    new Assertion(val, msg).is.ok;
-  };
-
-  /**
-   * ### .equal(actual, expected, [message])
-   *
-   * Asserts non-strict equality (`==`) of `actual` and `expected`.
-   *
-   *     assert.equal(3, '3', '== coerces values to strings');
-   *
-   * @name equal
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.equal = function (act, exp, msg) {
-    var test = new Assertion(act, msg);
-
-    test.assert(
-        exp == flag(test, 'object')
-      , 'expected #{this} to equal #{exp}'
-      , 'expected #{this} to not equal #{act}'
-      , exp
-      , act
-    );
-  };
-
-  /**
-   * ### .notEqual(actual, expected, [message])
-   *
-   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
-   *
-   *     assert.notEqual(3, 4, 'these numbers are not equal');
-   *
-   * @name notEqual
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notEqual = function (act, exp, msg) {
-    var test = new Assertion(act, msg);
-
-    test.assert(
-        exp != flag(test, 'object')
-      , 'expected #{this} to not equal #{exp}'
-      , 'expected #{this} to equal #{act}'
-      , exp
-      , act
-    );
-  };
-
-  /**
-   * ### .strictEqual(actual, expected, [message])
-   *
-   * Asserts strict equality (`===`) of `actual` and `expected`.
-   *
-   *     assert.strictEqual(true, true, 'these booleans are strictly equal');
-   *
-   * @name strictEqual
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.strictEqual = function (act, exp, msg) {
-    new Assertion(act, msg).to.equal(exp);
-  };
-
-  /**
-   * ### .notStrictEqual(actual, expected, [message])
-   *
-   * Asserts strict inequality (`!==`) of `actual` and `expected`.
-   *
-   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');
-   *
-   * @name notStrictEqual
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notStrictEqual = function (act, exp, msg) {
-    new Assertion(act, msg).to.not.equal(exp);
-  };
-
-  /**
-   * ### .deepEqual(actual, expected, [message])
-   *
-   * Asserts that `actual` is deeply equal to `expected`.
-   *
-   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });
-   *
-   * @name deepEqual
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.deepEqual = function (act, exp, msg) {
-    new Assertion(act, msg).to.eql(exp);
-  };
-
-  /**
-   * ### .notDeepEqual(actual, expected, [message])
-   *
-   * Assert that `actual` is not deeply equal to `expected`.
-   *
-   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
-   *
-   * @name notDeepEqual
-   * @param {Mixed} actual
-   * @param {Mixed} expected
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notDeepEqual = function (act, exp, msg) {
-    new Assertion(act, msg).to.not.eql(exp);
-  };
-
-  /**
-   * ### .isTrue(value, [message])
-   *
-   * Asserts that `value` is true.
-   *
-   *     var teaServed = true;
-   *     assert.isTrue(teaServed, 'the tea has been served');
-   *
-   * @name isTrue
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isTrue = function (val, msg) {
-    new Assertion(val, msg).is['true'];
-  };
-
-  /**
-   * ### .isFalse(value, [message])
-   *
-   * Asserts that `value` is false.
-   *
-   *     var teaServed = false;
-   *     assert.isFalse(teaServed, 'no tea yet? hmm...');
-   *
-   * @name isFalse
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isFalse = function (val, msg) {
-    new Assertion(val, msg).is['false'];
-  };
-
-  /**
-   * ### .isNull(value, [message])
-   *
-   * Asserts that `value` is null.
-   *
-   *     assert.isNull(err, 'there was no error');
-   *
-   * @name isNull
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNull = function (val, msg) {
-    new Assertion(val, msg).to.equal(null);
-  };
-
-  /**
-   * ### .isNotNull(value, [message])
-   *
-   * Asserts that `value` is not null.
-   *
-   *     var tea = 'tasty chai';
-   *     assert.isNotNull(tea, 'great, time for tea!');
-   *
-   * @name isNotNull
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotNull = function (val, msg) {
-    new Assertion(val, msg).to.not.equal(null);
-  };
-
-  /**
-   * ### .isUndefined(value, [message])
-   *
-   * Asserts that `value` is `undefined`.
-   *
-   *     var tea;
-   *     assert.isUndefined(tea, 'no tea defined');
-   *
-   * @name isUndefined
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isUndefined = function (val, msg) {
-    new Assertion(val, msg).to.equal(undefined);
-  };
-
-  /**
-   * ### .isDefined(value, [message])
-   *
-   * Asserts that `value` is not `undefined`.
-   *
-   *     var tea = 'cup of chai';
-   *     assert.isDefined(tea, 'tea has been defined');
-   *
-   * @name isUndefined
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isDefined = function (val, msg) {
-    new Assertion(val, msg).to.not.equal(undefined);
-  };
-
-  /**
-   * ### .isFunction(value, [message])
-   *
-   * Asserts that `value` is a function.
-   *
-   *     function serveTea() { return 'cup of tea'; };
-   *     assert.isFunction(serveTea, 'great, we can have tea now');
-   *
-   * @name isFunction
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isFunction = function (val, msg) {
-    new Assertion(val, msg).to.be.a('function');
-  };
-
-  /**
-   * ### .isNotFunction(value, [message])
-   *
-   * Asserts that `value` is _not_ a function.
-   *
-   *     var serveTea = [ 'heat', 'pour', 'sip' ];
-   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');
-   *
-   * @name isNotFunction
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotFunction = function (val, msg) {
-    new Assertion(val, msg).to.not.be.a('function');
-  };
-
-  /**
-   * ### .isObject(value, [message])
-   *
-   * Asserts that `value` is an object (as revealed by
-   * `Object.prototype.toString`).
-   *
-   *     var selection = { name: 'Chai', serve: 'with spices' };
-   *     assert.isObject(selection, 'tea selection is an object');
-   *
-   * @name isObject
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isObject = function (val, msg) {
-    new Assertion(val, msg).to.be.a('object');
-  };
-
-  /**
-   * ### .isNotObject(value, [message])
-   *
-   * Asserts that `value` is _not_ an object.
-   *
-   *     var selection = 'chai'
-   *     assert.isObject(selection, 'tea selection is not an object');
-   *     assert.isObject(null, 'null is not an object');
-   *
-   * @name isNotObject
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotObject = function (val, msg) {
-    new Assertion(val, msg).to.not.be.a('object');
-  };
-
-  /**
-   * ### .isArray(value, [message])
-   *
-   * Asserts that `value` is an array.
-   *
-   *     var menu = [ 'green', 'chai', 'oolong' ];
-   *     assert.isArray(menu, 'what kind of tea do we want?');
-   *
-   * @name isArray
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isArray = function (val, msg) {
-    new Assertion(val, msg).to.be.an('array');
-  };
-
-  /**
-   * ### .isNotArray(value, [message])
-   *
-   * Asserts that `value` is _not_ an array.
-   *
-   *     var menu = 'green|chai|oolong';
-   *     assert.isNotArray(menu, 'what kind of tea do we want?');
-   *
-   * @name isNotArray
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotArray = function (val, msg) {
-    new Assertion(val, msg).to.not.be.an('array');
-  };
-
-  /**
-   * ### .isString(value, [message])
-   *
-   * Asserts that `value` is a string.
-   *
-   *     var teaOrder = 'chai';
-   *     assert.isString(teaOrder, 'order placed');
-   *
-   * @name isString
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isString = function (val, msg) {
-    new Assertion(val, msg).to.be.a('string');
-  };
-
-  /**
-   * ### .isNotString(value, [message])
-   *
-   * Asserts that `value` is _not_ a string.
-   *
-   *     var teaOrder = 4;
-   *     assert.isNotString(teaOrder, 'order placed');
-   *
-   * @name isNotString
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotString = function (val, msg) {
-    new Assertion(val, msg).to.not.be.a('string');
-  };
-
-  /**
-   * ### .isNumber(value, [message])
-   *
-   * Asserts that `value` is a number.
-   *
-   *     var cups = 2;
-   *     assert.isNumber(cups, 'how many cups');
-   *
-   * @name isNumber
-   * @param {Number} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNumber = function (val, msg) {
-    new Assertion(val, msg).to.be.a('number');
-  };
-
-  /**
-   * ### .isNotNumber(value, [message])
-   *
-   * Asserts that `value` is _not_ a number.
-   *
-   *     var cups = '2 cups please';
-   *     assert.isNotNumber(cups, 'how many cups');
-   *
-   * @name isNotNumber
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotNumber = function (val, msg) {
-    new Assertion(val, msg).to.not.be.a('number');
-  };
-
-  /**
-   * ### .isBoolean(value, [message])
-   *
-   * Asserts that `value` is a boolean.
-   *
-   *     var teaReady = true
-   *       , teaServed = false;
-   *
-   *     assert.isBoolean(teaReady, 'is the tea ready');
-   *     assert.isBoolean(teaServed, 'has tea been served');
-   *
-   * @name isBoolean
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isBoolean = function (val, msg) {
-    new Assertion(val, msg).to.be.a('boolean');
-  };
-
-  /**
-   * ### .isNotBoolean(value, [message])
-   *
-   * Asserts that `value` is _not_ a boolean.
-   *
-   *     var teaReady = 'yep'
-   *       , teaServed = 'nope';
-   *
-   *     assert.isNotBoolean(teaReady, 'is the tea ready');
-   *     assert.isNotBoolean(teaServed, 'has tea been served');
-   *
-   * @name isNotBoolean
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.isNotBoolean = function (val, msg) {
-    new Assertion(val, msg).to.not.be.a('boolean');
-  };
-
-  /**
-   * ### .typeOf(value, name, [message])
-   *
-   * Asserts that `value`'s type is `name`, as determined by
-   * `Object.prototype.toString`.
-   *
-   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
-   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
-   *     assert.typeOf('tea', 'string', 'we have a string');
-   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
-   *     assert.typeOf(null, 'null', 'we have a null');
-   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');
-   *
-   * @name typeOf
-   * @param {Mixed} value
-   * @param {String} name
-   * @param {String} message
-   * @api public
-   */
-
-  assert.typeOf = function (val, type, msg) {
-    new Assertion(val, msg).to.be.a(type);
-  };
-
-  /**
-   * ### .notTypeOf(value, name, [message])
-   *
-   * Asserts that `value`'s type is _not_ `name`, as determined by
-   * `Object.prototype.toString`.
-   *
-   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');
-   *
-   * @name notTypeOf
-   * @param {Mixed} value
-   * @param {String} typeof name
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notTypeOf = function (val, type, msg) {
-    new Assertion(val, msg).to.not.be.a(type);
-  };
-
-  /**
-   * ### .instanceOf(object, constructor, [message])
-   *
-   * Asserts that `value` is an instance of `constructor`.
-   *
-   *     var Tea = function (name) { this.name = name; }
-   *       , chai = new Tea('chai');
-   *
-   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');
-   *
-   * @name instanceOf
-   * @param {Object} object
-   * @param {Constructor} constructor
-   * @param {String} message
-   * @api public
-   */
-
-  assert.instanceOf = function (val, type, msg) {
-    new Assertion(val, msg).to.be.instanceOf(type);
-  };
-
-  /**
-   * ### .notInstanceOf(object, constructor, [message])
-   *
-   * Asserts `value` is not an instance of `constructor`.
-   *
-   *     var Tea = function (name) { this.name = name; }
-   *       , chai = new String('chai');
-   *
-   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
-   *
-   * @name notInstanceOf
-   * @param {Object} object
-   * @param {Constructor} constructor
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notInstanceOf = function (val, type, msg) {
-    new Assertion(val, msg).to.not.be.instanceOf(type);
-  };
-
-  /**
-   * ### .include(haystack, needle, [message])
-   *
-   * Asserts that `haystack` includes `needle`. Works
-   * for strings and arrays.
-   *
-   *     assert.include('foobar', 'bar', 'foobar contains string "bar"');
-   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');
-   *
-   * @name include
-   * @param {Array|String} haystack
-   * @param {Mixed} needle
-   * @param {String} message
-   * @api public
-   */
-
-  assert.include = function (exp, inc, msg) {
-    var obj = new Assertion(exp, msg);
-
-    if (Array.isArray(exp)) {
-      obj.to.include(inc);
-    } else if ('string' === typeof exp) {
-      obj.to.contain.string(inc);
-    }
-  };
-
-  /**
-   * ### .match(value, regexp, [message])
-   *
-   * Asserts that `value` matches the regular expression `regexp`.
-   *
-   *     assert.match('foobar', /^foo/, 'regexp matches');
-   *
-   * @name match
-   * @param {Mixed} value
-   * @param {RegExp} regexp
-   * @param {String} message
-   * @api public
-   */
-
-  assert.match = function (exp, re, msg) {
-    new Assertion(exp, msg).to.match(re);
-  };
-
-  /**
-   * ### .notMatch(value, regexp, [message])
-   *
-   * Asserts that `value` does not match the regular expression `regexp`.
-   *
-   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');
-   *
-   * @name notMatch
-   * @param {Mixed} value
-   * @param {RegExp} regexp
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notMatch = function (exp, re, msg) {
-    new Assertion(exp, msg).to.not.match(re);
-  };
-
-  /**
-   * ### .property(object, property, [message])
-   *
-   * Asserts that `object` has a property named by `property`.
-   *
-   *     assert.property({ tea: { green: 'matcha' }}, 'tea');
-   *
-   * @name property
-   * @param {Object} object
-   * @param {String} property
-   * @param {String} message
-   * @api public
-   */
-
-  assert.property = function (obj, prop, msg) {
-    new Assertion(obj, msg).to.have.property(prop);
-  };
-
-  /**
-   * ### .notProperty(object, property, [message])
-   *
-   * Asserts that `object` does _not_ have a property named by `property`.
-   *
-   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
-   *
-   * @name notProperty
-   * @param {Object} object
-   * @param {String} property
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notProperty = function (obj, prop, msg) {
-    new Assertion(obj, msg).to.not.have.property(prop);
-  };
-
-  /**
-   * ### .deepProperty(object, property, [message])
-   *
-   * Asserts that `object` has a property named by `property`, which can be a
-   * string using dot- and bracket-notation for deep reference.
-   *
-   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');
-   *
-   * @name deepProperty
-   * @param {Object} object
-   * @param {String} property
-   * @param {String} message
-   * @api public
-   */
-
-  assert.deepProperty = function (obj, prop, msg) {
-    new Assertion(obj, msg).to.have.deep.property(prop);
-  };
-
-  /**
-   * ### .notDeepProperty(object, property, [message])
-   *
-   * Asserts that `object` does _not_ have a property named by `property`, which
-   * can be a string using dot- and bracket-notation for deep reference.
-   *
-   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
-   *
-   * @name notDeepProperty
-   * @param {Object} object
-   * @param {String} property
-   * @param {String} message
-   * @api public
-   */
-
-  assert.notDeepProperty = function (obj, prop, msg) {
-    new Assertion(obj, msg).to.not.have.deep.property(prop);
-  };
-
-  /**
-   * ### .propertyVal(object, property, value, [message])
-   *
-   * Asserts that `object` has a property named by `property` with value given
-   * by `value`.
-   *
-   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
-   *
-   * @name propertyVal
-   * @param {Object} object
-   * @param {String} property
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.propertyVal = function (obj, prop, val, msg) {
-    new Assertion(obj, msg).to.have.property(prop, val);
-  };
-
-  /**
-   * ### .propertyNotVal(object, property, value, [message])
-   *
-   * Asserts that `object` has a property named by `property`, but with a value
-   * different from that given by `value`.
-   *
-   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');
-   *
-   * @name propertyNotVal
-   * @param {Object} object
-   * @param {String} property
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.propertyNotVal = function (obj, prop, val, msg) {
-    new Assertion(obj, msg).to.not.have.property(prop, val);
-  };
-
-  /**
-   * ### .deepPropertyVal(object, property, value, [message])
-   *
-   * Asserts that `object` has a property named by `property` with value given
-   * by `value`. `property` can use dot- and bracket-notation for deep
-   * reference.
-   *
-   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
-   *
-   * @name deepPropertyVal
-   * @param {Object} object
-   * @param {String} property
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.deepPropertyVal = function (obj, prop, val, msg) {
-    new Assertion(obj, msg).to.have.deep.property(prop, val);
-  };
-
-  /**
-   * ### .deepPropertyNotVal(object, property, value, [message])
-   *
-   * Asserts that `object` has a property named by `property`, but with a value
-   * different from that given by `value`. `property` can use dot- and
-   * bracket-notation for deep reference.
-   *
-   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
-   *
-   * @name deepPropertyNotVal
-   * @param {Object} object
-   * @param {String} property
-   * @param {Mixed} value
-   * @param {String} message
-   * @api public
-   */
-
-  assert.deepPropertyNotVal = function (obj, prop, val, msg) {
-    new Assertion(obj, msg).to.not.have.deep.property(prop, val);
-  };
-
-  /**
-   * ### .lengthOf(object, length, [message])
-   *
-   * Asserts that `object` has a `length` property with the expected value.
-   *
-   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');
-   *     assert.lengthOf('foobar', 5, 'string has length of 6');
-   *
-   * @name lengthOf
-   * @param {Mixed} object
-   * @param {Number} length
-   * @param {String} message
-   * @api public
-   */
-
-  assert.lengthOf = function (exp, len, msg) {
-    new Assertion(exp, msg).to.have.length(len);
-  };
-
-  /**
-   * ### .throws(function, [constructor/regexp], [message])
-   *
-   * Asserts that `function` will throw an error that is an instance of
-   * `constructor`, or alternately that it will throw an error with message
-   * matching `regexp`.
-   *
-   *     assert.throw(fn, ReferenceError, 'function throws a reference error');
-   *
-   * @name throws
-   * @alias throw
-   * @alias Throw
-   * @param {Function} function
-   * @param {ErrorConstructor} constructor
-   * @param {RegExp} regexp
-   * @param {String} message
-   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
-   * @api public
-   */
-
-  assert.Throw = function (fn, type, msg) {
-    if ('string' === typeof type) {
-      msg = type;
-      type = null;
-    }
-
-    new Assertion(fn, msg).to.Throw(type);
-  };
-
-  /**
-   * ### .doesNotThrow(function, [constructor/regexp], [message])
-   *
-   * Asserts that `function` will _not_ throw an error that is an instance of
-   * `constructor`, or alternately that it will not throw an error with message
-   * matching `regexp`.
-   *
-   *     assert.doesNotThrow(fn, Error, 'function does not throw');
-   *
-   * @name doesNotThrow
-   * @param {Function} function
-   * @param {ErrorConstructor} constructor
-   * @param {RegExp} regexp
-   * @param {String} message
-   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
-   * @api public
-   */
-
-  assert.doesNotThrow = function (fn, type, msg) {
-    if ('string' === typeof type) {
-      msg = type;
-      type = null;
-    }
-
-    new Assertion(fn, msg).to.not.Throw(type);
-  };
-
-  /**
-   * ### .operator(val1, operator, val2, [message])
-   *
-   * Compares two values using `operator`.
-   *
-   *     assert.operator(1, '<', 2, 'everything is ok');
-   *     assert.operator(1, '>', 2, 'this will fail');
-   *
-   * @name operator
-   * @param {Mixed} val1
-   * @param {String} operator
-   * @param {Mixed} val2
-   * @param {String} message
-   * @api public
-   */
-
-  assert.operator = function (val, operator, val2, msg) {
-    if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
-      throw new Error('Invalid operator "' + operator + '"');
-    }
-    var test = new Assertion(eval(val + operator + val2), msg);
-    test.assert(
-        true === flag(test, 'object')
-      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
-      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
-  };
-
-  /*!
-   * Undocumented / untested
-   */
-
-  assert.ifError = function (val, msg) {
-    new Assertion(val, msg).to.not.be.ok;
-  };
-
-  /*!
-   * Aliases.
-   */
-
-  (function alias(name, as){
-    assert[as] = assert[name];
-    return alias;
-  })
-  ('Throw', 'throw')
-  ('Throw', 'throws');
-};
-
-}); // module: chai/interface/assert.js
-
-require.register("chai/interface/expect.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-module.exports = function (chai, util) {
-  chai.expect = function (val, message) {
-    return new chai.Assertion(val, message);
-  };
-};
-
-
-}); // module: chai/interface/expect.js
-
-require.register("chai/interface/should.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-module.exports = function (chai, util) {
-  var Assertion = chai.Assertion;
-
-  function loadShould () {
-    // modify Object.prototype to have `should`
-    Object.defineProperty(Object.prototype, 'should',
-      { set: function () {}
-      , get: function(){
-          if (this instanceof String || this instanceof Number) {
-            return new Assertion(this.constructor(this));
-          } else if (this instanceof Boolean) {
-            return new Assertion(this == true);
-          }
-          return new Assertion(this);
-        }
-      , configurable: true
-    });
-
-    var should = {};
-
-    should.equal = function (val1, val2) {
-      new Assertion(val1).to.equal(val2);
-    };
-
-    should.Throw = function (fn, errt, errs) {
-      new Assertion(fn).to.Throw(errt, errs);
-    };
-
-    should.exist = function (val) {
-      new Assertion(val).to.exist;
-    }
-
-    // negation
-    should.not = {}
-
-    should.not.equal = function (val1, val2) {
-      new Assertion(val1).to.not.equal(val2);
-    };
-
-    should.not.Throw = function (fn, errt, errs) {
-      new Assertion(fn).to.not.Throw(errt, errs);
-    };
-
-    should.not.exist = function (val) {
-      new Assertion(val).to.not.exist;
-    }
-
-    should['throw'] = should['Throw'];
-    should.not['throw'] = should.not['Throw'];
-
-    return should;
-  };
-
-  chai.should = loadShould;
-  chai.Should = loadShould;
-};
-
-}); // module: chai/interface/should.js
-
-require.register("chai/utils/addChainableMethod.js", function(module, exports, require){
-/*!
- * Chai - addChainingMethod utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/*!
- * Module dependencies
- */
-
-var transferFlags = require('./transferFlags');
-
-/**
- * ### addChainableMethod (ctx, name, method, chainingBehavior)
- *
- * Adds a method to an object, such that the method can also be chained.
- *
- *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
- *       var obj = utils.flag(this, 'object');
- *       new chai.Assertion(obj).to.be.equal(str);
- *     });
- *
- * Can also be accessed directly from `chai.Assertion`.
- *
- *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
- *
- * The result can then be used as both a method assertion, executing both `method` and
- * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
- *
- *     expect(fooStr).to.be.foo('bar');
- *     expect(fooStr).to.be.foo.equal('foo');
- *
- * @param {Object} ctx object to which the method is added
- * @param {String} name of method to add
- * @param {Function} method function to be used for `name`, when called
- * @param {Function} chainingBehavior function to be called every time the property is accessed
- * @name addChainableMethod
- * @api public
- */
-
-module.exports = function (ctx, name, method, chainingBehavior) {
-  if (typeof chainingBehavior !== 'function')
-    chainingBehavior = function () { };
-
-  Object.defineProperty(ctx, name,
-    { get: function () {
-        chainingBehavior.call(this);
-
-        var assert = function () {
-          var result = method.apply(this, arguments);
-          return result === undefined ? this : result;
-        };
-
-        // Re-enumerate every time to better accomodate plugins.
-        var asserterNames = Object.getOwnPropertyNames(ctx);
-        asserterNames.forEach(function (asserterName) {
-          var pd = Object.getOwnPropertyDescriptor(ctx, asserterName)
-            , functionProtoPD = Object.getOwnPropertyDescriptor(Function.prototype, asserterName);
-          // Avoid trying to overwrite things that we can't, like `length` and `arguments`.
-          if (functionProtoPD && !functionProtoPD.configurable) return;
-          if (asserterName === 'arguments') return; // @see chaijs/chai/issues/69
-          Object.defineProperty(assert, asserterName, pd);
-        });
-
-        transferFlags(this, assert);
-        return assert;
-      }
-    , configurable: true
-  });
-};
-
-}); // module: chai/utils/addChainableMethod.js
-
-require.register("chai/utils/addMethod.js", function(module, exports, require){
-/*!
- * Chai - addMethod utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### addMethod (ctx, name, method)
- *
- * Adds a method to the prototype of an object.
- *
- *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
- *       var obj = utils.flag(this, 'object');
- *       new chai.Assertion(obj).to.be.equal(str);
- *     });
- *
- * Can also be accessed directly from `chai.Assertion`.
- *
- *     chai.Assertion.addMethod('foo', fn);
- *
- * Then can be used as any other assertion.
- *
- *     expect(fooStr).to.be.foo('bar');
- *
- * @param {Object} ctx object to which the method is added
- * @param {String} name of method to add
- * @param {Function} method function to be used for name
- * @name addMethod
- * @api public
- */
-
-module.exports = function (ctx, name, method) {
-  ctx[name] = function () {
-    var result = method.apply(this, arguments);
-    return result === undefined ? this : result;
-  };
-};
-
-}); // module: chai/utils/addMethod.js
-
-require.register("chai/utils/addProperty.js", function(module, exports, require){
-/*!
- * Chai - addProperty utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### addProperty (ctx, name, getter)
- *
- * Adds a property to the prototype of an object.
- *
- *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {
- *       var obj = utils.flag(this, 'object');
- *       new chai.Assertion(obj).to.be.instanceof(Foo);
- *     });
- *
- * Can also be accessed directly from `chai.Assertion`.
- *
- *     chai.Assertion.addProperty('foo', fn);
- *
- * Then can be used as any other assertion.
- *
- *     expect(myFoo).to.be.foo;
- *
- * @param {Object} ctx object to which the property is added
- * @param {String} name of property to add
- * @param {Function} getter function to be used for name
- * @name addProperty
- * @api public
- */
-
-module.exports = function (ctx, name, getter) {
-  Object.defineProperty(ctx, name,
-    { get: function () {
-        var result = getter.call(this);
-        return result === undefined ? this : result;
-      }
-    , configurable: true
-  });
-};
-
-}); // module: chai/utils/addProperty.js
-
-require.register("chai/utils/eql.js", function(module, exports, require){
-// This is directly from Node.js assert
-// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
-
-
-module.exports = _deepEqual;
-
-// For browser implementation
-if (!Buffer) {
-  var Buffer = {
-    isBuffer: function () {
-      return false;
-    }
-  };
-}
-
-function _deepEqual(actual, expected) {
-  // 7.1. All identical values are equivalent, as determined by ===.
-  if (actual === expected) {
-    return true;
-
-  } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
-    if (actual.length != expected.length) return false;
-
-    for (var i = 0; i < actual.length; i++) {
-      if (actual[i] !== expected[i]) return false;
-    }
-
-    return true;
-
-  // 7.2. If the expected value is a Date object, the actual value is
-  // equivalent if it is also a Date object that refers to the same time.
-  } else if (actual instanceof Date && expected instanceof Date) {
-    return actual.getTime() === expected.getTime();
-
-  // 7.3. Other pairs that do not both pass typeof value == 'object',
-  // equivalence is determined by ==.
-  } else if (typeof actual != 'object' && typeof expected != 'object') {
-    return actual === expected;
-
-  // 7.4. For all other Object pairs, including Array objects, equivalence is
-  // determined by having the same number of owned properties (as verified
-  // with Object.prototype.hasOwnProperty.call), the same set of keys
-  // (although not necessarily the same order), equivalent values for every
-  // corresponding key, and an identical 'prototype' property. Note: this
-  // accounts for both named and indexed properties on Arrays.
-  } else {
-    return objEquiv(actual, expected);
-  }
-}
-
-function isUndefinedOrNull(value) {
-  return value === null || value === undefined;
-}
-
-function isArguments(object) {
-  return Object.prototype.toString.call(object) == '[object Arguments]';
-}
-
-function objEquiv(a, b) {
-  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
-    return false;
-  // an identical 'prototype' property.
-  if (a.prototype !== b.prototype) return false;
-  //~~~I've managed to break Object.keys through screwy arguments passing.
-  //   Converting to array solves the problem.
-  if (isArguments(a)) {
-    if (!isArguments(b)) {
-      return false;
-    }
-    a = pSlice.call(a);
-    b = pSlice.call(b);
-    return _deepEqual(a, b);
-  }
-  try {
-    var ka = Object.keys(a),
-        kb = Object.keys(b),
-        key, i;
-  } catch (e) {//happens when one is a string literal and the other isn't
-    return false;
-  }
-  // having the same number of owned properties (keys incorporates
-  // hasOwnProperty)
-  if (ka.length != kb.length)
-    return false;
-  //the same set of keys (although not necessarily the same order),
-  ka.sort();
-  kb.sort();
-  //~~~cheap key test
-  for (i = ka.length - 1; i >= 0; i--) {
-    if (ka[i] != kb[i])
-      return false;
-  }
-  //equivalent values for every corresponding key, and
-  //~~~possibly expensive deep test
-  for (i = ka.length - 1; i >= 0; i--) {
-    key = ka[i];
-    if (!_deepEqual(a[key], b[key])) return false;
-  }
-  return true;
-}
-}); // module: chai/utils/eql.js
-
-require.register("chai/utils/flag.js", function(module, exports, require){
-/*!
- * Chai - flag utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### flag(object ,key, [value])
- *
- * Get or set a flag value on an object. If a
- * value is provided it will be set, else it will
- * return the currently set value or `undefined` if
- * the value is not set.
- *
- *     utils.flag(this, 'foo', 'bar'); // setter
- *     utils.flag(this, 'foo'); // getter, returns `bar`
- *
- * @param {Object} object (constructed Assertion
- * @param {String} key
- * @param {Mixed} value (optional)
- * @name flag
- * @api private
- */
-
-module.exports = function (obj, key, value) {
-  var flags = obj.__flags || (obj.__flags = Object.create(null));
-  if (arguments.length === 3) {
-    flags[key] = value;
-  } else {
-    return flags[key];
-  }
-};
-
-}); // module: chai/utils/flag.js
-
-require.register("chai/utils/getActual.js", function(module, exports, require){
-/*!
- * Chai - getActual utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * # getActual(object, [actual])
- *
- * Returns the `actual` value for an Assertion
- *
- * @param {Object} object (constructed Assertion)
- * @param {Arguments} chai.Assertion.prototype.assert arguments
- */
-
-module.exports = function (obj, args) {
-  var actual = args[4];
-  return 'undefined' !== actual ? actual : obj.obj;
-};
-
-}); // module: chai/utils/getActual.js
-
-require.register("chai/utils/getMessage.js", function(module, exports, require){
-/*!
- * Chai - message composition utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/*!
- * Module dependancies
- */
-
-var flag = require('./flag')
-  , getActual = require('./getActual')
-  , inspect = require('./inspect');
-
-/**
- * # getMessage(object, message, negateMessage)
- *
- * Construct the error message based on flags
- * and template tags. Template tags will return
- * a stringified inspection of the object referenced.
- *
- * Messsage template tags:
- * - `#{this}` current asserted object
- * - `#{act}` actual value
- * - `#{exp}` expected value
- *
- * @param {Object} object (constructed Assertion)
- * @param {Arguments} chai.Assertion.prototype.assert arguments
- */
-
-module.exports = function (obj, args) {
-  var negate = flag(obj, 'negate')
-    , val = flag(obj, 'object')
-    , expected = args[3]
-    , actual = getActual(obj, args)
-    , msg = negate ? args[2] : args[1]
-    , flagMsg = flag(obj, 'message');
-
-  msg = msg || '';
-  msg = msg
-    .replace(/#{this}/g, inspect(val))
-    .replace(/#{act}/g, inspect(actual))
-    .replace(/#{exp}/g, inspect(expected));
-
-  return flagMsg ? flagMsg + ': ' + msg : msg;
-};
-
-}); // module: chai/utils/getMessage.js
-
-require.register("chai/utils/getName.js", function(module, exports, require){
-/*!
- * Chai - getName utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * # getName(func)
- *
- * Gets the name of a function, in a cross-browser way.
- *
- * @param {Function} a function (usually a constructor)
- */
-
-module.exports = function (func) {
-  if (func.name) return func.name;
-
-  var match = /^\s?function ([^(]*)\(/.exec(func);
-  return match && match[1] ? match[1] : "";
-};
-
-}); // module: chai/utils/getName.js
-
-require.register("chai/utils/getPathValue.js", function(module, exports, require){
-/*!
- * Chai - getPathValue utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * @see https://github.com/logicalparadox/filtr
- * MIT Licensed
- */
-
-/**
- * ### .getPathValue(path, object)
- *
- * This allows the retrieval of values in an
- * object given a string path.
- *
- *     var obj = {
- *         prop1: {
- *             arr: ['a', 'b', 'c']
- *           , str: 'Hello'
- *         }
- *       , prop2: {
- *             arr: [ { nested: 'Universe' } ]
- *           , str: 'Hello again!'
- *         }
- *     }
- *
- * The following would be the results.
- *
- *     getPathValue('prop1.str', obj); // Hello
- *     getPathValue('prop1.att[2]', obj); // b
- *     getPathValue('prop2.arr[0].nested', obj); // Universe
- *
- * @param {String} path
- * @param {Object} object
- * @returns {Object} value or `undefined`
- * @name getPathValue
- * @api public
- */
-
-var getPathValue = module.exports = function (path, obj) {
-  var parsed = parsePath(path);
-  return _getPathValue(parsed, obj);
-};
-
-/*!
- * ## parsePath(path)
- *
- * Helper function used to parse string object
- * paths. Use in conjunction with `_getPathValue`.
- *
- *      var parsed = parsePath('myobject.property.subprop');
- *
- * ### Paths:
- *
- * * Can be as near infinitely deep and nested
- * * Arrays are also valid using the formal `myobject.document[3].property`.
- *
- * @param {String} path
- * @returns {Object} parsed
- * @api private
- */
-
-function parsePath (path) {
-  var str = path.replace(/\[/g, '.[')
-    , parts = str.match(/(\\\.|[^.]+?)+/g);
-  return parts.map(function (value) {
-    var re = /\[(\d+)\]$/
-      , mArr = re.exec(value)
-    if (mArr) return { i: parseFloat(mArr[1]) };
-    else return { p: value };
-  });
-};
-
-/*!
- * ## _getPathValue(parsed, obj)
- *
- * Helper companion function for `.parsePath` that returns
- * the value located at the parsed address.
- *
- *      var value = getPathValue(parsed, obj);
- *
- * @param {Object} parsed definition from `parsePath`.
- * @param {Object} object to search against
- * @returns {Object|Undefined} value
- * @api private
- */
-
-function _getPathValue (parsed, obj) {
-  var tmp = obj
-    , res;
-  for (var i = 0, l = parsed.length; i < l; i++) {
-    var part = parsed[i];
-    if (tmp) {
-      if ('undefined' !== typeof part.p)
-        tmp = tmp[part.p];
-      else if ('undefined' !== typeof part.i)
-        tmp = tmp[part.i];
-      if (i == (l - 1)) res = tmp;
-    } else {
-      res = undefined;
-    }
-  }
-  return res;
-};
-
-}); // module: chai/utils/getPathValue.js
-
-require.register("chai/utils/index.js", function(module, exports, require){
-/*!
- * chai
- * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/*!
- * Main exports
- */
-
-var exports = module.exports = {};
-
-/*!
- * test utility
- */
-
-exports.test = require('./test');
-
-/*!
- * message utility
- */
-
-exports.getMessage = require('./getMessage');
-
-/*!
- * actual utility
- */
-
-exports.getActual = require('./getActual');
-
-/*!
- * Inspect util
- */
-
-exports.inspect = require('./inspect');
-
-/*!
- * Flag utility
- */
-
-exports.flag = require('./flag');
-
-/*!
- * Flag transferring utility
- */
-
-exports.transferFlags = require('./transferFlags');
-
-/*!
- * Deep equal utility
- */
-
-exports.eql = require('./eql');
-
-/*!
- * Deep path value
- */
-
-exports.getPathValue = require('./getPathValue');
-
-/*!
- * Function name
- */
-
-exports.getName = require('./getName');
-
-/*!
- * add Property
- */
-
-exports.addProperty = require('./addProperty');
-
-/*!
- * add Method
- */
-
-exports.addMethod = require('./addMethod');
-
-/*!
- * overwrite Property
- */
-
-exports.overwriteProperty = require('./overwriteProperty');
-
-/*!
- * overwrite Method
- */
-
-exports.overwriteMethod = require('./overwriteMethod');
-
-/*!
- * Add a chainable method
- */
-
-exports.addChainableMethod = require('./addChainableMethod');
-
-
-}); // module: chai/utils/index.js
-
-require.register("chai/utils/inspect.js", function(module, exports, require){
-// This is (almost) directly from Node.js utils
-// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
-
-var getName = require('./getName');
-
-module.exports = inspect;
-
-/**
- * Echos the value of a value. Trys to print the value out
- * in the best way possible given the different types.
- *
- * @param {Object} obj The object to print out.
- * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
- *    properties of objects.
- * @param {Number} depth Depth in which to descend in object. Default is 2.
- * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
- *    output. Default is false (no coloring).
- */
-function inspect(obj, showHidden, depth, colors) {
-  var ctx = {
-    showHidden: showHidden,
-    seen: [],
-    stylize: function (str) { return str; }
-  };
-  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
-}
-
-function formatValue(ctx, value, recurseTimes) {
-  // Provide a hook for user-specified inspect functions.
-  // Check that value is an object with an inspect function on it
-  if (value && typeof value.inspect === 'function' &&
-      // Filter out the util module, it's inspect function is special
-      value.inspect !== exports.inspect &&
-      // Also filter out any prototype objects using the circular check.
-      !(value.constructor && value.constructor.prototype === value)) {
-    return value.inspect(recurseTimes);
-  }
-
-  // Primitive types cannot have properties
-  var primitive = formatPrimitive(ctx, value);
-  if (primitive) {
-    return primitive;
-  }
-
-  // Look up the keys of the object.
-  var visibleKeys = Object.keys(value);
-  var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
-
-  // Some type of object without properties can be shortcutted.
-  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
-  // a `stack` plus `description` property; ignore those for consistency.
-  if (keys.length === 0 || (isError(value) && (
-      (keys.length === 1 && keys[0] === 'stack') ||
-      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
-     ))) {
-    if (typeof value === 'function') {
-      var name = getName(value);
-      var nameSuffix = name ? ': ' + name : '';
-      return ctx.stylize('[Function' + nameSuffix + ']', 'special');
-    }
-    if (isRegExp(value)) {
-      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
-    }
-    if (isDate(value)) {
-      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
-    }
-    if (isError(value)) {
-      return formatError(value);
-    }
-  }
-
-  var base = '', array = false, braces = ['{', '}'];
-
-  // Make Array say that they are Array
-  if (isArray(value)) {
-    array = true;
-    braces = ['[', ']'];
-  }
-
-  // Make functions say that they are functions
-  if (typeof value === 'function') {
-    var name = getName(value);
-    var nameSuffix = name ? ': ' + name : '';
-    base = ' [Function' + nameSuffix + ']';
-  }
-
-  // Make RegExps say that they are RegExps
-  if (isRegExp(value)) {
-    base = ' ' + RegExp.prototype.toString.call(value);
-  }
-
-  // Make dates with properties first say the date
-  if (isDate(value)) {
-    base = ' ' + Date.prototype.toUTCString.call(value);
-  }
-
-  // Make error with message first say the error
-  if (isError(value)) {
-    return formatError(value);
-  }
-
-  if (keys.length === 0 && (!array || value.length == 0)) {
-    return braces[0] + base + braces[1];
-  }
-
-  if (recurseTimes < 0) {
-    if (isRegExp(value)) {
-      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
-    } else {
-      return ctx.stylize('[Object]', 'special');
-    }
-  }
-
-  ctx.seen.push(value);
-
-  var output;
-  if (array) {
-    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
-  } else {
-    output = keys.map(function(key) {
-      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
-    });
-  }
-
-  ctx.seen.pop();
-
-  return reduceToSingleString(output, base, braces);
-}
-
-
-function formatPrimitive(ctx, value) {
-  switch (typeof value) {
-    case 'undefined':
-      return ctx.stylize('undefined', 'undefined');
-
-    case 'string':
-      var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
-                                               .replace(/'/g, "\\'")
-                                               .replace(/\\"/g, '"') + '\'';
-      return ctx.stylize(simple, 'string');
-
-    case 'number':
-      return ctx.stylize('' + value, 'number');
-
-    case 'boolean':
-      return ctx.stylize('' + value, 'boolean');
-  }
-  // For some reason typeof null is "object", so special case here.
-  if (value === null) {
-    return ctx.stylize('null', 'null');
-  }
-}
-
-
-function formatError(value) {
-  return '[' + Error.prototype.toString.call(value) + ']';
-}
-
-
-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
-  var output = [];
-  for (var i = 0, l = value.length; i < l; ++i) {
-    if (Object.prototype.hasOwnProperty.call(value, String(i))) {
-      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
-          String(i), true));
-    } else {
-      output.push('');
-    }
-  }
-  keys.forEach(function(key) {
-    if (!key.match(/^\d+$/)) {
-      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
-          key, true));
-    }
-  });
-  return output;
-}
-
-
-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
-  var name, str;
-  if (value.__lookupGetter__) {
-    if (value.__lookupGetter__(key)) {
-      if (value.__lookupSetter__(key)) {
-        str = ctx.stylize('[Getter/Setter]', 'special');
-      } else {
-        str = ctx.stylize('[Getter]', 'special');
-      }
-    } else {
-      if (value.__lookupSetter__(key)) {
-        str = ctx.stylize('[Setter]', 'special');
-      }
-    }
-  }
-  if (visibleKeys.indexOf(key) < 0) {
-    name = '[' + key + ']';
-  }
-  if (!str) {
-    if (ctx.seen.indexOf(value[key]) < 0) {
-      if (recurseTimes === null) {
-        str = formatValue(ctx, value[key], null);
-      } else {
-        str = formatValue(ctx, value[key], recurseTimes - 1);
-      }
-      if (str.indexOf('\n') > -1) {
-        if (array) {
-          str = str.split('\n').map(function(line) {
-            return '  ' + line;
-          }).join('\n').substr(2);
-        } else {
-          str = '\n' + str.split('\n').map(function(line) {
-            return '   ' + line;
-          }).join('\n');
-        }
-      }
-    } else {
-      str = ctx.stylize('[Circular]', 'special');
-    }
-  }
-  if (typeof name === 'undefined') {
-    if (array && key.match(/^\d+$/)) {
-      return str;
-    }
-    name = JSON.stringify('' + key);
-    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
-      name = name.substr(1, name.length - 2);
-      name = ctx.stylize(name, 'name');
-    } else {
-      name = name.replace(/'/g, "\\'")
-                 .replace(/\\"/g, '"')
-                 .replace(/(^"|"$)/g, "'");
-      name = ctx.stylize(name, 'string');
-    }
-  }
-
-  return name + ': ' + str;
-}
-
-
-function reduceToSingleString(output, base, braces) {
-  var numLinesEst = 0;
-  var length = output.reduce(function(prev, cur) {
-    numLinesEst++;
-    if (cur.indexOf('\n') >= 0) numLinesEst++;
-    return prev + cur.length + 1;
-  }, 0);
-
-  if (length > 60) {
-    return braces[0] +
-           (base === '' ? '' : base + '\n ') +
-           ' ' +
-           output.join(',\n  ') +
-           ' ' +
-           braces[1];
-  }
-
-  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
-}
-
-function isArray(ar) {
-  return Array.isArray(ar) ||
-         (typeof ar === 'object' && objectToString(ar) === '[object Array]');
-}
-
-function isRegExp(re) {
-  return typeof re === 'object' && objectToString(re) === '[object RegExp]';
-}
-
-function isDate(d) {
-  return typeof d === 'object' && objectToString(d) === '[object Date]';
-}
-
-function isError(e) {
-  return typeof e === 'object' && objectToString(e) === '[object Error]';
-}
-
-function objectToString(o) {
-  return Object.prototype.toString.call(o);
-}
-
-}); // module: chai/utils/inspect.js
-
-require.register("chai/utils/overwriteMethod.js", function(module, exports, require){
-/*!
- * Chai - overwriteMethod utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### overwriteMethod (ctx, name, fn)
- *
- * Overwites an already existing method and provides
- * access to previous function. Must return function
- * to be used for name.
- *
- *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
- *       return function (str) {
- *         var obj = utils.flag(this, 'object');
- *         if (obj instanceof Foo) {
- *           new chai.Assertion(obj.value).to.equal(str);
- *         } else {
- *           _super.apply(this, arguments);
- *         }
- *       }
- *     });
- *
- * Can also be accessed directly from `chai.Assertion`.
- *
- *     chai.Assertion.overwriteMethod('foo', fn);
- *
- * Then can be used as any other assertion.
- *
- *     expect(myFoo).to.equal('bar');
- *
- * @param {Object} ctx object whose method is to be overwritten
- * @param {String} name of method to overwrite
- * @param {Function} method function that returns a function to be used for name
- * @name overwriteMethod
- * @api public
- */
-
-module.exports = function (ctx, name, method) {
-  var _method = ctx[name]
-    , _super = function () { return this; };
-
-  if (_method && 'function' === typeof _method)
-    _super = _method;
-
-  ctx[name] = function () {
-    var result = method(_super).apply(this, arguments);
-    return result === undefined ? this : result;
-  }
-};
-
-}); // module: chai/utils/overwriteMethod.js
-
-require.register("chai/utils/overwriteProperty.js", function(module, exports, require){
-/*!
- * Chai - overwriteProperty utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### overwriteProperty (ctx, name, fn)
- *
- * Overwites an already existing property getter and provides
- * access to previous value. Must return function to use as getter.
- *
- *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
- *       return function () {
- *         var obj = utils.flag(this, 'object');
- *         if (obj instanceof Foo) {
- *           new chai.Assertion(obj.name).to.equal('bar');
- *         } else {
- *           _super.call(this);
- *         }
- *       }
- *     });
- *
- *
- * Can also be accessed directly from `chai.Assertion`.
- *
- *     chai.Assertion.overwriteProperty('foo', fn);
- *
- * Then can be used as any other assertion.
- *
- *     expect(myFoo).to.be.ok;
- *
- * @param {Object} ctx object whose property is to be overwritten
- * @param {String} name of property to overwrite
- * @param {Function} getter function that returns a getter function to be used for name
- * @name overwriteProperty
- * @api public
- */
-
-module.exports = function (ctx, name, getter) {
-  var _get = Object.getOwnPropertyDescriptor(ctx, name)
-    , _super = function () {};
-
-  if (_get && 'function' === typeof _get.get)
-    _super = _get.get
-
-  Object.defineProperty(ctx, name,
-    { get: function () {
-        var result = getter(_super).call(this);
-        return result === undefined ? this : result;
-      }
-    , configurable: true
-  });
-};
-
-}); // module: chai/utils/overwriteProperty.js
-
-require.register("chai/utils/test.js", function(module, exports, require){
-/*!
- * Chai - test utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/*!
- * Module dependancies
- */
-
-var flag = require('./flag');
-
-/**
- * # test(object, expression)
- *
- * Test and object for expression.
- *
- * @param {Object} object (constructed Assertion)
- * @param {Arguments} chai.Assertion.prototype.assert arguments
- */
-
-module.exports = function (obj, args) {
-  var negate = flag(obj, 'negate')
-    , expr = args[0];
-  return negate ? !expr : expr;
-};
-
-}); // module: chai/utils/test.js
-
-require.register("chai/utils/transferFlags.js", function(module, exports, require){
-/*!
- * Chai - transferFlags utility
- * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
-
-/**
- * ### transferFlags(assertion, object, includeAll = true)
- *
- * Transfer all the flags for `assertion` to `object`. If
- * `includeAll` is set to `false`, then the base Chai
- * assertion flags (namely `object`, `ssfi`, and `message`)
- * will not be transferred.
- *
- *
- *     var newAssertion = new Assertion();
- *     utils.transferFlags(assertion, newAssertion);
- *
- *     var anotherAsseriton = new Assertion(myObj);
- *     utils.transferFlags(assertion, anotherAssertion, false);
- *
- * @param {Assertion} assertion the assertion to transfer the flags from
- * @param {Object} object the object to transfer the flags too; usually a new assertion
- * @param {Boolean} includeAll
- * @name getAllFlags
- * @api private
- */
-
-module.exports = function (assertion, object, includeAll) {
-  var flags = assertion.__flags || (assertion.__flags = Object.create(null));
-
-  if (!object.__flags) {
-    object.__flags = Object.create(null);
-  }
-
-  includeAll = arguments.length === 3 ? includeAll : true;
-
-  for (var flag in flags) {
-    if (includeAll ||
-        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {
-      object.__flags[flag] = flags[flag];
-    }
-  }
-};
-
-}); // module: chai/utils/transferFlags.js
-
-
-  return require('chai');
-});
\ No newline at end of file
diff --git a/ckan/public-bs2/base/test/vendor/less.js b/ckan/public-bs2/base/test/vendor/less.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/vendor/less.js
+++ /dev/null
@@ -1,3478 +0,0 @@
-//
-// LESS - Leaner CSS v1.3.0
-// http://lesscss.org
-// 
-// Copyright (c) 2009-2011, Alexis Sellier
-// Licensed under the Apache 2.0 License.
-//
-(function (window, undefined) {
-//
-// Stub out `require` in the browser
-//
-function require(arg) {
-    return window.less[arg.split('/')[1]];
-};
-
-// amd.js
-//
-// Define Less as an AMD module.
-if (typeof define === "function" && define.amd) {
-    define("less", [], function () { return less; } );
-}
-
-// ecma-5.js
-//
-// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
-// -- tlrobinson Tom Robinson
-// dantman Daniel Friesen
-
-//
-// Array
-//
-if (!Array.isArray) {
-    Array.isArray = function(obj) {
-        return Object.prototype.toString.call(obj) === "[object Array]" ||
-               (obj instanceof Array);
-    };
-}
-if (!Array.prototype.forEach) {
-    Array.prototype.forEach =  function(block, thisObject) {
-        var len = this.length >>> 0;
-        for (var i = 0; i < len; i++) {
-            if (i in this) {
-                block.call(thisObject, this[i], i, this);
-            }
-        }
-    };
-}
-if (!Array.prototype.map) {
-    Array.prototype.map = function(fun /*, thisp*/) {
-        var len = this.length >>> 0;
-        var res = new Array(len);
-        var thisp = arguments[1];
-
-        for (var i = 0; i < len; i++) {
-            if (i in this) {
-                res[i] = fun.call(thisp, this[i], i, this);
-            }
-        }
-        return res;
-    };
-}
-if (!Array.prototype.filter) {
-    Array.prototype.filter = function (block /*, thisp */) {
-        var values = [];
-        var thisp = arguments[1];
-        for (var i = 0; i < this.length; i++) {
-            if (block.call(thisp, this[i])) {
-                values.push(this[i]);
-            }
-        }
-        return values;
-    };
-}
-if (!Array.prototype.reduce) {
-    Array.prototype.reduce = function(fun /*, initial*/) {
-        var len = this.length >>> 0;
-        var i = 0;
-
-        // no value to return if no initial value and an empty array
-        if (len === 0 && arguments.length === 1) throw new TypeError();
-
-        if (arguments.length >= 2) {
-            var rv = arguments[1];
-        } else {
-            do {
-                if (i in this) {
-                    rv = this[i++];
-                    break;
-                }
-                // if array contains no values, no initial value to return
-                if (++i >= len) throw new TypeError();
-            } while (true);
-        }
-        for (; i < len; i++) {
-            if (i in this) {
-                rv = fun.call(null, rv, this[i], i, this);
-            }
-        }
-        return rv;
-    };
-}
-if (!Array.prototype.indexOf) {
-    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
-        var length = this.length;
-        var i = arguments[1] || 0;
-
-        if (!length)     return -1;
-        if (i >= length) return -1;
-        if (i < 0)       i += length;
-
-        for (; i < length; i++) {
-            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
-            if (value === this[i]) return i;
-        }
-        return -1;
-    };
-}
-
-//
-// Object
-//
-if (!Object.keys) {
-    Object.keys = function (object) {
-        var keys = [];
-        for (var name in object) {
-            if (Object.prototype.hasOwnProperty.call(object, name)) {
-                keys.push(name);
-            }
-        }
-        return keys;
-    };
-}
-
-//
-// String
-//
-if (!String.prototype.trim) {
-    String.prototype.trim = function () {
-        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
-    };
-}
-var less, tree;
-
-if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
-    // Rhino
-    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
-    if (typeof(window) === 'undefined') { less = {} }
-    else                                { less = window.less = {} }
-    tree = less.tree = {};
-    less.mode = 'rhino';
-} else if (typeof(window) === 'undefined') {
-    // Node.js
-    less = exports,
-    tree = require('./tree');
-    less.mode = 'node';
-} else {
-    // Browser
-    if (typeof(window.less) === 'undefined') { window.less = {} }
-    less = window.less,
-    tree = window.less.tree = {};
-    less.mode = 'browser';
-}
-//
-// less.js - parser
-//
-//    A relatively straight-forward predictive parser.
-//    There is no tokenization/lexing stage, the input is parsed
-//    in one sweep.
-//
-//    To make the parser fast enough to run in the browser, several
-//    optimization had to be made:
-//
-//    - Matching and slicing on a huge input is often cause of slowdowns.
-//      The solution is to chunkify the input into smaller strings.
-//      The chunks are stored in the `chunks` var,
-//      `j` holds the current chunk index, and `current` holds
-//      the index of the current chunk in relation to `input`.
-//      This gives us an almost 4x speed-up.
-//
-//    - In many cases, we don't need to match individual tokens;
-//      for example, if a value doesn't hold any variables, operations
-//      or dynamic references, the parser can effectively 'skip' it,
-//      treating it as a literal.
-//      An example would be '1px solid #000' - which evaluates to itself,
-//      we don't need to know what the individual components are.
-//      The drawback, of course is that you don't get the benefits of
-//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
-//      and a smaller speed-up in the code-gen.
-//
-//
-//    Token matching is done with the `$` function, which either takes
-//    a terminal string or regexp, or a non-terminal function to call.
-//    It also takes care of moving all the indices forwards.
-//
-//
-less.Parser = function Parser(env) {
-    var input,       // LeSS input string
-        i,           // current index in `input`
-        j,           // current chunk
-        temp,        // temporarily holds a chunk's state, for backtracking
-        memo,        // temporarily holds `i`, when backtracking
-        furthest,    // furthest index the parser has gone to
-        chunks,      // chunkified input
-        current,     // index of current chunk, in `input`
-        parser;
-
-    var that = this;
-
-    // This function is called after all files
-    // have been imported through `@import`.
-    var finish = function () {};
-
-    var imports = this.imports = {
-        paths: env && env.paths || [],  // Search paths, when importing
-        queue: [],                      // Files which haven't been imported yet
-        files: {},                      // Holds the imported parse trees
-        contents: {},                   // Holds the imported file contents
-        mime:  env && env.mime,         // MIME type of .less files
-        error: null,                    // Error in parsing/evaluating an import
-        push: function (path, callback) {
-            var that = this;
-            this.queue.push(path);
-
-            //
-            // Import a file asynchronously
-            //
-            less.Parser.importer(path, this.paths, function (e, root, contents) {
-                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
-                that.files[path] = root;                        // Store the root
-                that.contents[path] = contents;
-
-                if (e && !that.error) { that.error = e }
-                callback(e, root);
-
-                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
-            }, env);
-        }
-    };
-
-    function save()    { temp = chunks[j], memo = i, current = i }
-    function restore() { chunks[j] = temp, i = memo, current = i }
-
-    function sync() {
-        if (i > current) {
-            chunks[j] = chunks[j].slice(i - current);
-            current = i;
-        }
-    }
-    //
-    // Parse from a token, regexp or string, and move forward if match
-    //
-    function $(tok) {
-        var match, args, length, c, index, endIndex, k, mem;
-
-        //
-        // Non-terminal
-        //
-        if (tok instanceof Function) {
-            return tok.call(parser.parsers);
-        //
-        // Terminal
-        //
-        //     Either match a single character in the input,
-        //     or match a regexp in the current chunk (chunk[j]).
-        //
-        } else if (typeof(tok) === 'string') {
-            match = input.charAt(i) === tok ? tok : null;
-            length = 1;
-            sync ();
-        } else {
-            sync ();
-
-            if (match = tok.exec(chunks[j])) {
-                length = match[0].length;
-            } else {
-                return null;
-            }
-        }
-
-        // The match is confirmed, add the match length to `i`,
-        // and consume any extra white-space characters (' ' || '\n')
-        // which come after that. The reason for this is that LeSS's
-        // grammar is mostly white-space insensitive.
-        //
-        if (match) {
-            mem = i += length;
-            endIndex = i + chunks[j].length - length;
-
-            while (i < endIndex) {
-                c = input.charCodeAt(i);
-                if (! (c === 32 || c === 10 || c === 9)) { break }
-                i++;
-            }
-            chunks[j] = chunks[j].slice(length + (i - mem));
-            current = i;
-
-            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
-
-            if(typeof(match) === 'string') {
-                return match;
-            } else {
-                return match.length === 1 ? match[0] : match;
-            }
-        }
-    }
-
-    function expect(arg, msg) {
-        var result = $(arg);
-        if (! result) {
-            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
-                                                   : "unexpected token"));
-        } else {
-            return result;
-        }
-    }
-
-    function error(msg, type) {
-        throw { index: i, type: type || 'Syntax', message: msg };
-    }
-
-    // Same as $(), but don't change the state of the parser,
-    // just return the match.
-    function peek(tok) {
-        if (typeof(tok) === 'string') {
-            return input.charAt(i) === tok;
-        } else {
-            if (tok.test(chunks[j])) {
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    function basename(pathname) {
-        if (less.mode === 'node') {
-            return require('path').basename(pathname);
-        } else {
-            return pathname.match(/[^\/]+$/)[0];
-        }
-    }
-
-    function getInput(e, env) {
-        if (e.filename && env.filename && (e.filename !== env.filename)) {
-            return parser.imports.contents[basename(e.filename)] || "";
-        } else {
-            return input;
-        }
-    }
-
-    function getLocation(index, input) {
-        for (var n = index, column = -1;
-                 n >= 0 && input.charAt(n) !== '\n';
-                 n--) { column++ }
-
-        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
-                 column: column };
-    }
-
-    function LessError(e, env) {
-        var input = getInput(e, env),
-            loc = getLocation(e.index, input),
-            line = loc.line,
-            col  = loc.column,
-            lines = input.split('\n');
-
-        this.type = e.type || 'Syntax';
-        this.message = e.message;
-        this.filename = e.filename || env.filename;
-        this.index = e.index;
-        this.line = typeof(line) === 'number' ? line + 1 : null;
-        this.callLine = e.call && (getLocation(e.call, input).line + 1);
-        this.callExtract = lines[getLocation(e.call, input).line];
-        this.stack = e.stack;
-        this.column = col;
-        this.extract = [
-            lines[line - 1],
-            lines[line],
-            lines[line + 1]
-        ];
-    }
-
-    this.env = env = env || {};
-
-    // The optimization level dictates the thoroughness of the parser,
-    // the lower the number, the less nodes it will create in the tree.
-    // This could matter for debugging, or if you want to access
-    // the individual nodes in the tree.
-    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
-
-    this.env.filename = this.env.filename || null;
-
-    //
-    // The Parser
-    //
-    return parser = {
-
-        imports: imports,
-        //
-        // Parse an input string into an abstract syntax tree,
-        // call `callback` when done.
-        //
-        parse: function (str, callback) {
-            var root, start, end, zone, line, lines, buff = [], c, error = null;
-
-            i = j = current = furthest = 0;
-            input = str.replace(/\r\n/g, '\n');
-
-            // Split the input into chunks.
-            chunks = (function (chunks) {
-                var j = 0,
-                    skip = /[^"'`\{\}\/\(\)\\]+/g,
-                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
-                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
-                    level = 0,
-                    match,
-                    chunk = chunks[0],
-                    inParam;
-
-                for (var i = 0, c, cc; i < input.length; i++) {
-                    skip.lastIndex = i;
-                    if (match = skip.exec(input)) {
-                        if (match.index === i) {
-                            i += match[0].length;
-                            chunk.push(match[0]);
-                        }
-                    }
-                    c = input.charAt(i);
-                    comment.lastIndex = string.lastIndex = i;
-
-                    if (match = string.exec(input)) {
-                        if (match.index === i) {
-                            i += match[0].length;
-                            chunk.push(match[0]);
-                            c = input.charAt(i);
-                        }
-                    }
-
-                    if (!inParam && c === '/') {
-                        cc = input.charAt(i + 1);
-                        if (cc === '/' || cc === '*') {
-                            if (match = comment.exec(input)) {
-                                if (match.index === i) {
-                                    i += match[0].length;
-                                    chunk.push(match[0]);
-                                    c = input.charAt(i);
-                                }
-                            }
-                        }
-                    }
-
-                    switch (c) {
-                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
-                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
-                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
-                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
-                        default:                                    chunk.push(c);
-                    }
-                }
-                if (level > 0) {
-                    error = new(LessError)({
-                        index: i,
-                        type: 'Parse',
-                        message: "missing closing `}`",
-                        filename: env.filename
-                    }, env);
-                }
-
-                return chunks.map(function (c) { return c.join('') });;
-            })([[]]);
-
-            if (error) {
-                return callback(error);
-            }
-
-            // Start with the primary rule.
-            // The whole syntax tree is held under a Ruleset node,
-            // with the `root` property set to true, so no `{}` are
-            // output. The callback is called when the input is parsed.
-            try {
-                root = new(tree.Ruleset)([], $(this.parsers.primary));
-                root.root = true;
-            } catch (e) {
-                return callback(new(LessError)(e, env));
-            }
-
-            root.toCSS = (function (evaluate) {
-                var line, lines, column;
-
-                return function (options, variables) {
-                    var frames = [], importError;
-
-                    options = options || {};
-                    //
-                    // Allows setting variables with a hash, so:
-                    //
-                    //   `{ color: new(tree.Color)('#f01') }` will become:
-                    //
-                    //   new(tree.Rule)('@color',
-                    //     new(tree.Value)([
-                    //       new(tree.Expression)([
-                    //         new(tree.Color)('#f01')
-                    //       ])
-                    //     ])
-                    //   )
-                    //
-                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
-                        variables = Object.keys(variables).map(function (k) {
-                            var value = variables[k];
-
-                            if (! (value instanceof tree.Value)) {
-                                if (! (value instanceof tree.Expression)) {
-                                    value = new(tree.Expression)([value]);
-                                }
-                                value = new(tree.Value)([value]);
-                            }
-                            return new(tree.Rule)('@' + k, value, false, 0);
-                        });
-                        frames = [new(tree.Ruleset)(null, variables)];
-                    }
-
-                    try {
-                        var css = evaluate.call(this, { frames: frames })
-                                          .toCSS([], { compress: options.compress || false });
-                    } catch (e) {
-                        throw new(LessError)(e, env);
-                    }
-
-                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
-                        if (importError instanceof LessError) throw importError;
-                        else                                  throw new(LessError)(importError, env);
-                    }
-
-                    if (options.yuicompress && less.mode === 'node') {
-                        return require('./cssmin').compressor.cssmin(css);
-                    } else if (options.compress) {
-                        return css.replace(/(\s)+/g, "$1");
-                    } else {
-                        return css;
-                    }
-                };
-            })(root.eval);
-
-            // If `i` is smaller than the `input.length - 1`,
-            // it means the parser wasn't able to parse the whole
-            // string, so we've got a parsing error.
-            //
-            // We try to extract a \n delimited string,
-            // showing the line where the parse error occured.
-            // We split it up into two parts (the part which parsed,
-            // and the part which didn't), so we can color them differently.
-            if (i < input.length - 1) {
-                i = furthest;
-                lines = input.split('\n');
-                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
-
-                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
-
-                error = {
-                    type: "Parse",
-                    message: "Syntax Error on line " + line,
-                    index: i,
-                    filename: env.filename,
-                    line: line,
-                    column: column,
-                    extract: [
-                        lines[line - 2],
-                        lines[line - 1],
-                        lines[line]
-                    ]
-                };
-            }
-
-            if (this.imports.queue.length > 0) {
-                finish = function () { callback(error, root) };
-            } else {
-                callback(error, root);
-            }
-        },
-
-        //
-        // Here in, the parsing rules/functions
-        //
-        // The basic structure of the syntax tree generated is as follows:
-        //
-        //   Ruleset ->  Rule -> Value -> Expression -> Entity
-        //
-        // Here's some LESS code:
-        //
-        //    .class {
-        //      color: #fff;
-        //      border: 1px solid #000;
-        //      width: @w + 4px;
-        //      > .child {...}
-        //    }
-        //
-        // And here's what the parse tree might look like:
-        //
-        //     Ruleset (Selector '.class', [
-        //         Rule ("color",  Value ([Expression [Color #fff]]))
-        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
-        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
-        //         Ruleset (Selector [Element '>', '.child'], [...])
-        //     ])
-        //
-        //  In general, most rules will try to parse a token with the `$()` function, and if the return
-        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
-        //  first, before parsing, that's when we use `peek()`.
-        //
-        parsers: {
-            //
-            // The `primary` rule is the *entry* and *exit* point of the parser.
-            // The rules here can appear at any level of the parse tree.
-            //
-            // The recursive nature of the grammar is an interplay between the `block`
-            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
-            // as represented by this simplified grammar:
-            //
-            //     primary  →  (ruleset | rule)+
-            //     ruleset  →  selector+ block
-            //     block    →  '{' primary '}'
-            //
-            // Only at one point is the primary rule not called from the
-            // block rule: at the root level.
-            //
-            primary: function () {
-                var node, root = [];
-
-                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
-                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
-                               || $(/^[\s\n]+/)) {
-                    node && root.push(node);
-                }
-                return root;
-            },
-
-            // We create a Comment node for CSS comments `/* */`,
-            // but keep the LeSS comments `//` silent, by just skipping
-            // over them.
-            comment: function () {
-                var comment;
-
-                if (input.charAt(i) !== '/') return;
-
-                if (input.charAt(i + 1) === '/') {
-                    return new(tree.Comment)($(/^\/\/.*/), true);
-                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
-                    return new(tree.Comment)(comment);
-                }
-            },
-
-            //
-            // Entities are tokens which can be found inside an Expression
-            //
-            entities: {
-                //
-                // A string, which supports escaping " and '
-                //
-                //     "milky way" 'he\'s the one!'
-                //
-                quoted: function () {
-                    var str, j = i, e;
-
-                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
-                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
-
-                    e && $('~');
-
-                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
-                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
-                    }
-                },
-
-                //
-                // A catch-all word, such as:
-                //
-                //     black border-collapse
-                //
-                keyword: function () {
-                    var k;
-
-                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
-                        if (tree.colors.hasOwnProperty(k)) {
-                            // detect named color
-                            return new(tree.Color)(tree.colors[k].slice(1));
-                        } else {
-                            return new(tree.Keyword)(k);
-                        }
-                    }
-                },
-
-                //
-                // A function call
-                //
-                //     rgb(255, 0, 255)
-                //
-                // We also try to catch IE's `alpha()`, but let the `alpha` parser
-                // deal with the details.
-                //
-                // The arguments are parsed with the `entities.arguments` parser.
-                //
-                call: function () {
-                    var name, args, index = i;
-
-                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
-
-                    name = name[1].toLowerCase();
-
-                    if (name === 'url') { return null }
-                    else                { i += name.length }
-
-                    if (name === 'alpha') { return $(this.alpha) }
-
-                    $('('); // Parse the '(' and consume whitespace.
-
-                    args = $(this.entities.arguments);
-
-                    if (! $(')')) return;
-
-                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
-                },
-                arguments: function () {
-                    var args = [], arg;
-
-                    while (arg = $(this.entities.assignment) || $(this.expression)) {
-                        args.push(arg);
-                        if (! $(',')) { break }
-                    }
-                    return args;
-                },
-                literal: function () {
-                    return $(this.entities.dimension) ||
-                           $(this.entities.color) ||
-                           $(this.entities.quoted);
-                },
-
-                // Assignments are argument entities for calls.
-                // They are present in ie filter properties as shown below.
-                //
-                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
-                //
-
-                assignment: function () {
-                    var key, value;
-                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
-                        return new(tree.Assignment)(key, value);
-                    }
-                },
-
-                //
-                // Parse url() tokens
-                //
-                // We use a specific rule for urls, because they don't really behave like
-                // standard function calls. The difference is that the argument doesn't have
-                // to be enclosed within a string, so it can't be parsed as an Expression.
-                //
-                url: function () {
-                    var value;
-
-                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
-                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
-                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
-
-                    expect(')');
-
-                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
-                                        ? value : new(tree.Anonymous)(value), imports.paths);
-                },
-
-                dataURI: function () {
-                    var obj;
-
-                    if ($(/^data:/)) {
-                        obj         = {};
-                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
-                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
-                        obj.base64  = $(/^;\s*base64/)          || '';
-                        obj.data    = $(/^,\s*[^)]+/);
-
-                        if (obj.data) { return obj }
-                    }
-                },
-
-                //
-                // A Variable entity, such as `@fink`, in
-                //
-                //     width: @fink + 2px
-                //
-                // We use a different parser for variable definitions,
-                // see `parsers.variable`.
-                //
-                variable: function () {
-                    var name, index = i;
-
-                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
-                        return new(tree.Variable)(name, index, env.filename);
-                    }
-                },
-
-                //
-                // A Hexadecimal color
-                //
-                //     #4F3C2F
-                //
-                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
-                //
-                color: function () {
-                    var rgb;
-
-                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
-                        return new(tree.Color)(rgb[1]);
-                    }
-                },
-
-                //
-                // A Dimension, that is, a number and a unit
-                //
-                //     0.5em 95%
-                //
-                dimension: function () {
-                    var value, c = input.charCodeAt(i);
-                    if ((c > 57 || c < 45) || c === 47) return;
-
-                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
-                        return new(tree.Dimension)(value[1], value[2]);
-                    }
-                },
-
-                //
-                // JavaScript code to be evaluated
-                //
-                //     `window.location.href`
-                //
-                javascript: function () {
-                    var str, j = i, e;
-
-                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
-                    if (input.charAt(j) !== '`') { return }
-
-                    e && $('~');
-
-                    if (str = $(/^`([^`]*)`/)) {
-                        return new(tree.JavaScript)(str[1], i, e);
-                    }
-                }
-            },
-
-            //
-            // The variable part of a variable definition. Used in the `rule` parser
-            //
-            //     @fink:
-            //
-            variable: function () {
-                var name;
-
-                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
-            },
-
-            //
-            // A font size/line-height shorthand
-            //
-            //     small/12px
-            //
-            // We need to peek first, or we'll match on keywords and dimensions
-            //
-            shorthand: function () {
-                var a, b;
-
-                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
-
-                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
-                    return new(tree.Shorthand)(a, b);
-                }
-            },
-
-            //
-            // Mixins
-            //
-            mixin: {
-                //
-                // A Mixin call, with an optional argument list
-                //
-                //     #mixins > .square(#fff);
-                //     .rounded(4px, black);
-                //     .button;
-                //
-                // The `while` loop is there because mixins can be
-                // namespaced, but we only support the child and descendant
-                // selector for now.
-                //
-                call: function () {
-                    var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
-
-                    if (s !== '.' && s !== '#') { return }
-
-                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
-                        elements.push(new(tree.Element)(c, e, i));
-                        c = $('>');
-                    }
-                    $('(') && (args = $(this.entities.arguments)) && $(')');
-
-                    if ($(this.important)) {
-                        important = true;
-                    }
-
-                    if (elements.length > 0 && ($(';') || peek('}'))) {
-                        return new(tree.mixin.Call)(elements, args || [], index, env.filename, important);
-                    }
-                },
-
-                //
-                // A Mixin definition, with a list of parameters
-                //
-                //     .rounded (@radius: 2px, @color) {
-                //        ...
-                //     }
-                //
-                // Until we have a finer grained state-machine, we have to
-                // do a look-ahead, to make sure we don't have a mixin call.
-                // See the `rule` function for more information.
-                //
-                // We start by matching `.rounded (`, and then proceed on to
-                // the argument list, which has optional default values.
-                // We store the parameters in `params`, with a `value` key,
-                // if there is a value, such as in the case of `@radius`.
-                //
-                // Once we've got our params list, and a closing `)`, we parse
-                // the `{...}` block.
-                //
-                definition: function () {
-                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
-                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
-                        peek(/^[^{]*(;|})/)) return;
-
-                    save();
-
-                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
-                        name = match[1];
-
-                        do {
-                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
-                                variadic = true;
-                                break;
-                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
-                                                                         || $(this.entities.keyword)) {
-                                // Variable
-                                if (param instanceof tree.Variable) {
-                                    if ($(':')) {
-                                        value = expect(this.expression, 'expected expression');
-                                        params.push({ name: param.name, value: value });
-                                    } else if ($(/^\.{3}/)) {
-                                        params.push({ name: param.name, variadic: true });
-                                        variadic = true;
-                                        break;
-                                    } else {
-                                        params.push({ name: param.name });
-                                    }
-                                } else {
-                                    params.push({ value: param });
-                                }
-                            } else {
-                                break;
-                            }
-                        } while ($(','))
-
-                        expect(')');
-
-                        if ($(/^when/)) { // Guard
-                            cond = expect(this.conditions, 'expected condition');
-                        }
-
-                        ruleset = $(this.block);
-
-                        if (ruleset) {
-                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
-                        } else {
-                            restore();
-                        }
-                    }
-                }
-            },
-
-            //
-            // Entities are the smallest recognized token,
-            // and can be found inside a rule's value.
-            //
-            entity: function () {
-                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
-                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
-                       $(this.comment);
-            },
-
-            //
-            // A Rule terminator. Note that we use `peek()` to check for '}',
-            // because the `block` rule will be expecting it, but we still need to make sure
-            // it's there, if ';' was ommitted.
-            //
-            end: function () {
-                return $(';') || peek('}');
-            },
-
-            //
-            // IE's alpha function
-            //
-            //     alpha(opacity=88)
-            //
-            alpha: function () {
-                var value;
-
-                if (! $(/^\(opacity=/i)) return;
-                if (value = $(/^\d+/) || $(this.entities.variable)) {
-                    expect(')');
-                    return new(tree.Alpha)(value);
-                }
-            },
-
-            //
-            // A Selector Element
-            //
-            //     div
-            //     + h1
-            //     #socks
-            //     input[type="text"]
-            //
-            // Elements are the building blocks for Selectors,
-            // they are made out of a `Combinator` (see combinator rule),
-            // and an element name, such as a tag a class, or `*`.
-            //
-            element: function () {
-                var e, t, c, v;
-
-                c = $(this.combinator);
-                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
-                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
-
-                if (! e) {
-                    $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
-                }
-
-                if (e) { return new(tree.Element)(c, e, i) }
-
-                if (c.value && c.value.charAt(0) === '&') {
-                    return new(tree.Element)(c, null, i);
-                }
-            },
-
-            //
-            // Combinators combine elements together, in a Selector.
-            //
-            // Because our parser isn't white-space sensitive, special care
-            // has to be taken, when parsing the descendant combinator, ` `,
-            // as it's an empty space. We have to check the previous character
-            // in the input, to see if it's a ` ` character. More info on how
-            // we deal with this in *combinator.js*.
-            //
-            combinator: function () {
-                var match, c = input.charAt(i);
-
-                if (c === '>' || c === '+' || c === '~') {
-                    i++;
-                    while (input.charAt(i) === ' ') { i++ }
-                    return new(tree.Combinator)(c);
-                } else if (c === '&') {
-                    match = '&';
-                    i++;
-                    if(input.charAt(i) === ' ') {
-                        match = '& ';
-                    }
-                    while (input.charAt(i) === ' ') { i++ }
-                    return new(tree.Combinator)(match);
-                } else if (input.charAt(i - 1) === ' ') {
-                    return new(tree.Combinator)(" ");
-                } else {
-                    return new(tree.Combinator)(null);
-                }
-            },
-
-            //
-            // A CSS Selector
-            //
-            //     .class > div + h1
-            //     li a:hover
-            //
-            // Selectors are made out of one or more Elements, see above.
-            //
-            selector: function () {
-                var sel, e, elements = [], c, match;
-
-                if ($('(')) {
-                    sel = $(this.entity);
-                    expect(')');
-                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
-                }
-
-                while (e = $(this.element)) {
-                    c = input.charAt(i);
-                    elements.push(e)
-                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
-                }
-
-                if (elements.length > 0) { return new(tree.Selector)(elements) }
-            },
-            tag: function () {
-                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
-            },
-            attribute: function () {
-                var attr = '', key, val, op;
-
-                if (! $('[')) return;
-
-                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
-                    if ((op = $(/^[|~*$^]?=/)) &&
-                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
-                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
-                    } else { attr = key }
-                }
-
-                if (! $(']')) return;
-
-                if (attr) { return "[" + attr + "]" }
-            },
-
-            //
-            // The `block` rule is used by `ruleset` and `mixin.definition`.
-            // It's a wrapper around the `primary` rule, with added `{}`.
-            //
-            block: function () {
-                var content;
-
-                if ($('{') && (content = $(this.primary)) && $('}')) {
-                    return content;
-                }
-            },
-
-            //
-            // div, .class, body > p {...}
-            //
-            ruleset: function () {
-                var selectors = [], s, rules, match;
-                save();
-
-                while (s = $(this.selector)) {
-                    selectors.push(s);
-                    $(this.comment);
-                    if (! $(',')) { break }
-                    $(this.comment);
-                }
-
-                if (selectors.length > 0 && (rules = $(this.block))) {
-                    return new(tree.Ruleset)(selectors, rules, env.strictImports);
-                } else {
-                    // Backtrack
-                    furthest = i;
-                    restore();
-                }
-            },
-            rule: function () {
-                var name, value, c = input.charAt(i), important, match;
-                save();
-
-                if (c === '.' || c === '#' || c === '&') { return }
-
-                if (name = $(this.variable) || $(this.property)) {
-                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
-                        i += match[0].length - 1;
-                        value = new(tree.Anonymous)(match[1]);
-                    } else if (name === "font") {
-                        value = $(this.font);
-                    } else {
-                        value = $(this.value);
-                    }
-                    important = $(this.important);
-
-                    if (value && $(this.end)) {
-                        return new(tree.Rule)(name, value, important, memo);
-                    } else {
-                        furthest = i;
-                        restore();
-                    }
-                }
-            },
-
-            //
-            // An @import directive
-            //
-            //     @import "lib";
-            //
-            // Depending on our environemnt, importing is done differently:
-            // In the browser, it's an XHR request, in Node, it would be a
-            // file-system operation. The function used for importing is
-            // stored in `import`, which we pass to the Import constructor.
-            //
-            "import": function () {
-                var path, features, index = i;
-                if ($(/^@import\s+/) &&
-                    (path = $(this.entities.quoted) || $(this.entities.url))) {
-                    features = $(this.mediaFeatures);
-                    if ($(';')) {
-                        return new(tree.Import)(path, imports, features, index);
-                    }
-                }
-            },
-
-            mediaFeature: function () {
-                var e, p, nodes = [];
-
-                do {
-                    if (e = $(this.entities.keyword)) {
-                        nodes.push(e);
-                    } else if ($('(')) {
-                        p = $(this.property);
-                        e = $(this.entity);
-                        if ($(')')) {
-                            if (p && e) {
-                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
-                            } else if (e) {
-                                nodes.push(new(tree.Paren)(e));
-                            } else {
-                                return null;
-                            }
-                        } else { return null }
-                    }
-                } while (e);
-
-                if (nodes.length > 0) {
-                    return new(tree.Expression)(nodes);
-                }
-            },
-
-            mediaFeatures: function () {
-                var e, features = [];
-                
-                do {
-                  if (e = $(this.mediaFeature)) {
-                      features.push(e);
-                      if (! $(',')) { break }
-                  } else if (e = $(this.entities.variable)) {
-                      features.push(e);
-                      if (! $(',')) { break }
-                  }
-                } while (e);
-                
-                return features.length > 0 ? features : null;
-            },
-
-            media: function () {
-                var features, rules;
-
-                if ($(/^@media/)) {
-                    features = $(this.mediaFeatures);
-
-                    if (rules = $(this.block)) {
-                        return new(tree.Media)(rules, features);
-                    }
-                }
-            },
-
-            //
-            // A CSS Directive
-            //
-            //     @charset "utf-8";
-            //
-            directive: function () {
-                var name, value, rules, types, e, nodes;
-
-                if (input.charAt(i) !== '@') return;
-
-                if (value = $(this['import']) || $(this.media)) {
-                    return value;
-                } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
-                    types = ($(/^[^{]+/) || '').trim();
-                    if (rules = $(this.block)) {
-                        return new(tree.Directive)(name + " " + types, rules);
-                    }
-                } else if (name = $(/^@[-a-z]+/)) {
-                    if (name === '@font-face') {
-                        if (rules = $(this.block)) {
-                            return new(tree.Directive)(name, rules);
-                        }
-                    } else if ((value = $(this.entity)) && $(';')) {
-                        return new(tree.Directive)(name, value);
-                    }
-                }
-            },
-            font: function () {
-                var value = [], expression = [], weight, shorthand, font, e;
-
-                while (e = $(this.shorthand) || $(this.entity)) {
-                    expression.push(e);
-                }
-                value.push(new(tree.Expression)(expression));
-
-                if ($(',')) {
-                    while (e = $(this.expression)) {
-                        value.push(e);
-                        if (! $(',')) { break }
-                    }
-                }
-                return new(tree.Value)(value);
-            },
-
-            //
-            // A Value is a comma-delimited list of Expressions
-            //
-            //     font-family: Baskerville, Georgia, serif;
-            //
-            // In a Rule, a Value represents everything after the `:`,
-            // and before the `;`.
-            //
-            value: function () {
-                var e, expressions = [], important;
-
-                while (e = $(this.expression)) {
-                    expressions.push(e);
-                    if (! $(',')) { break }
-                }
-
-                if (expressions.length > 0) {
-                    return new(tree.Value)(expressions);
-                }
-            },
-            important: function () {
-                if (input.charAt(i) === '!') {
-                    return $(/^! *important/);
-                }
-            },
-            sub: function () {
-                var e;
-
-                if ($('(') && (e = $(this.expression)) && $(')')) {
-                    return e;
-                }
-            },
-            multiplication: function () {
-                var m, a, op, operation;
-                if (m = $(this.operand)) {
-                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
-                        operation = new(tree.Operation)(op, [operation || m, a]);
-                    }
-                    return operation || m;
-                }
-            },
-            addition: function () {
-                var m, a, op, operation;
-                if (m = $(this.multiplication)) {
-                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
-                           (a = $(this.multiplication))) {
-                        operation = new(tree.Operation)(op, [operation || m, a]);
-                    }
-                    return operation || m;
-                }
-            },
-            conditions: function () {
-                var a, b, index = i, condition;
-
-                if (a = $(this.condition)) {
-                    while ($(',') && (b = $(this.condition))) {
-                        condition = new(tree.Condition)('or', condition || a, b, index);
-                    }
-                    return condition || a;
-                }
-            },
-            condition: function () {
-                var a, b, c, op, index = i, negate = false;
-
-                if ($(/^not/)) { negate = true }
-                expect('(');
-                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
-                    if (op = $(/^(?:>=|=<|[<=>])/)) {
-                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
-                            c = new(tree.Condition)(op, a, b, index, negate);
-                        } else {
-                            error('expected expression');
-                        }
-                    } else {
-                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
-                    }
-                    expect(')');
-                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
-                }
-            },
-
-            //
-            // An operand is anything that can be part of an operation,
-            // such as a Color, or a Variable
-            //
-            operand: function () {
-                var negate, p = input.charAt(i + 1);
-
-                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
-                var o = $(this.sub) || $(this.entities.dimension) ||
-                        $(this.entities.color) || $(this.entities.variable) ||
-                        $(this.entities.call);
-                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
-                              : o;
-            },
-
-            //
-            // Expressions either represent mathematical operations,
-            // or white-space delimited Entities.
-            //
-            //     1px solid black
-            //     @var * 2
-            //
-            expression: function () {
-                var e, delim, entities = [], d;
-
-                while (e = $(this.addition) || $(this.entity)) {
-                    entities.push(e);
-                }
-                if (entities.length > 0) {
-                    return new(tree.Expression)(entities);
-                }
-            },
-            property: function () {
-                var name;
-
-                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
-                    return name[1];
-                }
-            }
-        }
-    };
-};
-
-if (less.mode === 'browser' || less.mode === 'rhino') {
-    //
-    // Used by `@import` directives
-    //
-    less.Parser.importer = function (path, paths, callback, env) {
-        if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
-            path = paths[0] + path;
-        }
-        // We pass `true` as 3rd argument, to force the reload of the import.
-        // This is so we can get the syntax tree as opposed to just the CSS output,
-        // as we need this to evaluate the current stylesheet.
-        loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
-            if (e && typeof(env.errback) === "function") {
-                env.errback.call(null, path, paths, callback, env);
-            } else {
-                callback.apply(null, arguments);
-            }
-        }, true);
-    };
-}
-
-(function (tree) {
-
-tree.functions = {
-    rgb: function (r, g, b) {
-        return this.rgba(r, g, b, 1.0);
-    },
-    rgba: function (r, g, b, a) {
-        var rgb = [r, g, b].map(function (c) { return number(c) }),
-            a = number(a);
-        return new(tree.Color)(rgb, a);
-    },
-    hsl: function (h, s, l) {
-        return this.hsla(h, s, l, 1.0);
-    },
-    hsla: function (h, s, l, a) {
-        h = (number(h) % 360) / 360;
-        s = number(s); l = number(l); a = number(a);
-
-        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
-        var m1 = l * 2 - m2;
-
-        return this.rgba(hue(h + 1/3) * 255,
-                         hue(h)       * 255,
-                         hue(h - 1/3) * 255,
-                         a);
-
-        function hue(h) {
-            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
-            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
-            else if (h * 2 < 1) return m2;
-            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
-            else                return m1;
-        }
-    },
-    hue: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().h));
-    },
-    saturation: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
-    },
-    lightness: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
-    },
-    alpha: function (color) {
-        return new(tree.Dimension)(color.toHSL().a);
-    },
-    saturate: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.s += amount.value / 100;
-        hsl.s = clamp(hsl.s);
-        return hsla(hsl);
-    },
-    desaturate: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.s -= amount.value / 100;
-        hsl.s = clamp(hsl.s);
-        return hsla(hsl);
-    },
-    lighten: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.l += amount.value / 100;
-        hsl.l = clamp(hsl.l);
-        return hsla(hsl);
-    },
-    darken: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.l -= amount.value / 100;
-        hsl.l = clamp(hsl.l);
-        return hsla(hsl);
-    },
-    fadein: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.a += amount.value / 100;
-        hsl.a = clamp(hsl.a);
-        return hsla(hsl);
-    },
-    fadeout: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.a -= amount.value / 100;
-        hsl.a = clamp(hsl.a);
-        return hsla(hsl);
-    },
-    fade: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.a = amount.value / 100;
-        hsl.a = clamp(hsl.a);
-        return hsla(hsl);
-    },
-    spin: function (color, amount) {
-        var hsl = color.toHSL();
-        var hue = (hsl.h + amount.value) % 360;
-
-        hsl.h = hue < 0 ? 360 + hue : hue;
-
-        return hsla(hsl);
-    },
-    //
-    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
-    // http://sass-lang.com
-    //
-    mix: function (color1, color2, weight) {
-        var p = weight.value / 100.0;
-        var w = p * 2 - 1;
-        var a = color1.toHSL().a - color2.toHSL().a;
-
-        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
-        var w2 = 1 - w1;
-
-        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
-                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
-                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
-
-        var alpha = color1.alpha * p + color2.alpha * (1 - p);
-
-        return new(tree.Color)(rgb, alpha);
-    },
-    greyscale: function (color) {
-        return this.desaturate(color, new(tree.Dimension)(100));
-    },
-    e: function (str) {
-        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
-    },
-    escape: function (str) {
-        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
-    },
-    '%': function (quoted /* arg, arg, ...*/) {
-        var args = Array.prototype.slice.call(arguments, 1),
-            str = quoted.value;
-
-        for (var i = 0; i < args.length; i++) {
-            str = str.replace(/%[sda]/i, function(token) {
-                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
-                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
-            });
-        }
-        str = str.replace(/%%/g, '%');
-        return new(tree.Quoted)('"' + str + '"', str);
-    },
-    round: function (n) {
-        return this._math('round', n);
-    },
-    ceil: function (n) {
-        return this._math('ceil', n);
-    },
-    floor: function (n) {
-        return this._math('floor', n);
-    },
-    _math: function (fn, n) {
-        if (n instanceof tree.Dimension) {
-            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
-        } else if (typeof(n) === 'number') {
-            return Math[fn](n);
-        } else {
-            throw { type: "Argument", message: "argument must be a number" };
-        }
-    },
-    argb: function (color) {
-        return new(tree.Anonymous)(color.toARGB());
-
-    },
-    percentage: function (n) {
-        return new(tree.Dimension)(n.value * 100, '%');
-    },
-    color: function (n) {
-        if (n instanceof tree.Quoted) {
-            return new(tree.Color)(n.value.slice(1));
-        } else {
-            throw { type: "Argument", message: "argument must be a string" };
-        }
-    },
-    iscolor: function (n) {
-        return this._isa(n, tree.Color);
-    },
-    isnumber: function (n) {
-        return this._isa(n, tree.Dimension);
-    },
-    isstring: function (n) {
-        return this._isa(n, tree.Quoted);
-    },
-    iskeyword: function (n) {
-        return this._isa(n, tree.Keyword);
-    },
-    isurl: function (n) {
-        return this._isa(n, tree.URL);
-    },
-    ispixel: function (n) {
-        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
-    },
-    ispercentage: function (n) {
-        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
-    },
-    isem: function (n) {
-        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
-    },
-    _isa: function (n, Type) {
-        return (n instanceof Type) ? tree.True : tree.False;
-    }
-};
-
-function hsla(hsla) {
-    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
-}
-
-function number(n) {
-    if (n instanceof tree.Dimension) {
-        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
-    } else if (typeof(n) === 'number') {
-        return n;
-    } else {
-        throw {
-            error: "RuntimeError",
-            message: "color functions take numbers as parameters"
-        };
-    }
-}
-
-function clamp(val) {
-    return Math.min(1, Math.max(0, val));
-}
-
-})(require('./tree'));
-(function (tree) {
-    tree.colors = {
-        'aliceblue':'#f0f8ff',
-        'antiquewhite':'#faebd7',
-        'aqua':'#00ffff',
-        'aquamarine':'#7fffd4',
-        'azure':'#f0ffff',
-        'beige':'#f5f5dc',
-        'bisque':'#ffe4c4',
-        'black':'#000000',
-        'blanchedalmond':'#ffebcd',
-        'blue':'#0000ff',
-        'blueviolet':'#8a2be2',
-        'brown':'#a52a2a',
-        'burlywood':'#deb887',
-        'cadetblue':'#5f9ea0',
-        'chartreuse':'#7fff00',
-        'chocolate':'#d2691e',
-        'coral':'#ff7f50',
-        'cornflowerblue':'#6495ed',
-        'cornsilk':'#fff8dc',
-        'crimson':'#dc143c',
-        'cyan':'#00ffff',
-        'darkblue':'#00008b',
-        'darkcyan':'#008b8b',
-        'darkgoldenrod':'#b8860b',
-        'darkgray':'#a9a9a9',
-        'darkgrey':'#a9a9a9',
-        'darkgreen':'#006400',
-        'darkkhaki':'#bdb76b',
-        'darkmagenta':'#8b008b',
-        'darkolivegreen':'#556b2f',
-        'darkorange':'#ff8c00',
-        'darkorchid':'#9932cc',
-        'darkred':'#8b0000',
-        'darksalmon':'#e9967a',
-        'darkseagreen':'#8fbc8f',
-        'darkslateblue':'#483d8b',
-        'darkslategray':'#2f4f4f',
-        'darkslategrey':'#2f4f4f',
-        'darkturquoise':'#00ced1',
-        'darkviolet':'#9400d3',
-        'deeppink':'#ff1493',
-        'deepskyblue':'#00bfff',
-        'dimgray':'#696969',
-        'dimgrey':'#696969',
-        'dodgerblue':'#1e90ff',
-        'firebrick':'#b22222',
-        'floralwhite':'#fffaf0',
-        'forestgreen':'#228b22',
-        'fuchsia':'#ff00ff',
-        'gainsboro':'#dcdcdc',
-        'ghostwhite':'#f8f8ff',
-        'gold':'#ffd700',
-        'goldenrod':'#daa520',
-        'gray':'#808080',
-        'grey':'#808080',
-        'green':'#008000',
-        'greenyellow':'#adff2f',
-        'honeydew':'#f0fff0',
-        'hotpink':'#ff69b4',
-        'indianred':'#cd5c5c',
-        'indigo':'#4b0082',
-        'ivory':'#fffff0',
-        'khaki':'#f0e68c',
-        'lavender':'#e6e6fa',
-        'lavenderblush':'#fff0f5',
-        'lawngreen':'#7cfc00',
-        'lemonchiffon':'#fffacd',
-        'lightblue':'#add8e6',
-        'lightcoral':'#f08080',
-        'lightcyan':'#e0ffff',
-        'lightgoldenrodyellow':'#fafad2',
-        'lightgray':'#d3d3d3',
-        'lightgrey':'#d3d3d3',
-        'lightgreen':'#90ee90',
-        'lightpink':'#ffb6c1',
-        'lightsalmon':'#ffa07a',
-        'lightseagreen':'#20b2aa',
-        'lightskyblue':'#87cefa',
-        'lightslategray':'#778899',
-        'lightslategrey':'#778899',
-        'lightsteelblue':'#b0c4de',
-        'lightyellow':'#ffffe0',
-        'lime':'#00ff00',
-        'limegreen':'#32cd32',
-        'linen':'#faf0e6',
-        'magenta':'#ff00ff',
-        'maroon':'#800000',
-        'mediumaquamarine':'#66cdaa',
-        'mediumblue':'#0000cd',
-        'mediumorchid':'#ba55d3',
-        'mediumpurple':'#9370d8',
-        'mediumseagreen':'#3cb371',
-        'mediumslateblue':'#7b68ee',
-        'mediumspringgreen':'#00fa9a',
-        'mediumturquoise':'#48d1cc',
-        'mediumvioletred':'#c71585',
-        'midnightblue':'#191970',
-        'mintcream':'#f5fffa',
-        'mistyrose':'#ffe4e1',
-        'moccasin':'#ffe4b5',
-        'navajowhite':'#ffdead',
-        'navy':'#000080',
-        'oldlace':'#fdf5e6',
-        'olive':'#808000',
-        'olivedrab':'#6b8e23',
-        'orange':'#ffa500',
-        'orangered':'#ff4500',
-        'orchid':'#da70d6',
-        'palegoldenrod':'#eee8aa',
-        'palegreen':'#98fb98',
-        'paleturquoise':'#afeeee',
-        'palevioletred':'#d87093',
-        'papayawhip':'#ffefd5',
-        'peachpuff':'#ffdab9',
-        'peru':'#cd853f',
-        'pink':'#ffc0cb',
-        'plum':'#dda0dd',
-        'powderblue':'#b0e0e6',
-        'purple':'#800080',
-        'red':'#ff0000',
-        'rosybrown':'#bc8f8f',
-        'royalblue':'#4169e1',
-        'saddlebrown':'#8b4513',
-        'salmon':'#fa8072',
-        'sandybrown':'#f4a460',
-        'seagreen':'#2e8b57',
-        'seashell':'#fff5ee',
-        'sienna':'#a0522d',
-        'silver':'#c0c0c0',
-        'skyblue':'#87ceeb',
-        'slateblue':'#6a5acd',
-        'slategray':'#708090',
-        'slategrey':'#708090',
-        'snow':'#fffafa',
-        'springgreen':'#00ff7f',
-        'steelblue':'#4682b4',
-        'tan':'#d2b48c',
-        'teal':'#008080',
-        'thistle':'#d8bfd8',
-        'tomato':'#ff6347',
-        'turquoise':'#40e0d0',
-        'violet':'#ee82ee',
-        'wheat':'#f5deb3',
-        'white':'#ffffff',
-        'whitesmoke':'#f5f5f5',
-        'yellow':'#ffff00',
-        'yellowgreen':'#9acd32'
-    };
-})(require('./tree'));
-(function (tree) {
-
-tree.Alpha = function (val) {
-    this.value = val;
-};
-tree.Alpha.prototype = {
-    toCSS: function () {
-        return "alpha(opacity=" +
-               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
-    },
-    eval: function (env) {
-        if (this.value.eval) { this.value = this.value.eval(env) }
-        return this;
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Anonymous = function (string) {
-    this.value = string.value || string;
-};
-tree.Anonymous.prototype = {
-    toCSS: function () {
-        return this.value;
-    },
-    eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Assignment = function (key, val) {
-    this.key = key;
-    this.value = val;
-};
-tree.Assignment.prototype = {
-    toCSS: function () {
-        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
-    },
-    eval: function (env) {
-        if (this.value.eval) { this.value = this.value.eval(env) }
-        return this;
-    }
-};
-
-})(require('../tree'));(function (tree) {
-
-//
-// A function call node.
-//
-tree.Call = function (name, args, index, filename) {
-    this.name = name;
-    this.args = args;
-    this.index = index;
-    this.filename = filename;
-};
-tree.Call.prototype = {
-    //
-    // When evaluating a function call,
-    // we either find the function in `tree.functions` [1],
-    // in which case we call it, passing the  evaluated arguments,
-    // or we simply print it out as it appeared originally [2].
-    //
-    // The *functions.js* file contains the built-in functions.
-    //
-    // The reason why we evaluate the arguments, is in the case where
-    // we try to pass a variable to a function, like: `saturate(@color)`.
-    // The function should receive the value, not the variable.
-    //
-    eval: function (env) {
-        var args = this.args.map(function (a) { return a.eval(env) });
-
-        if (this.name in tree.functions) { // 1.
-            try {
-                return tree.functions[this.name].apply(tree.functions, args);
-            } catch (e) {
-                throw { type: e.type || "Runtime",
-                        message: "error evaluating function `" + this.name + "`" +
-                                 (e.message ? ': ' + e.message : ''),
-                        index: this.index, filename: this.filename };
-            }
-        } else { // 2.
-            return new(tree.Anonymous)(this.name +
-                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
-        }
-    },
-
-    toCSS: function (env) {
-        return this.eval(env).toCSS();
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// RGB Colors - #ff0014, #eee
-//
-tree.Color = function (rgb, a) {
-    //
-    // The end goal here, is to parse the arguments
-    // into an integer triplet, such as `128, 255, 0`
-    //
-    // This facilitates operations and conversions.
-    //
-    if (Array.isArray(rgb)) {
-        this.rgb = rgb;
-    } else if (rgb.length == 6) {
-        this.rgb = rgb.match(/.{2}/g).map(function (c) {
-            return parseInt(c, 16);
-        });
-    } else {
-        this.rgb = rgb.split('').map(function (c) {
-            return parseInt(c + c, 16);
-        });
-    }
-    this.alpha = typeof(a) === 'number' ? a : 1;
-};
-tree.Color.prototype = {
-    eval: function () { return this },
-
-    //
-    // If we have some transparency, the only way to represent it
-    // is via `rgba`. Otherwise, we use the hex representation,
-    // which has better compatibility with older browsers.
-    // Values are capped between `0` and `255`, rounded and zero-padded.
-    //
-    toCSS: function () {
-        if (this.alpha < 1.0) {
-            return "rgba(" + this.rgb.map(function (c) {
-                return Math.round(c);
-            }).concat(this.alpha).join(', ') + ")";
-        } else {
-            return '#' + this.rgb.map(function (i) {
-                i = Math.round(i);
-                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
-                return i.length === 1 ? '0' + i : i;
-            }).join('');
-        }
-    },
-
-    //
-    // Operations have to be done per-channel, if not,
-    // channels will spill onto each other. Once we have
-    // our result, in the form of an integer triplet,
-    // we create a new Color node to hold the result.
-    //
-    operate: function (op, other) {
-        var result = [];
-
-        if (! (other instanceof tree.Color)) {
-            other = other.toColor();
-        }
-
-        for (var c = 0; c < 3; c++) {
-            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
-        }
-        return new(tree.Color)(result, this.alpha + other.alpha);
-    },
-
-    toHSL: function () {
-        var r = this.rgb[0] / 255,
-            g = this.rgb[1] / 255,
-            b = this.rgb[2] / 255,
-            a = this.alpha;
-
-        var max = Math.max(r, g, b), min = Math.min(r, g, b);
-        var h, s, l = (max + min) / 2, d = max - min;
-
-        if (max === min) {
-            h = s = 0;
-        } else {
-            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
-            switch (max) {
-                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
-                case g: h = (b - r) / d + 2;               break;
-                case b: h = (r - g) / d + 4;               break;
-            }
-            h /= 6;
-        }
-        return { h: h * 360, s: s, l: l, a: a };
-    },
-    toARGB: function () {
-        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
-        return '#' + argb.map(function (i) {
-            i = Math.round(i);
-            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
-            return i.length === 1 ? '0' + i : i;
-        }).join('');
-    }
-};
-
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Comment = function (value, silent) {
-    this.value = value;
-    this.silent = !!silent;
-};
-tree.Comment.prototype = {
-    toCSS: function (env) {
-        return env.compress ? '' : this.value;
-    },
-    eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Condition = function (op, l, r, i, negate) {
-    this.op = op.trim();
-    this.lvalue = l;
-    this.rvalue = r;
-    this.index = i;
-    this.negate = negate;
-};
-tree.Condition.prototype.eval = function (env) {
-    var a = this.lvalue.eval(env),
-        b = this.rvalue.eval(env);
-
-    var i = this.index, result;
-
-    var result = (function (op) {
-        switch (op) {
-            case 'and':
-                return a && b;
-            case 'or':
-                return a || b;
-            default:
-                if (a.compare) {
-                    result = a.compare(b);
-                } else if (b.compare) {
-                    result = b.compare(a);
-                } else {
-                    throw { type: "Type",
-                            message: "Unable to perform comparison",
-                            index: i };
-                }
-                switch (result) {
-                    case -1: return op === '<' || op === '=<';
-                    case  0: return op === '=' || op === '>=' || op === '=<';
-                    case  1: return op === '>' || op === '>=';
-                }
-        }
-    })(this.op);
-    return this.negate ? !result : result;
-};
-
-})(require('../tree'));
-(function (tree) {
-
-//
-// A number with a unit
-//
-tree.Dimension = function (value, unit) {
-    this.value = parseFloat(value);
-    this.unit = unit || null;
-};
-
-tree.Dimension.prototype = {
-    eval: function () { return this },
-    toColor: function () {
-        return new(tree.Color)([this.value, this.value, this.value]);
-    },
-    toCSS: function () {
-        var css = this.value + this.unit;
-        return css;
-    },
-
-    // In an operation between two Dimensions,
-    // we default to the first Dimension's unit,
-    // so `1px + 2em` will yield `3px`.
-    // In the future, we could implement some unit
-    // conversions such that `100cm + 10mm` would yield
-    // `101cm`.
-    operate: function (op, other) {
-        return new(tree.Dimension)
-                  (tree.operate(op, this.value, other.value),
-                  this.unit || other.unit);
-    },
-
-    // TODO: Perform unit conversion before comparing
-    compare: function (other) {
-        if (other instanceof tree.Dimension) {
-            if (other.value > this.value) {
-                return -1;
-            } else if (other.value < this.value) {
-                return 1;
-            } else {
-                return 0;
-            }
-        } else {
-            return -1;
-        }
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Directive = function (name, value, features) {
-    this.name = name;
-
-    if (Array.isArray(value)) {
-        this.ruleset = new(tree.Ruleset)([], value);
-        this.ruleset.allowImports = true;
-    } else {
-        this.value = value;
-    }
-};
-tree.Directive.prototype = {
-    toCSS: function (ctx, env) {
-        if (this.ruleset) {
-            this.ruleset.root = true;
-            return this.name + (env.compress ? '{' : ' {\n  ') +
-                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
-                               (env.compress ? '}': '\n}\n');
-        } else {
-            return this.name + ' ' + this.value.toCSS() + ';\n';
-        }
-    },
-    eval: function (env) {
-        env.frames.unshift(this);
-        this.ruleset = this.ruleset && this.ruleset.eval(env);
-        env.frames.shift();
-        return this;
-    },
-    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
-    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
-    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Element = function (combinator, value, index) {
-    this.combinator = combinator instanceof tree.Combinator ?
-                      combinator : new(tree.Combinator)(combinator);
-
-    if (typeof(value) === 'string') {
-        this.value = value.trim();
-    } else if (value) {
-        this.value = value;
-    } else {
-        this.value = "";
-    }
-    this.index = index;
-};
-tree.Element.prototype.eval = function (env) {
-    return new(tree.Element)(this.combinator,
-                             this.value.eval ? this.value.eval(env) : this.value,
-                             this.index);
-};
-tree.Element.prototype.toCSS = function (env) {
-    return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
-};
-
-tree.Combinator = function (value) {
-    if (value === ' ') {
-        this.value = ' ';
-    } else if (value === '& ') {
-        this.value = '& ';
-    } else {
-        this.value = value ? value.trim() : "";
-    }
-};
-tree.Combinator.prototype.toCSS = function (env) {
-    return {
-        ''  : '',
-        ' ' : ' ',
-        '&' : '',
-        '& ' : ' ',
-        ':' : ' :',
-        '+' : env.compress ? '+' : ' + ',
-        '~' : env.compress ? '~' : ' ~ ',
-        '>' : env.compress ? '>' : ' > '
-    }[this.value];
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Expression = function (value) { this.value = value };
-tree.Expression.prototype = {
-    eval: function (env) {
-        if (this.value.length > 1) {
-            return new(tree.Expression)(this.value.map(function (e) {
-                return e.eval(env);
-            }));
-        } else if (this.value.length === 1) {
-            return this.value[0].eval(env);
-        } else {
-            return this;
-        }
-    },
-    toCSS: function (env) {
-        return this.value.map(function (e) {
-            return e.toCSS ? e.toCSS(env) : '';
-        }).join(' ');
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// CSS @import node
-//
-// The general strategy here is that we don't want to wait
-// for the parsing to be completed, before we start importing
-// the file. That's because in the context of a browser,
-// most of the time will be spent waiting for the server to respond.
-//
-// On creation, we push the import path to our import queue, though
-// `import,push`, we also pass it a callback, which it'll call once
-// the file has been fetched, and parsed.
-//
-tree.Import = function (path, imports, features, index) {
-    var that = this;
-
-    this.index = index;
-    this._path = path;
-    this.features = features && new(tree.Value)(features);
-
-    // The '.less' extension is optional
-    if (path instanceof tree.Quoted) {
-        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
-    } else {
-        this.path = path.value.value || path.value;
-    }
-
-    this.css = /css(\?.*)?$/.test(this.path);
-
-    // Only pre-compile .less files
-    if (! this.css) {
-        imports.push(this.path, function (e, root) {
-            if (e) { e.index = index }
-            that.root = root || new(tree.Ruleset)([], []);
-        });
-    }
-};
-
-//
-// The actual import node doesn't return anything, when converted to CSS.
-// The reason is that it's used at the evaluation stage, so that the rules
-// it imports can be treated like any other rules.
-//
-// In `eval`, we make sure all Import nodes get evaluated, recursively, so
-// we end up with a flat structure, which can easily be imported in the parent
-// ruleset.
-//
-tree.Import.prototype = {
-    toCSS: function (env) {
-        var features = this.features ? ' ' + this.features.toCSS(env) : '';
-
-        if (this.css) {
-            return "@import " + this._path.toCSS() + features + ';\n';
-        } else {
-            return "";
-        }
-    },
-    eval: function (env) {
-        var ruleset, features = this.features && this.features.eval(env);
-
-        if (this.css) {
-            return this;
-        } else {
-            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
-
-            for (var i = 0; i < ruleset.rules.length; i++) {
-                if (ruleset.rules[i] instanceof tree.Import) {
-                    Array.prototype
-                         .splice
-                         .apply(ruleset.rules,
-                                [i, 1].concat(ruleset.rules[i].eval(env)));
-                }
-            }
-            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
-        }
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.JavaScript = function (string, index, escaped) {
-    this.escaped = escaped;
-    this.expression = string;
-    this.index = index;
-};
-tree.JavaScript.prototype = {
-    eval: function (env) {
-        var result,
-            that = this,
-            context = {};
-
-        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
-            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
-        });
-
-        try {
-            expression = new(Function)('return (' + expression + ')');
-        } catch (e) {
-            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
-                    index: this.index };
-        }
-
-        for (var k in env.frames[0].variables()) {
-            context[k.slice(1)] = {
-                value: env.frames[0].variables()[k].value,
-                toJS: function () {
-                    return this.value.eval(env).toCSS();
-                }
-            };
-        }
-
-        try {
-            result = expression.call(context);
-        } catch (e) {
-            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
-                    index: this.index };
-        }
-        if (typeof(result) === 'string') {
-            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
-        } else if (Array.isArray(result)) {
-            return new(tree.Anonymous)(result.join(', '));
-        } else {
-            return new(tree.Anonymous)(result);
-        }
-    }
-};
-
-})(require('../tree'));
-
-(function (tree) {
-
-tree.Keyword = function (value) { this.value = value };
-tree.Keyword.prototype = {
-    eval: function () { return this },
-    toCSS: function () { return this.value },
-    compare: function (other) {
-        if (other instanceof tree.Keyword) {
-            return other.value === this.value ? 0 : 1;
-        } else {
-            return -1;
-        }
-    }
-};
-
-tree.True = new(tree.Keyword)('true');
-tree.False = new(tree.Keyword)('false');
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Media = function (value, features) {
-    var el = new(tree.Element)('&', null, 0),
-        selectors = [new(tree.Selector)([el])];
-
-    this.features = new(tree.Value)(features);
-    this.ruleset = new(tree.Ruleset)(selectors, value);
-    this.ruleset.allowImports = true;
-};
-tree.Media.prototype = {
-    toCSS: function (ctx, env) {
-        var features = this.features.toCSS(env);
-
-        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
-        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
-               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
-                           (env.compress ? '}': '\n}\n');
-    },
-    eval: function (env) {
-        if (!env.mediaBlocks) {
-            env.mediaBlocks = [];
-            env.mediaPath = [];
-        }
-        
-        var blockIndex = env.mediaBlocks.length;
-        env.mediaPath.push(this);
-        env.mediaBlocks.push(this);
-
-        var media = new(tree.Media)([], []);
-        media.features = this.features.eval(env);
-        
-        env.frames.unshift(this.ruleset);
-        media.ruleset = this.ruleset.eval(env);
-        env.frames.shift();
-        
-        env.mediaBlocks[blockIndex] = media;
-        env.mediaPath.pop();
-
-        return env.mediaPath.length === 0 ? media.evalTop(env) :
-                    media.evalNested(env)
-    },
-    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
-    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
-    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
-
-    evalTop: function (env) {
-        var result = this;
-
-        // Render all dependent Media blocks.
-        if (env.mediaBlocks.length > 1) {
-            var el = new(tree.Element)('&', null, 0);
-            var selectors = [new(tree.Selector)([el])];
-            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
-            result.multiMedia = true;
-        }
-
-        delete env.mediaBlocks;
-        delete env.mediaPath;
-
-        return result;
-    },
-    evalNested: function (env) {
-        var i, value,
-            path = env.mediaPath.concat([this]);
-
-        // Extract the media-query conditions separated with `,` (OR).
-        for (i = 0; i < path.length; i++) {
-            value = path[i].features instanceof tree.Value ?
-                        path[i].features.value : path[i].features;
-            path[i] = Array.isArray(value) ? value : [value];
-        }
-
-        // Trace all permutations to generate the resulting media-query.
-        //
-        // (a, b and c) with nested (d, e) ->
-        //    a and d
-        //    a and e
-        //    b and c and d
-        //    b and c and e
-        this.features = new(tree.Value)(this.permute(path).map(function (path) {
-            path = path.map(function (fragment) {
-                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
-            });
-
-            for(i = path.length - 1; i > 0; i--) {
-                path.splice(i, 0, new(tree.Anonymous)("and"));
-            }
-
-            return new(tree.Expression)(path);
-        }));
-
-        // Fake a tree-node that doesn't output anything.
-        return new(tree.Ruleset)([], []);
-    },
-    permute: function (arr) {
-      if (arr.length === 0) {
-          return [];
-      } else if (arr.length === 1) {
-          return arr[0];
-      } else {
-          var result = [];
-          var rest = this.permute(arr.slice(1));
-          for (var i = 0; i < rest.length; i++) {
-              for (var j = 0; j < arr[0].length; j++) {
-                  result.push([arr[0][j]].concat(rest[i]));
-              }
-          }
-          return result;
-      }
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.mixin = {};
-tree.mixin.Call = function (elements, args, index, filename, important) {
-    this.selector = new(tree.Selector)(elements);
-    this.arguments = args;
-    this.index = index;
-    this.filename = filename;
-    this.important = important;
-};
-tree.mixin.Call.prototype = {
-    eval: function (env) {
-        var mixins, args, rules = [], match = false;
-
-        for (var i = 0; i < env.frames.length; i++) {
-            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
-                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
-                for (var m = 0; m < mixins.length; m++) {
-                    if (mixins[m].match(args, env)) {
-                        try {
-                            Array.prototype.push.apply(
-                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
-                            match = true;
-                        } catch (e) {
-                            throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
-                        }
-                    }
-                }
-                if (match) {
-                    return rules;
-                } else {
-                    throw { type:    'Runtime',
-                            message: 'No matching definition was found for `' +
-                                      this.selector.toCSS().trim() + '('      +
-                                      this.arguments.map(function (a) {
-                                          return a.toCSS();
-                                      }).join(', ') + ")`",
-                            index:   this.index, filename: this.filename };
-                }
-            }
-        }
-        throw { type: 'Name',
-                message: this.selector.toCSS().trim() + " is undefined",
-                index: this.index, filename: this.filename };
-    }
-};
-
-tree.mixin.Definition = function (name, params, rules, condition, variadic) {
-    this.name = name;
-    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
-    this.params = params;
-    this.condition = condition;
-    this.variadic = variadic;
-    this.arity = params.length;
-    this.rules = rules;
-    this._lookups = {};
-    this.required = params.reduce(function (count, p) {
-        if (!p.name || (p.name && !p.value)) { return count + 1 }
-        else                                 { return count }
-    }, 0);
-    this.parent = tree.Ruleset.prototype;
-    this.frames = [];
-};
-tree.mixin.Definition.prototype = {
-    toCSS:     function ()     { return "" },
-    variable:  function (name) { return this.parent.variable.call(this, name) },
-    variables: function ()     { return this.parent.variables.call(this) },
-    find:      function ()     { return this.parent.find.apply(this, arguments) },
-    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
-
-    evalParams: function (env, args) {
-        var frame = new(tree.Ruleset)(null, []), varargs;
-
-        for (var i = 0, val, name; i < this.params.length; i++) {
-            if (name = this.params[i].name) {
-                if (this.params[i].variadic && args) {
-                    varargs = [];
-                    for (var j = i; j < args.length; j++) {
-                        varargs.push(args[j].eval(env));
-                    }
-                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
-                } else if (val = (args && args[i]) || this.params[i].value) {
-                    frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
-                } else {
-                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
-                            ' (' + args.length + ' for ' + this.arity + ')' };
-                }
-            }
-        }
-        return frame;
-    },
-    eval: function (env, args, important) {
-        var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
-
-        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
-            _arguments.push(args[i] || this.params[i].value);
-        }
-        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
-
-        rules = important ?
-            this.rules.map(function (r) {
-                return new(tree.Rule)(r.name, r.value, '!important', r.index);
-            }) : this.rules.slice(0);
-
-        return new(tree.Ruleset)(null, rules).eval({
-            frames: [this, frame].concat(this.frames, env.frames)
-        });
-    },
-    match: function (args, env) {
-        var argsLength = (args && args.length) || 0, len, frame;
-
-        if (! this.variadic) {
-            if (argsLength < this.required)                               { return false }
-            if (argsLength > this.params.length)                          { return false }
-            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
-        }
-
-        if (this.condition && !this.condition.eval({
-            frames: [this.evalParams(env, args)].concat(env.frames)
-        }))                                                           { return false }
-
-        len = Math.min(argsLength, this.arity);
-
-        for (var i = 0; i < len; i++) {
-            if (!this.params[i].name) {
-                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Operation = function (op, operands) {
-    this.op = op.trim();
-    this.operands = operands;
-};
-tree.Operation.prototype.eval = function (env) {
-    var a = this.operands[0].eval(env),
-        b = this.operands[1].eval(env),
-        temp;
-
-    if (a instanceof tree.Dimension && b instanceof tree.Color) {
-        if (this.op === '*' || this.op === '+') {
-            temp = b, b = a, a = temp;
-        } else {
-            throw { name: "OperationError",
-                    message: "Can't substract or divide a color from a number" };
-        }
-    }
-    return a.operate(this.op, b);
-};
-
-tree.operate = function (op, a, b) {
-    switch (op) {
-        case '+': return a + b;
-        case '-': return a - b;
-        case '*': return a * b;
-        case '/': return a / b;
-    }
-};
-
-})(require('../tree'));
-
-(function (tree) {
-
-tree.Paren = function (node) {
-    this.value = node;
-};
-tree.Paren.prototype = {
-    toCSS: function (env) {
-        return '(' + this.value.toCSS(env) + ')';
-    },
-    eval: function (env) {
-        return new(tree.Paren)(this.value.eval(env));
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Quoted = function (str, content, escaped, i) {
-    this.escaped = escaped;
-    this.value = content || '';
-    this.quote = str.charAt(0);
-    this.index = i;
-};
-tree.Quoted.prototype = {
-    toCSS: function () {
-        if (this.escaped) {
-            return this.value;
-        } else {
-            return this.quote + this.value + this.quote;
-        }
-    },
-    eval: function (env) {
-        var that = this;
-        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
-            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
-        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
-            var v = new(tree.Variable)('@' + name, that.index).eval(env);
-            return ('value' in v) ? v.value : v.toCSS();
-        });
-        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Rule = function (name, value, important, index, inline) {
-    this.name = name;
-    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
-    this.important = important ? ' ' + important.trim() : '';
-    this.index = index;
-    this.inline = inline || false;
-
-    if (name.charAt(0) === '@') {
-        this.variable = true;
-    } else { this.variable = false }
-};
-tree.Rule.prototype.toCSS = function (env) {
-    if (this.variable) { return "" }
-    else {
-        return this.name + (env.compress ? ':' : ': ') +
-               this.value.toCSS(env) +
-               this.important + (this.inline ? "" : ";");
-    }
-};
-
-tree.Rule.prototype.eval = function (context) {
-    return new(tree.Rule)(this.name,
-                          this.value.eval(context),
-                          this.important,
-                          this.index, this.inline);
-};
-
-tree.Shorthand = function (a, b) {
-    this.a = a;
-    this.b = b;
-};
-
-tree.Shorthand.prototype = {
-    toCSS: function (env) {
-        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
-    },
-    eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Ruleset = function (selectors, rules, strictImports) {
-    this.selectors = selectors;
-    this.rules = rules;
-    this._lookups = {};
-    this.strictImports = strictImports;
-};
-tree.Ruleset.prototype = {
-    eval: function (env) {
-        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
-        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
-
-        ruleset.root = this.root;
-        ruleset.allowImports = this.allowImports;
-
-        // push the current ruleset to the frames stack
-        env.frames.unshift(ruleset);
-
-        // Evaluate imports
-        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
-            for (var i = 0; i < ruleset.rules.length; i++) {
-                if (ruleset.rules[i] instanceof tree.Import) {
-                    Array.prototype.splice
-                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
-                }
-            }
-        }
-
-        // Store the frames around mixin definitions,
-        // so they can be evaluated like closures when the time comes.
-        for (var i = 0; i < ruleset.rules.length; i++) {
-            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
-                ruleset.rules[i].frames = env.frames.slice(0);
-            }
-        }
-
-        // Evaluate mixin calls.
-        for (var i = 0; i < ruleset.rules.length; i++) {
-            if (ruleset.rules[i] instanceof tree.mixin.Call) {
-                Array.prototype.splice
-                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
-            }
-        }
-
-        // Evaluate everything else
-        for (var i = 0, rule; i < ruleset.rules.length; i++) {
-            rule = ruleset.rules[i];
-
-            if (! (rule instanceof tree.mixin.Definition)) {
-                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
-            }
-        }
-
-        // Pop the stack
-        env.frames.shift();
-
-        return ruleset;
-    },
-    match: function (args) {
-        return !args || args.length === 0;
-    },
-    variables: function () {
-        if (this._variables) { return this._variables }
-        else {
-            return this._variables = this.rules.reduce(function (hash, r) {
-                if (r instanceof tree.Rule && r.variable === true) {
-                    hash[r.name] = r;
-                }
-                return hash;
-            }, {});
-        }
-    },
-    variable: function (name) {
-        return this.variables()[name];
-    },
-    rulesets: function () {
-        if (this._rulesets) { return this._rulesets }
-        else {
-            return this._rulesets = this.rules.filter(function (r) {
-                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
-            });
-        }
-    },
-    find: function (selector, self) {
-        self = self || this;
-        var rules = [], rule, match,
-            key = selector.toCSS();
-
-        if (key in this._lookups) { return this._lookups[key] }
-
-        this.rulesets().forEach(function (rule) {
-            if (rule !== self) {
-                for (var j = 0; j < rule.selectors.length; j++) {
-                    if (match = selector.match(rule.selectors[j])) {
-                        if (selector.elements.length > rule.selectors[j].elements.length) {
-                            Array.prototype.push.apply(rules, rule.find(
-                                new(tree.Selector)(selector.elements.slice(1)), self));
-                        } else {
-                            rules.push(rule);
-                        }
-                        break;
-                    }
-                }
-            }
-        });
-        return this._lookups[key] = rules;
-    },
-    //
-    // Entry point for code generation
-    //
-    //     `context` holds an array of arrays.
-    //
-    toCSS: function (context, env) {
-        var css = [],      // The CSS output
-            rules = [],    // node.Rule instances
-            rulesets = [], // node.Ruleset instances
-            paths = [],    // Current selectors
-            selector,      // The fully rendered selector
-            rule;
-
-        if (! this.root) {
-            if (context.length === 0) {
-                paths = this.selectors.map(function (s) { return [s] });
-            } else {
-                this.joinSelectors(paths, context, this.selectors);
-            }
-        }
-
-        // Compile rules and rulesets
-        for (var i = 0; i < this.rules.length; i++) {
-            rule = this.rules[i];
-
-            if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
-                rulesets.push(rule.toCSS(paths, env));
-            } else if (rule instanceof tree.Comment) {
-                if (!rule.silent) {
-                    if (this.root) {
-                        rulesets.push(rule.toCSS(env));
-                    } else {
-                        rules.push(rule.toCSS(env));
-                    }
-                }
-            } else {
-                if (rule.toCSS && !rule.variable) {
-                    rules.push(rule.toCSS(env));
-                } else if (rule.value && !rule.variable) {
-                    rules.push(rule.value.toString());
-                }
-            }
-        } 
-
-        rulesets = rulesets.join('');
-
-        // If this is the root node, we don't render
-        // a selector, or {}.
-        // Otherwise, only output if this ruleset has rules.
-        if (this.root) {
-            css.push(rules.join(env.compress ? '' : '\n'));
-        } else {
-            if (rules.length > 0) {
-                selector = paths.map(function (p) {
-                    return p.map(function (s) {
-                        return s.toCSS(env);
-                    }).join('').trim();
-                }).join( env.compress ? ',' : ',\n');
-
-                css.push(selector,
-                        (env.compress ? '{' : ' {\n  ') +
-                        rules.join(env.compress ? '' : '\n  ') +
-                        (env.compress ? '}' : '\n}\n'));
-            }
-        }
-        css.push(rulesets);
-
-        return css.join('') + (env.compress ? '\n' : '');
-    },
-
-    joinSelectors: function (paths, context, selectors) {
-        for (var s = 0; s < selectors.length; s++) {
-            this.joinSelector(paths, context, selectors[s]);
-        }
-    },
-
-    joinSelector: function (paths, context, selector) {
-        var before = [], after = [], beforeElements = [],
-            afterElements = [], hasParentSelector = false, el;
-
-        for (var i = 0; i < selector.elements.length; i++) {
-            el = selector.elements[i];
-            if (el.combinator.value.charAt(0) === '&') {
-                hasParentSelector = true;
-            }
-            if (hasParentSelector) afterElements.push(el);
-            else                   beforeElements.push(el);
-        }
-
-        if (! hasParentSelector) {
-            afterElements = beforeElements;
-            beforeElements = [];
-        }
-
-        if (beforeElements.length > 0) {
-            before.push(new(tree.Selector)(beforeElements));
-        }
-
-        if (afterElements.length > 0) {
-            after.push(new(tree.Selector)(afterElements));
-        }
-
-        for (var c = 0; c < context.length; c++) {
-            paths.push(before.concat(context[c]).concat(after));
-        }
-    }
-};
-})(require('../tree'));
-(function (tree) {
-
-tree.Selector = function (elements) {
-    this.elements = elements;
-    if (this.elements[0].combinator.value === "") {
-        this.elements[0].combinator.value = ' ';
-    }
-};
-tree.Selector.prototype.match = function (other) {
-    var len  = this.elements.length,
-        olen = other.elements.length,
-        max  = Math.min(len, olen);
-
-    if (len < olen) {
-        return false;
-    } else {
-        for (var i = 0; i < max; i++) {
-            if (this.elements[i].value !== other.elements[i].value) {
-                return false;
-            }
-        }
-    }
-    return true;
-};
-tree.Selector.prototype.eval = function (env) {
-    return new(tree.Selector)(this.elements.map(function (e) {
-        return e.eval(env);
-    }));
-};
-tree.Selector.prototype.toCSS = function (env) {
-    if (this._css) { return this._css }
-
-    return this._css = this.elements.map(function (e) {
-        if (typeof(e) === 'string') {
-            return ' ' + e.trim();
-        } else {
-            return e.toCSS(env);
-        }
-    }).join('');
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.URL = function (val, paths) {
-    if (val.data) {
-        this.attrs = val;
-    } else {
-        // Add the base path if the URL is relative and we are in the browser
-        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
-            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
-        }
-        this.value = val;
-        this.paths = paths;
-    }
-};
-tree.URL.prototype = {
-    toCSS: function () {
-        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
-                                    : this.value.toCSS()) + ")";
-    },
-    eval: function (ctx) {
-        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Value = function (value) {
-    this.value = value;
-    this.is = 'value';
-};
-tree.Value.prototype = {
-    eval: function (env) {
-        if (this.value.length === 1) {
-            return this.value[0].eval(env);
-        } else {
-            return new(tree.Value)(this.value.map(function (v) {
-                return v.eval(env);
-            }));
-        }
-    },
-    toCSS: function (env) {
-        return this.value.map(function (e) {
-            return e.toCSS(env);
-        }).join(env.compress ? ',' : ', ');
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
-tree.Variable.prototype = {
-    eval: function (env) {
-        var variable, v, name = this.name;
-
-        if (name.indexOf('@@') == 0) {
-            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
-        }
-
-        if (variable = tree.find(env.frames, function (frame) {
-            if (v = frame.variable(name)) {
-                return v.value.eval(env);
-            }
-        })) { return variable }
-        else {
-            throw { type: 'Name',
-                    message: "variable " + name + " is undefined",
-                    filename: this.file,
-                    index: this.index };
-        }
-    }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.find = function (obj, fun) {
-    for (var i = 0, r; i < obj.length; i++) {
-        if (r = fun.call(obj, obj[i])) { return r }
-    }
-    return null;
-};
-tree.jsify = function (obj) {
-    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
-        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
-    } else {
-        return obj.toCSS(false);
-    }
-};
-
-})(require('./tree'));
-//
-// browser.js - client-side engine
-//
-
-var isFileProtocol = (location.protocol === 'file:'    ||
-                      location.protocol === 'chrome:'  ||
-                      location.protocol === 'chrome-extension:'  ||
-                      location.protocol === 'resource:');
-
-less.env = less.env || (location.hostname == '127.0.0.1' ||
-                        location.hostname == '0.0.0.0'   ||
-                        location.hostname == 'localhost' ||
-                        location.port.length > 0         ||
-                        isFileProtocol                   ? 'development'
-                                                         : 'production');
-
-// Load styles asynchronously (default: false)
-//
-// This is set to `false` by default, so that the body
-// doesn't start loading before the stylesheets are parsed.
-// Setting this to `true` can result in flickering.
-//
-less.async = false;
-
-// Interval between watch polls
-less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
-
-//
-// Watch mode
-//
-less.watch   = function () { return this.watchMode = true };
-less.unwatch = function () { return this.watchMode = false };
-
-if (less.env === 'development') {
-    less.optimization = 0;
-
-    if (/!watch/.test(location.hash)) {
-        less.watch();
-    }
-    less.watchTimer = setInterval(function () {
-        if (less.watchMode) {
-            loadStyleSheets(function (e, root, _, sheet, env) {
-                if (root) {
-                    createCSS(root.toCSS(), sheet, env.lastModified);
-                }
-            });
-        }
-    }, less.poll);
-} else {
-    less.optimization = 3;
-}
-
-var cache;
-
-try {
-    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
-} catch (_) {
-    cache = null;
-}
-
-//
-// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
-//
-var links = document.getElementsByTagName('link');
-var typePattern = /^text\/(x-)?less$/;
-
-less.sheets = [];
-
-for (var i = 0; i < links.length; i++) {
-    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
-       (links[i].type.match(typePattern)))) {
-        less.sheets.push(links[i]);
-    }
-}
-
-
-less.refresh = function (reload) {
-    var startTime, endTime;
-    startTime = endTime = new(Date);
-
-    loadStyleSheets(function (e, root, _, sheet, env) {
-        if (env.local) {
-            log("loading " + sheet.href + " from cache.");
-        } else {
-            log("parsed " + sheet.href + " successfully.");
-            createCSS(root.toCSS(), sheet, env.lastModified);
-        }
-        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
-        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
-        endTime = new(Date);
-    }, reload);
-
-    loadStyles();
-};
-less.refreshStyles = loadStyles;
-
-less.refresh(less.env === 'development');
-
-function loadStyles() {
-    var styles = document.getElementsByTagName('style');
-    for (var i = 0; i < styles.length; i++) {
-        if (styles[i].type.match(typePattern)) {
-            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
-                var css = tree.toCSS();
-                var style = styles[i];
-                style.type = 'text/css';
-                if (style.styleSheet) {
-                    style.styleSheet.cssText = css;
-                } else {
-                    style.innerHTML = css;
-                }
-            });
-        }
-    }
-}
-
-function loadStyleSheets(callback, reload) {
-    for (var i = 0; i < less.sheets.length; i++) {
-        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
-    }
-}
-
-function loadStyleSheet(sheet, callback, reload, remaining) {
-    var url       = window.location.href.replace(/[#?].*$/, '');
-    var href      = sheet.href.replace(/\?.*$/, '');
-    var css       = cache && cache.getItem(href);
-    var timestamp = cache && cache.getItem(href + ':timestamp');
-    var styles    = { css: css, timestamp: timestamp };
-
-    // Stylesheets in IE don't always return the full path
-    if (! /^(https?|file):/.test(href)) {
-        if (href.charAt(0) == "/") {
-            href = window.location.protocol + "//" + window.location.host + href;
-        } else {
-            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
-        }
-    }
-    var filename = href.match(/([^\/]+)$/)[1];
-
-    xhr(sheet.href, sheet.type, function (data, lastModified) {
-        if (!reload && styles && lastModified &&
-           (new(Date)(lastModified).valueOf() ===
-            new(Date)(styles.timestamp).valueOf())) {
-            // Use local copy
-            createCSS(styles.css, sheet);
-            callback(null, null, data, sheet, { local: true, remaining: remaining });
-        } else {
-            // Use remote copy (re-parse)
-            try {
-                new(less.Parser)({
-                    optimization: less.optimization,
-                    paths: [href.replace(/[\w\.-]+$/, '')],
-                    mime: sheet.type,
-                    filename: filename
-                }).parse(data, function (e, root) {
-                    if (e) { return error(e, href) }
-                    try {
-                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
-                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
-                    } catch (e) {
-                        error(e, href);
-                    }
-                });
-            } catch (e) {
-                error(e, href);
-            }
-        }
-    }, function (status, url) {
-        throw new(Error)("Couldn't load " + url + " (" + status + ")");
-    });
-}
-
-function extractId(href) {
-    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
-               .replace(/^\//,                 '' )  // Remove root /
-               .replace(/\?.*$/,               '' )  // Remove query
-               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
-               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
-               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
-}
-
-function createCSS(styles, sheet, lastModified) {
-    var css;
-
-    // Strip the query-string
-    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
-
-    // If there is no title set, use the filename, minus the extension
-    var id = 'less:' + (sheet.title || extractId(href));
-
-    // If the stylesheet doesn't exist, create a new node
-    if ((css = document.getElementById(id)) === null) {
-        css = document.createElement('style');
-        css.type = 'text/css';
-        css.media = sheet.media || 'screen';
-        css.id = id;
-        document.getElementsByTagName('head')[0].appendChild(css);
-    }
-
-    if (css.styleSheet) { // IE
-        try {
-            css.styleSheet.cssText = styles;
-        } catch (e) {
-            throw new(Error)("Couldn't reassign styleSheet.cssText.");
-        }
-    } else {
-        (function (node) {
-            if (css.childNodes.length > 0) {
-                if (css.firstChild.nodeValue !== node.nodeValue) {
-                    css.replaceChild(node, css.firstChild);
-                }
-            } else {
-                css.appendChild(node);
-            }
-        })(document.createTextNode(styles));
-    }
-
-    // Don't update the local store if the file wasn't modified
-    if (lastModified && cache) {
-        log('saving ' + href + ' to cache.');
-        cache.setItem(href, styles);
-        cache.setItem(href + ':timestamp', lastModified);
-    }
-}
-
-function xhr(url, type, callback, errback) {
-    var xhr = getXMLHttpRequest();
-    var async = isFileProtocol ? false : less.async;
-
-    if (typeof(xhr.overrideMimeType) === 'function') {
-        xhr.overrideMimeType('text/css');
-    }
-    xhr.open('GET', url, async);
-    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
-    xhr.send(null);
-
-    if (isFileProtocol) {
-        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
-            callback(xhr.responseText);
-        } else {
-            errback(xhr.status, url);
-        }
-    } else if (async) {
-        xhr.onreadystatechange = function () {
-            if (xhr.readyState == 4) {
-                handleResponse(xhr, callback, errback);
-            }
-        };
-    } else {
-        handleResponse(xhr, callback, errback);
-    }
-
-    function handleResponse(xhr, callback, errback) {
-        if (xhr.status >= 200 && xhr.status < 300) {
-            callback(xhr.responseText,
-                     xhr.getResponseHeader("Last-Modified"));
-        } else if (typeof(errback) === 'function') {
-            errback(xhr.status, url);
-        }
-    }
-}
-
-function getXMLHttpRequest() {
-    if (window.XMLHttpRequest) {
-        return new(XMLHttpRequest);
-    } else {
-        try {
-            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
-        } catch (e) {
-            log("browser doesn't support AJAX.");
-            return null;
-        }
-    }
-}
-
-function removeNode(node) {
-    return node && node.parentNode.removeChild(node);
-}
-
-function log(str) {
-    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
-}
-
-function error(e, href) {
-    var id = 'less-error-message:' + extractId(href);
-    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
-    var elem = document.createElement('div'), timer, content, error = [];
-    var filename = e.filename || href;
-
-    elem.id        = id;
-    elem.className = "less-error-message";
-
-    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
-              '</h3>' + '<p>in <a href="' + filename   + '">' + filename + "</a> ";
-
-    var errorline = function (e, i, classname) {
-        if (e.extract[i]) {
-            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
-                               .replace(/\{class\}/, classname)
-                               .replace(/\{content\}/, e.extract[i]));
-        }
-    };
-
-    if (e.stack) {
-        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
-    } else if (e.extract) {
-        errorline(e, 0, '');
-        errorline(e, 1, 'line');
-        errorline(e, 2, '');
-        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
-                    '<ul>' + error.join('') + '</ul>';
-    }
-    elem.innerHTML = content;
-
-    // CSS for error messages
-    createCSS([
-        '.less-error-message ul, .less-error-message li {',
-            'list-style-type: none;',
-            'margin-right: 15px;',
-            'padding: 4px 0;',
-            'margin: 0;',
-        '}',
-        '.less-error-message label {',
-            'font-size: 12px;',
-            'margin-right: 15px;',
-            'padding: 4px 0;',
-            'color: #cc7777;',
-        '}',
-        '.less-error-message pre {',
-            'color: #dd6666;',
-            'padding: 4px 0;',
-            'margin: 0;',
-            'display: inline-block;',
-        '}',
-        '.less-error-message pre.line {',
-            'color: #ff0000;',
-        '}',
-        '.less-error-message h3 {',
-            'font-size: 20px;',
-            'font-weight: bold;',
-            'padding: 15px 0 5px 0;',
-            'margin: 0;',
-        '}',
-        '.less-error-message a {',
-            'color: #10a',
-        '}',
-        '.less-error-message .error {',
-            'color: red;',
-            'font-weight: bold;',
-            'padding-bottom: 2px;',
-            'border-bottom: 1px dashed red;',
-        '}'
-    ].join('\n'), { title: 'error-message' });
-
-    elem.style.cssText = [
-        "font-family: Arial, sans-serif",
-        "border: 1px solid #e00",
-        "background-color: #eee",
-        "border-radius: 5px",
-        "-webkit-border-radius: 5px",
-        "-moz-border-radius: 5px",
-        "color: #e00",
-        "padding: 15px",
-        "margin-bottom: 15px"
-    ].join(';');
-
-    if (less.env == 'development') {
-        timer = setInterval(function () {
-            if (document.body) {
-                if (document.getElementById(id)) {
-                    document.body.replaceChild(elem, document.getElementById(id));
-                } else {
-                    document.body.insertBefore(elem, document.body.firstChild);
-                }
-                clearInterval(timer);
-            }
-        }, 10);
-    }
-}
-
-})(window);
diff --git a/ckan/public-bs2/base/test/vendor/mocha.css b/ckan/public-bs2/base/test/vendor/mocha.css
deleted file mode 100644
--- a/ckan/public-bs2/base/test/vendor/mocha.css
+++ /dev/null
@@ -1,251 +0,0 @@
-@charset "utf-8";
-
-body {
-  margin:0;
-}
-
-#mocha {
-  font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
-  margin: 60px 50px;
-}
-
-#mocha ul, #mocha li {
-  margin: 0;
-  padding: 0;
-}
-
-#mocha ul {
-  list-style: none;
-}
-
-#mocha h1, #mocha h2 {
-  margin: 0;
-}
-
-#mocha h1 {
-  margin-top: 15px;
-  font-size: 1em;
-  font-weight: 200;
-}
-
-#mocha h1 a {
-  text-decoration: none;
-  color: inherit;
-}
-
-#mocha h1 a:hover {
-  text-decoration: underline;
-}
-
-#mocha .suite .suite h1 {
-  margin-top: 0;
-  font-size: .8em;
-}
-
-#mocha .hidden {
-  display: none;
-}
-
-#mocha h2 {
-  font-size: 12px;
-  font-weight: normal;
-  cursor: pointer;
-}
-
-#mocha .suite {
-  margin-left: 15px;
-}
-
-#mocha .test {
-  margin-left: 15px;
-  overflow: hidden;
-}
-
-#mocha .test.pending:hover h2::after {
-  content: '(pending)';
-  font-family: arial, sans-serif;
-}
-
-#mocha .test.pass.medium .duration {
-  background: #C09853;
-}
-
-#mocha .test.pass.slow .duration {
-  background: #B94A48;
-}
-
-#mocha .test.pass::before {
-  content: '✓';
-  font-size: 12px;
-  display: block;
-  float: left;
-  margin-right: 5px;
-  color: #00d6b2;
-}
-
-#mocha .test.pass .duration {
-  font-size: 9px;
-  margin-left: 5px;
-  padding: 2px 5px;
-  color: white;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-  -webkit-border-radius: 5px;
-  -moz-border-radius: 5px;
-  -ms-border-radius: 5px;
-  -o-border-radius: 5px;
-  border-radius: 5px;
-}
-
-#mocha .test.pass.fast .duration {
-  display: none;
-}
-
-#mocha .test.pending {
-  color: #0b97c4;
-}
-
-#mocha .test.pending::before {
-  content: '◦';
-  color: #0b97c4;
-}
-
-#mocha .test.fail {
-  color: #c00;
-}
-
-#mocha .test.fail pre {
-  color: black;
-}
-
-#mocha .test.fail::before {
-  content: '✖';
-  font-size: 12px;
-  display: block;
-  float: left;
-  margin-right: 5px;
-  color: #c00;
-}
-
-#mocha .test pre.error {
-  color: #c00;
-  max-height: 300px;
-  overflow: auto;
-}
-
-#mocha .test pre {
-  display: block;
-  float: left;
-  clear: left;
-  font: 12px/1.5 monaco, monospace;
-  margin: 5px;
-  padding: 15px;
-  border: 1px solid #eee;
-  border-bottom-color: #ddd;
-  -webkit-border-radius: 3px;
-  -webkit-box-shadow: 0 1px 3px #eee;
-  -moz-border-radius: 3px;
-  -moz-box-shadow: 0 1px 3px #eee;
-}
-
-#mocha .test h2 {
-  position: relative;
-}
-
-#mocha .test a.replay {
-  position: absolute;
-  top: 3px;
-  right: 0;
-  text-decoration: none;
-  vertical-align: middle;
-  display: block;
-  width: 15px;
-  height: 15px;
-  line-height: 15px;
-  text-align: center;
-  background: #eee;
-  font-size: 15px;
-  -moz-border-radius: 15px;
-  border-radius: 15px;
-  -webkit-transition: opacity 200ms;
-  -moz-transition: opacity 200ms;
-  transition: opacity 200ms;
-  opacity: 0.3;
-  color: #888;
-}
-
-#mocha .test:hover a.replay {
-  opacity: 1;
-}
-
-#mocha-report.pass .test.fail {
-  display: none;
-}
-
-#mocha-report.fail .test.pass {
-  display: none;
-}
-
-#mocha-error {
-  color: #c00;
-  font-size: 1.5em;
-  font-weight: 100;
-  letter-spacing: 1px;
-}
-
-#mocha-stats {
-  position: fixed;
-  top: 15px;
-  right: 10px;
-  font-size: 12px;
-  margin: 0;
-  color: #888;
-  z-index: 1;
-}
-
-#mocha-stats .progress {
-  float: right;
-  padding-top: 0;
-}
-
-#mocha-stats em {
-  color: black;
-}
-
-#mocha-stats a {
-  text-decoration: none;
-  color: inherit;
-}
-
-#mocha-stats a:hover {
-  border-bottom: 1px solid #eee;
-}
-
-#mocha-stats li {
-  display: inline-block;
-  margin: 0 5px;
-  list-style: none;
-  padding-top: 11px;
-}
-
-#mocha-stats canvas {
-  width: 40px;
-  height: 40px;
-}
-
-#mocha code .comment { color: #ddd }
-#mocha code .init { color: #2F6FAD }
-#mocha code .string { color: #5890AD }
-#mocha code .keyword { color: #8A6343 }
-#mocha code .number { color: #2F6FAD }
-
-@media screen and (max-device-width: 480px) {
-  #mocha  {
-    margin: 60px 0px;
-  }
-
-  #mocha #stats {
-    position: absolute;
-  }
-}
\ No newline at end of file
diff --git a/ckan/public-bs2/base/test/vendor/mocha.js b/ckan/public-bs2/base/test/vendor/mocha.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/vendor/mocha.js
+++ /dev/null
@@ -1,5428 +0,0 @@
-;(function(){
-
-// CommonJS require()
-
-function require(p){
-    var path = require.resolve(p)
-      , mod = require.modules[path];
-    if (!mod) throw new Error('failed to require "' + p + '"');
-    if (!mod.exports) {
-      mod.exports = {};
-      mod.call(mod.exports, mod, mod.exports, require.relative(path));
-    }
-    return mod.exports;
-  }
-
-require.modules = {};
-
-require.resolve = function (path){
-    var orig = path
-      , reg = path + '.js'
-      , index = path + '/index.js';
-    return require.modules[reg] && reg
-      || require.modules[index] && index
-      || orig;
-  };
-
-require.register = function (path, fn){
-    require.modules[path] = fn;
-  };
-
-require.relative = function (parent) {
-    return function(p){
-      if ('.' != p.charAt(0)) return require(p);
-
-      var path = parent.split('/')
-        , segs = p.split('/');
-      path.pop();
-
-      for (var i = 0; i < segs.length; i++) {
-        var seg = segs[i];
-        if ('..' == seg) path.pop();
-        else if ('.' != seg) path.push(seg);
-      }
-
-      return require(path.join('/'));
-    };
-  };
-
-
-require.register("browser/debug.js", function(module, exports, require){
-
-module.exports = function(type){
-  return function(){
-  }
-};
-
-}); // module: browser/debug.js
-
-require.register("browser/diff.js", function(module, exports, require){
-/* See license.txt for terms of usage */
-
-/*
- * Text diff implementation.
- * 
- * This library supports the following APIS:
- * JsDiff.diffChars: Character by character diff
- * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
- * JsDiff.diffLines: Line based diff
- * 
- * JsDiff.diffCss: Diff targeted at CSS content
- * 
- * These methods are based on the implementation proposed in
- * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
- * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
- */
-var JsDiff = (function() {
-  function clonePath(path) {
-    return { newPos: path.newPos, components: path.components.slice(0) };
-  }
-  function removeEmpty(array) {
-    var ret = [];
-    for (var i = 0; i < array.length; i++) {
-      if (array[i]) {
-        ret.push(array[i]);
-      }
-    }
-    return ret;
-  }
-  function escapeHTML(s) {
-    var n = s;
-    n = n.replace(/&/g, "&amp;");
-    n = n.replace(/</g, "&lt;");
-    n = n.replace(/>/g, "&gt;");
-    n = n.replace(/"/g, "&quot;");
-
-    return n;
-  }
-
-
-  var fbDiff = function(ignoreWhitespace) {
-    this.ignoreWhitespace = ignoreWhitespace;
-  };
-  fbDiff.prototype = {
-      diff: function(oldString, newString) {
-        // Handle the identity case (this is due to unrolling editLength == 0
-        if (newString == oldString) {
-          return [{ value: newString }];
-        }
-        if (!newString) {
-          return [{ value: oldString, removed: true }];
-        }
-        if (!oldString) {
-          return [{ value: newString, added: true }];
-        }
-
-        newString = this.tokenize(newString);
-        oldString = this.tokenize(oldString);
-
-        var newLen = newString.length, oldLen = oldString.length;
-        var maxEditLength = newLen + oldLen;
-        var bestPath = [{ newPos: -1, components: [] }];
-
-        // Seed editLength = 0
-        var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
-        if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
-          return bestPath[0].components;
-        }
-
-        for (var editLength = 1; editLength <= maxEditLength; editLength++) {
-          for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
-            var basePath;
-            var addPath = bestPath[diagonalPath-1],
-                removePath = bestPath[diagonalPath+1];
-            oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
-            if (addPath) {
-              // No one else is going to attempt to use this value, clear it
-              bestPath[diagonalPath-1] = undefined;
-            }
-
-            var canAdd = addPath && addPath.newPos+1 < newLen;
-            var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
-            if (!canAdd && !canRemove) {
-              bestPath[diagonalPath] = undefined;
-              continue;
-            }
-
-            // Select the diagonal that we want to branch from. We select the prior
-            // path whose position in the new string is the farthest from the origin
-            // and does not pass the bounds of the diff graph
-            if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
-              basePath = clonePath(removePath);
-              this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
-            } else {
-              basePath = clonePath(addPath);
-              basePath.newPos++;
-              this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
-            }
-
-            var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
-
-            if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
-              return basePath.components;
-            } else {
-              bestPath[diagonalPath] = basePath;
-            }
-          }
-        }
-      },
-
-      pushComponent: function(components, value, added, removed) {
-        var last = components[components.length-1];
-        if (last && last.added === added && last.removed === removed) {
-          // We need to clone here as the component clone operation is just
-          // as shallow array clone
-          components[components.length-1] =
-            {value: this.join(last.value, value), added: added, removed: removed };
-        } else {
-          components.push({value: value, added: added, removed: removed });
-        }
-      },
-      extractCommon: function(basePath, newString, oldString, diagonalPath) {
-        var newLen = newString.length,
-            oldLen = oldString.length,
-            newPos = basePath.newPos,
-            oldPos = newPos - diagonalPath;
-        while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
-          newPos++;
-          oldPos++;
-          
-          this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
-        }
-        basePath.newPos = newPos;
-        return oldPos;
-      },
-
-      equals: function(left, right) {
-        var reWhitespace = /\S/;
-        if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
-          return true;
-        } else {
-          return left == right;
-        }
-      },
-      join: function(left, right) {
-        return left + right;
-      },
-      tokenize: function(value) {
-        return value;
-      }
-  };
-  
-  var CharDiff = new fbDiff();
-  
-  var WordDiff = new fbDiff(true);
-  WordDiff.tokenize = function(value) {
-    return removeEmpty(value.split(/(\s+|\b)/));
-  };
-  
-  var CssDiff = new fbDiff(true);
-  CssDiff.tokenize = function(value) {
-    return removeEmpty(value.split(/([{}:;,]|\s+)/));
-  };
-  
-  var LineDiff = new fbDiff();
-  LineDiff.tokenize = function(value) {
-    return value.split(/^/m);
-  };
-  
-  return {
-    diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
-    diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
-    diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
-
-    diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
-
-    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
-      var ret = [];
-
-      ret.push("Index: " + fileName);
-      ret.push("===================================================================");
-      ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
-      ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
-
-      var diff = LineDiff.diff(oldStr, newStr);
-      if (!diff[diff.length-1].value) {
-        diff.pop();   // Remove trailing newline add
-      }
-      diff.push({value: "", lines: []});   // Append an empty value to make cleanup easier
-
-      function contextLines(lines) {
-        return lines.map(function(entry) { return ' ' + entry; });
-      }
-      function eofNL(curRange, i, current) {
-        var last = diff[diff.length-2],
-            isLast = i === diff.length-2,
-            isLastOfType = i === diff.length-3 && (current.added === !last.added || current.removed === !last.removed);
-
-        // Figure out if this is the last line for the given file and missing NL
-        if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
-          curRange.push('\\ No newline at end of file');
-        }
-      }
-
-      var oldRangeStart = 0, newRangeStart = 0, curRange = [],
-          oldLine = 1, newLine = 1;
-      for (var i = 0; i < diff.length; i++) {
-        var current = diff[i],
-            lines = current.lines || current.value.replace(/\n$/, "").split("\n");
-        current.lines = lines;
-
-        if (current.added || current.removed) {
-          if (!oldRangeStart) {
-            var prev = diff[i-1];
-            oldRangeStart = oldLine;
-            newRangeStart = newLine;
-            
-            if (prev) {
-              curRange = contextLines(prev.lines.slice(-4));
-              oldRangeStart -= curRange.length;
-              newRangeStart -= curRange.length;
-            }
-          }
-          curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
-          eofNL(curRange, i, current);
-
-          if (current.added) {
-            newLine += lines.length;
-          } else {
-            oldLine += lines.length;
-          }
-        } else {
-          if (oldRangeStart) {
-            // Close out any changes that have been output (or join overlapping)
-            if (lines.length <= 8 && i < diff.length-2) {
-              // Overlapping
-              curRange.push.apply(curRange, contextLines(lines));
-            } else {
-              // end the range and output
-              var contextSize = Math.min(lines.length, 4);
-              ret.push(
-                  "@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
-                  + " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
-                  + " @@");
-              ret.push.apply(ret, curRange);
-              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
-              if (lines.length <= 4) {
-                eofNL(ret, i, current);
-              }
-
-              oldRangeStart = 0;  newRangeStart = 0; curRange = [];
-            }
-          }
-          oldLine += lines.length;
-          newLine += lines.length;
-        }
-      }
-
-      return ret.join('\n') + '\n';
-    },
-
-    convertChangesToXML: function(changes){
-      var ret = [];
-      for ( var i = 0; i < changes.length; i++) {
-        var change = changes[i];
-        if (change.added) {
-          ret.push("<ins>");
-        } else if (change.removed) {
-          ret.push("<del>");
-        }
-
-        ret.push(escapeHTML(change.value));
-
-        if (change.added) {
-          ret.push("</ins>");
-        } else if (change.removed) {
-          ret.push("</del>");
-        }
-      }
-      return ret.join("");
-    }
-  };
-})();
-
-if (typeof module !== "undefined") {
-    module.exports = JsDiff;
-}
-
-}); // module: browser/diff.js
-
-require.register("browser/events.js", function(module, exports, require){
-
-/**
- * Module exports.
- */
-
-exports.EventEmitter = EventEmitter;
-
-/**
- * Check if `obj` is an array.
- */
-
-function isArray(obj) {
-  return '[object Array]' == {}.toString.call(obj);
-}
-
-/**
- * Event emitter constructor.
- *
- * @api public
- */
-
-function EventEmitter(){};
-
-/**
- * Adds a listener.
- *
- * @api public
- */
-
-EventEmitter.prototype.on = function (name, fn) {
-  if (!this.$events) {
-    this.$events = {};
-  }
-
-  if (!this.$events[name]) {
-    this.$events[name] = fn;
-  } else if (isArray(this.$events[name])) {
-    this.$events[name].push(fn);
-  } else {
-    this.$events[name] = [this.$events[name], fn];
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.addListener = EventEmitter.prototype.on;
-
-/**
- * Adds a volatile listener.
- *
- * @api public
- */
-
-EventEmitter.prototype.once = function (name, fn) {
-  var self = this;
-
-  function on () {
-    self.removeListener(name, on);
-    fn.apply(this, arguments);
-  };
-
-  on.listener = fn;
-  this.on(name, on);
-
-  return this;
-};
-
-/**
- * Removes a listener.
- *
- * @api public
- */
-
-EventEmitter.prototype.removeListener = function (name, fn) {
-  if (this.$events && this.$events[name]) {
-    var list = this.$events[name];
-
-    if (isArray(list)) {
-      var pos = -1;
-
-      for (var i = 0, l = list.length; i < l; i++) {
-        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
-          pos = i;
-          break;
-        }
-      }
-
-      if (pos < 0) {
-        return this;
-      }
-
-      list.splice(pos, 1);
-
-      if (!list.length) {
-        delete this.$events[name];
-      }
-    } else if (list === fn || (list.listener && list.listener === fn)) {
-      delete this.$events[name];
-    }
-  }
-
-  return this;
-};
-
-/**
- * Removes all listeners for an event.
- *
- * @api public
- */
-
-EventEmitter.prototype.removeAllListeners = function (name) {
-  if (name === undefined) {
-    this.$events = {};
-    return this;
-  }
-
-  if (this.$events && this.$events[name]) {
-    this.$events[name] = null;
-  }
-
-  return this;
-};
-
-/**
- * Gets all listeners for a certain event.
- *
- * @api public
- */
-
-EventEmitter.prototype.listeners = function (name) {
-  if (!this.$events) {
-    this.$events = {};
-  }
-
-  if (!this.$events[name]) {
-    this.$events[name] = [];
-  }
-
-  if (!isArray(this.$events[name])) {
-    this.$events[name] = [this.$events[name]];
-  }
-
-  return this.$events[name];
-};
-
-/**
- * Emits an event.
- *
- * @api public
- */
-
-EventEmitter.prototype.emit = function (name) {
-  if (!this.$events) {
-    return false;
-  }
-
-  var handler = this.$events[name];
-
-  if (!handler) {
-    return false;
-  }
-
-  var args = [].slice.call(arguments, 1);
-
-  if ('function' == typeof handler) {
-    handler.apply(this, args);
-  } else if (isArray(handler)) {
-    var listeners = handler.slice();
-
-    for (var i = 0, l = listeners.length; i < l; i++) {
-      listeners[i].apply(this, args);
-    }
-  } else {
-    return false;
-  }
-
-  return true;
-};
-}); // module: browser/events.js
-
-require.register("browser/fs.js", function(module, exports, require){
-
-}); // module: browser/fs.js
-
-require.register("browser/path.js", function(module, exports, require){
-
-}); // module: browser/path.js
-
-require.register("browser/progress.js", function(module, exports, require){
-
-/**
- * Expose `Progress`.
- */
-
-module.exports = Progress;
-
-/**
- * Initialize a new `Progress` indicator.
- */
-
-function Progress() {
-  this.percent = 0;
-  this.size(0);
-  this.fontSize(11);
-  this.font('helvetica, arial, sans-serif');
-}
-
-/**
- * Set progress size to `n`.
- *
- * @param {Number} n
- * @return {Progress} for chaining
- * @api public
- */
-
-Progress.prototype.size = function(n){
-  this._size = n;
-  return this;
-};
-
-/**
- * Set text to `str`.
- *
- * @param {String} str
- * @return {Progress} for chaining
- * @api public
- */
-
-Progress.prototype.text = function(str){
-  this._text = str;
-  return this;
-};
-
-/**
- * Set font size to `n`.
- *
- * @param {Number} n
- * @return {Progress} for chaining
- * @api public
- */
-
-Progress.prototype.fontSize = function(n){
-  this._fontSize = n;
-  return this;
-};
-
-/**
- * Set font `family`.
- *
- * @param {String} family
- * @return {Progress} for chaining
- */
-
-Progress.prototype.font = function(family){
-  this._font = family;
-  return this;
-};
-
-/**
- * Update percentage to `n`.
- *
- * @param {Number} n
- * @return {Progress} for chaining
- */
-
-Progress.prototype.update = function(n){
-  this.percent = n;
-  return this;
-};
-
-/**
- * Draw on `ctx`.
- *
- * @param {CanvasRenderingContext2d} ctx
- * @return {Progress} for chaining
- */
-
-Progress.prototype.draw = function(ctx){
-  var percent = Math.min(this.percent, 100)
-    , size = this._size
-    , half = size / 2
-    , x = half
-    , y = half
-    , rad = half - 1
-    , fontSize = this._fontSize;
-
-  ctx.font = fontSize + 'px ' + this._font;
-
-  var angle = Math.PI * 2 * (percent / 100);
-  ctx.clearRect(0, 0, size, size);
-
-  // outer circle
-  ctx.strokeStyle = '#9f9f9f';
-  ctx.beginPath();
-  ctx.arc(x, y, rad, 0, angle, false);
-  ctx.stroke();
-
-  // inner circle
-  ctx.strokeStyle = '#eee';
-  ctx.beginPath();
-  ctx.arc(x, y, rad - 1, 0, angle, true);
-  ctx.stroke();
-
-  // text
-  var text = this._text || (percent | 0) + '%'
-    , w = ctx.measureText(text).width;
-
-  ctx.fillText(
-      text
-    , x - w / 2 + 1
-    , y + fontSize / 2 - 1);
-
-  return this;
-};
-
-}); // module: browser/progress.js
-
-require.register("browser/tty.js", function(module, exports, require){
-
-exports.isatty = function(){
-  return true;
-};
-
-exports.getWindowSize = function(){
-  if ('innerHeight' in global) {
-    return [global.innerHeight, global.innerWidth];
-  } else {
-    // In a Web Worker, the DOM Window is not available.
-    return [640, 480];
-  }
-};
-
-}); // module: browser/tty.js
-
-require.register("context.js", function(module, exports, require){
-
-/**
- * Expose `Context`.
- */
-
-module.exports = Context;
-
-/**
- * Initialize a new `Context`.
- *
- * @api private
- */
-
-function Context(){}
-
-/**
- * Set or get the context `Runnable` to `runnable`.
- *
- * @param {Runnable} runnable
- * @return {Context}
- * @api private
- */
-
-Context.prototype.runnable = function(runnable){
-  if (0 == arguments.length) return this._runnable;
-  this.test = this._runnable = runnable;
-  return this;
-};
-
-/**
- * Set test timeout `ms`.
- *
- * @param {Number} ms
- * @return {Context} self
- * @api private
- */
-
-Context.prototype.timeout = function(ms){
-  this.runnable().timeout(ms);
-  return this;
-};
-
-/**
- * Set test slowness threshold `ms`.
- *
- * @param {Number} ms
- * @return {Context} self
- * @api private
- */
-
-Context.prototype.slow = function(ms){
-  this.runnable().slow(ms);
-  return this;
-};
-
-/**
- * Inspect the context void of `._runnable`.
- *
- * @return {String}
- * @api private
- */
-
-Context.prototype.inspect = function(){
-  return JSON.stringify(this, function(key, val){
-    if ('_runnable' == key) return;
-    if ('test' == key) return;
-    return val;
-  }, 2);
-};
-
-}); // module: context.js
-
-require.register("hook.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Runnable = require('./runnable');
-
-/**
- * Expose `Hook`.
- */
-
-module.exports = Hook;
-
-/**
- * Initialize a new `Hook` with the given `title` and callback `fn`.
- *
- * @param {String} title
- * @param {Function} fn
- * @api private
- */
-
-function Hook(title, fn) {
-  Runnable.call(this, title, fn);
-  this.type = 'hook';
-}
-
-/**
- * Inherit from `Runnable.prototype`.
- */
-
-function F(){};
-F.prototype = Runnable.prototype;
-Hook.prototype = new F;
-Hook.prototype.constructor = Hook;
-
-
-/**
- * Get or set the test `err`.
- *
- * @param {Error} err
- * @return {Error}
- * @api public
- */
-
-Hook.prototype.error = function(err){
-  if (0 == arguments.length) {
-    var err = this._error;
-    this._error = null;
-    return err;
-  }
-
-  this._error = err;
-};
-
-}); // module: hook.js
-
-require.register("interfaces/bdd.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Suite = require('../suite')
-  , Test = require('../test');
-
-/**
- * BDD-style interface:
- *
- *      describe('Array', function(){
- *        describe('#indexOf()', function(){
- *          it('should return -1 when not present', function(){
- *
- *          });
- *
- *          it('should return the index when present', function(){
- *
- *          });
- *        });
- *      });
- *
- */
-
-module.exports = function(suite){
-  var suites = [suite];
-
-  suite.on('pre-require', function(context, file, mocha){
-
-    /**
-     * Execute before running tests.
-     */
-
-    context.before = function(fn){
-      suites[0].beforeAll(fn);
-    };
-
-    /**
-     * Execute after running tests.
-     */
-
-    context.after = function(fn){
-      suites[0].afterAll(fn);
-    };
-
-    /**
-     * Execute before each test case.
-     */
-
-    context.beforeEach = function(fn){
-      suites[0].beforeEach(fn);
-    };
-
-    /**
-     * Execute after each test case.
-     */
-
-    context.afterEach = function(fn){
-      suites[0].afterEach(fn);
-    };
-
-    /**
-     * Describe a "suite" with the given `title`
-     * and callback `fn` containing nested suites
-     * and/or tests.
-     */
-
-    context.describe = context.context = function(title, fn){
-      var suite = Suite.create(suites[0], title);
-      suites.unshift(suite);
-      fn.call(suite);
-      suites.shift();
-      return suite;
-    };
-
-    /**
-     * Pending describe.
-     */
-
-    context.xdescribe =
-    context.xcontext =
-    context.describe.skip = function(title, fn){
-      var suite = Suite.create(suites[0], title);
-      suite.pending = true;
-      suites.unshift(suite);
-      fn.call(suite);
-      suites.shift();
-    };
-
-    /**
-     * Exclusive suite.
-     */
-
-    context.describe.only = function(title, fn){
-      var suite = context.describe(title, fn);
-      mocha.grep(suite.fullTitle());
-    };
-
-    /**
-     * Describe a specification or test-case
-     * with the given `title` and callback `fn`
-     * acting as a thunk.
-     */
-
-    context.it = context.specify = function(title, fn){
-      var suite = suites[0];
-      if (suite.pending) var fn = null;
-      var test = new Test(title, fn);
-      suite.addTest(test);
-      return test;
-    };
-
-    /**
-     * Exclusive test-case.
-     */
-
-    context.it.only = function(title, fn){
-      var test = context.it(title, fn);
-      mocha.grep(test.fullTitle());
-    };
-
-    /**
-     * Pending test case.
-     */
-
-    context.xit =
-    context.xspecify =
-    context.it.skip = function(title){
-      context.it(title);
-    };
-  });
-};
-
-}); // module: interfaces/bdd.js
-
-require.register("interfaces/exports.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Suite = require('../suite')
-  , Test = require('../test');
-
-/**
- * TDD-style interface:
- *
- *     exports.Array = {
- *       '#indexOf()': {
- *         'should return -1 when the value is not present': function(){
- *
- *         },
- *
- *         'should return the correct index when the value is present': function(){
- *
- *         }
- *       }
- *     };
- *
- */
-
-module.exports = function(suite){
-  var suites = [suite];
-
-  suite.on('require', visit);
-
-  function visit(obj) {
-    var suite;
-    for (var key in obj) {
-      if ('function' == typeof obj[key]) {
-        var fn = obj[key];
-        switch (key) {
-          case 'before':
-            suites[0].beforeAll(fn);
-            break;
-          case 'after':
-            suites[0].afterAll(fn);
-            break;
-          case 'beforeEach':
-            suites[0].beforeEach(fn);
-            break;
-          case 'afterEach':
-            suites[0].afterEach(fn);
-            break;
-          default:
-            suites[0].addTest(new Test(key, fn));
-        }
-      } else {
-        var suite = Suite.create(suites[0], key);
-        suites.unshift(suite);
-        visit(obj[key]);
-        suites.shift();
-      }
-    }
-  }
-};
-
-}); // module: interfaces/exports.js
-
-require.register("interfaces/index.js", function(module, exports, require){
-
-exports.bdd = require('./bdd');
-exports.tdd = require('./tdd');
-exports.qunit = require('./qunit');
-exports.exports = require('./exports');
-
-}); // module: interfaces/index.js
-
-require.register("interfaces/qunit.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Suite = require('../suite')
-  , Test = require('../test');
-
-/**
- * QUnit-style interface:
- *
- *     suite('Array');
- *
- *     test('#length', function(){
- *       var arr = [1,2,3];
- *       ok(arr.length == 3);
- *     });
- *
- *     test('#indexOf()', function(){
- *       var arr = [1,2,3];
- *       ok(arr.indexOf(1) == 0);
- *       ok(arr.indexOf(2) == 1);
- *       ok(arr.indexOf(3) == 2);
- *     });
- *
- *     suite('String');
- *
- *     test('#length', function(){
- *       ok('foo'.length == 3);
- *     });
- *
- */
-
-module.exports = function(suite){
-  var suites = [suite];
-
-  suite.on('pre-require', function(context, file, mocha){
-
-    /**
-     * Execute before running tests.
-     */
-
-    context.before = function(fn){
-      suites[0].beforeAll(fn);
-    };
-
-    /**
-     * Execute after running tests.
-     */
-
-    context.after = function(fn){
-      suites[0].afterAll(fn);
-    };
-
-    /**
-     * Execute before each test case.
-     */
-
-    context.beforeEach = function(fn){
-      suites[0].beforeEach(fn);
-    };
-
-    /**
-     * Execute after each test case.
-     */
-
-    context.afterEach = function(fn){
-      suites[0].afterEach(fn);
-    };
-
-    /**
-     * Describe a "suite" with the given `title`.
-     */
-
-    context.suite = function(title){
-      if (suites.length > 1) suites.shift();
-      var suite = Suite.create(suites[0], title);
-      suites.unshift(suite);
-      return suite;
-    };
-
-    /**
-     * Exclusive test-case.
-     */
-
-    context.suite.only = function(title, fn){
-      var suite = context.suite(title, fn);
-      mocha.grep(suite.fullTitle());
-    };
-
-    /**
-     * Describe a specification or test-case
-     * with the given `title` and callback `fn`
-     * acting as a thunk.
-     */
-
-    context.test = function(title, fn){
-      var test = new Test(title, fn);
-      suites[0].addTest(test);
-      return test;
-    };
-
-    /**
-     * Exclusive test-case.
-     */
-
-    context.test.only = function(title, fn){
-      var test = context.test(title, fn);
-      mocha.grep(test.fullTitle());
-    };
-
-    /**
-     * Pending test case.
-     */
-
-    context.test.skip = function(title){
-      context.test(title);
-    };
-  });
-};
-
-}); // module: interfaces/qunit.js
-
-require.register("interfaces/tdd.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Suite = require('../suite')
-  , Test = require('../test');
-
-/**
- * TDD-style interface:
- *
- *      suite('Array', function(){
- *        suite('#indexOf()', function(){
- *          suiteSetup(function(){
- *
- *          });
- *
- *          test('should return -1 when not present', function(){
- *
- *          });
- *
- *          test('should return the index when present', function(){
- *
- *          });
- *
- *          suiteTeardown(function(){
- *
- *          });
- *        });
- *      });
- *
- */
-
-module.exports = function(suite){
-  var suites = [suite];
-
-  suite.on('pre-require', function(context, file, mocha){
-
-    /**
-     * Execute before each test case.
-     */
-
-    context.setup = function(fn){
-      suites[0].beforeEach(fn);
-    };
-
-    /**
-     * Execute after each test case.
-     */
-
-    context.teardown = function(fn){
-      suites[0].afterEach(fn);
-    };
-
-    /**
-     * Execute before the suite.
-     */
-
-    context.suiteSetup = function(fn){
-      suites[0].beforeAll(fn);
-    };
-
-    /**
-     * Execute after the suite.
-     */
-
-    context.suiteTeardown = function(fn){
-      suites[0].afterAll(fn);
-    };
-
-    /**
-     * Describe a "suite" with the given `title`
-     * and callback `fn` containing nested suites
-     * and/or tests.
-     */
-
-    context.suite = function(title, fn){
-      var suite = Suite.create(suites[0], title);
-      suites.unshift(suite);
-      fn.call(suite);
-      suites.shift();
-      return suite;
-    };
-
-    /**
-     * Pending suite.
-     */
-    context.suite.skip = function(title, fn) {
-      var suite = Suite.create(suites[0], title);
-      suite.pending = true;
-      suites.unshift(suite);
-      fn.call(suite);
-      suites.shift();
-    };
-
-    /**
-     * Exclusive test-case.
-     */
-
-    context.suite.only = function(title, fn){
-      var suite = context.suite(title, fn);
-      mocha.grep(suite.fullTitle());
-    };
-
-    /**
-     * Describe a specification or test-case
-     * with the given `title` and callback `fn`
-     * acting as a thunk.
-     */
-
-    context.test = function(title, fn){
-      var suite = suites[0];
-      if (suite.pending) var fn = null;
-      var test = new Test(title, fn);
-      suite.addTest(test);
-      return test;
-    };
-
-    /**
-     * Exclusive test-case.
-     */
-
-    context.test.only = function(title, fn){
-      var test = context.test(title, fn);
-      mocha.grep(test.fullTitle());
-    };
-
-    /**
-     * Pending test case.
-     */
-
-    context.test.skip = function(title){
-      context.test(title);
-    };
-  });
-};
-
-}); // module: interfaces/tdd.js
-
-require.register("mocha.js", function(module, exports, require){
-/*!
- * mocha
- * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var path = require('browser/path')
-  , utils = require('./utils');
-
-/**
- * Expose `Mocha`.
- */
-
-exports = module.exports = Mocha;
-
-/**
- * Expose internals.
- */
-
-exports.utils = utils;
-exports.interfaces = require('./interfaces');
-exports.reporters = require('./reporters');
-exports.Runnable = require('./runnable');
-exports.Context = require('./context');
-exports.Runner = require('./runner');
-exports.Suite = require('./suite');
-exports.Hook = require('./hook');
-exports.Test = require('./test');
-
-/**
- * Return image `name` path.
- *
- * @param {String} name
- * @return {String}
- * @api private
- */
-
-function image(name) {
-  return __dirname + '/../images/' + name + '.png';
-}
-
-/**
- * Setup mocha with `options`.
- *
- * Options:
- *
- *   - `ui` name "bdd", "tdd", "exports" etc
- *   - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
- *   - `globals` array of accepted globals
- *   - `timeout` timeout in milliseconds
- *   - `bail` bail on the first test failure
- *   - `slow` milliseconds to wait before considering a test slow
- *   - `ignoreLeaks` ignore global leaks
- *   - `grep` string or regexp to filter tests with
- *
- * @param {Object} options
- * @api public
- */
-
-function Mocha(options) {
-  options = options || {};
-  this.files = [];
-  this.options = options;
-  this.grep(options.grep);
-  this.suite = new exports.Suite('', new exports.Context);
-  this.ui(options.ui);
-  this.bail(options.bail);
-  this.reporter(options.reporter);
-  if (options.timeout) this.timeout(options.timeout);
-  if (options.slow) this.slow(options.slow);
-}
-
-/**
- * Enable or disable bailing on the first failure.
- *
- * @param {Boolean} [bail]
- * @api public
- */
-
-Mocha.prototype.bail = function(bail){
-  if (0 == arguments.length) bail = true;
-  this.suite.bail(bail);
-  return this;
-};
-
-/**
- * Add test `file`.
- *
- * @param {String} file
- * @api public
- */
-
-Mocha.prototype.addFile = function(file){
-  this.files.push(file);
-  return this;
-};
-
-/**
- * Set reporter to `reporter`, defaults to "dot".
- *
- * @param {String|Function} reporter name or constructor
- * @api public
- */
-
-Mocha.prototype.reporter = function(reporter){
-  if ('function' == typeof reporter) {
-    this._reporter = reporter;
-  } else {
-    reporter = reporter || 'dot';
-    try {
-      this._reporter = require('./reporters/' + reporter);
-    } catch (err) {
-      this._reporter = require(reporter);
-    }
-    if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
-  }
-  return this;
-};
-
-/**
- * Set test UI `name`, defaults to "bdd".
- *
- * @param {String} bdd
- * @api public
- */
-
-Mocha.prototype.ui = function(name){
-  name = name || 'bdd';
-  this._ui = exports.interfaces[name];
-  if (!this._ui) throw new Error('invalid interface "' + name + '"');
-  this._ui = this._ui(this.suite);
-  return this;
-};
-
-/**
- * Load registered files.
- *
- * @api private
- */
-
-Mocha.prototype.loadFiles = function(fn){
-  var self = this;
-  var suite = this.suite;
-  var pending = this.files.length;
-  this.files.forEach(function(file){
-    file = path.resolve(file);
-    suite.emit('pre-require', global, file, self);
-    suite.emit('require', require(file), file, self);
-    suite.emit('post-require', global, file, self);
-    --pending || (fn && fn());
-  });
-};
-
-/**
- * Enable growl support.
- *
- * @api private
- */
-
-Mocha.prototype._growl = function(runner, reporter) {
-  var notify = require('growl');
-
-  runner.on('end', function(){
-    var stats = reporter.stats;
-    if (stats.failures) {
-      var msg = stats.failures + ' of ' + runner.total + ' tests failed';
-      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
-    } else {
-      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
-          name: 'mocha'
-        , title: 'Passed'
-        , image: image('ok')
-      });
-    }
-  });
-};
-
-/**
- * Add regexp to grep, if `re` is a string it is escaped.
- *
- * @param {RegExp|String} re
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.grep = function(re){
-  this.options.grep = 'string' == typeof re
-    ? new RegExp(utils.escapeRegexp(re))
-    : re;
-  return this;
-};
-
-/**
- * Invert `.grep()` matches.
- *
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.invert = function(){
-  this.options.invert = true;
-  return this;
-};
-
-/**
- * Ignore global leaks.
- *
- * @param {Boolean} ignore
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.ignoreLeaks = function(ignore){
-  this.options.ignoreLeaks = !!ignore;
-  return this;
-};
-
-/**
- * Enable global leak checking.
- *
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.checkLeaks = function(){
-  this.options.ignoreLeaks = false;
-  return this;
-};
-
-/**
- * Enable growl support.
- *
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.growl = function(){
-  this.options.growl = true;
-  return this;
-};
-
-/**
- * Ignore `globals` array or string.
- *
- * @param {Array|String} globals
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.globals = function(globals){
-  this.options.globals = (this.options.globals || []).concat(globals);
-  return this;
-};
-
-/**
- * Set the timeout in milliseconds.
- *
- * @param {Number} timeout
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.timeout = function(timeout){
-  this.suite.timeout(timeout);
-  return this;
-};
-
-/**
- * Set slowness threshold in milliseconds.
- *
- * @param {Number} slow
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.slow = function(slow){
-  this.suite.slow(slow);
-  return this;
-};
-
-/**
- * Makes all tests async (accepting a callback)
- *
- * @return {Mocha}
- * @api public
- */
-
-Mocha.prototype.asyncOnly = function(){
-  this.options.asyncOnly = true;
-  return this;
-};
-
-/**
- * Run tests and invoke `fn()` when complete.
- *
- * @param {Function} fn
- * @return {Runner}
- * @api public
- */
-
-Mocha.prototype.run = function(fn){
-  if (this.files.length) this.loadFiles();
-  var suite = this.suite;
-  var options = this.options;
-  var runner = new exports.Runner(suite);
-  var reporter = new this._reporter(runner);
-  runner.ignoreLeaks = false !== options.ignoreLeaks;
-  runner.asyncOnly = options.asyncOnly;
-  if (options.grep) runner.grep(options.grep, options.invert);
-  if (options.globals) runner.globals(options.globals);
-  if (options.growl) this._growl(runner, reporter);
-  return runner.run(fn);
-};
-
-}); // module: mocha.js
-
-require.register("ms.js", function(module, exports, require){
-
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-
-/**
- * Parse or format the given `val`.
- *
- * @param {String|Number} val
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val){
-  if ('string' == typeof val) return parse(val);
-  return format(val);
-}
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  var m = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
-  if (!m) return;
-  var n = parseFloat(m[1]);
-  var type = (m[2] || 'ms').toLowerCase();
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'y':
-      return n * 31557600000;
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * 86400000;
-    case 'hours':
-    case 'hour':
-    case 'h':
-      return n * 3600000;
-    case 'minutes':
-    case 'minute':
-    case 'm':
-      return n * 60000;
-    case 'seconds':
-    case 'second':
-    case 's':
-      return n * 1000;
-    case 'ms':
-      return n;
-  }
-}
-
-/**
- * Format the given `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api public
- */
-
-function format(ms) {
-  if (ms == d) return Math.round(ms / d) + ' day';
-  if (ms > d) return Math.round(ms / d) + ' days';
-  if (ms == h) return Math.round(ms / h) + ' hour';
-  if (ms > h) return Math.round(ms / h) + ' hours';
-  if (ms == m) return Math.round(ms / m) + ' minute';
-  if (ms > m) return Math.round(ms / m) + ' minutes';
-  if (ms == s) return Math.round(ms / s) + ' second';
-  if (ms > s) return Math.round(ms / s) + ' seconds';
-  return ms + ' ms';
-}
-}); // module: ms.js
-
-require.register("reporters/base.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var tty = require('browser/tty')
-  , diff = require('browser/diff')
-  , ms = require('../ms');
-
-/**
- * Save timer references to avoid Sinon interfering (see GH-237).
- */
-
-var Date = global.Date
-  , setTimeout = global.setTimeout
-  , setInterval = global.setInterval
-  , clearTimeout = global.clearTimeout
-  , clearInterval = global.clearInterval;
-
-/**
- * Check if both stdio streams are associated with a tty.
- */
-
-var isatty = tty.isatty(1) && tty.isatty(2);
-
-/**
- * Expose `Base`.
- */
-
-exports = module.exports = Base;
-
-/**
- * Enable coloring by default.
- */
-
-exports.useColors = isatty;
-
-/**
- * Default color map.
- */
-
-exports.colors = {
-    'pass': 90
-  , 'fail': 31
-  , 'bright pass': 92
-  , 'bright fail': 91
-  , 'bright yellow': 93
-  , 'pending': 36
-  , 'suite': 0
-  , 'error title': 0
-  , 'error message': 31
-  , 'error stack': 90
-  , 'checkmark': 32
-  , 'fast': 90
-  , 'medium': 33
-  , 'slow': 31
-  , 'green': 32
-  , 'light': 90
-  , 'diff gutter': 90
-  , 'diff added': 42
-  , 'diff removed': 41
-};
-
-/**
- * Default symbol map.
- */
-
-exports.symbols = {
-  ok: '✓',
-  err: '✖',
-  dot: '․'
-};
-
-// With node.js on Windows: use symbols available in terminal default fonts
-if ('win32' == process.platform) {
-  exports.symbols.ok = '\u221A';
-  exports.symbols.err = '\u00D7';
-  exports.symbols.dot = '.';
-}
-
-/**
- * Color `str` with the given `type`,
- * allowing colors to be disabled,
- * as well as user-defined color
- * schemes.
- *
- * @param {String} type
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-var color = exports.color = function(type, str) {
-  if (!exports.useColors) return str;
-  return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
-};
-
-/**
- * Expose term window size, with some
- * defaults for when stderr is not a tty.
- */
-
-exports.window = {
-  width: isatty
-    ? process.stdout.getWindowSize
-      ? process.stdout.getWindowSize(1)[0]
-      : tty.getWindowSize()[1]
-    : 75
-};
-
-/**
- * Expose some basic cursor interactions
- * that are common among reporters.
- */
-
-exports.cursor = {
-  hide: function(){
-    process.stdout.write('\u001b[?25l');
-  },
-
-  show: function(){
-    process.stdout.write('\u001b[?25h');
-  },
-
-  deleteLine: function(){
-    process.stdout.write('\u001b[2K');
-  },
-
-  beginningOfLine: function(){
-    process.stdout.write('\u001b[0G');
-  },
-
-  CR: function(){
-    exports.cursor.deleteLine();
-    exports.cursor.beginningOfLine();
-  }
-};
-
-/**
- * Outut the given `failures` as a list.
- *
- * @param {Array} failures
- * @api public
- */
-
-exports.list = function(failures){
-  console.error();
-  failures.forEach(function(test, i){
-    // format
-    var fmt = color('error title', '  %s) %s:\n')
-      + color('error message', '     %s')
-      + color('error stack', '\n%s\n');
-
-    // msg
-    var err = test.err
-      , message = err.message || ''
-      , stack = err.stack || message
-      , index = stack.indexOf(message) + message.length
-      , msg = stack.slice(0, index)
-      , actual = err.actual
-      , expected = err.expected
-      , escape = true;
-
-    // uncaught
-    if (err.uncaught) {
-      msg = 'Uncaught ' + msg;
-    }
-
-    // explicitly show diff
-    if (err.showDiff && sameType(actual, expected)) {
-      escape = false;
-      err.actual = actual = stringify(actual);
-      err.expected = expected = stringify(expected);
-    }
-
-    // actual / expected diff
-    if ('string' == typeof actual && 'string' == typeof expected) {
-      msg = errorDiff(err, 'Words', escape);
-
-      // linenos
-      var lines = msg.split('\n');
-      if (lines.length > 4) {
-        var width = String(lines.length).length;
-        msg = lines.map(function(str, i){
-          return pad(++i, width) + ' |' + ' ' + str;
-        }).join('\n');
-      }
-
-      // legend
-      msg = '\n'
-        + color('diff removed', 'actual')
-        + ' '
-        + color('diff added', 'expected')
-        + '\n\n'
-        + msg
-        + '\n';
-
-      // indent
-      msg = msg.replace(/^/gm, '      ');
-
-      fmt = color('error title', '  %s) %s:\n%s')
-        + color('error stack', '\n%s\n');
-    }
-
-    // indent stack trace without msg
-    stack = stack.slice(index ? index + 1 : index)
-      .replace(/^/gm, '  ');
-
-    console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
-  });
-};
-
-/**
- * Initialize a new `Base` reporter.
- *
- * All other reporters generally
- * inherit from this reporter, providing
- * stats such as test duration, number
- * of tests passed / failed etc.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Base(runner) {
-  var self = this
-    , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
-    , failures = this.failures = [];
-
-  if (!runner) return;
-  this.runner = runner;
-
-  runner.stats = stats;
-
-  runner.on('start', function(){
-    stats.start = new Date;
-  });
-
-  runner.on('suite', function(suite){
-    stats.suites = stats.suites || 0;
-    suite.root || stats.suites++;
-  });
-
-  runner.on('test end', function(test){
-    stats.tests = stats.tests || 0;
-    stats.tests++;
-  });
-
-  runner.on('pass', function(test){
-    stats.passes = stats.passes || 0;
-
-    var medium = test.slow() / 2;
-    test.speed = test.duration > test.slow()
-      ? 'slow'
-      : test.duration > medium
-        ? 'medium'
-        : 'fast';
-
-    stats.passes++;
-  });
-
-  runner.on('fail', function(test, err){
-    stats.failures = stats.failures || 0;
-    stats.failures++;
-    test.err = err;
-    failures.push(test);
-  });
-
-  runner.on('end', function(){
-    stats.end = new Date;
-    stats.duration = new Date - stats.start;
-  });
-
-  runner.on('pending', function(){
-    stats.pending++;
-  });
-}
-
-/**
- * Output common epilogue used by many of
- * the bundled reporters.
- *
- * @api public
- */
-
-Base.prototype.epilogue = function(){
-  var stats = this.stats;
-  var tests;
-  var fmt;
-
-  console.log();
-
-  // passes
-  fmt = color('bright pass', ' ')
-    + color('green', ' %d passing')
-    + color('light', ' (%s)');
-
-  console.log(fmt,
-    stats.passes || 0,
-    ms(stats.duration));
-
-  // pending
-  if (stats.pending) {
-    fmt = color('pending', ' ')
-      + color('pending', ' %d pending');
-
-    console.log(fmt, stats.pending);
-  }
-
-  // failures
-  if (stats.failures) {
-    fmt = color('fail', '  %d failing');
-
-    console.error(fmt,
-      stats.failures);
-
-    Base.list(this.failures);
-    console.error();
-  }
-
-  console.log();
-};
-
-/**
- * Pad the given `str` to `len`.
- *
- * @param {String} str
- * @param {String} len
- * @return {String}
- * @api private
- */
-
-function pad(str, len) {
-  str = String(str);
-  return Array(len - str.length + 1).join(' ') + str;
-}
-
-/**
- * Return a character diff for `err`.
- *
- * @param {Error} err
- * @return {String}
- * @api private
- */
-
-function errorDiff(err, type, escape) {
-  return diff['diff' + type](err.actual, err.expected).map(function(str){
-    if (escape) {
-      str.value = str.value
-        .replace(/\t/g, '<tab>')
-        .replace(/\r/g, '<CR>')
-        .replace(/\n/g, '<LF>\n');
-    }
-    if (str.added) return colorLines('diff added', str.value);
-    if (str.removed) return colorLines('diff removed', str.value);
-    return str.value;
-  }).join('');
-}
-
-/**
- * Color lines for `str`, using the color `name`.
- *
- * @param {String} name
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-function colorLines(name, str) {
-  return str.split('\n').map(function(str){
-    return color(name, str);
-  }).join('\n');
-}
-
-/**
- * Stringify `obj`.
- *
- * @param {Mixed} obj
- * @return {String}
- * @api private
- */
-
-function stringify(obj) {
-  if (obj instanceof RegExp) return obj.toString();
-  return JSON.stringify(obj, null, 2);
-}
-
-/**
- * Check that a / b have the same type.
- *
- * @param {Object} a
- * @param {Object} b
- * @return {Boolean}
- * @api private
- */
-
-function sameType(a, b) {
-  a = Object.prototype.toString.call(a);
-  b = Object.prototype.toString.call(b);
-  return a == b;
-}
-
-}); // module: reporters/base.js
-
-require.register("reporters/doc.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , utils = require('../utils');
-
-/**
- * Expose `Doc`.
- */
-
-exports = module.exports = Doc;
-
-/**
- * Initialize a new `Doc` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Doc(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , total = runner.total
-    , indents = 2;
-
-  function indent() {
-    return Array(indents).join('  ');
-  }
-
-  runner.on('suite', function(suite){
-    if (suite.root) return;
-    ++indents;
-    console.log('%s<section class="suite">', indent());
-    ++indents;
-    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
-    console.log('%s<dl>', indent());
-  });
-
-  runner.on('suite end', function(suite){
-    if (suite.root) return;
-    console.log('%s</dl>', indent());
-    --indents;
-    console.log('%s</section>', indent());
-    --indents;
-  });
-
-  runner.on('pass', function(test){
-    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));
-    var code = utils.escape(utils.clean(test.fn.toString()));
-    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);
-  });
-}
-
-}); // module: reporters/doc.js
-
-require.register("reporters/dot.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , color = Base.color;
-
-/**
- * Expose `Dot`.
- */
-
-exports = module.exports = Dot;
-
-/**
- * Initialize a new `Dot` matrix test reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Dot(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , width = Base.window.width * .75 | 0
-    , n = 0;
-
-  runner.on('start', function(){
-    process.stdout.write('\n  ');
-  });
-
-  runner.on('pending', function(test){
-    process.stdout.write(color('pending', Base.symbols.dot));
-  });
-
-  runner.on('pass', function(test){
-    if (++n % width == 0) process.stdout.write('\n  ');
-    if ('slow' == test.speed) {
-      process.stdout.write(color('bright yellow', Base.symbols.dot));
-    } else {
-      process.stdout.write(color(test.speed, Base.symbols.dot));
-    }
-  });
-
-  runner.on('fail', function(test, err){
-    if (++n % width == 0) process.stdout.write('\n  ');
-    process.stdout.write(color('fail', Base.symbols.dot));
-  });
-
-  runner.on('end', function(){
-    console.log();
-    self.epilogue();
-  });
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-Dot.prototype = new F;
-Dot.prototype.constructor = Dot;
-
-}); // module: reporters/dot.js
-
-require.register("reporters/html-cov.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var JSONCov = require('./json-cov')
-  , fs = require('browser/fs');
-
-/**
- * Expose `HTMLCov`.
- */
-
-exports = module.exports = HTMLCov;
-
-/**
- * Initialize a new `JsCoverage` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function HTMLCov(runner) {
-  var jade = require('jade')
-    , file = __dirname + '/templates/coverage.jade'
-    , str = fs.readFileSync(file, 'utf8')
-    , fn = jade.compile(str, { filename: file })
-    , self = this;
-
-  JSONCov.call(this, runner, false);
-
-  runner.on('end', function(){
-    process.stdout.write(fn({
-        cov: self.cov
-      , coverageClass: coverageClass
-    }));
-  });
-}
-
-/**
- * Return coverage class for `n`.
- *
- * @return {String}
- * @api private
- */
-
-function coverageClass(n) {
-  if (n >= 75) return 'high';
-  if (n >= 50) return 'medium';
-  if (n >= 25) return 'low';
-  return 'terrible';
-}
-}); // module: reporters/html-cov.js
-
-require.register("reporters/html.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , utils = require('../utils')
-  , Progress = require('../browser/progress')
-  , escape = utils.escape;
-
-/**
- * Save timer references to avoid Sinon interfering (see GH-237).
- */
-
-var Date = global.Date
-  , setTimeout = global.setTimeout
-  , setInterval = global.setInterval
-  , clearTimeout = global.clearTimeout
-  , clearInterval = global.clearInterval;
-
-/**
- * Expose `Doc`.
- */
-
-exports = module.exports = HTML;
-
-/**
- * Stats template.
- */
-
-var statsTemplate = '<ul id="mocha-stats">'
-  + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
-  + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
-  + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
-  + '<li class="duration">duration: <em>0</em>s</li>'
-  + '</ul>';
-
-/**
- * Initialize a new `Doc` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function HTML(runner, root) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , total = runner.total
-    , stat = fragment(statsTemplate)
-    , items = stat.getElementsByTagName('li')
-    , passes = items[1].getElementsByTagName('em')[0]
-    , passesLink = items[1].getElementsByTagName('a')[0]
-    , failures = items[2].getElementsByTagName('em')[0]
-    , failuresLink = items[2].getElementsByTagName('a')[0]
-    , duration = items[3].getElementsByTagName('em')[0]
-    , canvas = stat.getElementsByTagName('canvas')[0]
-    , report = fragment('<ul id="mocha-report"></ul>')
-    , stack = [report]
-    , progress
-    , ctx
-
-  root = root || document.getElementById('mocha');
-
-  if (canvas.getContext) {
-    var ratio = window.devicePixelRatio || 1;
-    canvas.style.width = canvas.width;
-    canvas.style.height = canvas.height;
-    canvas.width *= ratio;
-    canvas.height *= ratio;
-    ctx = canvas.getContext('2d');
-    ctx.scale(ratio, ratio);
-    progress = new Progress;
-  }
-
-  if (!root) return error('#mocha div missing, add it to your document');
-
-  // pass toggle
-  on(passesLink, 'click', function(){
-    unhide();
-    var name = /pass/.test(report.className) ? '' : ' pass';
-    report.className = report.className.replace(/fail|pass/g, '') + name;
-    if (report.className.trim()) hideSuitesWithout('test pass');
-  });
-
-  // failure toggle
-  on(failuresLink, 'click', function(){
-    unhide();
-    var name = /fail/.test(report.className) ? '' : ' fail';
-    report.className = report.className.replace(/fail|pass/g, '') + name;
-    if (report.className.trim()) hideSuitesWithout('test fail');
-  });
-
-  root.appendChild(stat);
-  root.appendChild(report);
-
-  if (progress) progress.size(40);
-
-  runner.on('suite', function(suite){
-    if (suite.root) return;
-
-    // suite
-    var url = '?grep=' + encodeURIComponent(suite.fullTitle());
-    var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
-
-    // container
-    stack[0].appendChild(el);
-    stack.unshift(document.createElement('ul'));
-    el.appendChild(stack[0]);
-  });
-
-  runner.on('suite end', function(suite){
-    if (suite.root) return;
-    stack.shift();
-  });
-
-  runner.on('fail', function(test, err){
-    if ('hook' == test.type) runner.emit('test end', test);
-  });
-
-  runner.on('test end', function(test){
-    // TODO: add to stats
-    var percent = stats.tests / this.total * 100 | 0;
-    if (progress) progress.update(percent).draw(ctx);
-
-    // update stats
-    var ms = new Date - stats.start;
-    text(passes, stats.passes);
-    text(failures, stats.failures);
-    text(duration, (ms / 1000).toFixed(2));
-
-    // test
-    if ('passed' == test.state) {
-      var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="?grep=%e" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, encodeURIComponent(test.fullTitle()));
-    } else if (test.pending) {
-      var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
-    } else {
-      var el = fragment('<li class="test fail"><h2>%e <a href="?grep=%e" class="replay">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));
-      var str = test.err.stack || test.err.toString();
-
-      // FF / Opera do not add the message
-      if (!~str.indexOf(test.err.message)) {
-        str = test.err.message + '\n' + str;
-      }
-
-      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
-      // check for the result of the stringifying.
-      if ('[object Error]' == str) str = test.err.message;
-
-      // Safari doesn't give you a stack. Let's at least provide a source line.
-      if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
-        str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
-      }
-
-      el.appendChild(fragment('<pre class="error">%e</pre>', str));
-    }
-
-    // toggle code
-    // TODO: defer
-    if (!test.pending) {
-      var h2 = el.getElementsByTagName('h2')[0];
-
-      on(h2, 'click', function(){
-        pre.style.display = 'none' == pre.style.display
-          ? 'block'
-          : 'none';
-      });
-
-      var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
-      el.appendChild(pre);
-      pre.style.display = 'none';
-    }
-
-    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
-    if (stack[0]) stack[0].appendChild(el);
-  });
-}
-
-/**
- * Display error `msg`.
- */
-
-function error(msg) {
-  document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
-}
-
-/**
- * Return a DOM fragment from `html`.
- */
-
-function fragment(html) {
-  var args = arguments
-    , div = document.createElement('div')
-    , i = 1;
-
-  div.innerHTML = html.replace(/%([se])/g, function(_, type){
-    switch (type) {
-      case 's': return String(args[i++]);
-      case 'e': return escape(args[i++]);
-    }
-  });
-
-  return div.firstChild;
-}
-
-/**
- * Check for suites that do not have elements
- * with `classname`, and hide them.
- */
-
-function hideSuitesWithout(classname) {
-  var suites = document.getElementsByClassName('suite');
-  for (var i = 0; i < suites.length; i++) {
-    var els = suites[i].getElementsByClassName(classname);
-    if (0 == els.length) suites[i].className += ' hidden';
-  }
-}
-
-/**
- * Unhide .hidden suites.
- */
-
-function unhide() {
-  var els = document.getElementsByClassName('suite hidden');
-  for (var i = 0; i < els.length; ++i) {
-    els[i].className = els[i].className.replace('suite hidden', 'suite');
-  }
-}
-
-/**
- * Set `el` text to `str`.
- */
-
-function text(el, str) {
-  if (el.textContent) {
-    el.textContent = str;
-  } else {
-    el.innerText = str;
-  }
-}
-
-/**
- * Listen on `event` with callback `fn`.
- */
-
-function on(el, event, fn) {
-  if (el.addEventListener) {
-    el.addEventListener(event, fn, false);
-  } else {
-    el.attachEvent('on' + event, fn);
-  }
-}
-
-}); // module: reporters/html.js
-
-require.register("reporters/index.js", function(module, exports, require){
-
-exports.Base = require('./base');
-exports.Dot = require('./dot');
-exports.Doc = require('./doc');
-exports.TAP = require('./tap');
-exports.JSON = require('./json');
-exports.HTML = require('./html');
-exports.List = require('./list');
-exports.Min = require('./min');
-exports.Spec = require('./spec');
-exports.Nyan = require('./nyan');
-exports.XUnit = require('./xunit');
-exports.Markdown = require('./markdown');
-exports.Progress = require('./progress');
-exports.Landing = require('./landing');
-exports.JSONCov = require('./json-cov');
-exports.HTMLCov = require('./html-cov');
-exports.JSONStream = require('./json-stream');
-exports.Teamcity = require('./teamcity');
-
-}); // module: reporters/index.js
-
-require.register("reporters/json-cov.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base');
-
-/**
- * Expose `JSONCov`.
- */
-
-exports = module.exports = JSONCov;
-
-/**
- * Initialize a new `JsCoverage` reporter.
- *
- * @param {Runner} runner
- * @param {Boolean} output
- * @api public
- */
-
-function JSONCov(runner, output) {
-  var self = this
-    , output = 1 == arguments.length ? true : output;
-
-  Base.call(this, runner);
-
-  var tests = []
-    , failures = []
-    , passes = [];
-
-  runner.on('test end', function(test){
-    tests.push(test);
-  });
-
-  runner.on('pass', function(test){
-    passes.push(test);
-  });
-
-  runner.on('fail', function(test){
-    failures.push(test);
-  });
-
-  runner.on('end', function(){
-    var cov = global._$jscoverage || {};
-    var result = self.cov = map(cov);
-    result.stats = self.stats;
-    result.tests = tests.map(clean);
-    result.failures = failures.map(clean);
-    result.passes = passes.map(clean);
-    if (!output) return;
-    process.stdout.write(JSON.stringify(result, null, 2 ));
-  });
-}
-
-/**
- * Map jscoverage data to a JSON structure
- * suitable for reporting.
- *
- * @param {Object} cov
- * @return {Object}
- * @api private
- */
-
-function map(cov) {
-  var ret = {
-      instrumentation: 'node-jscoverage'
-    , sloc: 0
-    , hits: 0
-    , misses: 0
-    , coverage: 0
-    , files: []
-  };
-
-  for (var filename in cov) {
-    var data = coverage(filename, cov[filename]);
-    ret.files.push(data);
-    ret.hits += data.hits;
-    ret.misses += data.misses;
-    ret.sloc += data.sloc;
-  }
-
-  ret.files.sort(function(a, b) {
-    return a.filename.localeCompare(b.filename);
-  });
-
-  if (ret.sloc > 0) {
-    ret.coverage = (ret.hits / ret.sloc) * 100;
-  }
-
-  return ret;
-};
-
-/**
- * Map jscoverage data for a single source file
- * to a JSON structure suitable for reporting.
- *
- * @param {String} filename name of the source file
- * @param {Object} data jscoverage coverage data
- * @return {Object}
- * @api private
- */
-
-function coverage(filename, data) {
-  var ret = {
-    filename: filename,
-    coverage: 0,
-    hits: 0,
-    misses: 0,
-    sloc: 0,
-    source: {}
-  };
-
-  data.source.forEach(function(line, num){
-    num++;
-
-    if (data[num] === 0) {
-      ret.misses++;
-      ret.sloc++;
-    } else if (data[num] !== undefined) {
-      ret.hits++;
-      ret.sloc++;
-    }
-
-    ret.source[num] = {
-        source: line
-      , coverage: data[num] === undefined
-        ? ''
-        : data[num]
-    };
-  });
-
-  ret.coverage = ret.hits / ret.sloc * 100;
-
-  return ret;
-}
-
-/**
- * Return a plain-object representation of `test`
- * free of cyclic properties etc.
- *
- * @param {Object} test
- * @return {Object}
- * @api private
- */
-
-function clean(test) {
-  return {
-      title: test.title
-    , fullTitle: test.fullTitle()
-    , duration: test.duration
-  }
-}
-
-}); // module: reporters/json-cov.js
-
-require.register("reporters/json-stream.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , color = Base.color;
-
-/**
- * Expose `List`.
- */
-
-exports = module.exports = List;
-
-/**
- * Initialize a new `List` test reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function List(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , total = runner.total;
-
-  runner.on('start', function(){
-    console.log(JSON.stringify(['start', { total: total }]));
-  });
-
-  runner.on('pass', function(test){
-    console.log(JSON.stringify(['pass', clean(test)]));
-  });
-
-  runner.on('fail', function(test, err){
-    console.log(JSON.stringify(['fail', clean(test)]));
-  });
-
-  runner.on('end', function(){
-    process.stdout.write(JSON.stringify(['end', self.stats]));
-  });
-}
-
-/**
- * Return a plain-object representation of `test`
- * free of cyclic properties etc.
- *
- * @param {Object} test
- * @return {Object}
- * @api private
- */
-
-function clean(test) {
-  return {
-      title: test.title
-    , fullTitle: test.fullTitle()
-    , duration: test.duration
-  }
-}
-}); // module: reporters/json-stream.js
-
-require.register("reporters/json.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `JSON`.
- */
-
-exports = module.exports = JSONReporter;
-
-/**
- * Initialize a new `JSON` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function JSONReporter(runner) {
-  var self = this;
-  Base.call(this, runner);
-
-  var tests = []
-    , failures = []
-    , passes = [];
-
-  runner.on('test end', function(test){
-    tests.push(test);
-  });
-
-  runner.on('pass', function(test){
-    passes.push(test);
-  });
-
-  runner.on('fail', function(test){
-    failures.push(test);
-  });
-
-  runner.on('end', function(){
-    var obj = {
-        stats: self.stats
-      , tests: tests.map(clean)
-      , failures: failures.map(clean)
-      , passes: passes.map(clean)
-    };
-
-    process.stdout.write(JSON.stringify(obj, null, 2));
-  });
-}
-
-/**
- * Return a plain-object representation of `test`
- * free of cyclic properties etc.
- *
- * @param {Object} test
- * @return {Object}
- * @api private
- */
-
-function clean(test) {
-  return {
-      title: test.title
-    , fullTitle: test.fullTitle()
-    , duration: test.duration
-  }
-}
-}); // module: reporters/json.js
-
-require.register("reporters/landing.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `Landing`.
- */
-
-exports = module.exports = Landing;
-
-/**
- * Airplane color.
- */
-
-Base.colors.plane = 0;
-
-/**
- * Airplane crash color.
- */
-
-Base.colors['plane crash'] = 31;
-
-/**
- * Runway color.
- */
-
-Base.colors.runway = 90;
-
-/**
- * Initialize a new `Landing` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Landing(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , width = Base.window.width * .75 | 0
-    , total = runner.total
-    , stream = process.stdout
-    , plane = color('plane', '✈')
-    , crashed = -1
-    , n = 0;
-
-  function runway() {
-    var buf = Array(width).join('-');
-    return '  ' + color('runway', buf);
-  }
-
-  runner.on('start', function(){
-    stream.write('\n  ');
-    cursor.hide();
-  });
-
-  runner.on('test end', function(test){
-    // check if the plane crashed
-    var col = -1 == crashed
-      ? width * ++n / total | 0
-      : crashed;
-
-    // show the crash
-    if ('failed' == test.state) {
-      plane = color('plane crash', '✈');
-      crashed = col;
-    }
-
-    // render landing strip
-    stream.write('\u001b[4F\n\n');
-    stream.write(runway());
-    stream.write('\n  ');
-    stream.write(color('runway', Array(col).join('⋅')));
-    stream.write(plane)
-    stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
-    stream.write(runway());
-    stream.write('\u001b[0m');
-  });
-
-  runner.on('end', function(){
-    cursor.show();
-    console.log();
-    self.epilogue();
-  });
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-Landing.prototype = new F;
-Landing.prototype.constructor = Landing;
-
-}); // module: reporters/landing.js
-
-require.register("reporters/list.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `List`.
- */
-
-exports = module.exports = List;
-
-/**
- * Initialize a new `List` test reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function List(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , n = 0;
-
-  runner.on('start', function(){
-    console.log();
-  });
-
-  runner.on('test', function(test){
-    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));
-  });
-
-  runner.on('pending', function(test){
-    var fmt = color('checkmark', '  -')
-      + color('pending', ' %s');
-    console.log(fmt, test.fullTitle());
-  });
-
-  runner.on('pass', function(test){
-    var fmt = color('checkmark', '  '+Base.symbols.dot)
-      + color('pass', ' %s: ')
-      + color(test.speed, '%dms');
-    cursor.CR();
-    console.log(fmt, test.fullTitle(), test.duration);
-  });
-
-  runner.on('fail', function(test, err){
-    cursor.CR();
-    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());
-  });
-
-  runner.on('end', self.epilogue.bind(self));
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-List.prototype = new F;
-List.prototype.constructor = List;
-
-
-}); // module: reporters/list.js
-
-require.register("reporters/markdown.js", function(module, exports, require){
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , utils = require('../utils');
-
-/**
- * Expose `Markdown`.
- */
-
-exports = module.exports = Markdown;
-
-/**
- * Initialize a new `Markdown` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Markdown(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , level = 0
-    , buf = '';
-
-  function title(str) {
-    return Array(level).join('#') + ' ' + str;
-  }
-
-  function indent() {
-    return Array(level).join('  ');
-  }
-
-  function mapTOC(suite, obj) {
-    var ret = obj;
-    obj = obj[suite.title] = obj[suite.title] || { suite: suite };
-    suite.suites.forEach(function(suite){
-      mapTOC(suite, obj);
-    });
-    return ret;
-  }
-
-  function stringifyTOC(obj, level) {
-    ++level;
-    var buf = '';
-    var link;
-    for (var key in obj) {
-      if ('suite' == key) continue;
-      if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
-      if (key) buf += Array(level).join('  ') + link;
-      buf += stringifyTOC(obj[key], level);
-    }
-    --level;
-    return buf;
-  }
-
-  function generateTOC(suite) {
-    var obj = mapTOC(suite, {});
-    return stringifyTOC(obj, 0);
-  }
-
-  generateTOC(runner.suite);
-
-  runner.on('suite', function(suite){
-    ++level;
-    var slug = utils.slug(suite.fullTitle());
-    buf += '<a name="' + slug + '"></a>' + '\n';
-    buf += title(suite.title) + '\n';
-  });
-
-  runner.on('suite end', function(suite){
-    --level;
-  });
-
-  runner.on('pass', function(test){
-    var code = utils.clean(test.fn.toString());
-    buf += test.title + '.\n';
-    buf += '\n```js\n';
-    buf += code + '\n';
-    buf += '```\n\n';
-  });
-
-  runner.on('end', function(){
-    process.stdout.write('# TOC\n');
-    process.stdout.write(generateTOC(runner.suite));
-    process.stdout.write(buf);
-  });
-}
-}); // module: reporters/markdown.js
-
-require.register("reporters/min.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base');
-
-/**
- * Expose `Min`.
- */
-
-exports = module.exports = Min;
-
-/**
- * Initialize a new `Min` minimal test reporter (best used with --watch).
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Min(runner) {
-  Base.call(this, runner);
-
-  runner.on('start', function(){
-    // clear screen
-    process.stdout.write('\u001b[2J');
-    // set cursor position
-    process.stdout.write('\u001b[1;3H');
-  });
-
-  runner.on('end', this.epilogue.bind(this));
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-Min.prototype = new F;
-Min.prototype.constructor = Min;
-
-
-}); // module: reporters/min.js
-
-require.register("reporters/nyan.js", function(module, exports, require){
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , color = Base.color;
-
-/**
- * Expose `Dot`.
- */
-
-exports = module.exports = NyanCat;
-
-/**
- * Initialize a new `Dot` matrix test reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function NyanCat(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , width = Base.window.width * .75 | 0
-    , rainbowColors = this.rainbowColors = self.generateColors()
-    , colorIndex = this.colorIndex = 0
-    , numerOfLines = this.numberOfLines = 4
-    , trajectories = this.trajectories = [[], [], [], []]
-    , nyanCatWidth = this.nyanCatWidth = 11
-    , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
-    , scoreboardWidth = this.scoreboardWidth = 5
-    , tick = this.tick = 0
-    , n = 0;
-
-  runner.on('start', function(){
-    Base.cursor.hide();
-    self.draw('start');
-  });
-
-  runner.on('pending', function(test){
-    self.draw('pending');
-  });
-
-  runner.on('pass', function(test){
-    self.draw('pass');
-  });
-
-  runner.on('fail', function(test, err){
-    self.draw('fail');
-  });
-
-  runner.on('end', function(){
-    Base.cursor.show();
-    for (var i = 0; i < self.numberOfLines; i++) write('\n');
-    self.epilogue();
-  });
-}
-
-/**
- * Draw the nyan cat with runner `status`.
- *
- * @param {String} status
- * @api private
- */
-
-NyanCat.prototype.draw = function(status){
-  this.appendRainbow();
-  this.drawScoreboard();
-  this.drawRainbow();
-  this.drawNyanCat(status);
-  this.tick = !this.tick;
-};
-
-/**
- * Draw the "scoreboard" showing the number
- * of passes, failures and pending tests.
- *
- * @api private
- */
-
-NyanCat.prototype.drawScoreboard = function(){
-  var stats = this.stats;
-  var colors = Base.colors;
-
-  function draw(color, n) {
-    write(' ');
-    write('\u001b[' + color + 'm' + n + '\u001b[0m');
-    write('\n');
-  }
-
-  draw(colors.green, stats.passes);
-  draw(colors.fail, stats.failures);
-  draw(colors.pending, stats.pending);
-  write('\n');
-
-  this.cursorUp(this.numberOfLines);
-};
-
-/**
- * Append the rainbow.
- *
- * @api private
- */
-
-NyanCat.prototype.appendRainbow = function(){
-  var segment = this.tick ? '_' : '-';
-  var rainbowified = this.rainbowify(segment);
-
-  for (var index = 0; index < this.numberOfLines; index++) {
-    var trajectory = this.trajectories[index];
-    if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
-    trajectory.push(rainbowified);
-  }
-};
-
-/**
- * Draw the rainbow.
- *
- * @api private
- */
-
-NyanCat.prototype.drawRainbow = function(){
-  var self = this;
-
-  this.trajectories.forEach(function(line, index) {
-    write('\u001b[' + self.scoreboardWidth + 'C');
-    write(line.join(''));
-    write('\n');
-  });
-
-  this.cursorUp(this.numberOfLines);
-};
-
-/**
- * Draw the nyan cat with `status`.
- *
- * @param {String} status
- * @api private
- */
-
-NyanCat.prototype.drawNyanCat = function(status) {
-  var self = this;
-  var startWidth = this.scoreboardWidth + this.trajectories[0].length;
-  var color = '\u001b[' + startWidth + 'C';
-  var padding = '';
-  
-  write(color);
-  write('_,------,');
-  write('\n');
-  
-  write(color);
-  padding = self.tick ? '  ' : '   ';
-  write('_|' + padding + '/\\_/\\ ');
-  write('\n');
-  
-  write(color);
-  padding = self.tick ? '_' : '__';
-  var tail = self.tick ? '~' : '^';
-  var face;
-  switch (status) {
-    case 'pass':
-      face = '( ^ .^)';
-      break;
-    case 'fail':
-      face = '( o .o)';
-      break;
-    default:
-      face = '( - .-)';
-  }
-  write(tail + '|' + padding + face + ' ');
-  write('\n');
-  
-  write(color);
-  padding = self.tick ? ' ' : '  ';
-  write(padding + '""  "" ');
-  write('\n');
-
-  this.cursorUp(this.numberOfLines);
-};
-
-/**
- * Move cursor up `n`.
- *
- * @param {Number} n
- * @api private
- */
-
-NyanCat.prototype.cursorUp = function(n) {
-  write('\u001b[' + n + 'A');
-};
-
-/**
- * Move cursor down `n`.
- *
- * @param {Number} n
- * @api private
- */
-
-NyanCat.prototype.cursorDown = function(n) {
-  write('\u001b[' + n + 'B');
-};
-
-/**
- * Generate rainbow colors.
- *
- * @return {Array}
- * @api private
- */
-
-NyanCat.prototype.generateColors = function(){
-  var colors = [];
-
-  for (var i = 0; i < (6 * 7); i++) {
-    var pi3 = Math.floor(Math.PI / 3);
-    var n = (i * (1.0 / 6));
-    var r = Math.floor(3 * Math.sin(n) + 3);
-    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
-    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
-    colors.push(36 * r + 6 * g + b + 16);
-  }
-
-  return colors;
-};
-
-/**
- * Apply rainbow to the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-NyanCat.prototype.rainbowify = function(str){
-  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
-  this.colorIndex += 1;
-  return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
-};
-
-/**
- * Stdout helper.
- */
-
-function write(string) {
-  process.stdout.write(string);
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-NyanCat.prototype = new F;
-NyanCat.prototype.constructor = NyanCat;
-
-
-}); // module: reporters/nyan.js
-
-require.register("reporters/progress.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `Progress`.
- */
-
-exports = module.exports = Progress;
-
-/**
- * General progress bar color.
- */
-
-Base.colors.progress = 90;
-
-/**
- * Initialize a new `Progress` bar test reporter.
- *
- * @param {Runner} runner
- * @param {Object} options
- * @api public
- */
-
-function Progress(runner, options) {
-  Base.call(this, runner);
-
-  var self = this
-    , options = options || {}
-    , stats = this.stats
-    , width = Base.window.width * .50 | 0
-    , total = runner.total
-    , complete = 0
-    , max = Math.max;
-
-  // default chars
-  options.open = options.open || '[';
-  options.complete = options.complete || '▬';
-  options.incomplete = options.incomplete || Base.symbols.dot;
-  options.close = options.close || ']';
-  options.verbose = false;
-
-  // tests started
-  runner.on('start', function(){
-    console.log();
-    cursor.hide();
-  });
-
-  // tests complete
-  runner.on('test end', function(){
-    complete++;
-    var incomplete = total - complete
-      , percent = complete / total
-      , n = width * percent | 0
-      , i = width - n;
-
-    cursor.CR();
-    process.stdout.write('\u001b[J');
-    process.stdout.write(color('progress', '  ' + options.open));
-    process.stdout.write(Array(n).join(options.complete));
-    process.stdout.write(Array(i).join(options.incomplete));
-    process.stdout.write(color('progress', options.close));
-    if (options.verbose) {
-      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
-    }
-  });
-
-  // tests are complete, output some stats
-  // and the failures if any
-  runner.on('end', function(){
-    cursor.show();
-    console.log();
-    self.epilogue();
-  });
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-Progress.prototype = new F;
-Progress.prototype.constructor = Progress;
-
-
-}); // module: reporters/progress.js
-
-require.register("reporters/spec.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `Spec`.
- */
-
-exports = module.exports = Spec;
-
-/**
- * Initialize a new `Spec` test reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Spec(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , indents = 0
-    , n = 0;
-
-  function indent() {
-    return Array(indents).join('  ')
-  }
-
-  runner.on('start', function(){
-    console.log();
-  });
-
-  runner.on('suite', function(suite){
-    ++indents;
-    console.log(color('suite', '%s%s'), indent(), suite.title);
-  });
-
-  runner.on('suite end', function(suite){
-    --indents;
-    if (1 == indents) console.log();
-  });
-
-  runner.on('test', function(test){
-    process.stdout.write(indent() + color('pass', '  ◦ ' + test.title + ': '));
-  });
-
-  runner.on('pending', function(test){
-    var fmt = indent() + color('pending', '  - %s');
-    console.log(fmt, test.title);
-  });
-
-  runner.on('pass', function(test){
-    if ('fast' == test.speed) {
-      var fmt = indent()
-        + color('checkmark', '  ' + Base.symbols.ok)
-        + color('pass', ' %s ');
-      cursor.CR();
-      console.log(fmt, test.title);
-    } else {
-      var fmt = indent()
-        + color('checkmark', '  ' + Base.symbols.ok)
-        + color('pass', ' %s ')
-        + color(test.speed, '(%dms)');
-      cursor.CR();
-      console.log(fmt, test.title, test.duration);
-    }
-  });
-
-  runner.on('fail', function(test, err){
-    cursor.CR();
-    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);
-  });
-
-  runner.on('end', self.epilogue.bind(self));
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-Spec.prototype = new F;
-Spec.prototype.constructor = Spec;
-
-
-}); // module: reporters/spec.js
-
-require.register("reporters/tap.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , cursor = Base.cursor
-  , color = Base.color;
-
-/**
- * Expose `TAP`.
- */
-
-exports = module.exports = TAP;
-
-/**
- * Initialize a new `TAP` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function TAP(runner) {
-  Base.call(this, runner);
-
-  var self = this
-    , stats = this.stats
-    , n = 1
-    , passes = 0
-    , failures = 0;
-
-  runner.on('start', function(){
-    var total = runner.grepTotal(runner.suite);
-    console.log('%d..%d', 1, total);
-  });
-
-  runner.on('test end', function(){
-    ++n;
-  });
-
-  runner.on('pending', function(test){
-    console.log('ok %d %s # SKIP -', n, title(test));
-  });
-
-  runner.on('pass', function(test){
-    passes++;
-    console.log('ok %d %s', n, title(test));
-  });
-
-  runner.on('fail', function(test, err){
-    failures++;
-    console.log('not ok %d %s', n, title(test));
-    if (err.stack) console.log(err.stack.replace(/^/gm, '  '));
-  });
-
-  runner.on('end', function(){
-    console.log('# tests ' + (passes + failures));
-    console.log('# pass ' + passes);
-    console.log('# fail ' + failures);
-  });
-}
-
-/**
- * Return a TAP-safe title of `test`
- *
- * @param {Object} test
- * @return {String}
- * @api private
- */
-
-function title(test) {
-  return test.fullTitle().replace(/#/g, '');
-}
-
-}); // module: reporters/tap.js
-
-require.register("reporters/teamcity.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base');
-
-/**
- * Expose `Teamcity`.
- */
-
-exports = module.exports = Teamcity;
-
-/**
- * Initialize a new `Teamcity` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function Teamcity(runner) {
-  Base.call(this, runner);
-  var stats = this.stats;
-
-  runner.on('start', function() {
-    console.log("##teamcity[testSuiteStarted name='mocha.suite']");
-  });
-
-  runner.on('test', function(test) {
-    console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
-  });
-
-  runner.on('fail', function(test, err) {
-    console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
-  });
-
-  runner.on('pending', function(test) {
-    console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
-  });
-
-  runner.on('test end', function(test) {
-    console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
-  });
-
-  runner.on('end', function() {
-    console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
-  });
-}
-
-/**
- * Escape the given `str`.
- */
-
-function escape(str) {
-  return str
-    .replace(/\|/g, "||")
-    .replace(/\n/g, "|n")
-    .replace(/\r/g, "|r")
-    .replace(/\[/g, "|[")
-    .replace(/\]/g, "|]")
-    .replace(/\u0085/g, "|x")
-    .replace(/\u2028/g, "|l")
-    .replace(/\u2029/g, "|p")
-    .replace(/'/g, "|'");
-}
-
-}); // module: reporters/teamcity.js
-
-require.register("reporters/xunit.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Base = require('./base')
-  , utils = require('../utils')
-  , escape = utils.escape;
-
-/**
- * Save timer references to avoid Sinon interfering (see GH-237).
- */
-
-var Date = global.Date
-  , setTimeout = global.setTimeout
-  , setInterval = global.setInterval
-  , clearTimeout = global.clearTimeout
-  , clearInterval = global.clearInterval;
-
-/**
- * Expose `XUnit`.
- */
-
-exports = module.exports = XUnit;
-
-/**
- * Initialize a new `XUnit` reporter.
- *
- * @param {Runner} runner
- * @api public
- */
-
-function XUnit(runner) {
-  Base.call(this, runner);
-  var stats = this.stats
-    , tests = []
-    , self = this;
-
-  runner.on('pass', function(test){
-    tests.push(test);
-  });
-
-  runner.on('fail', function(test){
-    tests.push(test);
-  });
-
-  runner.on('end', function(){
-    console.log(tag('testsuite', {
-        name: 'Mocha Tests'
-      , tests: stats.tests
-      , failures: stats.failures
-      , errors: stats.failures
-      , skipped: stats.tests - stats.failures - stats.passes
-      , timestamp: (new Date).toUTCString()
-      , time: (stats.duration / 1000) || 0
-    }, false));
-
-    tests.forEach(test);
-    console.log('</testsuite>');
-  });
-}
-
-/**
- * Inherit from `Base.prototype`.
- */
-
-function F(){};
-F.prototype = Base.prototype;
-XUnit.prototype = new F;
-XUnit.prototype.constructor = XUnit;
-
-
-/**
- * Output tag for the given `test.`
- */
-
-function test(test) {
-  var attrs = {
-      classname: test.parent.fullTitle()
-    , name: test.title
-    , time: test.duration / 1000
-  };
-
-  if ('failed' == test.state) {
-    var err = test.err;
-    attrs.message = escape(err.message);
-    console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
-  } else if (test.pending) {
-    console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
-  } else {
-    console.log(tag('testcase', attrs, true) );
-  }
-}
-
-/**
- * HTML tag helper.
- */
-
-function tag(name, attrs, close, content) {
-  var end = close ? '/>' : '>'
-    , pairs = []
-    , tag;
-
-  for (var key in attrs) {
-    pairs.push(key + '="' + escape(attrs[key]) + '"');
-  }
-
-  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
-  if (content) tag += content + '</' + name + end;
-  return tag;
-}
-
-/**
- * Return cdata escaped CDATA `str`.
- */
-
-function cdata(str) {
-  return '<![CDATA[' + escape(str) + ']]>';
-}
-
-}); // module: reporters/xunit.js
-
-require.register("runnable.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var EventEmitter = require('browser/events').EventEmitter
-  , debug = require('browser/debug')('mocha:runnable')
-  , milliseconds = require('./ms');
-
-/**
- * Save timer references to avoid Sinon interfering (see GH-237).
- */
-
-var Date = global.Date
-  , setTimeout = global.setTimeout
-  , setInterval = global.setInterval
-  , clearTimeout = global.clearTimeout
-  , clearInterval = global.clearInterval;
-
-/**
- * Object#toString().
- */
-
-var toString = Object.prototype.toString;
-
-/**
- * Expose `Runnable`.
- */
-
-module.exports = Runnable;
-
-/**
- * Initialize a new `Runnable` with the given `title` and callback `fn`.
- *
- * @param {String} title
- * @param {Function} fn
- * @api private
- */
-
-function Runnable(title, fn) {
-  this.title = title;
-  this.fn = fn;
-  this.async = fn && fn.length;
-  this.sync = ! this.async;
-  this._timeout = 2000;
-  this._slow = 75;
-  this.timedOut = false;
-}
-
-/**
- * Inherit from `EventEmitter.prototype`.
- */
-
-function F(){};
-F.prototype = EventEmitter.prototype;
-Runnable.prototype = new F;
-Runnable.prototype.constructor = Runnable;
-
-
-/**
- * Set & get timeout `ms`.
- *
- * @param {Number|String} ms
- * @return {Runnable|Number} ms or self
- * @api private
- */
-
-Runnable.prototype.timeout = function(ms){
-  if (0 == arguments.length) return this._timeout;
-  if ('string' == typeof ms) ms = milliseconds(ms);
-  debug('timeout %d', ms);
-  this._timeout = ms;
-  if (this.timer) this.resetTimeout();
-  return this;
-};
-
-/**
- * Set & get slow `ms`.
- *
- * @param {Number|String} ms
- * @return {Runnable|Number} ms or self
- * @api private
- */
-
-Runnable.prototype.slow = function(ms){
-  if (0 === arguments.length) return this._slow;
-  if ('string' == typeof ms) ms = milliseconds(ms);
-  debug('timeout %d', ms);
-  this._slow = ms;
-  return this;
-};
-
-/**
- * Return the full title generated by recursively
- * concatenating the parent's full title.
- *
- * @return {String}
- * @api public
- */
-
-Runnable.prototype.fullTitle = function(){
-  return this.parent.fullTitle() + ' ' + this.title;
-};
-
-/**
- * Clear the timeout.
- *
- * @api private
- */
-
-Runnable.prototype.clearTimeout = function(){
-  clearTimeout(this.timer);
-};
-
-/**
- * Inspect the runnable void of private properties.
- *
- * @return {String}
- * @api private
- */
-
-Runnable.prototype.inspect = function(){
-  return JSON.stringify(this, function(key, val){
-    if ('_' == key[0]) return;
-    if ('parent' == key) return '#<Suite>';
-    if ('ctx' == key) return '#<Context>';
-    return val;
-  }, 2);
-};
-
-/**
- * Reset the timeout.
- *
- * @api private
- */
-
-Runnable.prototype.resetTimeout = function(){
-  var self = this;
-  var ms = this.timeout() || 1e9;
-
-  this.clearTimeout();
-  this.timer = setTimeout(function(){
-    self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
-    self.timedOut = true;
-  }, ms);
-};
-
-/**
- * Run the test and invoke `fn(err)`.
- *
- * @param {Function} fn
- * @api private
- */
-
-Runnable.prototype.run = function(fn){
-  var self = this
-    , ms = this.timeout()
-    , start = new Date
-    , ctx = this.ctx
-    , finished
-    , emitted;
-
-  if (ctx) ctx.runnable(this);
-
-  // timeout
-  if (this.async) {
-    if (ms) {
-      this.timer = setTimeout(function(){
-        done(new Error('timeout of ' + ms + 'ms exceeded'));
-        self.timedOut = true;
-      }, ms);
-    }
-  }
-
-  // called multiple times
-  function multiple(err) {
-    if (emitted) return;
-    emitted = true;
-    self.emit('error', err || new Error('done() called multiple times'));
-  }
-
-  // finished
-  function done(err) {
-    if (self.timedOut) return;
-    if (finished) return multiple(err);
-    self.clearTimeout();
-    self.duration = new Date - start;
-    finished = true;
-    fn(err);
-  }
-
-  // for .resetTimeout()
-  this.callback = done;
-
-  // async
-  if (this.async) {
-    try {
-      this.fn.call(ctx, function(err){
-        if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
-        if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
-        done();
-      });
-    } catch (err) {
-      done(err);
-    }
-    return;
-  }
-
-  if (this.asyncOnly) {
-    return done(new Error('--async-only option in use without declaring `done()`'));
-  }
-
-  // sync
-  try {
-    if (!this.pending) this.fn.call(ctx);
-    this.duration = new Date - start;
-    fn();
-  } catch (err) {
-    fn(err);
-  }
-};
-
-}); // module: runnable.js
-
-require.register("runner.js", function(module, exports, require){
-/**
- * Module dependencies.
- */
-
-var EventEmitter = require('browser/events').EventEmitter
-  , debug = require('browser/debug')('mocha:runner')
-  , Test = require('./test')
-  , utils = require('./utils')
-  , filter = utils.filter
-  , keys = utils.keys;
-
-/**
- * Non-enumerable globals.
- */
-
-var globals = [
-  'setTimeout',
-  'clearTimeout',
-  'setInterval',
-  'clearInterval',
-  'XMLHttpRequest',
-  'Date'
-];
-
-/**
- * Expose `Runner`.
- */
-
-module.exports = Runner;
-
-/**
- * Initialize a `Runner` for the given `suite`.
- *
- * Events:
- *
- *   - `start`  execution started
- *   - `end`  execution complete
- *   - `suite`  (suite) test suite execution started
- *   - `suite end`  (suite) all tests (and sub-suites) have finished
- *   - `test`  (test) test execution started
- *   - `test end`  (test) test completed
- *   - `hook`  (hook) hook execution started
- *   - `hook end`  (hook) hook complete
- *   - `pass`  (test) test passed
- *   - `fail`  (test, err) test failed
- *   - `pending`  (test) test pending
- *
- * @api public
- */
-
-function Runner(suite) {
-  var self = this;
-  this._globals = [];
-  this.suite = suite;
-  this.total = suite.total();
-  this.failures = 0;
-  this.on('test end', function(test){ self.checkGlobals(test); });
-  this.on('hook end', function(hook){ self.checkGlobals(hook); });
-  this.grep(/.*/);
-  this.globals(this.globalProps().concat(['errno']));
-}
-
-/**
- * Wrapper for setImmediate, process.nextTick, or browser polyfill.
- *
- * @param {Function} fn
- * @api private
- */
-
-Runner.immediately = global.setImmediate || process.nextTick;
-
-/**
- * Inherit from `EventEmitter.prototype`.
- */
-
-function F(){};
-F.prototype = EventEmitter.prototype;
-Runner.prototype = new F;
-Runner.prototype.constructor = Runner;
-
-
-/**
- * Run tests with full titles matching `re`. Updates runner.total
- * with number of tests matched.
- *
- * @param {RegExp} re
- * @param {Boolean} invert
- * @return {Runner} for chaining
- * @api public
- */
-
-Runner.prototype.grep = function(re, invert){
-  debug('grep %s', re);
-  this._grep = re;
-  this._invert = invert;
-  this.total = this.grepTotal(this.suite);
-  return this;
-};
-
-/**
- * Returns the number of tests matching the grep search for the
- * given suite.
- *
- * @param {Suite} suite
- * @return {Number}
- * @api public
- */
-
-Runner.prototype.grepTotal = function(suite) {
-  var self = this;
-  var total = 0;
-
-  suite.eachTest(function(test){
-    var match = self._grep.test(test.fullTitle());
-    if (self._invert) match = !match;
-    if (match) total++;
-  });
-
-  return total;
-};
-
-/**
- * Return a list of global properties.
- *
- * @return {Array}
- * @api private
- */
-
-Runner.prototype.globalProps = function() {
-  var props = utils.keys(global);
-
-  // non-enumerables
-  for (var i = 0; i < globals.length; ++i) {
-    if (~utils.indexOf(props, globals[i])) continue;
-    props.push(globals[i]);
-  }
-
-  return props;
-};
-
-/**
- * Allow the given `arr` of globals.
- *
- * @param {Array} arr
- * @return {Runner} for chaining
- * @api public
- */
-
-Runner.prototype.globals = function(arr){
-  if (0 == arguments.length) return this._globals;
-  debug('globals %j', arr);
-  utils.forEach(arr, function(arr){
-    this._globals.push(arr);
-  }, this);
-  return this;
-};
-
-/**
- * Check for global variable leaks.
- *
- * @api private
- */
-
-Runner.prototype.checkGlobals = function(test){
-  if (this.ignoreLeaks) return;
-  var ok = this._globals;
-  var globals = this.globalProps();
-  var isNode = process.kill;
-  var leaks;
-
-  // check length - 2 ('errno' and 'location' globals)
-  if (isNode && 1 == ok.length - globals.length) return
-  else if (2 == ok.length - globals.length) return;
-
-  leaks = filterLeaks(ok, globals);
-  this._globals = this._globals.concat(leaks);
-
-  if (leaks.length > 1) {
-    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
-  } else if (leaks.length) {
-    this.fail(test, new Error('global leak detected: ' + leaks[0]));
-  }
-};
-
-/**
- * Fail the given `test`.
- *
- * @param {Test} test
- * @param {Error} err
- * @api private
- */
-
-Runner.prototype.fail = function(test, err){
-  ++this.failures;
-  test.state = 'failed';
-
-  if ('string' == typeof err) {
-    err = new Error('the string "' + err + '" was thrown, throw an Error :)');
-  }
-
-  this.emit('fail', test, err);
-};
-
-/**
- * Fail the given `hook` with `err`.
- *
- * Hook failures (currently) hard-end due
- * to that fact that a failing hook will
- * surely cause subsequent tests to fail,
- * causing jumbled reporting.
- *
- * @param {Hook} hook
- * @param {Error} err
- * @api private
- */
-
-Runner.prototype.failHook = function(hook, err){
-  this.fail(hook, err);
-  this.emit('end');
-};
-
-/**
- * Run hook `name` callbacks and then invoke `fn()`.
- *
- * @param {String} name
- * @param {Function} function
- * @api private
- */
-
-Runner.prototype.hook = function(name, fn){
-  var suite = this.suite
-    , hooks = suite['_' + name]
-    , self = this
-    , timer;
-
-  function next(i) {
-    var hook = hooks[i];
-    if (!hook) return fn();
-    if (self.failures && suite.bail()) return fn();
-    self.currentRunnable = hook;
-
-    hook.ctx.currentTest = self.test;
-
-    self.emit('hook', hook);
-
-    hook.on('error', function(err){
-      self.failHook(hook, err);
-    });
-
-    hook.run(function(err){
-      hook.removeAllListeners('error');
-      var testError = hook.error();
-      if (testError) self.fail(self.test, testError);
-      if (err) return self.failHook(hook, err);
-      self.emit('hook end', hook);
-      delete hook.ctx.currentTest;
-      next(++i);
-    });
-  }
-
-  Runner.immediately(function(){
-    next(0);
-  });
-};
-
-/**
- * Run hook `name` for the given array of `suites`
- * in order, and callback `fn(err)`.
- *
- * @param {String} name
- * @param {Array} suites
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.hooks = function(name, suites, fn){
-  var self = this
-    , orig = this.suite;
-
-  function next(suite) {
-    self.suite = suite;
-
-    if (!suite) {
-      self.suite = orig;
-      return fn();
-    }
-
-    self.hook(name, function(err){
-      if (err) {
-        self.suite = orig;
-        return fn(err);
-      }
-
-      next(suites.pop());
-    });
-  }
-
-  next(suites.pop());
-};
-
-/**
- * Run hooks from the top level down.
- *
- * @param {String} name
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.hookUp = function(name, fn){
-  var suites = [this.suite].concat(this.parents()).reverse();
-  this.hooks(name, suites, fn);
-};
-
-/**
- * Run hooks from the bottom up.
- *
- * @param {String} name
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.hookDown = function(name, fn){
-  var suites = [this.suite].concat(this.parents());
-  this.hooks(name, suites, fn);
-};
-
-/**
- * Return an array of parent Suites from
- * closest to furthest.
- *
- * @return {Array}
- * @api private
- */
-
-Runner.prototype.parents = function(){
-  var suite = this.suite
-    , suites = [];
-  while (suite = suite.parent) suites.push(suite);
-  return suites;
-};
-
-/**
- * Run the current test and callback `fn(err)`.
- *
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.runTest = function(fn){
-  var test = this.test
-    , self = this;
-
-  if (this.asyncOnly) test.asyncOnly = true;
-
-  try {
-    test.on('error', function(err){
-      self.fail(test, err);
-    });
-    test.run(fn);
-  } catch (err) {
-    fn(err);
-  }
-};
-
-/**
- * Run tests in the given `suite` and invoke
- * the callback `fn()` when complete.
- *
- * @param {Suite} suite
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.runTests = function(suite, fn){
-  var self = this
-    , tests = suite.tests.slice()
-    , test;
-
-  function next(err) {
-    // if we bail after first err
-    if (self.failures && suite._bail) return fn();
-
-    // next test
-    test = tests.shift();
-
-    // all done
-    if (!test) return fn();
-
-    // grep
-    var match = self._grep.test(test.fullTitle());
-    if (self._invert) match = !match;
-    if (!match) return next();
-
-    // pending
-    if (test.pending) {
-      self.emit('pending', test);
-      self.emit('test end', test);
-      return next();
-    }
-
-    // execute test and hook(s)
-    self.emit('test', self.test = test);
-    self.hookDown('beforeEach', function(){
-      self.currentRunnable = self.test;
-      self.runTest(function(err){
-        test = self.test;
-
-        if (err) {
-          self.fail(test, err);
-          self.emit('test end', test);
-          return self.hookUp('afterEach', next);
-        }
-
-        test.state = 'passed';
-        self.emit('pass', test);
-        self.emit('test end', test);
-        self.hookUp('afterEach', next);
-      });
-    });
-  }
-
-  this.next = next;
-  next();
-};
-
-/**
- * Run the given `suite` and invoke the
- * callback `fn()` when complete.
- *
- * @param {Suite} suite
- * @param {Function} fn
- * @api private
- */
-
-Runner.prototype.runSuite = function(suite, fn){
-  var total = this.grepTotal(suite)
-    , self = this
-    , i = 0;
-
-  debug('run suite %s', suite.fullTitle());
-
-  if (!total) return fn();
-
-  this.emit('suite', this.suite = suite);
-
-  function next() {
-    var curr = suite.suites[i++];
-    if (!curr) return done();
-    self.runSuite(curr, next);
-  }
-
-  function done() {
-    self.suite = suite;
-    self.hook('afterAll', function(){
-      self.emit('suite end', suite);
-      fn();
-    });
-  }
-
-  this.hook('beforeAll', function(){
-    self.runTests(suite, next);
-  });
-};
-
-/**
- * Handle uncaught exceptions.
- *
- * @param {Error} err
- * @api private
- */
-
-Runner.prototype.uncaught = function(err){
-  debug('uncaught exception %s', err.message);
-  var runnable = this.currentRunnable;
-  if (!runnable || 'failed' == runnable.state) return;
-  runnable.clearTimeout();
-  err.uncaught = true;
-  this.fail(runnable, err);
-
-  // recover from test
-  if ('test' == runnable.type) {
-    this.emit('test end', runnable);
-    this.hookUp('afterEach', this.next);
-    return;
-  }
-
-  // bail on hooks
-  this.emit('end');
-};
-
-/**
- * Run the root suite and invoke `fn(failures)`
- * on completion.
- *
- * @param {Function} fn
- * @return {Runner} for chaining
- * @api public
- */
-
-Runner.prototype.run = function(fn){
-  var self = this
-    , fn = fn || function(){};
-
-  function uncaught(err){
-    self.uncaught(err);
-  }
-
-  debug('start');
-
-  // callback
-  this.on('end', function(){
-    debug('end');
-    process.removeListener('uncaughtException', uncaught);
-    fn(self.failures);
-  });
-
-  // run suites
-  this.emit('start');
-  this.runSuite(this.suite, function(){
-    debug('finished running');
-    self.emit('end');
-  });
-
-  // uncaught exception
-  process.on('uncaughtException', uncaught);
-
-  return this;
-};
-
-/**
- * Filter leaks with the given globals flagged as `ok`.
- *
- * @param {Array} ok
- * @param {Array} globals
- * @return {Array}
- * @api private
- */
-
-function filterLeaks(ok, globals) {
-  return filter(globals, function(key){
-    // Firefox and Chrome exposes iframes as index inside the window object
-    if (/^d+/.test(key)) return false;
-    var matched = filter(ok, function(ok){
-      if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
-      // Opera and IE expose global variables for HTML element IDs (issue #243)
-      if (/^mocha-/.test(key)) return true;
-      return key == ok;
-    });
-    return matched.length == 0 && (!global.navigator || 'onerror' !== key);
-  });
-}
-
-}); // module: runner.js
-
-require.register("suite.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var EventEmitter = require('browser/events').EventEmitter
-  , debug = require('browser/debug')('mocha:suite')
-  , milliseconds = require('./ms')
-  , utils = require('./utils')
-  , Hook = require('./hook');
-
-/**
- * Expose `Suite`.
- */
-
-exports = module.exports = Suite;
-
-/**
- * Create a new `Suite` with the given `title`
- * and parent `Suite`. When a suite with the
- * same title is already present, that suite
- * is returned to provide nicer reporter
- * and more flexible meta-testing.
- *
- * @param {Suite} parent
- * @param {String} title
- * @return {Suite}
- * @api public
- */
-
-exports.create = function(parent, title){
-  var suite = new Suite(title, parent.ctx);
-  suite.parent = parent;
-  if (parent.pending) suite.pending = true;
-  title = suite.fullTitle();
-  parent.addSuite(suite);
-  return suite;
-};
-
-/**
- * Initialize a new `Suite` with the given
- * `title` and `ctx`.
- *
- * @param {String} title
- * @param {Context} ctx
- * @api private
- */
-
-function Suite(title, ctx) {
-  this.title = title;
-  this.ctx = ctx;
-  this.suites = [];
-  this.tests = [];
-  this.pending = false;
-  this._beforeEach = [];
-  this._beforeAll = [];
-  this._afterEach = [];
-  this._afterAll = [];
-  this.root = !title;
-  this._timeout = 2000;
-  this._slow = 75;
-  this._bail = false;
-}
-
-/**
- * Inherit from `EventEmitter.prototype`.
- */
-
-function F(){};
-F.prototype = EventEmitter.prototype;
-Suite.prototype = new F;
-Suite.prototype.constructor = Suite;
-
-
-/**
- * Return a clone of this `Suite`.
- *
- * @return {Suite}
- * @api private
- */
-
-Suite.prototype.clone = function(){
-  var suite = new Suite(this.title);
-  debug('clone');
-  suite.ctx = this.ctx;
-  suite.timeout(this.timeout());
-  suite.slow(this.slow());
-  suite.bail(this.bail());
-  return suite;
-};
-
-/**
- * Set timeout `ms` or short-hand such as "2s".
- *
- * @param {Number|String} ms
- * @return {Suite|Number} for chaining
- * @api private
- */
-
-Suite.prototype.timeout = function(ms){
-  if (0 == arguments.length) return this._timeout;
-  if ('string' == typeof ms) ms = milliseconds(ms);
-  debug('timeout %d', ms);
-  this._timeout = parseInt(ms, 10);
-  return this;
-};
-
-/**
- * Set slow `ms` or short-hand such as "2s".
- *
- * @param {Number|String} ms
- * @return {Suite|Number} for chaining
- * @api private
- */
-
-Suite.prototype.slow = function(ms){
-  if (0 === arguments.length) return this._slow;
-  if ('string' == typeof ms) ms = milliseconds(ms);
-  debug('slow %d', ms);
-  this._slow = ms;
-  return this;
-};
-
-/**
- * Sets whether to bail after first error.
- *
- * @parma {Boolean} bail
- * @return {Suite|Number} for chaining
- * @api private
- */
-
-Suite.prototype.bail = function(bail){
-  if (0 == arguments.length) return this._bail;
-  debug('bail %s', bail);
-  this._bail = bail;
-  return this;
-};
-
-/**
- * Run `fn(test[, done])` before running tests.
- *
- * @param {Function} fn
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.beforeAll = function(fn){
-  if (this.pending) return this;
-  var hook = new Hook('"before all" hook', fn);
-  hook.parent = this;
-  hook.timeout(this.timeout());
-  hook.slow(this.slow());
-  hook.ctx = this.ctx;
-  this._beforeAll.push(hook);
-  this.emit('beforeAll', hook);
-  return this;
-};
-
-/**
- * Run `fn(test[, done])` after running tests.
- *
- * @param {Function} fn
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.afterAll = function(fn){
-  if (this.pending) return this;
-  var hook = new Hook('"after all" hook', fn);
-  hook.parent = this;
-  hook.timeout(this.timeout());
-  hook.slow(this.slow());
-  hook.ctx = this.ctx;
-  this._afterAll.push(hook);
-  this.emit('afterAll', hook);
-  return this;
-};
-
-/**
- * Run `fn(test[, done])` before each test case.
- *
- * @param {Function} fn
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.beforeEach = function(fn){
-  if (this.pending) return this;
-  var hook = new Hook('"before each" hook', fn);
-  hook.parent = this;
-  hook.timeout(this.timeout());
-  hook.slow(this.slow());
-  hook.ctx = this.ctx;
-  this._beforeEach.push(hook);
-  this.emit('beforeEach', hook);
-  return this;
-};
-
-/**
- * Run `fn(test[, done])` after each test case.
- *
- * @param {Function} fn
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.afterEach = function(fn){
-  if (this.pending) return this;
-  var hook = new Hook('"after each" hook', fn);
-  hook.parent = this;
-  hook.timeout(this.timeout());
-  hook.slow(this.slow());
-  hook.ctx = this.ctx;
-  this._afterEach.push(hook);
-  this.emit('afterEach', hook);
-  return this;
-};
-
-/**
- * Add a test `suite`.
- *
- * @param {Suite} suite
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.addSuite = function(suite){
-  suite.parent = this;
-  suite.timeout(this.timeout());
-  suite.slow(this.slow());
-  suite.bail(this.bail());
-  this.suites.push(suite);
-  this.emit('suite', suite);
-  return this;
-};
-
-/**
- * Add a `test` to this suite.
- *
- * @param {Test} test
- * @return {Suite} for chaining
- * @api private
- */
-
-Suite.prototype.addTest = function(test){
-  test.parent = this;
-  test.timeout(this.timeout());
-  test.slow(this.slow());
-  test.ctx = this.ctx;
-  this.tests.push(test);
-  this.emit('test', test);
-  return this;
-};
-
-/**
- * Return the full title generated by recursively
- * concatenating the parent's full title.
- *
- * @return {String}
- * @api public
- */
-
-Suite.prototype.fullTitle = function(){
-  if (this.parent) {
-    var full = this.parent.fullTitle();
-    if (full) return full + ' ' + this.title;
-  }
-  return this.title;
-};
-
-/**
- * Return the total number of tests.
- *
- * @return {Number}
- * @api public
- */
-
-Suite.prototype.total = function(){
-  return utils.reduce(this.suites, function(sum, suite){
-    return sum + suite.total();
-  }, 0) + this.tests.length;
-};
-
-/**
- * Iterates through each suite recursively to find
- * all tests. Applies a function in the format
- * `fn(test)`.
- *
- * @param {Function} fn
- * @return {Suite}
- * @api private
- */
-
-Suite.prototype.eachTest = function(fn){
-  utils.forEach(this.tests, fn);
-  utils.forEach(this.suites, function(suite){
-    suite.eachTest(fn);
-  });
-  return this;
-};
-
-}); // module: suite.js
-
-require.register("test.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var Runnable = require('./runnable');
-
-/**
- * Expose `Test`.
- */
-
-module.exports = Test;
-
-/**
- * Initialize a new `Test` with the given `title` and callback `fn`.
- *
- * @param {String} title
- * @param {Function} fn
- * @api private
- */
-
-function Test(title, fn) {
-  Runnable.call(this, title, fn);
-  this.pending = !fn;
-  this.type = 'test';
-}
-
-/**
- * Inherit from `Runnable.prototype`.
- */
-
-function F(){};
-F.prototype = Runnable.prototype;
-Test.prototype = new F;
-Test.prototype.constructor = Test;
-
-
-}); // module: test.js
-
-require.register("utils.js", function(module, exports, require){
-
-/**
- * Module dependencies.
- */
-
-var fs = require('browser/fs')
-  , path = require('browser/path')
-  , join = path.join
-  , debug = require('browser/debug')('mocha:watch');
-
-/**
- * Ignored directories.
- */
-
-var ignore = ['node_modules', '.git'];
-
-/**
- * Escape special characters in the given string of html.
- *
- * @param  {String} html
- * @return {String}
- * @api private
- */
-
-exports.escape = function(html){
-  return String(html)
-    .replace(/&/g, '&amp;')
-    .replace(/"/g, '&quot;')
-    .replace(/</g, '&lt;')
-    .replace(/>/g, '&gt;');
-};
-
-/**
- * Array#forEach (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @param {Object} scope
- * @api private
- */
-
-exports.forEach = function(arr, fn, scope){
-  for (var i = 0, l = arr.length; i < l; i++)
-    fn.call(scope, arr[i], i);
-};
-
-/**
- * Array#indexOf (<=IE8)
- *
- * @parma {Array} arr
- * @param {Object} obj to find index of
- * @param {Number} start
- * @api private
- */
-
-exports.indexOf = function(arr, obj, start){
-  for (var i = start || 0, l = arr.length; i < l; i++) {
-    if (arr[i] === obj)
-      return i;
-  }
-  return -1;
-};
-
-/**
- * Array#reduce (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @param {Object} initial value
- * @api private
- */
-
-exports.reduce = function(arr, fn, val){
-  var rval = val;
-
-  for (var i = 0, l = arr.length; i < l; i++) {
-    rval = fn(rval, arr[i], i, arr);
-  }
-
-  return rval;
-};
-
-/**
- * Array#filter (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @api private
- */
-
-exports.filter = function(arr, fn){
-  var ret = [];
-
-  for (var i = 0, l = arr.length; i < l; i++) {
-    var val = arr[i];
-    if (fn(val, i, arr)) ret.push(val);
-  }
-
-  return ret;
-};
-
-/**
- * Object.keys (<=IE8)
- *
- * @param {Object} obj
- * @return {Array} keys
- * @api private
- */
-
-exports.keys = Object.keys || function(obj) {
-  var keys = []
-    , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
-
-  for (var key in obj) {
-    if (has.call(obj, key)) {
-      keys.push(key);
-    }
-  }
-
-  return keys;
-};
-
-/**
- * Watch the given `files` for changes
- * and invoke `fn(file)` on modification.
- *
- * @param {Array} files
- * @param {Function} fn
- * @api private
- */
-
-exports.watch = function(files, fn){
-  var options = { interval: 100 };
-  files.forEach(function(file){
-    debug('file %s', file);
-    fs.watchFile(file, options, function(curr, prev){
-      if (prev.mtime < curr.mtime) fn(file);
-    });
-  });
-};
-
-/**
- * Ignored files.
- */
-
-function ignored(path){
-  return !~ignore.indexOf(path);
-}
-
-/**
- * Lookup files in the given `dir`.
- *
- * @return {Array}
- * @api private
- */
-
-exports.files = function(dir, ret){
-  ret = ret || [];
-
-  fs.readdirSync(dir)
-  .filter(ignored)
-  .forEach(function(path){
-    path = join(dir, path);
-    if (fs.statSync(path).isDirectory()) {
-      exports.files(path, ret);
-    } else if (path.match(/\.(js|coffee)$/)) {
-      ret.push(path);
-    }
-  });
-
-  return ret;
-};
-
-/**
- * Compute a slug from the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-exports.slug = function(str){
-  return str
-    .toLowerCase()
-    .replace(/ +/g, '-')
-    .replace(/[^-\w]/g, '');
-};
-
-/**
- * Strip the function definition from `str`,
- * and re-indent for pre whitespace.
- */
-
-exports.clean = function(str) {
-  str = str
-    .replace(/^function *\(.*\) *{/, '')
-    .replace(/\s+\}$/, '');
-
-  var whitespace = str.match(/^\n?(\s*)/)[1]
-    , re = new RegExp('^' + whitespace, 'gm');
-
-  str = str.replace(re, '');
-
-  return exports.trim(str);
-};
-
-/**
- * Escape regular expression characters in `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-exports.escapeRegexp = function(str){
-  return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
-};
-
-/**
- * Trim the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-exports.trim = function(str){
-  return str.replace(/^\s+|\s+$/g, '');
-};
-
-/**
- * Parse the given `qs`.
- *
- * @param {String} qs
- * @return {Object}
- * @api private
- */
-
-exports.parseQuery = function(qs){
-  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
-    var i = pair.indexOf('=')
-      , key = pair.slice(0, i)
-      , val = pair.slice(++i);
-
-    obj[key] = decodeURIComponent(val);
-    return obj;
-  }, {});
-};
-
-/**
- * Highlight the given string of `js`.
- *
- * @param {String} js
- * @return {String}
- * @api private
- */
-
-function highlight(js) {
-  return js
-    .replace(/</g, '&lt;')
-    .replace(/>/g, '&gt;')
-    .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
-    .replace(/('.*?')/gm, '<span class="string">$1</span>')
-    .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
-    .replace(/(\d+)/gm, '<span class="number">$1</span>')
-    .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
-    .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
-}
-
-/**
- * Highlight the contents of tag `name`.
- *
- * @param {String} name
- * @api private
- */
-
-exports.highlightTags = function(name) {
-  var code = document.getElementsByTagName(name);
-  for (var i = 0, len = code.length; i < len; ++i) {
-    code[i].innerHTML = highlight(code[i].innerHTML);
-  }
-};
-
-}); // module: utils.js
-// The global object is "self" in Web Workers.
-global = (function() { return this; })();
-
-/**
- * Save timer references to avoid Sinon interfering (see GH-237).
- */
-
-var Date = global.Date;
-var setTimeout = global.setTimeout;
-var setInterval = global.setInterval;
-var clearTimeout = global.clearTimeout;
-var clearInterval = global.clearInterval;
-
-/**
- * Node shims.
- *
- * These are meant only to allow
- * mocha.js to run untouched, not
- * to allow running node code in
- * the browser.
- */
-
-var process = {};
-process.exit = function(status){};
-process.stdout = {};
-
-/**
- * Remove uncaughtException listener.
- */
-
-process.removeListener = function(e){
-  if ('uncaughtException' == e) {
-    global.onerror = function() {};
-  }
-};
-
-/**
- * Implements uncaughtException listener.
- */
-
-process.on = function(e, fn){
-  if ('uncaughtException' == e) {
-    global.onerror = function(err, url, line){
-      fn(new Error(err + ' (' + url + ':' + line + ')'));
-    };
-  }
-};
-
-/**
- * Expose mocha.
- */
-
-var Mocha = global.Mocha = require('mocha'),
-    mocha = global.mocha = new Mocha({ reporter: 'html' });
-
-var immediateQueue = []
-  , immediateTimeout;
-
-function timeslice() {
-  var immediateStart = new Date().getTime();
-  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
-    immediateQueue.shift()();
-  }
-  if (immediateQueue.length) {
-    immediateTimeout = setTimeout(timeslice, 0);
-  } else {
-    immediateTimeout = null;
-  }
-}
-
-/**
- * High-performance override of Runner.immediately.
- */
-
-Mocha.Runner.immediately = function(callback) {
-  immediateQueue.push(callback);
-  if (!immediateTimeout) {
-    immediateTimeout = setTimeout(timeslice, 0);
-  }
-};
-
-/**
- * Override ui to ensure that the ui functions are initialized.
- * Normally this would happen in Mocha.prototype.loadFiles.
- */
-
-mocha.ui = function(ui){
-  Mocha.prototype.ui.call(this, ui);
-  this.suite.emit('pre-require', global, null, this);
-  return this;
-};
-
-/**
- * Setup mocha with the given setting options.
- */
-
-mocha.setup = function(opts){
-  if ('string' == typeof opts) opts = { ui: opts };
-  for (var opt in opts) this[opt](opts[opt]);
-  return this;
-};
-
-/**
- * Run mocha, returning the Runner.
- */
-
-mocha.run = function(fn){
-  var options = mocha.options;
-  mocha.globals('location');
-
-  var query = Mocha.utils.parseQuery(global.location.search || '');
-  if (query.grep) mocha.grep(query.grep);
-  if (query.invert) mocha.invert();
-
-  return Mocha.prototype.run.call(mocha, function(){
-    // The DOM Document is not available in Web Workers.
-    if (global.document) {
-      Mocha.utils.highlightTags('code');
-    }
-    if (fn) fn();
-  });
-};
-
-/**
- * Expose the process shim.
- */
-
-Mocha.process = process;
-})();
\ No newline at end of file
diff --git a/ckan/public-bs2/base/test/vendor/sinon.js b/ckan/public-bs2/base/test/vendor/sinon.js
deleted file mode 100644
--- a/ckan/public-bs2/base/test/vendor/sinon.js
+++ /dev/null
@@ -1,4080 +0,0 @@
-/**
- * Sinon.JS 1.4.0, 2012/07/09
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
- *
- * (The BSD License)
- * 
- * Copyright (c) 2010-2012, Christian Johansen, christian@cjohansen.no
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 
- *     * Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright notice,
- *       this list of conditions and the following disclaimer in the documentation
- *       and/or other materials provided with the distribution.
- *     * Neither the name of Christian Johansen nor the names of his contributors
- *       may be used to endorse or promote products derived from this software
- *       without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-"use strict";
-var sinon = (function () {
-var buster = (function (setTimeout, B) {
-    var isNode = typeof require == "function" && typeof module == "object";
-    var div = typeof document != "undefined" && document.createElement("div");
-    var F = function () {};
-
-    var buster = {
-        bind: function bind(obj, methOrProp) {
-            var method = typeof methOrProp == "string" ? obj[methOrProp] : methOrProp;
-            var args = Array.prototype.slice.call(arguments, 2);
-            return function () {
-                var allArgs = args.concat(Array.prototype.slice.call(arguments));
-                return method.apply(obj, allArgs);
-            };
-        },
-
-        partial: function partial(fn) {
-            var args = [].slice.call(arguments, 1);
-            return function () {
-                return fn.apply(this, args.concat([].slice.call(arguments)));
-            };
-        },
-
-        create: function create(object) {
-            F.prototype = object;
-            return new F();
-        },
-
-        extend: function extend(target) {
-            if (!target) { return; }
-            for (var i = 1, l = arguments.length, prop; i < l; ++i) {
-                for (prop in arguments[i]) {
-                    target[prop] = arguments[i][prop];
-                }
-            }
-            return target;
-        },
-
-        nextTick: function nextTick(callback) {
-            if (typeof process != "undefined" && process.nextTick) {
-                return process.nextTick(callback);
-            }
-            setTimeout(callback, 0);
-        },
-
-        functionName: function functionName(func) {
-            if (!func) return "";
-            if (func.displayName) return func.displayName;
-            if (func.name) return func.name;
-            var matches = func.toString().match(/function\s+([^\(]+)/m);
-            return matches && matches[1] || "";
-        },
-
-        isNode: function isNode(obj) {
-            if (!div) return false;
-            try {
-                obj.appendChild(div);
-                obj.removeChild(div);
-            } catch (e) {
-                return false;
-            }
-            return true;
-        },
-
-        isElement: function isElement(obj) {
-            return obj && obj.nodeType === 1 && buster.isNode(obj);
-        },
-
-        isArray: function isArray(arr) {
-            return Object.prototype.toString.call(arr) == "[object Array]";
-        },
-
-        flatten: function flatten(arr) {
-            var result = [], arr = arr || [];
-            for (var i = 0, l = arr.length; i < l; ++i) {
-                result = result.concat(buster.isArray(arr[i]) ? flatten(arr[i]) : arr[i]);
-            }
-            return result;
-        },
-
-        each: function each(arr, callback) {
-            for (var i = 0, l = arr.length; i < l; ++i) {
-                callback(arr[i]);
-            }
-        },
-
-        map: function map(arr, callback) {
-            var results = [];
-            for (var i = 0, l = arr.length; i < l; ++i) {
-                results.push(callback(arr[i]));
-            }
-            return results;
-        },
-
-        parallel: function parallel(fns, callback) {
-            function cb(err, res) {
-                if (typeof callback == "function") {
-                    callback(err, res);
-                    callback = null;
-                }
-            }
-            if (fns.length == 0) { return cb(null, []); }
-            var remaining = fns.length, results = [];
-            function makeDone(num) {
-                return function done(err, result) {
-                    if (err) { return cb(err); }
-                    results[num] = result;
-                    if (--remaining == 0) { cb(null, results); }
-                };
-            }
-            for (var i = 0, l = fns.length; i < l; ++i) {
-                fns[i](makeDone(i));
-            }
-        },
-
-        series: function series(fns, callback) {
-            function cb(err, res) {
-                if (typeof callback == "function") {
-                    callback(err, res);
-                }
-            }
-            var remaining = fns.slice();
-            var results = [];
-            function callNext() {
-                if (remaining.length == 0) return cb(null, results);
-                var promise = remaining.shift()(next);
-                if (promise && typeof promise.then == "function") {
-                    promise.then(buster.partial(next, null), next);
-                }
-            }
-            function next(err, result) {
-                if (err) return cb(err);
-                results.push(result);
-                callNext();
-            }
-            callNext();
-        },
-
-        countdown: function countdown(num, done) {
-            return function () {
-                if (--num == 0) done();
-            };
-        }
-    };
-
-    if (typeof process === "object") {
-        var crypto = require("crypto");
-        var path = require("path");
-
-        buster.tmpFile = function (fileName) {
-            var hashed = crypto.createHash("sha1");
-            hashed.update(fileName);
-            var tmpfileName = hashed.digest("hex");
-
-            if (process.platform == "win32") {
-                return path.join(process.env["TEMP"], tmpfileName);
-            } else {
-                return path.join("/tmp", tmpfileName);
-            }
-        };
-    }
-
-    if (Array.prototype.some) {
-        buster.some = function (arr, fn, thisp) {
-            return arr.some(fn, thisp);
-        };
-    } else {
-        // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
-        buster.some = function (arr, fun, thisp) {
-                        if (arr == null) { throw new TypeError(); }
-            arr = Object(arr);
-            var len = arr.length >>> 0;
-            if (typeof fun !== "function") { throw new TypeError(); }
-
-            for (var i = 0; i < len; i++) {
-                if (arr.hasOwnProperty(i) && fun.call(thisp, arr[i], i, arr)) {
-                    return true;
-                }
-            }
-
-            return false;
-        };
-    }
-
-    if (Array.prototype.filter) {
-        buster.filter = function (arr, fn, thisp) {
-            return arr.filter(fn, thisp);
-        };
-    } else {
-        // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
-        buster.filter = function (fn, thisp) {
-                        if (this == null) { throw new TypeError(); }
-
-            var t = Object(this);
-            var len = t.length >>> 0;
-            if (typeof fn != "function") { throw new TypeError(); }
-
-            var res = [];
-            for (var i = 0; i < len; i++) {
-                if (i in t) {
-                    var val = t[i]; // in case fun mutates this
-                    if (fn.call(thisp, val, i, t)) { res.push(val); }
-                }
-            }
-
-            return res;
-        };
-    }
-
-    if (isNode) {
-        module.exports = buster;
-        buster.eventEmitter = require("./buster-event-emitter");
-        Object.defineProperty(buster, "defineVersionGetter", {
-            get: function () {
-                return require("./define-version-getter");
-            }
-        });
-    }
-
-    return buster.extend(B || {}, buster);
-}(setTimeout, buster));
-if (typeof buster === "undefined") {
-    var buster = {};
-}
-
-if (typeof module === "object" && typeof require === "function") {
-    buster = require("buster-core");
-}
-
-buster.format = buster.format || {};
-buster.format.excludeConstructors = ["Object", /^.$/];
-buster.format.quoteStrings = true;
-
-buster.format.ascii = (function () {
-    
-    var hasOwn = Object.prototype.hasOwnProperty;
-
-    var specialObjects = [];
-    if (typeof global != "undefined") {
-        specialObjects.push({ obj: global, value: "[object global]" });
-    }
-    if (typeof document != "undefined") {
-        specialObjects.push({ obj: document, value: "[object HTMLDocument]" });
-    }
-    if (typeof window != "undefined") {
-        specialObjects.push({ obj: window, value: "[object Window]" });
-    }
-
-    function keys(object) {
-        var k = Object.keys && Object.keys(object) || [];
-
-        if (k.length == 0) {
-            for (var prop in object) {
-                if (hasOwn.call(object, prop)) {
-                    k.push(prop);
-                }
-            }
-        }
-
-        return k.sort();
-    }
-
-    function isCircular(object, objects) {
-        if (typeof object != "object") {
-            return false;
-        }
-
-        for (var i = 0, l = objects.length; i < l; ++i) {
-            if (objects[i] === object) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    function ascii(object, processed, indent) {
-        if (typeof object == "string") {
-            var quote = typeof this.quoteStrings != "boolean" || this.quoteStrings;
-            return processed || quote ? '"' + object + '"' : object;
-        }
-
-        if (typeof object == "function" && !(object instanceof RegExp)) {
-            return ascii.func(object);
-        }
-
-        processed = processed || [];
-
-        if (isCircular(object, processed)) {
-            return "[Circular]";
-        }
-
-        if (Object.prototype.toString.call(object) == "[object Array]") {
-            return ascii.array.call(this, object, processed);
-        }
-
-        if (!object) {
-            return "" + object;
-        }
-
-        if (buster.isElement(object)) {
-            return ascii.element(object);
-        }
-
-        if (typeof object.toString == "function" &&
-            object.toString !== Object.prototype.toString) {
-            return object.toString();
-        }
-
-        for (var i = 0, l = specialObjects.length; i < l; i++) {
-            if (object === specialObjects[i].obj) {
-                return specialObjects[i].value;
-            }
-        }
-
-        return ascii.object.call(this, object, processed, indent);
-    }
-
-    ascii.func = function (func) {
-        return "function " + buster.functionName(func) + "() {}";
-    };
-
-    ascii.array = function (array, processed) {
-        processed = processed || [];
-        processed.push(array);
-        var pieces = [];
-
-        for (var i = 0, l = array.length; i < l; ++i) {
-            pieces.push(ascii.call(this, array[i], processed));
-        }
-
-        return "[" + pieces.join(", ") + "]";
-    };
-
-    ascii.object = function (object, processed, indent) {
-        processed = processed || [];
-        processed.push(object);
-        indent = indent || 0;
-        var pieces = [], properties = keys(object), prop, str, obj;
-        var is = "";
-        var length = 3;
-
-        for (var i = 0, l = indent; i < l; ++i) {
-            is += " ";
-        }
-
-        for (i = 0, l = properties.length; i < l; ++i) {
-            prop = properties[i];
-            obj = object[prop];
-
-            if (isCircular(obj, processed)) {
-                str = "[Circular]";
-            } else {
-                str = ascii.call(this, obj, processed, indent + 2);
-            }
-
-            str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
-            length += str.length;
-            pieces.push(str);
-        }
-
-        var cons = ascii.constructorName.call(this, object);
-        var prefix = cons ? "[" + cons + "] " : ""
-
-        return (length + indent) > 80 ?
-            prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" + is + "}" :
-            prefix + "{ " + pieces.join(", ") + " }";
-    };
-
-    ascii.element = function (element) {
-        var tagName = element.tagName.toLowerCase();
-        var attrs = element.attributes, attribute, pairs = [], attrName;
-
-        for (var i = 0, l = attrs.length; i < l; ++i) {
-            attribute = attrs.item(i);
-            attrName = attribute.nodeName.toLowerCase().replace("html:", "");
-
-            if (attrName == "contenteditable" && attribute.nodeValue == "inherit") {
-                continue;
-            }
-
-            if (!!attribute.nodeValue) {
-                pairs.push(attrName + "=\"" + attribute.nodeValue + "\"");
-            }
-        }
-
-        var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
-        var content = element.innerHTML;
-
-        if (content.length > 20) {
-            content = content.substr(0, 20) + "[...]";
-        }
-
-        var res = formatted + pairs.join(" ") + ">" + content + "</" + tagName + ">";
-
-        return res.replace(/ contentEditable="inherit"/, "");
-    };
-
-    ascii.constructorName = function (object) {
-        var name = buster.functionName(object && object.constructor);
-        var excludes = this.excludeConstructors || buster.format.excludeConstructors || [];
-
-        for (var i = 0, l = excludes.length; i < l; ++i) {
-            if (typeof excludes[i] == "string" && excludes[i] == name) {
-                return "";
-            } else if (excludes[i].test && excludes[i].test(name)) {
-                return "";
-            }
-        }
-
-        return name;
-    };
-
-    return ascii;
-}());
-
-if (typeof module != "undefined") {
-    module.exports = buster.format;
-}
-/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
-/*global module, require, __dirname, document*/
-/**
- * Sinon core utilities. For internal use only.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-var sinon = (function (buster) {
-    var div = typeof document != "undefined" && document.createElement("div");
-    var hasOwn = Object.prototype.hasOwnProperty;
-
-    function isDOMNode(obj) {
-        var success = false;
-
-        try {
-            obj.appendChild(div);
-            success = div.parentNode == obj;
-        } catch (e) {
-            return false;
-        } finally {
-            try {
-                obj.removeChild(div);
-            } catch (e) {
-                // Remove failed, not much we can do about that
-            }
-        }
-
-        return success;
-    }
-
-    function isElement(obj) {
-        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
-    }
-
-    function isFunction(obj) {
-        return !!(obj && obj.constructor && obj.call && obj.apply);
-    }
-
-    function mirrorProperties(target, source) {
-        for (var prop in source) {
-            if (!hasOwn.call(target, prop)) {
-                target[prop] = source[prop];
-            }
-        }
-    }
-
-    var sinon = {
-        wrapMethod: function wrapMethod(object, property, method) {
-            if (!object) {
-                throw new TypeError("Should wrap property of object");
-            }
-
-            if (typeof method != "function") {
-                throw new TypeError("Method wrapper should be function");
-            }
-
-            var wrappedMethod = object[property];
-
-            if (!isFunction(wrappedMethod)) {
-                throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
-                                    property + " as function");
-            }
-
-            if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
-                throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
-            }
-
-            if (wrappedMethod.calledBefore) {
-                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
-                throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
-            }
-
-            // IE 8 does not support hasOwnProperty on the window object.
-            var owned = hasOwn.call(object, property);
-            object[property] = method;
-            method.displayName = property;
-
-            method.restore = function () {
-                // For prototype properties try to reset by delete first.
-                // If this fails (ex: localStorage on mobile safari) then force a reset
-                // via direct assignment.
-                if (!owned) {
-                    delete object[property];
-                }
-                if (object[property] === method) {
-                    object[property] = wrappedMethod;
-                }
-            };
-
-            method.restore.sinon = true;
-            mirrorProperties(method, wrappedMethod);
-
-            return method;
-        },
-
-        extend: function extend(target) {
-            for (var i = 1, l = arguments.length; i < l; i += 1) {
-                for (var prop in arguments[i]) {
-                    if (arguments[i].hasOwnProperty(prop)) {
-                        target[prop] = arguments[i][prop];
-                    }
-
-                    // DONT ENUM bug, only care about toString
-                    if (arguments[i].hasOwnProperty("toString") &&
-                        arguments[i].toString != target.toString) {
-                        target.toString = arguments[i].toString;
-                    }
-                }
-            }
-
-            return target;
-        },
-
-        create: function create(proto) {
-            var F = function () {};
-            F.prototype = proto;
-            return new F();
-        },
-
-        deepEqual: function deepEqual(a, b) {
-            if (sinon.match && sinon.match.isMatcher(a)) {
-                return a.test(b);
-            }
-            if (typeof a != "object" || typeof b != "object") {
-                return a === b;
-            }
-
-            if (isElement(a) || isElement(b)) {
-                return a === b;
-            }
-
-            if (a === b) {
-                return true;
-            }
-
-            var aString = Object.prototype.toString.call(a);
-            if (aString != Object.prototype.toString.call(b)) {
-                return false;
-            }
-
-            if (aString == "[object Array]") {
-                if (a.length !== b.length) {
-                    return false;
-                }
-
-                for (var i = 0, l = a.length; i < l; i += 1) {
-                    if (!deepEqual(a[i], b[i])) {
-                        return false;
-                    }
-                }
-
-                return true;
-            }
-
-            var prop, aLength = 0, bLength = 0;
-
-            for (prop in a) {
-                aLength += 1;
-
-                if (!deepEqual(a[prop], b[prop])) {
-                    return false;
-                }
-            }
-
-            for (prop in b) {
-                bLength += 1;
-            }
-
-            if (aLength != bLength) {
-                return false;
-            }
-
-            return true;
-        },
-
-        functionName: function functionName(func) {
-            var name = func.displayName || func.name;
-
-            // Use function decomposition as a last resort to get function
-            // name. Does not rely on function decomposition to work - if it
-            // doesn't debugging will be slightly less informative
-            // (i.e. toString will say 'spy' rather than 'myFunc').
-            if (!name) {
-                var matches = func.toString().match(/function ([^\s\(]+)/);
-                name = matches && matches[1];
-            }
-
-            return name;
-        },
-
-        functionToString: function toString() {
-            if (this.getCall && this.callCount) {
-                var thisValue, prop, i = this.callCount;
-
-                while (i--) {
-                    thisValue = this.getCall(i).thisValue;
-
-                    for (prop in thisValue) {
-                        if (thisValue[prop] === this) {
-                            return prop;
-                        }
-                    }
-                }
-            }
-
-            return this.displayName || "sinon fake";
-        },
-
-        getConfig: function (custom) {
-            var config = {};
-            custom = custom || {};
-            var defaults = sinon.defaultConfig;
-
-            for (var prop in defaults) {
-                if (defaults.hasOwnProperty(prop)) {
-                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
-                }
-            }
-
-            return config;
-        },
-
-        format: function (val) {
-            return "" + val;
-        },
-
-        defaultConfig: {
-            injectIntoThis: true,
-            injectInto: null,
-            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
-            useFakeTimers: true,
-            useFakeServer: true
-        },
-
-        timesInWords: function timesInWords(count) {
-            return count == 1 && "once" ||
-                count == 2 && "twice" ||
-                count == 3 && "thrice" ||
-                (count || 0) + " times";
-        },
-
-        calledInOrder: function (spies) {
-            for (var i = 1, l = spies.length; i < l; i++) {
-                if (!spies[i - 1].calledBefore(spies[i])) {
-                    return false;
-                }
-            }
-
-            return true;
-        },
-
-        orderByFirstCall: function (spies) {
-            return spies.sort(function (a, b) {
-                // uuid, won't ever be equal
-                var aCall = a.getCall(0);
-                var bCall = b.getCall(0);
-                var aId = aCall && aCall.callId || -1;
-                var bId = bCall && bCall.callId || -1;
-
-                return aId < bId ? -1 : 1;
-            });
-        },
-
-        log: function () {},
-
-        logError: function (label, err) {
-            var msg = label + " threw exception: "
-            sinon.log(msg + "[" + err.name + "] " + err.message);
-            if (err.stack) { sinon.log(err.stack); }
-
-            setTimeout(function () {
-                err.message = msg + err.message;
-                throw err;
-            }, 0);
-        },
-
-        typeOf: function (value) {
-            if (value === null) {
-              return "null";
-            }
-            var string = Object.prototype.toString.call(value);
-            return string.substring(8, string.length - 1).toLowerCase();
-        }
-    };
-
-    var isNode = typeof module == "object" && typeof require == "function";
-
-    if (isNode) {
-        try {
-            buster = { format: require("buster-format") };
-        } catch (e) {}
-        module.exports = sinon;
-        module.exports.spy = require("./sinon/spy");
-        module.exports.stub = require("./sinon/stub");
-        module.exports.mock = require("./sinon/mock");
-        module.exports.collection = require("./sinon/collection");
-        module.exports.assert = require("./sinon/assert");
-        module.exports.sandbox = require("./sinon/sandbox");
-        module.exports.test = require("./sinon/test");
-        module.exports.testCase = require("./sinon/test_case");
-        module.exports.assert = require("./sinon/assert");
-        module.exports.match = require("./sinon/match");
-    }
-
-    if (buster) {
-        var formatter = sinon.create(buster.format);
-        formatter.quoteStrings = false;
-        sinon.format = function () {
-            return formatter.ascii.apply(formatter, arguments);
-        };
-    } else if (isNode) {
-        try {
-            var util = require("util");
-            sinon.format = function (value) {
-                return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
-            };
-        } catch (e) {
-            /* Node, but no util module - would be very old, but better safe than
-             sorry */
-        }
-    }
-
-    return sinon;
-}(typeof buster == "object" && buster));
-
-/* @depend ../sinon.js */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Match functions
- *
- * @author Maximilian Antoni (mail@maxantoni.de)
- * @license BSD
- *
- * Copyright (c) 2012 Maximilian Antoni
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function assertType(value, type, name) {
-        var actual = sinon.typeOf(value);
-        if (actual !== type) {
-            throw new TypeError("Expected type of " + name + " to be " +
-                type + ", but was " + actual);
-        }
-    }
-
-    var matcher = {
-        toString: function () {
-            return this.message;
-        }
-    };
-
-    function isMatcher(object) {
-        return matcher.isPrototypeOf(object);
-    }
-
-    function matchObject(expectation, actual) {
-        if (actual === null || actual === undefined) {
-            return false;
-        }
-        for (var key in expectation) {
-            if (expectation.hasOwnProperty(key)) {
-                var exp = expectation[key];
-                var act = actual[key];
-                if (match.isMatcher(exp)) {
-                    if (!exp.test(act)) {
-                        return false;
-                    }
-                } else if (sinon.typeOf(exp) === "object") {
-                    if (!matchObject(exp, act)) {
-                        return false;
-                    }
-                } else if (exp !== act) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    matcher.or = function (m2) {
-        if (!isMatcher(m2)) {
-            throw new TypeError("Matcher expected");
-        }
-        var m1 = this;
-        var or = sinon.create(matcher);
-        or.test = function (actual) {
-            return m1.test(actual) || m2.test(actual);
-        };
-        or.message = m1.message + ".or(" + m2.message + ")";
-        return or;
-    };
-
-    matcher.and = function (m2) {
-        if (!isMatcher(m2)) {
-            throw new TypeError("Matcher expected");
-        }
-        var m1 = this;
-        var and = sinon.create(matcher);
-        and.test = function (actual) {
-            return m1.test(actual) && m2.test(actual);
-        };
-        and.message = m1.message + ".and(" + m2.message + ")";
-        return and;
-    };
-
-    var match = function (expectation, message) {
-        var m = sinon.create(matcher);
-        var type = sinon.typeOf(expectation);
-        switch (type) {
-        case "object":
-            if (typeof expectation.test === "function") {
-                m.test = function (actual) {
-                    return expectation.test(actual) === true;
-                };
-                m.message = "match(" + sinon.functionName(expectation.test) + ")";
-                return m;
-            }
-            var str = [];
-            for (var key in expectation) {
-                if (expectation.hasOwnProperty(key)) {
-                    str.push(key + ": " + expectation[key]);
-                }
-            }
-            m.test = function (actual) {
-                return matchObject(expectation, actual);
-            };
-            m.message = "match(" + str.join(", ") + ")";
-            break;
-        case "number":
-            m.test = function (actual) {
-                return expectation == actual;
-            };
-            break;
-        case "string":
-            m.test = function (actual) {
-                if (typeof actual !== "string") {
-                    return false;
-                }
-                return actual.indexOf(expectation) !== -1;
-            };
-            m.message = "match(\"" + expectation + "\")";
-            break;
-        case "regexp":
-            m.test = function (actual) {
-                if (typeof actual !== "string") {
-                    return false;
-                }
-                return expectation.test(actual);
-            };
-            break;
-        case "function":
-            m.test = expectation;
-            if (message) {
-                m.message = message;
-            } else {
-                m.message = "match(" + sinon.functionName(expectation) + ")";
-            }
-            break;
-        default:
-            m.test = function (actual) {
-              return sinon.deepEqual(expectation, actual);
-            };
-        }
-        if (!m.message) {
-            m.message = "match(" + expectation + ")";
-        }
-        return m;
-    };
-
-    match.isMatcher = isMatcher;
-
-    match.any = match(function () {
-        return true;
-    }, "any");
-
-    match.defined = match(function (actual) {
-        return actual !== null && actual !== undefined;
-    }, "defined");
-
-    match.truthy = match(function (actual) {
-        return !!actual;
-    }, "truthy");
-
-    match.falsy = match(function (actual) {
-        return !actual;
-    }, "falsy");
-
-    match.same = function (expectation) {
-        return match(function (actual) {
-            return expectation === actual;
-        }, "same(" + expectation + ")");
-    };
-
-    match.typeOf = function (type) {
-        assertType(type, "string", "type");
-        return match(function (actual) {
-            return sinon.typeOf(actual) === type;
-        }, "typeOf(\"" + type + "\")");
-    };
-
-    match.instanceOf = function (type) {
-        assertType(type, "function", "type");
-        return match(function (actual) {
-            return actual instanceof type;
-        }, "instanceOf(" + sinon.functionName(type) + ")");
-    };
-
-    function createPropertyMatcher(propertyTest, messagePrefix) {
-        return function (property, value) {
-            assertType(property, "string", "property");
-            var onlyProperty = arguments.length === 1;
-            var message = messagePrefix + "(\"" + property + "\"";
-            if (!onlyProperty) {
-                message += ", " + value;
-            }
-            message += ")";
-            return match(function (actual) {
-                if (actual === undefined || actual === null ||
-                        !propertyTest(actual, property)) {
-                    return false;
-                }
-                return onlyProperty || sinon.deepEqual(value, actual[property]);
-            }, message);
-        };
-    }
-
-    match.has = createPropertyMatcher(function (actual, property) {
-        if (typeof actual === "object") {
-            return property in actual;
-        }
-        return actual[property] !== undefined;
-    }, "has");
-
-    match.hasOwn = createPropertyMatcher(function (actual, property) {
-        return actual.hasOwnProperty(property);
-    }, "hasOwn");
-
-    match.bool = match.typeOf("boolean");
-    match.number = match.typeOf("number");
-    match.string = match.typeOf("string");
-    match.object = match.typeOf("object");
-    match.func = match.typeOf("function");
-    match.array = match.typeOf("array");
-    match.regexp = match.typeOf("regexp");
-    match.date = match.typeOf("date");
-
-    if (commonJSModule) {
-        module.exports = match;
-    } else {
-        sinon.match = match;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend match.js
- */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Spy functions
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-    var spyCall;
-    var callId = 0;
-    var push = [].push;
-    var slice = Array.prototype.slice;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function spy(object, property) {
-        if (!property && typeof object == "function") {
-            return spy.create(object);
-        }
-
-        if (!object && !property) {
-            return spy.create(function () {});
-        }
-
-        var method = object[property];
-        return sinon.wrapMethod(object, property, spy.create(method));
-    }
-
-    sinon.extend(spy, (function () {
-
-        function delegateToCalls(api, method, matchAny, actual, notCalled) {
-            api[method] = function () {
-                if (!this.called) {
-                    if (notCalled) {
-                        return notCalled.apply(this, arguments);
-                    }
-                    return false;
-                }
-
-                var currentCall;
-                var matches = 0;
-
-                for (var i = 0, l = this.callCount; i < l; i += 1) {
-                    currentCall = this.getCall(i);
-
-                    if (currentCall[actual || method].apply(currentCall, arguments)) {
-                        matches += 1;
-
-                        if (matchAny) {
-                            return true;
-                        }
-                    }
-                }
-
-                return matches === this.callCount;
-            };
-        }
-
-        function matchingFake(fakes, args, strict) {
-            if (!fakes) {
-                return;
-            }
-
-            var alen = args.length;
-
-            for (var i = 0, l = fakes.length; i < l; i++) {
-                if (fakes[i].matches(args, strict)) {
-                    return fakes[i];
-                }
-            }
-        }
-
-        function incrementCallCount() {
-            this.called = true;
-            this.callCount += 1;
-            this.notCalled = false;
-            this.calledOnce = this.callCount == 1;
-            this.calledTwice = this.callCount == 2;
-            this.calledThrice = this.callCount == 3;
-        }
-
-        function createCallProperties() {
-            this.firstCall = this.getCall(0);
-            this.secondCall = this.getCall(1);
-            this.thirdCall = this.getCall(2);
-            this.lastCall = this.getCall(this.callCount - 1);
-        }
-
-        var uuid = 0;
-
-        // Public API
-        var spyApi = {
-            reset: function () {
-                this.called = false;
-                this.notCalled = true;
-                this.calledOnce = false;
-                this.calledTwice = false;
-                this.calledThrice = false;
-                this.callCount = 0;
-                this.firstCall = null;
-                this.secondCall = null;
-                this.thirdCall = null;
-                this.lastCall = null;
-                this.args = [];
-                this.returnValues = [];
-                this.thisValues = [];
-                this.exceptions = [];
-                this.callIds = [];
-                if (this.fakes) {
-                    for (var i = 0; i < this.fakes.length; i++) {
-                        this.fakes[i].reset();
-                    }
-                }
-            },
-
-            create: function create(func) {
-                var name;
-
-                if (typeof func != "function") {
-                    func = function () {};
-                } else {
-                    name = sinon.functionName(func);
-                }
-
-                function proxy() {
-                    return proxy.invoke(func, this, slice.call(arguments));
-                }
-
-                sinon.extend(proxy, spy);
-                delete proxy.create;
-                sinon.extend(proxy, func);
-
-                proxy.reset();
-                proxy.prototype = func.prototype;
-                proxy.displayName = name || "spy";
-                proxy.toString = sinon.functionToString;
-                proxy._create = sinon.spy.create;
-                proxy.id = "spy#" + uuid++;
-
-                return proxy;
-            },
-
-            invoke: function invoke(func, thisValue, args) {
-                var matching = matchingFake(this.fakes, args);
-                var exception, returnValue;
-
-                incrementCallCount.call(this);
-                push.call(this.thisValues, thisValue);
-                push.call(this.args, args);
-                push.call(this.callIds, callId++);
-
-                try {
-                    if (matching) {
-                        returnValue = matching.invoke(func, thisValue, args);
-                    } else {
-                        returnValue = (this.func || func).apply(thisValue, args);
-                    }
-                } catch (e) {
-                    push.call(this.returnValues, undefined);
-                    exception = e;
-                    throw e;
-                } finally {
-                    push.call(this.exceptions, exception);
-                }
-
-                push.call(this.returnValues, returnValue);
-
-                createCallProperties.call(this);
-
-                return returnValue;
-            },
-
-            getCall: function getCall(i) {
-                if (i < 0 || i >= this.callCount) {
-                    return null;
-                }
-
-                return spyCall.create(this, this.thisValues[i], this.args[i],
-                                      this.returnValues[i], this.exceptions[i],
-                                      this.callIds[i]);
-            },
-
-            calledBefore: function calledBefore(spyFn) {
-                if (!this.called) {
-                    return false;
-                }
-
-                if (!spyFn.called) {
-                    return true;
-                }
-
-                return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
-            },
-
-            calledAfter: function calledAfter(spyFn) {
-                if (!this.called || !spyFn.called) {
-                    return false;
-                }
-
-                return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
-            },
-
-            withArgs: function () {
-                var args = slice.call(arguments);
-
-                if (this.fakes) {
-                    var match = matchingFake(this.fakes, args, true);
-
-                    if (match) {
-                        return match;
-                    }
-                } else {
-                    this.fakes = [];
-                }
-
-                var original = this;
-                var fake = this._create();
-                fake.matchingAguments = args;
-                push.call(this.fakes, fake);
-
-                fake.withArgs = function () {
-                    return original.withArgs.apply(original, arguments);
-                };
-
-                for (var i = 0; i < this.args.length; i++) {
-                    if (fake.matches(this.args[i])) {
-                        incrementCallCount.call(fake);
-                        push.call(fake.thisValues, this.thisValues[i]);
-                        push.call(fake.args, this.args[i]);
-                        push.call(fake.returnValues, this.returnValues[i]);
-                        push.call(fake.exceptions, this.exceptions[i]);
-                        push.call(fake.callIds, this.callIds[i]);
-                    }
-                }
-                createCallProperties.call(fake);
-
-                return fake;
-            },
-
-            matches: function (args, strict) {
-                var margs = this.matchingAguments;
-
-                if (margs.length <= args.length &&
-                    sinon.deepEqual(margs, args.slice(0, margs.length))) {
-                    return !strict || margs.length == args.length;
-                }
-            },
-
-            printf: function (format) {
-                var spy = this;
-                var args = slice.call(arguments, 1);
-                var formatter;
-
-                return (format || "").replace(/%(.)/g, function (match, specifyer) {
-                    formatter = spyApi.formatters[specifyer];
-
-                    if (typeof formatter == "function") {
-                        return formatter.call(null, spy, args);
-                    } else if (!isNaN(parseInt(specifyer), 10)) {
-                        return sinon.format(args[specifyer - 1]);
-                    }
-
-                    return "%" + specifyer;
-                });
-            }
-        };
-
-        delegateToCalls(spyApi, "calledOn", true);
-        delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn");
-        delegateToCalls(spyApi, "calledWith", true);
-        delegateToCalls(spyApi, "calledWithMatch", true);
-        delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
-        delegateToCalls(spyApi, "alwaysCalledWithMatch", false, "calledWithMatch");
-        delegateToCalls(spyApi, "calledWithExactly", true);
-        delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
-        delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
-            function () { return true; });
-        delegateToCalls(spyApi, "neverCalledWithMatch", false, "notCalledWithMatch",
-            function () { return true; });
-        delegateToCalls(spyApi, "threw", true);
-        delegateToCalls(spyApi, "alwaysThrew", false, "threw");
-        delegateToCalls(spyApi, "returned", true);
-        delegateToCalls(spyApi, "alwaysReturned", false, "returned");
-        delegateToCalls(spyApi, "calledWithNew", true);
-        delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
-        delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
-            throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
-        });
-        spyApi.callArgWith = spyApi.callArg;
-        delegateToCalls(spyApi, "yield", false, "yield", function () {
-            throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
-        });
-        // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
-        spyApi.invokeCallback = spyApi.yield;
-        delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
-            throw new Error(this.toString() + " cannot yield to '" + property +
-                "' since it was not yet invoked.");
-        });
-
-        spyApi.formatters = {
-            "c": function (spy) {
-                return sinon.timesInWords(spy.callCount);
-            },
-
-            "n": function (spy) {
-                return spy.toString();
-            },
-
-            "C": function (spy) {
-                var calls = [];
-
-                for (var i = 0, l = spy.callCount; i < l; ++i) {
-                    push.call(calls, "    " + spy.getCall(i).toString());
-                }
-
-                return calls.length > 0 ? "\n" + calls.join("\n") : "";
-            },
-
-            "t": function (spy) {
-                var objects = [];
-
-                for (var i = 0, l = spy.callCount; i < l; ++i) {
-                    push.call(objects, sinon.format(spy.thisValues[i]));
-                }
-
-                return objects.join(", ");
-            },
-
-            "*": function (spy, args) {
-                var formatted = [];
-
-                for (var i = 0, l = args.length; i < l; ++i) {
-                    push.call(formatted, sinon.format(args[i]));
-                }
-
-                return formatted.join(", ");
-            }
-        };
-
-        return spyApi;
-    }()));
-
-    spyCall = (function () {
-
-        function throwYieldError(proxy, text, args) {
-            var msg = sinon.functionName(proxy) + text;
-            if (args.length) {
-                msg += " Received [" + slice.call(args).join(", ") + "]";
-            }
-            throw new Error(msg);
-        }
-
-        return {
-            create: function create(spy, thisValue, args, returnValue, exception, id) {
-                var proxyCall = sinon.create(spyCall);
-                delete proxyCall.create;
-                proxyCall.proxy = spy;
-                proxyCall.thisValue = thisValue;
-                proxyCall.args = args;
-                proxyCall.returnValue = returnValue;
-                proxyCall.exception = exception;
-                proxyCall.callId = typeof id == "number" && id || callId++;
-
-                return proxyCall;
-            },
-
-            calledOn: function calledOn(thisValue) {
-                return this.thisValue === thisValue;
-            },
-
-            calledWith: function calledWith() {
-                for (var i = 0, l = arguments.length; i < l; i += 1) {
-                    if (!sinon.deepEqual(arguments[i], this.args[i])) {
-                        return false;
-                    }
-                }
-
-                return true;
-            },
-
-            calledWithMatch: function calledWithMatch() {
-              for (var i = 0, l = arguments.length; i < l; i += 1) {
-                  var actual = this.args[i];
-                  var expectation = arguments[i];
-                  if (!sinon.match || !sinon.match(expectation).test(actual)) {
-                      return false;
-                  }
-              }
-              return true;
-            },
-
-            calledWithExactly: function calledWithExactly() {
-                return arguments.length == this.args.length &&
-                    this.calledWith.apply(this, arguments);
-            },
-
-            notCalledWith: function notCalledWith() {
-                return !this.calledWith.apply(this, arguments);
-            },
-
-            notCalledWithMatch: function notCalledWithMatch() {
-              return !this.calledWithMatch.apply(this, arguments);
-            },
-
-            returned: function returned(value) {
-                return sinon.deepEqual(value, this.returnValue);
-            },
-
-            threw: function threw(error) {
-                if (typeof error == "undefined" || !this.exception) {
-                    return !!this.exception;
-                }
-
-                if (typeof error == "string") {
-                    return this.exception.name == error;
-                }
-
-                return this.exception === error;
-            },
-
-            calledWithNew: function calledWithNew(thisValue) {
-                return this.thisValue instanceof this.proxy;
-            },
-
-            calledBefore: function (other) {
-                return this.callId < other.callId;
-            },
-
-            calledAfter: function (other) {
-                return this.callId > other.callId;
-            },
-
-            callArg: function (pos) {
-                this.args[pos]();
-            },
-
-            callArgWith: function (pos) {
-                var args = slice.call(arguments, 1);
-                this.args[pos].apply(null, args);
-            },
-
-            "yield": function () {
-                var args = this.args;
-                for (var i = 0, l = args.length; i < l; ++i) {
-                    if (typeof args[i] === "function") {
-                        args[i].apply(null, slice.call(arguments));
-                        return;
-                    }
-                }
-                throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
-            },
-
-            yieldTo: function (prop) {
-                var args = this.args;
-                for (var i = 0, l = args.length; i < l; ++i) {
-                    if (args[i] && typeof args[i][prop] === "function") {
-                        args[i][prop].apply(null, slice.call(arguments, 1));
-                        return;
-                    }
-                }
-                throwYieldError(this.proxy, " cannot yield to '" + prop +
-                    "' since no callback was passed.", args);
-            },
-
-            toString: function () {
-                var callStr = this.proxy.toString() + "(";
-                var args = [];
-
-                for (var i = 0, l = this.args.length; i < l; ++i) {
-                    push.call(args, sinon.format(this.args[i]));
-                }
-
-                callStr = callStr + args.join(", ") + ")";
-
-                if (typeof this.returnValue != "undefined") {
-                    callStr += " => " + sinon.format(this.returnValue);
-                }
-
-                if (this.exception) {
-                    callStr += " !" + this.exception.name;
-
-                    if (this.exception.message) {
-                        callStr += "(" + this.exception.message + ")";
-                    }
-                }
-
-                return callStr;
-            }
-        };
-    }());
-
-    spy.spyCall = spyCall;
-
-    // This steps outside the module sandbox and will be removed
-    sinon.spyCall = spyCall;
-
-    if (commonJSModule) {
-        module.exports = spy;
-    } else {
-        sinon.spy = spy;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend spy.js
- */
-/*jslint eqeqeq: false, onevar: false*/
-/*global module, require, sinon*/
-/**
- * Stub functions
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function stub(object, property, func) {
-        if (!!func && typeof func != "function") {
-            throw new TypeError("Custom stub should be function");
-        }
-
-        var wrapper;
-
-        if (func) {
-            wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
-        } else {
-            wrapper = stub.create();
-        }
-
-        if (!object && !property) {
-            return sinon.stub.create();
-        }
-
-        if (!property && !!object && typeof object == "object") {
-            for (var prop in object) {
-                if (typeof object[prop] === "function") {
-                    stub(object, prop);
-                }
-            }
-
-            return object;
-        }
-
-        return sinon.wrapMethod(object, property, wrapper);
-    }
-
-    function getCallback(stub, args) {
-        if (stub.callArgAt < 0) {
-            for (var i = 0, l = args.length; i < l; ++i) {
-                if (!stub.callArgProp && typeof args[i] == "function") {
-                    return args[i];
-                }
-
-                if (stub.callArgProp && args[i] &&
-                    typeof args[i][stub.callArgProp] == "function") {
-                    return args[i][stub.callArgProp];
-                }
-            }
-
-            return null;
-        }
-
-        return args[stub.callArgAt];
-    }
-
-    var join = Array.prototype.join;
-
-    function getCallbackError(stub, func, args) {
-        if (stub.callArgAt < 0) {
-            var msg;
-
-            if (stub.callArgProp) {
-                msg = sinon.functionName(stub) +
-                    " expected to yield to '" + stub.callArgProp +
-                    "', but no object with such a property was passed."
-            } else {
-                msg = sinon.functionName(stub) +
-                            " expected to yield, but no callback was passed."
-            }
-
-            if (args.length > 0) {
-                msg += " Received [" + join.call(args, ", ") + "]";
-            }
-
-            return msg;
-        }
-
-        return "argument at index " + stub.callArgAt + " is not a function: " + func;
-    }
-
-    var nextTick = (function () {
-        if (typeof process === "object" && typeof process.nextTick === "function") {
-            return process.nextTick;
-        } else if (typeof msSetImmediate === "function") {
-            return msSetImmediate.bind(window);
-        } else if (typeof setImmediate === "function") {
-            return setImmediate;
-        } else {
-            return function (callback) {
-                setTimeout(callback, 0);
-            };
-        }
-    })();
-
-    function callCallback(stub, args) {
-        if (typeof stub.callArgAt == "number") {
-            var func = getCallback(stub, args);
-
-            if (typeof func != "function") {
-                throw new TypeError(getCallbackError(stub, func, args));
-            }
-
-            if (stub.callbackAsync) {
-                nextTick(function() {
-                    func.apply(stub.callbackContext, stub.callbackArguments);
-                });
-            } else {
-                func.apply(stub.callbackContext, stub.callbackArguments);
-            }
-        }
-    }
-
-    var uuid = 0;
-
-    sinon.extend(stub, (function () {
-        var slice = Array.prototype.slice, proto;
-
-        function throwsException(error, message) {
-            if (typeof error == "string") {
-                this.exception = new Error(message || "");
-                this.exception.name = error;
-            } else if (!error) {
-                this.exception = new Error("Error");
-            } else {
-                this.exception = error;
-            }
-
-            return this;
-        }
-
-        proto = {
-            create: function create() {
-                var functionStub = function () {
-
-                    callCallback(functionStub, arguments);
-
-                    if (functionStub.exception) {
-                        throw functionStub.exception;
-                    } else if (typeof functionStub.returnArgAt == 'number') {
-                        return arguments[functionStub.returnArgAt];
-                    } else if (functionStub.returnThis) {
-                        return this;
-                    }
-                    return functionStub.returnValue;
-                };
-
-                functionStub.id = "stub#" + uuid++;
-                var orig = functionStub;
-                functionStub = sinon.spy.create(functionStub);
-                functionStub.func = orig;
-
-                sinon.extend(functionStub, stub);
-                functionStub._create = sinon.stub.create;
-                functionStub.displayName = "stub";
-                functionStub.toString = sinon.functionToString;
-
-                return functionStub;
-            },
-
-            returns: function returns(value) {
-                this.returnValue = value;
-
-                return this;
-            },
-
-            returnsArg: function returnsArg(pos) {
-                if (typeof pos != "number") {
-                    throw new TypeError("argument index is not number");
-                }
-
-                this.returnArgAt = pos;
-
-                return this;
-            },
-
-            returnsThis: function returnsThis() {
-                this.returnThis = true;
-
-                return this;
-            },
-
-            "throws": throwsException,
-            throwsException: throwsException,
-
-            callsArg: function callsArg(pos) {
-                if (typeof pos != "number") {
-                    throw new TypeError("argument index is not number");
-                }
-
-                this.callArgAt = pos;
-                this.callbackArguments = [];
-
-                return this;
-            },
-
-            callsArgOn: function callsArgOn(pos, context) {
-                if (typeof pos != "number") {
-                    throw new TypeError("argument index is not number");
-                }
-                if (typeof context != "object") {
-                    throw new TypeError("argument context is not an object");
-                }
-
-                this.callArgAt = pos;
-                this.callbackArguments = [];
-                this.callbackContext = context;
-
-                return this;
-            },
-
-            callsArgWith: function callsArgWith(pos) {
-                if (typeof pos != "number") {
-                    throw new TypeError("argument index is not number");
-                }
-
-                this.callArgAt = pos;
-                this.callbackArguments = slice.call(arguments, 1);
-
-                return this;
-            },
-
-            callsArgOnWith: function callsArgWith(pos, context) {
-                if (typeof pos != "number") {
-                    throw new TypeError("argument index is not number");
-                }
-                if (typeof context != "object") {
-                    throw new TypeError("argument context is not an object");
-                }
-
-                this.callArgAt = pos;
-                this.callbackArguments = slice.call(arguments, 2);
-                this.callbackContext = context;
-
-                return this;
-            },
-
-            yields: function () {
-                this.callArgAt = -1;
-                this.callbackArguments = slice.call(arguments, 0);
-
-                return this;
-            },
-
-            yieldsOn: function (context) {
-                if (typeof context != "object") {
-                    throw new TypeError("argument context is not an object");
-                }
-
-                this.callArgAt = -1;
-                this.callbackArguments = slice.call(arguments, 1);
-                this.callbackContext = context;
-
-                return this;
-            },
-
-            yieldsTo: function (prop) {
-                this.callArgAt = -1;
-                this.callArgProp = prop;
-                this.callbackArguments = slice.call(arguments, 1);
-
-                return this;
-            },
-
-            yieldsToOn: function (prop, context) {
-                if (typeof context != "object") {
-                    throw new TypeError("argument context is not an object");
-                }
-
-                this.callArgAt = -1;
-                this.callArgProp = prop;
-                this.callbackArguments = slice.call(arguments, 2);
-                this.callbackContext = context;
-
-                return this;
-            }
-        };
-        
-        // create asynchronous versions of callsArg* and yields* methods
-        for (var method in proto) {
-            if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/)) {
-                proto[method + 'Async'] = (function (syncFnName) {
-                    return function () {
-                        this.callbackAsync = true;
-                        return this[syncFnName].apply(this, arguments);
-                    };
-                })(method);
-            }
-        }
-        
-        return proto;
-        
-    }()));
-
-    if (commonJSModule) {
-        module.exports = stub;
-    } else {
-        sinon.stub = stub;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- */
-/*jslint eqeqeq: false, onevar: false, nomen: false*/
-/*global module, require, sinon*/
-/**
- * Mock functions.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-    var push = [].push;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function mock(object) {
-        if (!object) {
-            return sinon.expectation.create("Anonymous mock");
-        }
-
-        return mock.create(object);
-    }
-
-    sinon.mock = mock;
-
-    sinon.extend(mock, (function () {
-        function each(collection, callback) {
-            if (!collection) {
-                return;
-            }
-
-            for (var i = 0, l = collection.length; i < l; i += 1) {
-                callback(collection[i]);
-            }
-        }
-
-        return {
-            create: function create(object) {
-                if (!object) {
-                    throw new TypeError("object is null");
-                }
-
-                var mockObject = sinon.extend({}, mock);
-                mockObject.object = object;
-                delete mockObject.create;
-
-                return mockObject;
-            },
-
-            expects: function expects(method) {
-                if (!method) {
-                    throw new TypeError("method is falsy");
-                }
-
-                if (!this.expectations) {
-                    this.expectations = {};
-                    this.proxies = [];
-                }
-
-                if (!this.expectations[method]) {
-                    this.expectations[method] = [];
-                    var mockObject = this;
-
-                    sinon.wrapMethod(this.object, method, function () {
-                        return mockObject.invokeMethod(method, this, arguments);
-                    });
-
-                    push.call(this.proxies, method);
-                }
-
-                var expectation = sinon.expectation.create(method);
-                push.call(this.expectations[method], expectation);
-
-                return expectation;
-            },
-
-            restore: function restore() {
-                var object = this.object;
-
-                each(this.proxies, function (proxy) {
-                    if (typeof object[proxy].restore == "function") {
-                        object[proxy].restore();
-                    }
-                });
-            },
-
-            verify: function verify() {
-                var expectations = this.expectations || {};
-                var messages = [], met = [];
-
-                each(this.proxies, function (proxy) {
-                    each(expectations[proxy], function (expectation) {
-                        if (!expectation.met()) {
-                            push.call(messages, expectation.toString());
-                        } else {
-                            push.call(met, expectation.toString());
-                        }
-                    });
-                });
-
-                this.restore();
-
-                if (messages.length > 0) {
-                    sinon.expectation.fail(messages.concat(met).join("\n"));
-                } else {
-                    sinon.expectation.pass(messages.concat(met).join("\n"));
-                }
-
-                return true;
-            },
-
-            invokeMethod: function invokeMethod(method, thisValue, args) {
-                var expectations = this.expectations && this.expectations[method];
-                var length = expectations && expectations.length || 0, i;
-
-                for (i = 0; i < length; i += 1) {
-                    if (!expectations[i].met() &&
-                        expectations[i].allowsCall(thisValue, args)) {
-                        return expectations[i].apply(thisValue, args);
-                    }
-                }
-
-                var messages = [], available, exhausted = 0;
-
-                for (i = 0; i < length; i += 1) {
-                    if (expectations[i].allowsCall(thisValue, args)) {
-                        available = available || expectations[i];
-                    } else {
-                        exhausted += 1;
-                    }
-                    push.call(messages, "    " + expectations[i].toString());
-                }
-
-                if (exhausted === 0) {
-                    return available.apply(thisValue, args);
-                }
-
-                messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
-                    proxy: method,
-                    args: args
-                }));
-
-                sinon.expectation.fail(messages.join("\n"));
-            }
-        };
-    }()));
-
-    var times = sinon.timesInWords;
-
-    sinon.expectation = (function () {
-        var slice = Array.prototype.slice;
-        var _invoke = sinon.spy.invoke;
-
-        function callCountInWords(callCount) {
-            if (callCount == 0) {
-                return "never called";
-            } else {
-                return "called " + times(callCount);
-            }
-        }
-
-        function expectedCallCountInWords(expectation) {
-            var min = expectation.minCalls;
-            var max = expectation.maxCalls;
-
-            if (typeof min == "number" && typeof max == "number") {
-                var str = times(min);
-
-                if (min != max) {
-                    str = "at least " + str + " and at most " + times(max);
-                }
-
-                return str;
-            }
-
-            if (typeof min == "number") {
-                return "at least " + times(min);
-            }
-
-            return "at most " + times(max);
-        }
-
-        function receivedMinCalls(expectation) {
-            var hasMinLimit = typeof expectation.minCalls == "number";
-            return !hasMinLimit || expectation.callCount >= expectation.minCalls;
-        }
-
-        function receivedMaxCalls(expectation) {
-            if (typeof expectation.maxCalls != "number") {
-                return false;
-            }
-
-            return expectation.callCount == expectation.maxCalls;
-        }
-
-        return {
-            minCalls: 1,
-            maxCalls: 1,
-
-            create: function create(methodName) {
-                var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
-                delete expectation.create;
-                expectation.method = methodName;
-
-                return expectation;
-            },
-
-            invoke: function invoke(func, thisValue, args) {
-                this.verifyCallAllowed(thisValue, args);
-
-                return _invoke.apply(this, arguments);
-            },
-
-            atLeast: function atLeast(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not number");
-                }
-
-                if (!this.limitsSet) {
-                    this.maxCalls = null;
-                    this.limitsSet = true;
-                }
-
-                this.minCalls = num;
-
-                return this;
-            },
-
-            atMost: function atMost(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not number");
-                }
-
-                if (!this.limitsSet) {
-                    this.minCalls = null;
-                    this.limitsSet = true;
-                }
-
-                this.maxCalls = num;
-
-                return this;
-            },
-
-            never: function never() {
-                return this.exactly(0);
-            },
-
-            once: function once() {
-                return this.exactly(1);
-            },
-
-            twice: function twice() {
-                return this.exactly(2);
-            },
-
-            thrice: function thrice() {
-                return this.exactly(3);
-            },
-
-            exactly: function exactly(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not a number");
-                }
-
-                this.atLeast(num);
-                return this.atMost(num);
-            },
-
-            met: function met() {
-                return !this.failed && receivedMinCalls(this);
-            },
-
-            verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
-                if (receivedMaxCalls(this)) {
-                    this.failed = true;
-                    sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
-                }
-
-                if ("expectedThis" in this && this.expectedThis !== thisValue) {
-                    sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
-                        this.expectedThis);
-                }
-
-                if (!("expectedArguments" in this)) {
-                    return;
-                }
-
-                if (!args) {
-                    sinon.expectation.fail(this.method + " received no arguments, expected " +
-                        this.expectedArguments.join());
-                }
-
-                if (args.length < this.expectedArguments.length) {
-                    sinon.expectation.fail(this.method + " received too few arguments (" + args.join() +
-                        "), expected " + this.expectedArguments.join());
-                }
-
-                if (this.expectsExactArgCount &&
-                    args.length != this.expectedArguments.length) {
-                    sinon.expectation.fail(this.method + " received too many arguments (" + args.join() +
-                        "), expected " + this.expectedArguments.join());
-                }
-
-                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
-                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
-                        sinon.expectation.fail(this.method + " received wrong arguments (" + args.join() +
-                            "), expected " + this.expectedArguments.join());
-                    }
-                }
-            },
-
-            allowsCall: function allowsCall(thisValue, args) {
-                if (this.met() && receivedMaxCalls(this)) {
-                    return false;
-                }
-
-                if ("expectedThis" in this && this.expectedThis !== thisValue) {
-                    return false;
-                }
-
-                if (!("expectedArguments" in this)) {
-                    return true;
-                }
-
-                args = args || [];
-
-                if (args.length < this.expectedArguments.length) {
-                    return false;
-                }
-
-                if (this.expectsExactArgCount &&
-                    args.length != this.expectedArguments.length) {
-                    return false;
-                }
-
-                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
-                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
-                        return false;
-                    }
-                }
-
-                return true;
-            },
-
-            withArgs: function withArgs() {
-                this.expectedArguments = slice.call(arguments);
-                return this;
-            },
-
-            withExactArgs: function withExactArgs() {
-                this.withArgs.apply(this, arguments);
-                this.expectsExactArgCount = true;
-                return this;
-            },
-
-            on: function on(thisValue) {
-                this.expectedThis = thisValue;
-                return this;
-            },
-
-            toString: function () {
-                var args = (this.expectedArguments || []).slice();
-
-                if (!this.expectsExactArgCount) {
-                    push.call(args, "[...]");
-                }
-
-                var callStr = sinon.spyCall.toString.call({
-                    proxy: this.method, args: args
-                });
-
-                var message = callStr.replace(", [...", "[, ...") + " " +
-                    expectedCallCountInWords(this);
-
-                if (this.met()) {
-                    return "Expectation met: " + message;
-                }
-
-                return "Expected " + message + " (" +
-                    callCountInWords(this.callCount) + ")";
-            },
-
-            verify: function verify() {
-                if (!this.met()) {
-                    sinon.expectation.fail(this.toString());
-                } else {
-                    sinon.expectation.pass(this.toString());
-                }
-
-                return true;
-            },
-
-            pass: function(message) {
-              sinon.assert.pass(message);
-            },
-            fail: function (message) {
-                var exception = new Error(message);
-                exception.name = "ExpectationError";
-
-                throw exception;
-            }
-        };
-    }());
-
-    if (commonJSModule) {
-        module.exports = mock;
-    } else {
-        sinon.mock = mock;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- * @depend mock.js
- */
-/*jslint eqeqeq: false, onevar: false, forin: true*/
-/*global module, require, sinon*/
-/**
- * Collections of stubs, spies and mocks.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-    var push = [].push;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function getFakes(fakeCollection) {
-        if (!fakeCollection.fakes) {
-            fakeCollection.fakes = [];
-        }
-
-        return fakeCollection.fakes;
-    }
-
-    function each(fakeCollection, method) {
-        var fakes = getFakes(fakeCollection);
-
-        for (var i = 0, l = fakes.length; i < l; i += 1) {
-            if (typeof fakes[i][method] == "function") {
-                fakes[i][method]();
-            }
-        }
-    }
-
-    function compact(fakeCollection) {
-        var fakes = getFakes(fakeCollection);
-        var i = 0;
-        while (i < fakes.length) {
-          fakes.splice(i, 1);
-        }
-    }
-
-    var collection = {
-        verify: function resolve() {
-            each(this, "verify");
-        },
-
-        restore: function restore() {
-            each(this, "restore");
-            compact(this);
-        },
-
-        verifyAndRestore: function verifyAndRestore() {
-            var exception;
-
-            try {
-                this.verify();
-            } catch (e) {
-                exception = e;
-            }
-
-            this.restore();
-
-            if (exception) {
-                throw exception;
-            }
-        },
-
-        add: function add(fake) {
-            push.call(getFakes(this), fake);
-            return fake;
-        },
-
-        spy: function spy() {
-            return this.add(sinon.spy.apply(sinon, arguments));
-        },
-
-        stub: function stub(object, property, value) {
-            if (property) {
-                var original = object[property];
-
-                if (typeof original != "function") {
-                    if (!object.hasOwnProperty(property)) {
-                        throw new TypeError("Cannot stub non-existent own property " + property);
-                    }
-
-                    object[property] = value;
-
-                    return this.add({
-                        restore: function () {
-                            object[property] = original;
-                        }
-                    });
-                }
-            }
-            if (!property && !!object && typeof object == "object") {
-                var stubbedObj = sinon.stub.apply(sinon, arguments);
-
-                for (var prop in stubbedObj) {
-                    if (typeof stubbedObj[prop] === "function") {
-                        this.add(stubbedObj[prop]);
-                    }
-                }
-
-                return stubbedObj;
-            }
-
-            return this.add(sinon.stub.apply(sinon, arguments));
-        },
-
-        mock: function mock() {
-            return this.add(sinon.mock.apply(sinon, arguments));
-        },
-
-        inject: function inject(obj) {
-            var col = this;
-
-            obj.spy = function () {
-                return col.spy.apply(col, arguments);
-            };
-
-            obj.stub = function () {
-                return col.stub.apply(col, arguments);
-            };
-
-            obj.mock = function () {
-                return col.mock.apply(col, arguments);
-            };
-
-            return obj;
-        }
-    };
-
-    if (commonJSModule) {
-        module.exports = collection;
-    } else {
-        sinon.collection = collection;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
-/*global module, require, window*/
-/**
- * Fake timer API
- * setTimeout
- * setInterval
- * clearTimeout
- * clearInterval
- * tick
- * reset
- * Date
- *
- * Inspired by jsUnitMockTimeOut from JsUnit
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    var sinon = {};
-}
-
-(function (global) {
-    var id = 1;
-
-    function addTimer(args, recurring) {
-        if (args.length === 0) {
-            throw new Error("Function requires at least 1 parameter");
-        }
-
-        var toId = id++;
-        var delay = args[1] || 0;
-
-        if (!this.timeouts) {
-            this.timeouts = {};
-        }
-
-        this.timeouts[toId] = {
-            id: toId,
-            func: args[0],
-            callAt: this.now + delay,
-            invokeArgs: Array.prototype.slice.call(args, 2)
-        };
-
-        if (recurring === true) {
-            this.timeouts[toId].interval = delay;
-        }
-
-        return toId;
-    }
-
-    function parseTime(str) {
-        if (!str) {
-            return 0;
-        }
-
-        var strings = str.split(":");
-        var l = strings.length, i = l;
-        var ms = 0, parsed;
-
-        if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
-            throw new Error("tick only understands numbers and 'h:m:s'");
-        }
-
-        while (i--) {
-            parsed = parseInt(strings[i], 10);
-
-            if (parsed >= 60) {
-                throw new Error("Invalid time " + str);
-            }
-
-            ms += parsed * Math.pow(60, (l - i - 1));
-        }
-
-        return ms * 1000;
-    }
-
-    function createObject(object) {
-        var newObject;
-
-        if (Object.create) {
-            newObject = Object.create(object);
-        } else {
-            var F = function () {};
-            F.prototype = object;
-            newObject = new F();
-        }
-
-        newObject.Date.clock = newObject;
-        return newObject;
-    }
-
-    sinon.clock = {
-        now: 0,
-
-        create: function create(now) {
-            var clock = createObject(this);
-
-            if (typeof now == "number") {
-                clock.now = now;
-            }
-
-            if (!!now && typeof now == "object") {
-                throw new TypeError("now should be milliseconds since UNIX epoch");
-            }
-
-            return clock;
-        },
-
-        setTimeout: function setTimeout(callback, timeout) {
-            return addTimer.call(this, arguments, false);
-        },
-
-        clearTimeout: function clearTimeout(timerId) {
-            if (!this.timeouts) {
-                this.timeouts = [];
-            }
-
-            if (timerId in this.timeouts) {
-                delete this.timeouts[timerId];
-            }
-        },
-
-        setInterval: function setInterval(callback, timeout) {
-            return addTimer.call(this, arguments, true);
-        },
-
-        clearInterval: function clearInterval(timerId) {
-            this.clearTimeout(timerId);
-        },
-
-        tick: function tick(ms) {
-            ms = typeof ms == "number" ? ms : parseTime(ms);
-            var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
-            var timer = this.firstTimerInRange(tickFrom, tickTo);
-
-            var firstException;
-            while (timer && tickFrom <= tickTo) {
-                if (this.timeouts[timer.id]) {
-                    tickFrom = this.now = timer.callAt;
-                    try {
-                      this.callTimer(timer);
-                    } catch (e) {
-                      firstException = firstException || e;
-                    }
-                }
-
-                timer = this.firstTimerInRange(previous, tickTo);
-                previous = tickFrom;
-            }
-
-            this.now = tickTo;
-
-            if (firstException) {
-              throw firstException;
-            }
-        },
-
-        firstTimerInRange: function (from, to) {
-            var timer, smallest, originalTimer;
-
-            for (var id in this.timeouts) {
-                if (this.timeouts.hasOwnProperty(id)) {
-                    if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
-                        continue;
-                    }
-
-                    if (!smallest || this.timeouts[id].callAt < smallest) {
-                        originalTimer = this.timeouts[id];
-                        smallest = this.timeouts[id].callAt;
-
-                        timer = {
-                            func: this.timeouts[id].func,
-                            callAt: this.timeouts[id].callAt,
-                            interval: this.timeouts[id].interval,
-                            id: this.timeouts[id].id,
-                            invokeArgs: this.timeouts[id].invokeArgs
-                        };
-                    }
-                }
-            }
-
-            return timer || null;
-        },
-
-        callTimer: function (timer) {
-            if (typeof timer.interval == "number") {
-                this.timeouts[timer.id].callAt += timer.interval;
-            } else {
-                delete this.timeouts[timer.id];
-            }
-
-            try {
-                if (typeof timer.func == "function") {
-                    timer.func.apply(null, timer.invokeArgs);
-                } else {
-                    eval(timer.func);
-                }
-            } catch (e) {
-              var exception = e;
-            }
-
-            if (!this.timeouts[timer.id]) {
-                if (exception) {
-                  throw exception;
-                }
-                return;
-            }
-
-            if (exception) {
-              throw exception;
-            }
-        },
-
-        reset: function reset() {
-            this.timeouts = {};
-        },
-
-        Date: (function () {
-            var NativeDate = Date;
-
-            function ClockDate(year, month, date, hour, minute, second, ms) {
-                // Defensive and verbose to avoid potential harm in passing
-                // explicit undefined when user does not pass argument
-                switch (arguments.length) {
-                case 0:
-                    return new NativeDate(ClockDate.clock.now);
-                case 1:
-                    return new NativeDate(year);
-                case 2:
-                    return new NativeDate(year, month);
-                case 3:
-                    return new NativeDate(year, month, date);
-                case 4:
-                    return new NativeDate(year, month, date, hour);
-                case 5:
-                    return new NativeDate(year, month, date, hour, minute);
-                case 6:
-                    return new NativeDate(year, month, date, hour, minute, second);
-                default:
-                    return new NativeDate(year, month, date, hour, minute, second, ms);
-                }
-            }
-
-            return mirrorDateProperties(ClockDate, NativeDate);
-        }())
-    };
-
-    function mirrorDateProperties(target, source) {
-        if (source.now) {
-            target.now = function now() {
-                return target.clock.now;
-            };
-        } else {
-            delete target.now;
-        }
-
-        if (source.toSource) {
-            target.toSource = function toSource() {
-                return source.toSource();
-            };
-        } else {
-            delete target.toSource;
-        }
-
-        target.toString = function toString() {
-            return source.toString();
-        };
-
-        target.prototype = source.prototype;
-        target.parse = source.parse;
-        target.UTC = source.UTC;
-        target.prototype.toUTCString = source.prototype.toUTCString;
-        return target;
-    }
-
-    var methods = ["Date", "setTimeout", "setInterval",
-                   "clearTimeout", "clearInterval"];
-
-    function restore() {
-        var method;
-
-        for (var i = 0, l = this.methods.length; i < l; i++) {
-            method = this.methods[i];
-            if (global[method].hadOwnProperty) {
-                global[method] = this["_" + method];
-            } else {
-                delete global[method];
-            }
-        }
-
-        // Prevent multiple executions which will completely remove these props
-        this.methods = [];
-    }
-
-    function stubGlobal(method, clock) {
-        clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
-        clock["_" + method] = global[method];
-
-        if (method == "Date") {
-            var date = mirrorDateProperties(clock[method], global[method]);
-            global[method] = date;
-        } else {
-            global[method] = function () {
-                return clock[method].apply(clock, arguments);
-            };
-
-            for (var prop in clock[method]) {
-                if (clock[method].hasOwnProperty(prop)) {
-                    global[method][prop] = clock[method][prop];
-                }
-            }
-        }
-
-        global[method].clock = clock;
-    }
-
-    sinon.useFakeTimers = function useFakeTimers(now) {
-        var clock = sinon.clock.create(now);
-        clock.restore = restore;
-        clock.methods = Array.prototype.slice.call(arguments,
-                                                   typeof now == "number" ? 1 : 0);
-
-        if (clock.methods.length === 0) {
-            clock.methods = methods;
-        }
-
-        for (var i = 0, l = clock.methods.length; i < l; i++) {
-            stubGlobal(clock.methods[i], clock);
-        }
-
-        return clock;
-    };
-}(typeof global != "undefined" && typeof global !== "function" ? global : this));
-
-sinon.timers = {
-    setTimeout: setTimeout,
-    clearTimeout: clearTimeout,
-    setInterval: setInterval,
-    clearInterval: clearInterval,
-    Date: Date
-};
-
-if (typeof module == "object" && typeof require == "function") {
-    module.exports = sinon;
-}
-
-/*jslint eqeqeq: false, onevar: false*/
-/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
-/**
- * Minimal Event interface implementation
- *
- * Original implementation by Sven Fuchs: https://gist.github.com/995028
- * Modifications and tests by Christian Johansen.
- *
- * @author Sven Fuchs (svenfuchs@artweb-design.de)
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2011 Sven Fuchs, Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    this.sinon = {};
-}
-
-(function () {
-    var push = [].push;
-
-    sinon.Event = function Event(type, bubbles, cancelable) {
-        this.initEvent(type, bubbles, cancelable);
-    };
-
-    sinon.Event.prototype = {
-        initEvent: function(type, bubbles, cancelable) {
-            this.type = type;
-            this.bubbles = bubbles;
-            this.cancelable = cancelable;
-        },
-
-        stopPropagation: function () {},
-
-        preventDefault: function () {
-            this.defaultPrevented = true;
-        }
-    };
-
-    sinon.EventTarget = {
-        addEventListener: function addEventListener(event, listener, useCapture) {
-            this.eventListeners = this.eventListeners || {};
-            this.eventListeners[event] = this.eventListeners[event] || [];
-            push.call(this.eventListeners[event], listener);
-        },
-
-        removeEventListener: function removeEventListener(event, listener, useCapture) {
-            var listeners = this.eventListeners && this.eventListeners[event] || [];
-
-            for (var i = 0, l = listeners.length; i < l; ++i) {
-                if (listeners[i] == listener) {
-                    return listeners.splice(i, 1);
-                }
-            }
-        },
-
-        dispatchEvent: function dispatchEvent(event) {
-            var type = event.type;
-            var listeners = this.eventListeners && this.eventListeners[type] || [];
-
-            for (var i = 0; i < listeners.length; i++) {
-                if (typeof listeners[i] == "function") {
-                    listeners[i].call(this, event);
-                } else {
-                    listeners[i].handleEvent(event);
-                }
-            }
-
-            return !!event.defaultPrevented;
-        }
-    };
-}());
-
-/**
- * @depend event.js
- */
-/*jslint eqeqeq: false, onevar: false*/
-/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
-/**
- * Fake XMLHttpRequest object
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    this.sinon = {};
-}
-sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
-
-// wrapper for global
-(function(global) {
-    var xhr = sinon.xhr;
-    xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
-    xhr.GlobalActiveXObject = global.ActiveXObject;
-    xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
-    xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
-    xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
-                                     ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
-
-    /*jsl:ignore*/
-    var unsafeHeaders = {
-        "Accept-Charset": true,
-        "Accept-Encoding": true,
-        "Connection": true,
-        "Content-Length": true,
-        "Cookie": true,
-        "Cookie2": true,
-        "Content-Transfer-Encoding": true,
-        "Date": true,
-        "Expect": true,
-        "Host": true,
-        "Keep-Alive": true,
-        "Referer": true,
-        "TE": true,
-        "Trailer": true,
-        "Transfer-Encoding": true,
-        "Upgrade": true,
-        "User-Agent": true,
-        "Via": true
-    };
-    /*jsl:end*/
-
-    function FakeXMLHttpRequest() {
-        this.readyState = FakeXMLHttpRequest.UNSENT;
-        this.requestHeaders = {};
-        this.requestBody = null;
-        this.status = 0;
-        this.statusText = "";
-
-        if (typeof FakeXMLHttpRequest.onCreate == "function") {
-            FakeXMLHttpRequest.onCreate(this);
-        }
-    }
-
-    function verifyState(xhr) {
-        if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
-            throw new Error("INVALID_STATE_ERR");
-        }
-
-        if (xhr.sendFlag) {
-            throw new Error("INVALID_STATE_ERR");
-        }
-    }
-
-    // filtering to enable a white-list version of Sinon FakeXhr,
-    // where whitelisted requests are passed through to real XHR
-    function each(collection, callback) {
-        if (!collection) return;
-        for (var i = 0, l = collection.length; i < l; i += 1) {
-            callback(collection[i]);
-        }
-    }
-    function some(collection, callback) {
-        for (var index = 0; index < collection.length; index++) {
-            if(callback(collection[index]) === true) return true;
-        };
-        return false;
-    }
-    // largest arity in XHR is 5 - XHR#open
-    var apply = function(obj,method,args) {
-        switch(args.length) {
-        case 0: return obj[method]();
-        case 1: return obj[method](args[0]);
-        case 2: return obj[method](args[0],args[1]);
-        case 3: return obj[method](args[0],args[1],args[2]);
-        case 4: return obj[method](args[0],args[1],args[2],args[3]);
-        case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
-        };
-    };
-
-    FakeXMLHttpRequest.filters = [];
-    FakeXMLHttpRequest.addFilter = function(fn) {
-        this.filters.push(fn)
-    };
-    var IE6Re = /MSIE 6/;
-    FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
-        var xhr = new sinon.xhr.workingXHR();
-        each(["open","setRequestHeader","send","abort","getResponseHeader",
-              "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
-             function(method) {
-                 fakeXhr[method] = function() {
-                   return apply(xhr,method,arguments);
-                 };
-             });
-
-        var copyAttrs = function(args) {
-            each(args, function(attr) {
-              try {
-                fakeXhr[attr] = xhr[attr]
-              } catch(e) {
-                if(!IE6Re.test(navigator.userAgent)) throw e;
-              }
-            });
-        };
-
-        var stateChange = function() {
-            fakeXhr.readyState = xhr.readyState;
-            if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                copyAttrs(["status","statusText"]);
-            }
-            if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
-                copyAttrs(["responseText"]);
-            }
-            if(xhr.readyState === FakeXMLHttpRequest.DONE) {
-                copyAttrs(["responseXML"]);
-            }
-            if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
-        };
-        if(xhr.addEventListener) {
-          for(var event in fakeXhr.eventListeners) {
-              if(fakeXhr.eventListeners.hasOwnProperty(event)) {
-                  each(fakeXhr.eventListeners[event],function(handler) {
-                      xhr.addEventListener(event, handler);
-                  });
-              }
-          }
-          xhr.addEventListener("readystatechange",stateChange);
-        } else {
-          xhr.onreadystatechange = stateChange;
-        }
-        apply(xhr,"open",xhrArgs);
-    };
-    FakeXMLHttpRequest.useFilters = false;
-
-    function verifyRequestSent(xhr) {
-        if (xhr.readyState == FakeXMLHttpRequest.DONE) {
-            throw new Error("Request done");
-        }
-    }
-
-    function verifyHeadersReceived(xhr) {
-        if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
-            throw new Error("No headers received");
-        }
-    }
-
-    function verifyResponseBodyType(body) {
-        if (typeof body != "string") {
-            var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
-                                 body + ", which is not a string.");
-            error.name = "InvalidBodyException";
-            throw error;
-        }
-    }
-
-    sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
-        async: true,
-
-        open: function open(method, url, async, username, password) {
-            this.method = method;
-            this.url = url;
-            this.async = typeof async == "boolean" ? async : true;
-            this.username = username;
-            this.password = password;
-            this.responseText = null;
-            this.responseXML = null;
-            this.requestHeaders = {};
-            this.sendFlag = false;
-            if(sinon.FakeXMLHttpRequest.useFilters === true) {
-                var xhrArgs = arguments;
-                var defake = some(FakeXMLHttpRequest.filters,function(filter) {
-                    return filter.apply(this,xhrArgs)
-                });
-                if (defake) {
-                  return sinon.FakeXMLHttpRequest.defake(this,arguments);
-                }
-            }
-            this.readyStateChange(FakeXMLHttpRequest.OPENED);
-        },
-
-        readyStateChange: function readyStateChange(state) {
-            this.readyState = state;
-
-            if (typeof this.onreadystatechange == "function") {
-                try {
-                    this.onreadystatechange();
-                } catch (e) {
-                    sinon.logError("Fake XHR onreadystatechange handler", e);
-                }
-            }
-
-            this.dispatchEvent(new sinon.Event("readystatechange"));
-        },
-
-        setRequestHeader: function setRequestHeader(header, value) {
-            verifyState(this);
-
-            if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
-                throw new Error("Refused to set unsafe header \"" + header + "\"");
-            }
-
-            if (this.requestHeaders[header]) {
-                this.requestHeaders[header] += "," + value;
-            } else {
-                this.requestHeaders[header] = value;
-            }
-        },
-
-        // Helps testing
-        setResponseHeaders: function setResponseHeaders(headers) {
-            this.responseHeaders = {};
-
-            for (var header in headers) {
-                if (headers.hasOwnProperty(header)) {
-                    this.responseHeaders[header] = headers[header];
-                }
-            }
-
-            if (this.async) {
-                this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
-            }
-        },
-
-        // Currently treats ALL data as a DOMString (i.e. no Document)
-        send: function send(data) {
-            verifyState(this);
-
-            if (!/^(get|head)$/i.test(this.method)) {
-                if (this.requestHeaders["Content-Type"]) {
-                    var value = this.requestHeaders["Content-Type"].split(";");
-                    this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
-                } else {
-                    this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
-                }
-
-                this.requestBody = data;
-            }
-
-            this.errorFlag = false;
-            this.sendFlag = this.async;
-            this.readyStateChange(FakeXMLHttpRequest.OPENED);
-
-            if (typeof this.onSend == "function") {
-                this.onSend(this);
-            }
-        },
-
-        abort: function abort() {
-            this.aborted = true;
-            this.responseText = null;
-            this.errorFlag = true;
-            this.requestHeaders = {};
-
-            if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
-                this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
-                this.sendFlag = false;
-            }
-
-            this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
-        },
-
-        getResponseHeader: function getResponseHeader(header) {
-            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                return null;
-            }
-
-            if (/^Set-Cookie2?$/i.test(header)) {
-                return null;
-            }
-
-            header = header.toLowerCase();
-
-            for (var h in this.responseHeaders) {
-                if (h.toLowerCase() == header) {
-                    return this.responseHeaders[h];
-                }
-            }
-
-            return null;
-        },
-
-        getAllResponseHeaders: function getAllResponseHeaders() {
-            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                return "";
-            }
-
-            var headers = "";
-
-            for (var header in this.responseHeaders) {
-                if (this.responseHeaders.hasOwnProperty(header) &&
-                    !/^Set-Cookie2?$/i.test(header)) {
-                    headers += header + ": " + this.responseHeaders[header] + "\r\n";
-                }
-            }
-
-            return headers;
-        },
-
-        setResponseBody: function setResponseBody(body) {
-            verifyRequestSent(this);
-            verifyHeadersReceived(this);
-            verifyResponseBodyType(body);
-
-            var chunkSize = this.chunkSize || 10;
-            var index = 0;
-            this.responseText = "";
-
-            do {
-                if (this.async) {
-                    this.readyStateChange(FakeXMLHttpRequest.LOADING);
-                }
-
-                this.responseText += body.substring(index, index + chunkSize);
-                index += chunkSize;
-            } while (index < body.length);
-
-            var type = this.getResponseHeader("Content-Type");
-
-            if (this.responseText &&
-                (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
-                try {
-                    this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
-                } catch (e) {
-                    // Unable to parse XML - no biggie
-                }
-            }
-
-            if (this.async) {
-                this.readyStateChange(FakeXMLHttpRequest.DONE);
-            } else {
-                this.readyState = FakeXMLHttpRequest.DONE;
-            }
-        },
-
-        respond: function respond(status, headers, body) {
-            this.setResponseHeaders(headers || {});
-            this.status = typeof status == "number" ? status : 200;
-            this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
-            this.setResponseBody(body || "");
-        }
-    });
-
-    sinon.extend(FakeXMLHttpRequest, {
-        UNSENT: 0,
-        OPENED: 1,
-        HEADERS_RECEIVED: 2,
-        LOADING: 3,
-        DONE: 4
-    });
-
-    // Borrowed from JSpec
-    FakeXMLHttpRequest.parseXML = function parseXML(text) {
-        var xmlDoc;
-
-        if (typeof DOMParser != "undefined") {
-            var parser = new DOMParser();
-            xmlDoc = parser.parseFromString(text, "text/xml");
-        } else {
-            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
-            xmlDoc.async = "false";
-            xmlDoc.loadXML(text);
-        }
-
-        return xmlDoc;
-    };
-
-    FakeXMLHttpRequest.statusCodes = {
-        100: "Continue",
-        101: "Switching Protocols",
-        200: "OK",
-        201: "Created",
-        202: "Accepted",
-        203: "Non-Authoritative Information",
-        204: "No Content",
-        205: "Reset Content",
-        206: "Partial Content",
-        300: "Multiple Choice",
-        301: "Moved Permanently",
-        302: "Found",
-        303: "See Other",
-        304: "Not Modified",
-        305: "Use Proxy",
-        307: "Temporary Redirect",
-        400: "Bad Request",
-        401: "Unauthorized",
-        402: "Payment Required",
-        403: "Forbidden",
-        404: "Not Found",
-        405: "Method Not Allowed",
-        406: "Not Acceptable",
-        407: "Proxy Authentication Required",
-        408: "Request Timeout",
-        409: "Conflict",
-        410: "Gone",
-        411: "Length Required",
-        412: "Precondition Failed",
-        413: "Request Entity Too Large",
-        414: "Request-URI Too Long",
-        415: "Unsupported Media Type",
-        416: "Requested Range Not Satisfiable",
-        417: "Expectation Failed",
-        422: "Unprocessable Entity",
-        500: "Internal Server Error",
-        501: "Not Implemented",
-        502: "Bad Gateway",
-        503: "Service Unavailable",
-        504: "Gateway Timeout",
-        505: "HTTP Version Not Supported"
-    };
-
-    sinon.useFakeXMLHttpRequest = function () {
-        sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
-            if (xhr.supportsXHR) {
-                global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
-            }
-
-            if (xhr.supportsActiveX) {
-                global.ActiveXObject = xhr.GlobalActiveXObject;
-            }
-
-            delete sinon.FakeXMLHttpRequest.restore;
-
-            if (keepOnCreate !== true) {
-                delete sinon.FakeXMLHttpRequest.onCreate;
-            }
-        };
-        if (xhr.supportsXHR) {
-            global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
-        }
-
-        if (xhr.supportsActiveX) {
-            global.ActiveXObject = function ActiveXObject(objId) {
-                if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
-
-                    return new sinon.FakeXMLHttpRequest();
-                }
-
-                return new xhr.GlobalActiveXObject(objId);
-            };
-        }
-
-        return sinon.FakeXMLHttpRequest;
-    };
-
-    sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
-})(this);
-
-if (typeof module == "object" && typeof require == "function") {
-    module.exports = sinon;
-}
-
-/**
- * @depend fake_xml_http_request.js
- */
-/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
-/*global module, require, window*/
-/**
- * The Sinon "server" mimics a web server that receives requests from
- * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
- * both synchronously and asynchronously. To respond synchronuously, canned
- * answers have to be provided upfront.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    var sinon = {};
-}
-
-sinon.fakeServer = (function () {
-    var push = [].push;
-    function F() {}
-
-    function create(proto) {
-        F.prototype = proto;
-        return new F();
-    }
-
-    function responseArray(handler) {
-        var response = handler;
-
-        if (Object.prototype.toString.call(handler) != "[object Array]") {
-            response = [200, {}, handler];
-        }
-
-        if (typeof response[2] != "string") {
-            throw new TypeError("Fake server response body should be string, but was " +
-                                typeof response[2]);
-        }
-
-        return response;
-    }
-
-    var wloc = typeof window !== "undefined" ? window.location : {};
-    var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
-
-    function matchOne(response, reqMethod, reqUrl) {
-        var rmeth = response.method;
-        var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
-        var url = response.url;
-        var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
-
-        return matchMethod && matchUrl;
-    }
-
-    function match(response, request) {
-        var requestMethod = this.getHTTPMethod(request);
-        var requestUrl = request.url;
-
-        if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
-            requestUrl = requestUrl.replace(rCurrLoc, "");
-        }
-
-        if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
-            if (typeof response.response == "function") {
-                var ru = response.url;
-                var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
-                return response.response.apply(response, args);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    return {
-        create: function () {
-            var server = create(this);
-            this.xhr = sinon.useFakeXMLHttpRequest();
-            server.requests = [];
-
-            this.xhr.onCreate = function (xhrObj) {
-                server.addRequest(xhrObj);
-            };
-
-            return server;
-        },
-
-        addRequest: function addRequest(xhrObj) {
-            var server = this;
-            push.call(this.requests, xhrObj);
-
-            xhrObj.onSend = function () {
-                server.handleRequest(this);
-            };
-
-            if (this.autoRespond && !this.responding) {
-                setTimeout(function () {
-                    server.responding = false;
-                    server.respond();
-                }, this.autoRespondAfter || 10);
-
-                this.responding = true;
-            }
-        },
-
-        getHTTPMethod: function getHTTPMethod(request) {
-            if (this.fakeHTTPMethods && /post/i.test(request.method)) {
-                var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
-                return !!matches ? matches[1] : request.method;
-            }
-
-            return request.method;
-        },
-
-        handleRequest: function handleRequest(xhr) {
-            if (xhr.async) {
-                if (!this.queue) {
-                    this.queue = [];
-                }
-
-                push.call(this.queue, xhr);
-            } else {
-                this.processRequest(xhr);
-            }
-        },
-
-        respondWith: function respondWith(method, url, body) {
-            if (arguments.length == 1 && typeof method != "function") {
-                this.response = responseArray(method);
-                return;
-            }
-
-            if (!this.responses) { this.responses = []; }
-
-            if (arguments.length == 1) {
-                body = method;
-                url = method = null;
-            }
-
-            if (arguments.length == 2) {
-                body = url;
-                url = method;
-                method = null;
-            }
-
-            push.call(this.responses, {
-                method: method,
-                url: url,
-                response: typeof body == "function" ? body : responseArray(body)
-            });
-        },
-
-        respond: function respond() {
-            if (arguments.length > 0) this.respondWith.apply(this, arguments);
-            var queue = this.queue || [];
-            var request;
-
-            while(request = queue.shift()) {
-                this.processRequest(request);
-            }
-        },
-
-        processRequest: function processRequest(request) {
-            try {
-                if (request.aborted) {
-                    return;
-                }
-
-                var response = this.response || [404, {}, ""];
-
-                if (this.responses) {
-                    for (var i = 0, l = this.responses.length; i < l; i++) {
-                        if (match.call(this, this.responses[i], request)) {
-                            response = this.responses[i].response;
-                            break;
-                        }
-                    }
-                }
-
-                if (request.readyState != 4) {
-                    request.respond(response[0], response[1], response[2]);
-                }
-            } catch (e) {
-                sinon.logError("Fake server request processing", e);
-            }
-        },
-
-        restore: function restore() {
-            return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
-        }
-    };
-}());
-
-if (typeof module == "object" && typeof require == "function") {
-    module.exports = sinon;
-}
-
-/**
- * @depend fake_server.js
- * @depend fake_timers.js
- */
-/*jslint browser: true, eqeqeq: false, onevar: false*/
-/*global sinon*/
-/**
- * Add-on for sinon.fakeServer that automatically handles a fake timer along with
- * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
- * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
- * it polls the object for completion with setInterval. Dispite the direct
- * motivation, there is nothing jQuery-specific in this file, so it can be used
- * in any environment where the ajax implementation depends on setInterval or
- * setTimeout.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function () {
-    function Server() {}
-    Server.prototype = sinon.fakeServer;
-
-    sinon.fakeServerWithClock = new Server();
-
-    sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
-        if (xhr.async) {
-            if (typeof setTimeout.clock == "object") {
-                this.clock = setTimeout.clock;
-            } else {
-                this.clock = sinon.useFakeTimers();
-                this.resetClock = true;
-            }
-
-            if (!this.longestTimeout) {
-                var clockSetTimeout = this.clock.setTimeout;
-                var clockSetInterval = this.clock.setInterval;
-                var server = this;
-
-                this.clock.setTimeout = function (fn, timeout) {
-                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
-
-                    return clockSetTimeout.apply(this, arguments);
-                };
-
-                this.clock.setInterval = function (fn, timeout) {
-                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
-
-                    return clockSetInterval.apply(this, arguments);
-                };
-            }
-        }
-
-        return sinon.fakeServer.addRequest.call(this, xhr);
-    };
-
-    sinon.fakeServerWithClock.respond = function respond() {
-        var returnVal = sinon.fakeServer.respond.apply(this, arguments);
-
-        if (this.clock) {
-            this.clock.tick(this.longestTimeout || 0);
-            this.longestTimeout = 0;
-
-            if (this.resetClock) {
-                this.clock.restore();
-                this.resetClock = false;
-            }
-        }
-
-        return returnVal;
-    };
-
-    sinon.fakeServerWithClock.restore = function restore() {
-        if (this.clock) {
-            this.clock.restore();
-        }
-
-        return sinon.fakeServer.restore.apply(this, arguments);
-    };
-}());
-
-/**
- * @depend ../sinon.js
- * @depend collection.js
- * @depend util/fake_timers.js
- * @depend util/fake_server_with_clock.js
- */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global require, module*/
-/**
- * Manages fake collections as well as fake utilities such as Sinon's
- * timers and fake XHR implementation in one convenient object.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-if (typeof module == "object" && typeof require == "function") {
-    var sinon = require("../sinon");
-    sinon.extend(sinon, require("./util/fake_timers"));
-}
-
-(function () {
-    var push = [].push;
-
-    function exposeValue(sandbox, config, key, value) {
-        if (!value) {
-            return;
-        }
-
-        if (config.injectInto) {
-            config.injectInto[key] = value;
-        } else {
-            push.call(sandbox.args, value);
-        }
-    }
-
-    function prepareSandboxFromConfig(config) {
-        var sandbox = sinon.create(sinon.sandbox);
-
-        if (config.useFakeServer) {
-            if (typeof config.useFakeServer == "object") {
-                sandbox.serverPrototype = config.useFakeServer;
-            }
-
-            sandbox.useFakeServer();
-        }
-
-        if (config.useFakeTimers) {
-            if (typeof config.useFakeTimers == "object") {
-                sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
-            } else {
-                sandbox.useFakeTimers();
-            }
-        }
-
-        return sandbox;
-    }
-
-    sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
-        useFakeTimers: function useFakeTimers() {
-            this.clock = sinon.useFakeTimers.apply(sinon, arguments);
-
-            return this.add(this.clock);
-        },
-
-        serverPrototype: sinon.fakeServer,
-
-        useFakeServer: function useFakeServer() {
-            var proto = this.serverPrototype || sinon.fakeServer;
-
-            if (!proto || !proto.create) {
-                return null;
-            }
-
-            this.server = proto.create();
-            return this.add(this.server);
-        },
-
-        inject: function (obj) {
-            sinon.collection.inject.call(this, obj);
-
-            if (this.clock) {
-                obj.clock = this.clock;
-            }
-
-            if (this.server) {
-                obj.server = this.server;
-                obj.requests = this.server.requests;
-            }
-
-            return obj;
-        },
-
-        create: function (config) {
-            if (!config) {
-                return sinon.create(sinon.sandbox);
-            }
-
-            var sandbox = prepareSandboxFromConfig(config);
-            sandbox.args = sandbox.args || [];
-            var prop, value, exposed = sandbox.inject({});
-
-            if (config.properties) {
-                for (var i = 0, l = config.properties.length; i < l; i++) {
-                    prop = config.properties[i];
-                    value = exposed[prop] || prop == "sandbox" && sandbox;
-                    exposeValue(sandbox, config, prop, value);
-                }
-            } else {
-                exposeValue(sandbox, config, "sandbox", value);
-            }
-
-            return sandbox;
-        }
-    });
-
-    sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
-
-    if (typeof module == "object" && typeof require == "function") {
-        module.exports = sinon.sandbox;
-    }
-}());
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- * @depend mock.js
- * @depend sandbox.js
- */
-/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Test function, sandboxes fakes
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function test(callback) {
-        var type = typeof callback;
-
-        if (type != "function") {
-            throw new TypeError("sinon.test needs to wrap a test function, got " + type);
-        }
-
-        return function () {
-            var config = sinon.getConfig(sinon.config);
-            config.injectInto = config.injectIntoThis && this || config.injectInto;
-            var sandbox = sinon.sandbox.create(config);
-            var exception, result;
-            var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
-
-            try {
-                result = callback.apply(this, args);
-            } finally {
-                sandbox.verifyAndRestore();
-            }
-
-            return result;
-        };
-    }
-
-    test.config = {
-        injectIntoThis: true,
-        injectInto: null,
-        properties: ["spy", "stub", "mock", "clock", "server", "requests"],
-        useFakeTimers: true,
-        useFakeServer: true
-    };
-
-    if (commonJSModule) {
-        module.exports = test;
-    } else {
-        sinon.test = test;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend test.js
- */
-/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
-/*global module, require, sinon*/
-/**
- * Test case, sandboxes all test functions
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon || !Object.prototype.hasOwnProperty) {
-        return;
-    }
-
-    function createTest(property, setUp, tearDown) {
-        return function () {
-            if (setUp) {
-                setUp.apply(this, arguments);
-            }
-
-            var exception, result;
-
-            try {
-                result = property.apply(this, arguments);
-            } catch (e) {
-                exception = e;
-            }
-
-            if (tearDown) {
-                tearDown.apply(this, arguments);
-            }
-
-            if (exception) {
-                throw exception;
-            }
-
-            return result;
-        };
-    }
-
-    function testCase(tests, prefix) {
-        /*jsl:ignore*/
-        if (!tests || typeof tests != "object") {
-            throw new TypeError("sinon.testCase needs an object with test functions");
-        }
-        /*jsl:end*/
-
-        prefix = prefix || "test";
-        var rPrefix = new RegExp("^" + prefix);
-        var methods = {}, testName, property, method;
-        var setUp = tests.setUp;
-        var tearDown = tests.tearDown;
-
-        for (testName in tests) {
-            if (tests.hasOwnProperty(testName)) {
-                property = tests[testName];
-
-                if (/^(setUp|tearDown)$/.test(testName)) {
-                    continue;
-                }
-
-                if (typeof property == "function" && rPrefix.test(testName)) {
-                    method = property;
-
-                    if (setUp || tearDown) {
-                        method = createTest(property, setUp, tearDown);
-                    }
-
-                    methods[testName] = sinon.test(method);
-                } else {
-                    methods[testName] = tests[testName];
-                }
-            }
-        }
-
-        return methods;
-    }
-
-    if (commonJSModule) {
-        module.exports = testCase;
-    } else {
-        sinon.testCase = testCase;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- */
-/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Assertions matching the test spy retrieval interface.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
-
-(function (sinon, global) {
-    var commonJSModule = typeof module == "object" && typeof require == "function";
-    var slice = Array.prototype.slice;
-    var assert;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function verifyIsStub() {
-        var method;
-
-        for (var i = 0, l = arguments.length; i < l; ++i) {
-            method = arguments[i];
-
-            if (!method) {
-                assert.fail("fake is not a spy");
-            }
-
-            if (typeof method != "function") {
-                assert.fail(method + " is not a function");
-            }
-
-            if (typeof method.getCall != "function") {
-                assert.fail(method + " is not stubbed");
-            }
-        }
-    }
-
-    function failAssertion(object, msg) {
-        object = object || global;
-        var failMethod = object.fail || assert.fail;
-        failMethod.call(object, msg);
-    }
-
-    function mirrorPropAsAssertion(name, method, message) {
-        if (arguments.length == 2) {
-            message = method;
-            method = name;
-        }
-
-        assert[name] = function (fake) {
-            verifyIsStub(fake);
-
-            var args = slice.call(arguments, 1);
-            var failed = false;
-
-            if (typeof method == "function") {
-                failed = !method(fake);
-            } else {
-                failed = typeof fake[method] == "function" ?
-                    !fake[method].apply(fake, args) : !fake[method];
-            }
-
-            if (failed) {
-                failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
-            } else {
-                assert.pass(name);
-            }
-        };
-    }
-
-    function exposedName(prefix, prop) {
-        return !prefix || /^fail/.test(prop) ? prop :
-            prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
-    };
-
-    assert = {
-        failException: "AssertError",
-
-        fail: function fail(message) {
-            var error = new Error(message);
-            error.name = this.failException || assert.failException;
-
-            throw error;
-        },
-
-        pass: function pass(assertion) {},
-
-        callOrder: function assertCallOrder() {
-            verifyIsStub.apply(null, arguments);
-            var expected = "", actual = "";
-
-            if (!sinon.calledInOrder(arguments)) {
-                try {
-                    expected = [].join.call(arguments, ", ");
-                    actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
-                } catch (e) {
-                    // If this fails, we'll just fall back to the blank string
-                }
-
-                failAssertion(this, "expected " + expected + " to be " +
-                              "called in order but were called as " + actual);
-            } else {
-                assert.pass("callOrder");
-            }
-        },
-
-        callCount: function assertCallCount(method, count) {
-            verifyIsStub(method);
-
-            if (method.callCount != count) {
-                var msg = "expected %n to be called " + sinon.timesInWords(count) +
-                    " but was called %c%C";
-                failAssertion(this, method.printf(msg));
-            } else {
-                assert.pass("callCount");
-            }
-        },
-
-        expose: function expose(target, options) {
-            if (!target) {
-                throw new TypeError("target is null or undefined");
-            }
-
-            var o = options || {};
-            var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
-            var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
-
-            for (var method in this) {
-                if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
-                    target[exposedName(prefix, method)] = this[method];
-                }
-            }
-
-            return target;
-        }
-    };
-
-    mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
-    mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
-                          "expected %n to not have been called but was called %c%C");
-    mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
-    mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
-    mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
-    mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
-    mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
-    mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
-    mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
-    mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
-    mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
-    mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
-    mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
-    mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
-    mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
-    mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
-    mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
-    mirrorPropAsAssertion("threw", "%n did not throw exception%C");
-    mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
-
-    if (commonJSModule) {
-        module.exports = assert;
-    } else {
-        sinon.assert = assert;
-    }
-}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));
-
-return sinon;}.call(typeof window != 'undefined' && window || {}));
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/buttons.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/buttons.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/buttons.html
+++ /dev/null
@@ -1,139 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Buttons &middot; Bootstrap</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-    <div class="container">
-
-      <h2>Dropups</h2>
-      <div class="btn-toolbar">
-        <div class="btn-group dropup">
-          <button class="btn">Dropup</button>
-          <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-primary">Dropup</button>
-          <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-danger">Dropup</button>
-          <button class="btn btn-danger dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-warning">Dropup</button>
-          <button class="btn btn-warning dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-success">Dropup</button>
-          <button class="btn btn-success dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-info">Dropup</button>
-          <button class="btn btn-info dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-inverse">Dropup</button>
-          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-      </div><!-- /btn-toolbar -->
-
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.css b/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.css
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.css
+++ /dev/null
@@ -1,150 +0,0 @@
-/*!
- * Bootstrap CSS Tests
- */
-
-
-/* Remove background image */
-body {
-  background-image: none;
-}
-
-/* Space out subhead */
-.subhead {
-  margin-bottom: 36px;
-}
-/*h4 {
-  margin-bottom: 5px;
-}
-*/
-
-.type-test {
-  margin-bottom: 20px;
-  padding: 0 20px 20px;
-  background: url(../../docs/assets/img/grid-baseline-20px.png);
-}
-.type-test h1,
-.type-test h2,
-.type-test h3,
-.type-test h4,
-.type-test h5,
-.type-test h6 {
-  background-color: rgba(255,0,0,.2);
-}
-
-
-/* colgroup tests */
-.col1 {
-  background-color: rgba(255,0,0,.1);
-}
-.col2 {
-  background-color: rgba(0,255,0,.1);
-}
-.col3 {
-  background-color: rgba(0,0,255,.1);
-}
-
-
-/* Fluid row inputs */
-#rowInputs .row > [class*=span],
-#fluidRowInputs .row-fluid > [class*=span] {
-  background-color: rgba(255,0,0,.1);
-}
-
-
-/* Fluid grid */
-.fluid-grid {
-  margin-bottom: 45px;
-}
-.fluid-grid .row {
-  height: 40px;
-  padding-top: 10px;
-  margin-top: 10px;
-  color: #ddd;
-  text-align: center;
-}
-.fluid-grid .span1 {
-  background-color: #999;
-}
-
-
-/* Gradients */
-
-[class^="gradient-"] {
-  width: 100%;
-  height: 400px;
-  margin: 20px 0;
-  -webkit-border-radius: 5px;
-     -moz-border-radius: 5px;
-          border-radius: 5px;
-}
-
-.gradient-horizontal {
-  background-color: #333333;
-  background-image: -moz-linear-gradient(left, #555555, #333333);
-  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#555555), to(#333333));
-  background-image: -webkit-linear-gradient(left, #555555, #333333);
-  background-image: -o-linear-gradient(left, #555555, #333333);
-  background-image: linear-gradient(to right, #555555, #333333);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff555555', endColorstr='#ff333333', GradientType=1);
-}
-
-.gradient-vertical {
-  background-color: #474747;
-  background-image: -moz-linear-gradient(top, #555555, #333333);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#333333));
-  background-image: -webkit-linear-gradient(top, #555555, #333333);
-  background-image: -o-linear-gradient(top, #555555, #333333);
-  background-image: linear-gradient(to bottom, #555555, #333333);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff555555', endColorstr='#ff333333', GradientType=0);
-}
-
-.gradient-directional {
-  background-color: #333333;
-  background-image: -moz-linear-gradient(45deg, #555555, #333333);
-  background-image: -webkit-linear-gradient(45deg, #555555, #333333);
-  background-image: -o-linear-gradient(45deg, #555555, #333333);
-  background-image: linear-gradient(45deg, #555555, #333333);
-  background-repeat: repeat-x;
-}
-
-.gradient-vertical-three {
-  background-color: #8940a5;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#00b3ee), color-stop(50%, #7a43b6), to(#c3325f));
-  background-image: -webkit-linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -moz-linear-gradient(top, #00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -o-linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-image: linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-repeat: no-repeat;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff00b3ee', endColorstr='#ffc3325f', GradientType=0);
-}
-
-.gradient-radial {
-  background-color: #333333;
-  background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(#555555), to(#333333));
-  background-image: -webkit-radial-gradient(circle, #555555, #333333);
-  background-image: -moz-radial-gradient(circle, #555555, #333333);
-  background-image: -o-radial-gradient(circle, #555555, #333333);
-  background-repeat: no-repeat;
-}
-
-.gradient-striped {
-  background-color: #555555;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-
-.gradient-horizontal-three {
-  background-color: #00b3ee;
-  background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(#00b3ee), color-stop(50%, #7a43b6), to(#c3325f));
-  background-image: -webkit-linear-gradient(left, #00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -moz-linear-gradient(left, #00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -o-linear-gradient(left, #00b3ee, #7a43b6 50%, #c3325f);
-  background-image: linear-gradient(to right, #00b3ee, #7a43b6 50%, #c3325f);
-  background-repeat: no-repeat;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00b3ee', endColorstr='#c3325f', GradientType=0);
-}
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/css-tests.html
+++ /dev/null
@@ -1,1399 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>CSS Tests · Twitter Bootstrap</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <link href="../../docs/assets/css/docs.css" rel="stylesheet">
-    <link href="../../docs/assets/js/google-code-prettify/prettify.css" rel="stylesheet">
-
-    <!-- CSS just for the tests page -->
-    <link href="css-tests.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-
-  <!-- Navbar
-    ================================================== -->
-    <div class="navbar navbar-inverse navbar-fixed-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="brand" href="../../docs/index.html">Bootstrap</a>
-        </div>
-      </div>
-    </div>
-
-
-<!-- Masthead
-================================================== -->
-<header class="jumbotron subhead" id="overview">
-  <div class="container">
-    <h1>CSS Tests</h1>
-    <p class="lead">One stop shop for quick debugging and edge-case tests of CSS.</p>
-  </div>
-</header>
-
-
-<div class="bs-docs-canvas">
-
-  <div class="container">
-
-
-
-<!-- Typography
-================================================== -->
-
-<div class="page-header">
-  <h1>Typography</h1>
-</div>
-
-<div class="row">
-  <div class="span6">
-    <div class="type-test">
-      <h1>h1. Heading 1</h1>
-      <h2>h2. Heading 2</h2>
-      <h3>h3. Heading 3</h3>
-      <h4>h4. Heading 4</h4>
-      <h5>h5. Heading 5</h5>
-      <h6>h6. Heading 6</h6>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-    </div>
-  </div>
-  <div class="span6">
-    <div class="type-test">
-      <h1>h1. Heading 1</h1>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h2>h2. Heading 2</h2>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h3>h3. Heading 3</h3>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h4>h4. Heading 4</h4>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h5>h5. Heading 5</h5>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h6>h6. Heading 6</h6>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-    </div>
-  </div>
-</div>
-
-
-
-<!-- Responsive images
-================================================== -->
-
-<div class="page-header">
-  <h1>Responsive images</h1>
-</div>
-
-<div class="row">
-  <div class="span4">
-    <img data-src="holder.js/600x600" height="200">
-  </div>
-  <div class="span4">
-    <img data-src="holder.js/600x600">
-  </div>
-  <div class="span4">
-    <img data-src="holder.js/600x600">
-  </div>
-</div>
-
-<br>
-
-<div class="row">
-  <div class="span4">
-    <img data-src="holder.js/600x900" style="width: 200px;">
-  </div>
-  <div class="span4">
-    <img data-src="holder.js/200x300">
-  </div>
-  <div class="span4">
-    <img data-src="holder.js/600x600">
-  </div>
-</div>
-
-<br><br>
-
-
-
-
-<!-- Fluid grid
-================================================== -->
-
-<div class="page-header">
-  <h1>Fluid grids</h1>
-</div>
-
-<div class="fluid-grid">
-  <div class="row">
-    <div class="span12">12
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span11">11
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span1">1
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span10">10
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span2">2
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span9">9
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span3">3
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span8">8
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span4">4
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span7">7
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span5">5
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span6">6
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span6">6
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-</div> <!-- fluid grids -->
-
-
-
-<!-- Tables
-================================================== -->
-
-<div class="page-header">
-  <h1>Tables</h1>
-</div>
-
-<div class="row">
-  <div class="span6">
-    <h4>Bordered without thead</h4>
-    <table class="table table-bordered">
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-    </table>
-    <h4>Bordered without thead, with caption</h4>
-    <table class="table table-bordered">
-      <caption>Table caption</caption>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-    </table>
-    <h4>Bordered without thead, with colgroup</h4>
-    <table class="table table-bordered">
-      <colgroup>
-        <col class="col1">
-        <col class="col2">
-        <col class="col3">
-      </colgroup>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-    <h4>Bordered with thead, with colgroup</h4>
-    <table class="table table-bordered">
-      <colgroup>
-        <col class="col1">
-        <col class="col2">
-        <col class="col3">
-      </colgroup>
-      <thead>
-        <tr>
-          <th>A</th>
-          <th>B</th>
-          <th>C</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-  </div><!--/span-->
-  <div class="span6">
-    <h4>Bordered with thead and caption</h4>
-    <table class="table table-bordered">
-      <caption>Table caption</caption>
-      <thead>
-        <tr>
-          <th>1</th>
-          <th>2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-    <h4>Bordered with rowspan and colspan</h4>
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th>1</th>
-          <th>2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div><!--/span-->
-</div><!--/row-->
-
-
-<h4>Grid sizing</h4>
-<div class="row">
-  <div class="span12">
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th class="span3">1</th>
-          <th class="span4">2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</div><!--/row-->
-
-<h4>Nesting and striping</h4>
-<table class="table table-bordered table-striped">
-  <thead>
-    <tr>
-      <th>Test</th>
-    </tr>
-  </thead>
-  <tbody>
-    <tr>
-      <td>
-        <table class="table table-bordered table-striped">
-          <thead>
-            <tr>
-              <th>Test</th>
-              <th>Test</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr>
-              <td>
-                test
-              </td>
-              <td>
-                test
-              </td>
-            </tr>
-            <tr>
-              <td>
-                test
-              </td>
-              <td>
-                test
-              </td>
-            </tr>
-            <tr>
-              <td>
-                test
-              </td>
-              <td>
-                test
-              </td>
-            </tr>
-          </tbody>
-        </table>
-      </td>
-    </tr>
-  </tbody>
-</table>
-
-<h4>Fluid grid sizing</h4>
-<div class="row-fluid">
-  <div class="span12">
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th class="span3">1</th>
-          <th class="span4">2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</div><!--/row-->
-
-
-
-<!-- Forms
-================================================== -->
-
-<div class="page-header">
-  <h1>Forms</h1>
-</div>
-
-<h4>Buttons and button groups</h4>
-<form class="form-inline">
-  <button class="btn btn-success">Save</button>
-  <button class="btn btn-info">Add new</button>
-  <div class="btn-group">
-    <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
-      <i class="fa fa-user"></i> User
-      <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Profile</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Sign Out</a></li>
-    </ul>
-  </div>
-</form>
-
-<h4>Horizontal form errors</h4>
-<form class="form-horizontal">
-  <div class="control-group error">
-    <label class="control-label" for="inputError">Radio with error</label>
-    <div class="controls">
-      <label class="radio">
-        <input type="radio" id="inputError"> Oh hai
-      </label>
-      <span class="help-inline">Please correct the error</span>
-    </div>
-  </div>
-</form>
-
-<div class="row">
-  <div class="span4">
-    <h4>Prepend and append on inputs</h4>
-    <form>
-      <div class="controls">
-        <div class="input-prepend">
-          <span class="add-on">@</span>
-          <input class="span2" id="prependedInput" size="16" type="text">
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-append">
-          <input class="span2" id="prependedInput" size="16" type="text">
-          <span class="add-on">@</span>
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-prepend input-append">
-          <span class="add-on">$</span>
-          <input class="span2" id="prependedInput" size="16" type="text">
-          <span class="add-on">.00</span>
-        </div>
-      </div>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <h4>Prepend and append with uneditable</h4>
-    <form>
-      <div class="input-prepend">
-        <span class="add-on">$</span>
-        <span class="span2 uneditable-input">Some value here</span>
-      </div>
-      <div class="input-append">
-        <span class="span2 uneditable-input">Some value here</span>
-        <span class="add-on">.00</span>
-      </div>
-      <div class="input-prepend input-append">
-        <span class="add-on">$</span>
-        <span class="span2 uneditable-input">Some value here</span>
-        <span class="add-on">.00</span>
-      </div>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <h4>Prepend with type="submit"</h4>
-    <form class="form-search">
-      <div class="input-append">
-        <input type="text" class="span2 search-query" value="" name="q">
-        <input type="submit" value="Search" class="btn">
-      </div>
-    </form>
-    <div class="input-append">
-      <input type="text" class="span2" value="" name="">
-      <input type="submit" value="Button" class="btn">
-    </div>
-    <div class="input-append">
-      <input type="text" size="16" id="appendedInputButtons" class="span2">
-      <input type="submit" value="Search" class="btn">
-      <button type="button" class="btn">Options</button>
-    </div>
-  </div><!--/span-->
-</div><!--/row-->
-
-<h4>Fluid prepended and appended inputs</h4>
-<div class="row-fluid">
-  <div class="span6">
-    <form>
-      <div class="controls">
-        <div class="input-prepend">
-          <span class="add-on">@</span><input class="span2" id="prependedInput" size="16" type="text">
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-append">
-          <input class="span2" id="prependedInput" size="16" type="text"><span class="add-on">@</span>
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-prepend input-append">
-          <span class="add-on">$</span><input class="span2" id="prependedInput" size="16" type="text"><span class="add-on">.00</span>
-        </div>
-      </div>
-    </form>
-  </div>
-</div>
-
-<h4>Fixed row with inputs</h4>
-<p>Inputs should not extend past the light red background, set on their parent, a <code>.span*</code> column.</p>
-
-<div class="rowInputs">
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span1" placeholder="span1">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span2" placeholder="span2">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span3" placeholder="span3">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span4" placeholder="span4">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span5" placeholder="span5">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span6" placeholder="span6">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span7" placeholder="span7">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span8" placeholder="span8">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span9" placeholder="span9">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span10" placeholder="span10">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span11" placeholder="span11">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span12" placeholder="span12">
-    </div><!--/span-->
-  </div><!--/row-->
-</div>
-<br>
-
-<h4>Fluid row with inputs</h4>
-<p>Inputs should not extend past the light red background, set on their parent, a <code>.span*</code> column.</p>
-<div id="fluidRowInputs">
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span1" placeholder="span1">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span2" placeholder="span2">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span3" placeholder="span3">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span4" placeholder="span4">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span5" placeholder="span5">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span6" placeholder="span6">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span7" placeholder="span7">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span8" placeholder="span8">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span9" placeholder="span9">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span10" placeholder="span10">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span11" placeholder="span11">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span12" placeholder="span12">
-    </div><!--/span-->
-  </div><!--/row-->
-</div>
-
-<br>
-
-<h4>Inline form in fluid row</h4>
-
-<div class="row-fluid">
-  <div class="span12">
-    <form class="form-inline">
-      <input type="text" class="span3" placeholder="Email">
-      <input type="password" class="span3" placeholder="Password">
-      <label class="checkbox">
-        <input type="checkbox"> Remember me
-      </label>
-      <button type="submit" class="btn">Sign in</button>
-    </form>
-  </div>
-</div>
-
-
-<br>
-
-
-<h4>Fluid textarea at .span12</h4>
-<div class="row-fluid">
-  <div class="span12">
-    <textarea class="span12"></textarea>
-  </div>
-</div>
-
-
-<br>
-
-
-<h4>Selects</h4>
-<form>
-  <select class="span4">
-    <option>Option</option>
-  </select>
-</form>
-
-
-<br>
-
-
-
-
-<!-- Dropdowns
-================================================== -->
-
-<div class="page-header">
-  <h1>Dropdowns</h1>
-</div>
-
-<h4>Dropdown link with hash URL</h4>
-<ul class="nav nav-pills">
-  <li class="active"><a href="#">Link</a></li>
-  <li><a href="#">Example link</a></li>
-  <li class="dropdown">
-    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
-      Dropdown <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Action</a></li>
-      <li><a href="#">Another action</a></li>
-      <li><a href="#">Something else here</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Separated link</a></li>
-    </ul>
-  </li>
-</ul>
-
-<h4>Dropdown link with custom URL and data-target</h4>
-<ul class="nav nav-pills">
-  <li class="active"><a href="#">Link</a></li>
-  <li><a href="#">Example link</a></li>
-  <li class="dropdown">
-    <a class="dropdown-toggle" data-toggle="dropdown" data-target="#" href="path/to/page.html">
-      Dropdown <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Action</a></li>
-      <li><a href="#">Another action</a></li>
-      <li><a href="#">Something else here</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Separated link</a></li>
-    </ul>
-  </li>
-</ul>
-
-<h4>Dropdown on a button</h4>
-<div style="position: relative;">
-  <button class="btn" type="button" data-toggle="dropdown">Dropdown <span class="caret"></span></button>
-  <ul class="dropdown-menu">
-    <li><a href="#">Action</a></li>
-    <li><a href="#">Another action</a></li>
-    <li><a href="#">Something else here</a></li>
-    <li class="divider"></li>
-    <li><a href="#">Separated link</a></li>
-  </ul>
-</div>
-
-<br>
-
-
-<!-- Thumbnails
-================================================== -->
-
-<div class="page-header">
-  <h1>Thumbnails</h1>
-</div>
-
-<h4>Default thumbnails (no grid sizing)</h4>
-<ul class="thumbnails">
-  <li class="thumbnail">
-    <img data-src="holder.js/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img data-src="holder.js/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img data-src="holder.js/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img data-src="holder.js/260x180" alt="">
-  </li>
-</ul>
-
-<!-- NOT CURRENTLY SUPPORTED
-<h4>Offset thumbnails</h4>
-<ul class="thumbnails">
-  <li class="span3 offset3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-</ul>
--->
-
-<h4>Standard grid sizing</h4>
-<ul class="thumbnails">
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3 offset3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img data-src="holder.js/260x180" alt="">
-    </a>
-  </li>
-</ul>
-
-<h4>Fluid thumbnails</h4>
-<div class="row-fluid">
-  <div class="span8">
-    <ul class="thumbnails">
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img data-src="holder.js/260x180" alt="">
-        </a>
-      </li>
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img data-src="holder.js/260x180" alt="">
-        </a>
-      </li>
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img data-src="holder.js/260x180" alt="">
-        </a>
-      </li>
-    </ul>
-  </div>
-</div>
-
-
-
-<!-- Tabs
-================================================== -->
-
-<div class="page-header">
-  <h1>Tabs</h1>
-</div>
-
-<div class="tabbable tabs-left" style="margin-bottom: 18px;">
-  <ul class="nav nav-tabs">
-    <li class="active"><a href="#tab1" data-toggle="tab">Section 1</a></li>
-    <li><a href="#tab2" data-toggle="tab">Section 2</a></li>
-    <li><a href="#tab3" data-toggle="tab">Section 3</a></li>
-  </ul>
-  <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
-    <div class="tab-pane active" id="tab1">
-      <p>I'm in Section 1.</p>
-
-      <div class="tabbable" style="background: #f5f5f5; padding: 20px;">
-        <ul class="nav nav-tabs">
-          <li class="active"><a href="#tab1-1" data-toggle="tab">1.1</a></li>
-          <li><a href="#tab1-2" data-toggle="tab">1.2</a></li>
-          <li><a href="#tab1-3" data-toggle="tab">1.3</a></li>
-        </ul>
-        <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
-          <div class="tab-pane active" id="tab1-1">
-            <p>I'm in Section 1.1.</p>
-          </div>
-          <div class="tab-pane" id="tab1-2">
-            <p>I'm in Section 1.2.</p>
-          </div>
-          <div class="tab-pane" id="tab1-3">
-            <p>I'm in Section 1.3.</p>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="tab-pane" id="tab2">
-      <p>Howdy, I'm in Section 2.</p>
-    </div>
-    <div class="tab-pane" id="tab3">
-      <p>What up girl, this is Section 3.</p>
-    </div>
-  </div>
-</div> <!-- /tabbable -->
-
-<br>
-
-
-<!-- Labels
-================================================== -->
-
-<div class="page-header">
-  <h1>Labels</h1>
-</div>
-
-<div class="row">
-  <div class="span4">
-    <h4>Inline label</h4>
-    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam <span class="label label-warning">Label name</span> eget risus varius blandit sit amet non magna. Fusce <code>.class-name</code> dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
-  </div><!--/span-->
-  <div class="span4">
-    <form class="form-horizontal">
-      <label>Example label</label>
-      <input type="text" placeholder="Input"> <span class="help-inline"><span class="label">Hey!</span> Read this.</span>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <button class="btn">Action <span class="badge">2</span></button>
-    <button class="btn">Action <span class="label">2</span></button>
-  </div><!--/span-->
-</div><!--/row-->
-
-<br>
-
-
-<!-- Button groups
-================================================== -->
-
-<div class="page-header">
-  <h1>Buttons</h1>
-</div>
-
-<table class="table table-bordered">
-  <tbody>
-    <tr>
-      <td>
-        Maecenas faucibus mollis interdum. Nulla vitae elit libero, a pharetra augue. Donec ullamcorper nulla non metus auctor fringilla. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
-      </td>
-      <td>
-        <div class="btn-group">
-          <button class="btn">1</button>
-          <button class="btn">2</button>
-          <button class="btn">3</button>
-          <button class="btn">4</button>
-        </div>
-      </td>
-    </tr>
-  </tbody>
-</table>
-
-<h4>Mini buttons: text and icon</h4>
-<div class="btn-group">
-  <button class="btn btn-mini">Button text</button>
-  <button class="btn btn-mini"><i class="fa fa-cog"></i></button>
-</div>
-
-<br>
-
-
-
-<!-- Responsive utility classes
-================================================== -->
-
-<div class="page-header">
-  <h1>Responsive utility classes</h1>
-</div>
-
-<h4>Visible on...</h4>
-<ul class="responsive-utilities-test visible-on">
-  <li>Phone<span class="visible-phone">✔ Phone</span></li>
-  <li>Tablet<span class="visible-tablet">✔ Tablet</span></li>
-  <li>Desktop<span class="visible-desktop">✔ Desktop</span></li>
-</ul>
-<ul class="responsive-utilities-test visible-on">
-  <li>Phone + Tablet<span class="visible-phone visible-tablet">✔ Phone + Tablet</span></li>
-  <li>Tablet + Desktop<span class="visible-tablet visible-desktop">✔ Tablet + Desktop</span></li>
-  <li>All<span class="visible-phone visible-tablet visible-desktop">✔ All</span></li>
-</ul>
-
-<h4>Hidden on...</h4>
-<ul class="responsive-utilities-test hidden-on">
-  <li>Phone<span class="hidden-phone">✔ Phone</span></li>
-  <li>Tablet<span class="hidden-tablet">✔ Tablet</span></li>
-  <li>Desktop<span class="hidden-desktop">✔ Desktop</span></li>
-</ul>
-<ul class="responsive-utilities-test hidden-on">
-  <li>Phone + Tablet<span class="hidden-phone hidden-tablet">✔ Phone + Tablet</span></li>
-  <li>Tablet + Desktop<span class="hidden-tablet hidden-desktop">✔ Tablet + Desktop</span></li>
-  <li>All<span class="hidden-phone hidden-tablet hidden-desktop">✔ All</span></li>
-</ul>
-
-
-
-<!-- Gradients
-================================================== -->
-
-<div class="page-header">
-  <h1>Gradients</h1>
-</div>
-
-<h4>Horizontal</h4>
-<div class="gradient-horizontal"></div>
-
-<h4>Vertical</h4>
-<div class="gradient-vertical"></div>
-
-<h4>Directional</h4>
-<div class="gradient-directional"></div>
-
-<h4>Three colors</h4>
-<div class="gradient-vertical-three"></div>
-
-<h4>Radial</h4>
-<div class="gradient-radial"></div>
-
-<h4>Striped</h4>
-<div class="gradient-striped"></div>
-
-<h4>Horizontal three colors</h4>
-<div class="gradient-horizontal-three"></div>
-
-
-
-<div class="page-header">
-  <h1>Alerts</h1>
-</div>
-
-<h4>Alert default</h4>
-<div class="alert">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <strong>Alert!</strong> Best check yourself, you're not looking too good.
-</div>
-<div class="alert alert-block">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <p><strong>Alert!</strong> Best check yourself, you're not looking too good.</p>
-</div>
-
-<h4>Success</h4>
-<div class="alert alert-success">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <strong>Success!</strong> Best check yourself, you're not looking too good.
-</div>
-<div class="alert alert-block alert-success">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <p><strong>Success!</strong> Best check yourself, you're not looking too good.</p>
-</div>
-
-<h4>Info</h4>
-<div class="alert alert-info">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <strong>Info!</strong> Best check yourself, you're not looking too good.
-</div>
-<div class="alert alert-block alert-info">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <p><strong>Info!</strong> Best check yourself, you're not looking too good.</p>
-</div>
-
-<h4>Warning</h4>
-<div class="alert ">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <strong>Warning!</strong> Best check yourself, you're not looking too good.
-</div>
-<div class="alert alert-block alert-warning">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <p><strong>Warning!</strong> Best check yourself, you're not looking too good.</p>
-</div>
-
-<h4>Error</h4>
-<div class="alert alert-error">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <strong>Error!</strong> Best check yourself, you're not looking too good.
-</div>
-<div class="alert alert-block alert-error">
-  <button type="button" class="close" data-dismiss="alert">&times;</button>
-  <p><strong>Error!</strong> Best check yourself, you're not looking too good.</p>
-</div>
-
-
-    </div><!-- /container -->
-
-
-
-    <!-- Footer
-    ================================================== -->
-    <footer class="footer">
-      <div class="container">
-        <p class="pull-right"><a href="#">Back to top</a></p>
-        <p>Designed and built with all the love in the world <a href="http://twitter.com/twitter" target="_blank">@twitter</a> by <a href="http://twitter.com/mdo" target="_blank">@mdo</a> and <a href="http://twitter.com/fat" target="_blank">@fat</a>.</p>
-        <p>Code licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License v2.0</a>. Documentation licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
-        <p>Icons from <a href="http://glyphicons.com">Glyphicons Free</a>, licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
-        <ul class="footer-links">
-          <li><a href="http://blog.getbootstrap.com">Read the blog</a></li>
-          <li><a href="https://github.com/twitter/bootstrap/issues?state=open">Submit issues</a></li>
-          <li><a href="https://github.com/twitter/bootstrap/wiki">Roadmap and changelog</a></li>
-        </ul>
-      </div>
-    </footer>
-
-</div>
-
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/google-code-prettify/prettify.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-    <script src="../../docs/assets/js/application.js"></script>
-
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms-responsive.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms-responsive.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms-responsive.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-    <form class="container">
-
-      <div class="page-header">
-        <h1>Fixed grid</h1>
-      </div>
-
-      <h3>Vertical alignment</h3>
-      <input type="text" class="span2" placeholder="span2">
-      <select class="span2"><option>span2</option></select>
-      <span class="uneditable-input span2">span1</span>
-
-      <h3>Width across elements</h3>
-      <div>
-        <input type="text" class="span2" placeholder="span2">
-      </div>
-      <div>
-        <select class="span2"><option>span2</option></select>
-      </div>
-      <div>
-        <span class="uneditable-input span2">span2</span>
-      </div>
-
-
-      <div class="page-header">
-        <h1>Fluid grid</h1>
-      </div>
-
-      <div class="row-fluid">
-        <input type="text" class="span2" placeholder="span2">
-        <select class="span2"><option>span2</option></select>
-        <span class="uneditable-input span2">span1</span>
-      </div>
-
-    </form> <!-- /container -->
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/forms.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <form class="container">
-
-      <div class="page-header">
-        <h1>Form controls</h1>
-      </div>
-
-      <div class="row">
-        <div class="span4">
-
-          <label>Select</label>
-          <select>
-            <option>Select</option>
-            <option>Option 2</option>
-            <option>Option 3</option>
-          </select>
-
-          <hr>
-
-          <label>textarea</label>
-          <textarea>Textarea</textarea>
-
-          <hr>
-
-          <label>text</label>
-          <input type="text" value="Text input">
-
-          <hr>
-
-          <label>password</label>
-          <input type="password" value="Password input">
-
-          <hr>
-
-          <label>checkbox</label>
-          <input type="checkbox" value="">
-
-          <hr>
-
-          <label>radio</label>
-          <input type="radio" value="">
-
-          <hr>
-
-          <label>button</label>
-          <input type="button" value="Button">
-
-          <hr>
-
-          <label>submit</label>
-          <input type="submit" value="Submit">
-
-          <hr>
-
-          <label>reset</label>
-          <input type="reset" value="Reset">
-
-        </div><!-- /span4 -->
-        <div class="span4">
-
-          <label>file</label>
-          <input type="file" value="">
-
-          <hr>
-
-          <label>hidden</label>
-          <input type="hidden" value="hidden">
-
-          <hr>
-
-          <label>image</label>
-          <input type="image" value="">
-
-          <hr>
-
-          <label>datetime</label>
-          <input type="datetime" value="">
-
-          <hr>
-
-          <label>datetime-local</label>
-          <input type="datetime-local" value="">
-
-          <hr>
-
-          <label>date</label>
-          <input type="date" value="">
-
-          <hr>
-
-          <label>month</label>
-          <input type="month" value="">
-
-          <hr>
-
-          <label>time</label>
-          <input type="time" value="">
-
-          <hr>
-
-          <label>week</label>
-          <input type="week" value="">
-
-        </div><!-- /span4 -->
-        <div class="span4">
-
-          <label>number</label>
-          <input type="number" value="">
-
-          <hr>
-
-          <label>range</label>
-          <input type="range" value="">
-
-          <hr>
-
-          <label>email</label>
-          <input type="email" value="">
-
-          <hr>
-
-          <label>url</label>
-          <input type="url" value="">
-
-          <hr>
-
-          <label>search</label>
-          <input type="search" value="">
-
-          <hr>
-
-          <label>tel</label>
-          <input type="tel" value="">
-
-          <hr>
-
-          <label>color</label>
-          <input type="color" value="">
-
-        </div><!-- /span4 -->
-      </div><!-- /row -->
-
-    </form> <!-- /container -->
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-fixed-top.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-fixed-top.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-fixed-top.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 60px;
-        padding-bottom: 30px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-    <!-- Fixed navbar -->
-    <div class="navbar navbar-fixed-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-            <span class="fa-bar"></span>
-            <span class="fa-bar"></span>
-            <span class="fa-bar"></span>
-          </a>
-          <a class="brand" href="#">Project name</a>
-          <div class="nav-collapse collapse">
-            <ul class="nav">
-              <li class="active"><a href="#">Home</a></li>
-              <li><a href="#about">About</a></li>
-              <li><a href="#contact">Contact</a></li>
-              <li class="dropdown">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                <ul class="dropdown-menu">
-                  <li><a href="#">Action</a></li>
-                  <li><a href="#">Another action</a></li>
-                  <li><a href="#">Something else here</a></li>
-                  <li class="divider"></li>
-                  <li class="nav-header">Nav header</li>
-                  <li><a href="#">Separated link</a></li>
-                  <li><a href="#">One more separated link</a></li>
-                </ul>
-              </li>
-            </ul>
-            <ul class="nav pull-right">
-              <li><a href="./navbar.html">Default</a></li>
-              <li><a href="./navbar-static-top.html">Static top</a></li>
-              <li class="active"><a href="./navbar-fixed-top.html">Fixed top</a></li>
-            </ul>
-          </div><!--/.nav-collapse -->
-        </div>
-      </div>
-    </div>
-
-    <div class="container">
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-static-top.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-static-top.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar-static-top.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-bottom: 30px;
-      }
-      .hero-unit {
-        margin-top: 20px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-    <!-- Static navbar -->
-    <div class="navbar navbar-static-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-            <span class="fa-bar"></span>
-            <span class="fa-bar"></span>
-            <span class="fa-bar"></span>
-          </a>
-          <a class="brand" href="#">Project name</a>
-          <div class="nav-collapse collapse">
-            <ul class="nav">
-              <li class="active"><a href="#">Home</a></li>
-              <li><a href="#about">About</a></li>
-              <li><a href="#contact">Contact</a></li>
-              <li class="dropdown">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                <ul class="dropdown-menu">
-                  <li><a href="#">Action</a></li>
-                  <li><a href="#">Another action</a></li>
-                  <li><a href="#">Something else here</a></li>
-                  <li class="divider"></li>
-                  <li class="nav-header">Nav header</li>
-                  <li><a href="#">Separated link</a></li>
-                  <li><a href="#">One more separated link</a></li>
-                </ul>
-              </li>
-            </ul>
-          <ul class="nav pull-right">
-            <li><a href="./navbar.html">Default</a></li>
-            <li class="active"><a href="./navbar-static-top.html">Static top</a></li>
-            <li><a href="./navbar-fixed-top.html">Fixed top</a></li>
-          </ul>
-          </div><!--/.nav-collapse -->
-        </div>
-      </div>
-    </div>
-
-
-    <div class="container">
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>
diff --git a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar.html b/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar.html
deleted file mode 100755
--- a/ckan/public-bs2/base/vendor/bootstrap/less/tests/navbar.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 0;
-        padding-bottom: 30px;
-      }
-      .navbar {
-        margin-top: 20px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-                    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-                                   <link rel="shortcut icon" href="../../docs/assets/ico/favicon.png">
-  </head>
-
-  <body>
-
-    <div class="container">
-
-      <!-- Static navbar -->
-      <div class="navbar">
-        <div class="navbar-inner">
-          <div class="container">
-            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-              <span class="fa-bar"></span>
-              <span class="fa-bar"></span>
-              <span class="fa-bar"></span>
-            </a>
-            <a class="brand" href="#">Project name</a>
-            <div class="nav-collapse collapse">
-              <ul class="nav">
-                <li class="active"><a href="#">Home</a></li>
-                <li><a href="#about">About</a></li>
-                <li><a href="#contact">Contact</a></li>
-                <li class="dropdown">
-                  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                  <ul class="dropdown-menu">
-                    <li><a href="#">Action</a></li>
-                    <li><a href="#">Another action</a></li>
-                    <li><a href="#">Something else here</a></li>
-                    <li class="divider"></li>
-                    <li class="nav-header">Nav header</li>
-                    <li><a href="#">Separated link</a></li>
-                    <li><a href="#">One more separated link</a></li>
-                  </ul>
-                </li>
-              </ul>
-              <ul class="nav pull-right">
-                <li class="active"><a href="./navbar.html">Default</a></li>
-                <li><a href="./navbar-static-top.html">Static top</a></li>
-                <li><a href="./navbar-fixed-top.html">Fixed top</a></li>
-              </ul>
-            </div><!--/.nav-collapse -->
-          </div>
-        </div>
-      </div>
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>
diff --git a/ckan/templates-bs2/tests/broken_helper_as_attribute.html b/ckan/templates-bs2/tests/broken_helper_as_attribute.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/broken_helper_as_attribute.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends 'page.html' %}
-
-{% block page %}
-    {{ h.not_here() }}
-{% endblock %}
diff --git a/ckan/templates-bs2/tests/broken_helper_as_item.html b/ckan/templates-bs2/tests/broken_helper_as_item.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/broken_helper_as_item.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends 'page.html' %}
-
-{% block page %}
-    {{ h['not_here']() }}
-{% endblock %}
diff --git a/ckan/templates-bs2/tests/flash_messages.html b/ckan/templates-bs2/tests/flash_messages.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/flash_messages.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Hello</title>
-    </head>
-    <body>
-        Flash messages:
-        {% for message in h.flash.pop_messages() | list %}
-          <div>
-            {{ message.category }}: {{ h.literal(message) }}
-          </div>
-        {% endfor %}
-    </body>
-</html>
diff --git a/ckan/templates-bs2/tests/helper_as_attribute.html b/ckan/templates-bs2/tests/helper_as_attribute.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/helper_as_attribute.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends 'page.html' %}
-
-{% block page %}
-    My lang is: {{ h.lang() }}
-{% endblock %}
diff --git a/ckan/templates-bs2/tests/helper_as_item.html b/ckan/templates-bs2/tests/helper_as_item.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/helper_as_item.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends 'page.html' %}
-
-{% block page %}
-    My lang is: {{ h['lang']() }}
-{% endblock %}
diff --git a/ckan/templates-bs2/tests/mock_json_resource_preview_template.html b/ckan/templates-bs2/tests/mock_json_resource_preview_template.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/mock_json_resource_preview_template.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends 'dataviewer/base.html' %}
-
-{% block page %}
-  <div>
-    <pre data-module="mock-json-preview">
-      <div class="loading">
-        {{ _('Loading...') }}
-      </div>
-    </pre>
-  </div>
-{% endblock %}
-
-{% block scripts %}
-  {{ super() }}
-
-  <script src="mock-json-preview.js"></script>
-{% endblock %}
diff --git a/ckan/templates-bs2/tests/mock_resource_preview_template.html b/ckan/templates-bs2/tests/mock_resource_preview_template.html
deleted file mode 100644
--- a/ckan/templates-bs2/tests/mock_resource_preview_template.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends 'dataviewer/base.html' %}
-
-{% block page %}
-  <div>
-    <pre data-module="mock-preview">
-      <div class="loading">
-        {{ _('Loading...') }}
-      </div>
-    </pre>
-  </div>
-{% endblock %}
-
-{% block scripts %}
-  {{ super() }}
-
-  <script src="mock-preview.js"></script>
-{% endblock %}