diff --git a/dev/demo/about.html b/dev/demo/about.html
index 9dd3c29..ee41571 100644
--- a/dev/demo/about.html
+++ b/dev/demo/about.html
@@ -1,10 +1,9 @@
- <!DOCTYPE html>
+<!DOCTYPE html>
 <html>
   <head>
     <title>Tutorial demo</title>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
-    <script src="../js/src/session.js"></script>
-    <script src="../js/src/tutorial.js"></script>
+    <script data-main="all.js" src="../js/lib/require.js" async="async"></script>
   </head>
   <body class="embedded">
     <div id="sidebar" tabindex="0" class="active">
@@ -14,13 +13,14 @@
 -->
 	<nav>
 	  <ul>
-	    <li><a href="/doc/korap">KorAP</a>
+	    <li><a href="/doc/korap" class="active">KorAP</a>
 	      <ul>
-		<li><a href="/doc/kalamar" class="active">Kalamar</a></li>
-		<li><a href="/doc/koral">Koral</a></li>
+		<!-- Versionsnummer -->
+		<li><a href="/doc/kalamar">Kalamar</a></li>
 		<li><a href="/doc/kustvakt">Kustvakt</a></li>
+		<li><a href="/doc/koral">Koral</a></li>
 		<li><a href="/doc/krill">Krill</a></li>
-		<!-- <li>Karang</li> -->
+		<li><a href="/doc/karang">Karang</a></li>
 	      </ul>
 	    </li>
 	    <li><a href="/doc/ql">Query Languages</a>
@@ -58,12 +58,19 @@
 	      </ul>
 -->
 	    </li>
+	    <li><a href="/doc/faq">FAQ</a>
 	  </ul>
 	</nav>
       </div>
     </div>
     <main class="tutorial">
-      <h2>KorAP-Tutorial</h2>
+      <h2>KorAP</h2>
+
+      <object data="../img/korap-overview.svg#korap"
+	      type="image/svg+xml"
+	      alt="KorAP-Overview"
+	      id="overview"></object>
+
       <section id="tut-intro">
 	<h3>Frontend Features</h3>
 	<p>This frontend ...</p>
diff --git a/dev/demo/all.html b/dev/demo/all.html
index a1a4cae..fcd72a5 100644
--- a/dev/demo/all.html
+++ b/dev/demo/all.html
@@ -1,14 +1,19 @@
  <!DOCTYPE html>
 <html>
   <head>
-    <title>CSS demo</title>
+    <title>Complete Demo</title>
     <meta charset="utf-8" />
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
+    <script data-main="all.js" src="../js/lib/require.js" async="async"></script>
   </head>
   <body>
     <div id="kalamar-bg"></div>
     <header>
       <a href="/" class="logo"><h1><span>KorAP - Corpus Analysis Platform</span></h1></a>
+
+      <a href="#">Feedback</a>
+      <a href="#">Login</a>
+
       <form autocomplete="off" action="/kalamar">
 	<div id="searchbar">
 	  <input type="search"
@@ -46,8 +51,12 @@
     </header>
 
     <div id="sidebar" tabindex="0">
-      <h2>Tutorial</h2>
-      <p>Hui</p>
+      <h2>Einstellungen</h2>
+      <p>Anzahl Treffer pro Seite</p>
+      <p>Kontext:</p>
+      <p>200 Zeichen/Token - 200 Zeichen/Token</p>
+      <p>1 Satz 1 Paragraph</p>
+      <a>Deutsch|Englisch</a>
     </div>
 
     <main>
@@ -142,20 +151,13 @@
 
     <footer>
       <a href="/doc/KorAP">About</a>
+      <a href="http://korap.ids-mannheim.de/">About</a>
+      <a href="#">V 0.14</a>
     </footer>
 
-    <script src="../js/lib/dagre/dagre.min.js"></script>
-    <script src="../js/src/api.js"></script>
-    <script src="../js/src/hint.js"></script>
-    <script src="../js/src/match.js"></script>
-    <script src="../js/src/menu.js"></script>
-    <script src="../js/src/vc.js"></script>
-    <script src="../js/src/session.js"></script>
-    <script src="../js/src/tutorial.js"></script>
-    <script src="../js/src/init.js"></script>
     <script>
+      var KorAP = KorAP || {};
       KorAP.URL = 'http://localhost:3000';
     </script>
-    <script src="./all.js"></script>
   </body>
 </html>
diff --git a/dev/demo/all.js b/dev/demo/all.js
index 5ce1266..29dd405 100644
--- a/dev/demo/all.js
+++ b/dev/demo/all.js
@@ -271,8 +271,7 @@
   ]
 };
 
-
-KorAP.hintArray = {
+var hintArray = {
   "-" : [
     ["Connexor",   "cnx/",     "Constituency, Lemma, Morphology, Part-of-Speech, Syntax"],
     ["CoreNLP",    "corenlp/", "Named Entities"],
@@ -417,44 +416,48 @@
   ]
 };
 
-// Parse and show the table
-// Override getMatchInfo API call
-KorAP.API.getMatchInfo = function(match, callObj, cb) {
-  if (callObj["spans"] !== undefined && callObj["spans"] === true) {
-    cb({ "snippet": treeSnippet2 });
+
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
   }
-  else {
-    cb({ "snippet": snippet });
-  }
-};
+});
 
+require(['init'], function (init) {
 
-/**
- * Do some things at the beginning.
- */
-document.addEventListener('DOMContentLoaded', function () {
+  KorAP.hintArray = hintArray;
 
-  // Decorate actions
-  var init = KorAP.init();
+  // Parse and show the table
+  // Override getMatchInfo API call
+  KorAP.API.getMatchInfo = function(match, callObj, cb) {
+    if (callObj["spans"] !== undefined && callObj["spans"] === true) {
+      cb({ "snippet": treeSnippet2 });
+    }
+    else {
+      cb({ "snippet": snippet });
+    }
+  };
+
+  /**
+   * Do some things at the beginning.
+   */
 
   // document.getElementById('vc-choose').click();
-
   // init.tutorial.show();
 
-/*
+  /*
+    KorAP.HintMenu.hide = function () {};
+    init.hint.show();
 
-  KorAP.HintMenu.hide = function () {};
-  init.hint.show();
-
-
-  var menu = KorAP.MatchTreeMenu.create(
-    undefined,
-    menuContent
-  );
-  menu.hide = function () {};
-  document.getElementById('menu').appendChild(menu.element());
-  menu.limit(3);
-  menu.show();
-  menu.focus();
-*/
+    var menu = KorAP.MatchTreeMenu.create(
+      undefined,
+      menuContent
+    );
+    menu.hide = function () {};
+    document.getElementById('menu').appendChild(menu.element());
+    menu.limit(3);
+    menu.show();
+    menu.focus();
+  */
 });
diff --git a/dev/demo/hint.html b/dev/demo/hint.html
index 240f370..7d93d73 100644
--- a/dev/demo/hint.html
+++ b/dev/demo/hint.html
@@ -3,229 +3,8 @@
   <head>
     <title>Hint demo</title>
     <meta charset="utf-8" />
-    <script src="../js/src/menu.js"></script>
-    <script src="../js/src/hint.js"></script>
+    <script data-main="hintdemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
-    <script>
-// http://www.nlpado.de/~sebastian/software/ner_german.shtml
-// http://www.cnts.ua.ac.be/conll2003/ner/
-var namedEntities = [
-  ["I-LOC",  "I-LOC ",  "Location"],
-  ["I-MISC", "I-MISC ", "Miscellaneous"],
-  ["I-ORG",  "I-ORG ",  "Organization"],
-  ["I-PER",  "I-PER ",  "Person"]
-];
-
-// http://www.ids-mannheim.de/cosmas2/projekt/referenz/stts/morph.html
-// http://nachhalt.sfb632.uni-potsdam.de/owl-docu/stts.html
-var sttsArray = [
-  // "$.", "$(", "$,"
-  ["ADJA","ADJA ", "Attributive Adjective"],
-  ["ADJD","ADJD ", "Predicative Adjective"],
-  ["ADV","ADV ", "Adverb"],
-  ["APPO","APPO ", "Postposition"],
-  ["APPR","APPR ", "Preposition"],
-  ["APPRART","APPRART ", "Preposition with Determiner"],
-  ["APZR","APZR ","Right Circumposition"],
-  ["ART","ART ", "Determiner"],
-  ["CARD","CARD ", "Cardinal Number"],
-  ["FM","FM ", "Foreign Material"],
-  ["ITJ","ITJ ", "Interjection"],
-  ["KOKOM","KOKOM ", "Comparison Particle"],
-  ["KON","KON ", "Coordinating Conjuncion"],
-  ["KOUI","KOUI ", "Subordinating Conjunction with 'zu'"],
-  ["KOUS","KOUS ", "Subordinating Conjunction with Sentence"],
-  ["NE","NE ", "Named Entity"],
-  ["NN","NN ", "Normal Nomina"],
-  ["PAV", "PAV ", "Pronominal Adverb"],
-  ["PDAT","PDAT ","Attributive Demonstrative Pronoun"],
-  ["PDS","PDS ", "Substitutive Demonstrative Pronoun"],
-  ["PIAT","PIAT ", "Attributive Indefinite Pronoun without Determiner"],
-  ["PIDAT","PIDAT ", "Attributive Indefinite Pronoun with Determiner"],
-  ["PIS","PIS ", "Substitutive Indefinite Pronoun"],
-  ["PPER","PPER ", "Personal Pronoun"],
-  ["PPOSAT","PPOSAT ", "Attributive Possessive Pronoun"],
-  ["PPOSS","PPOSS ", "Substitutive Possessive Pronoun"],
-  ["PRELAT","PRELAT ", "Attributive Relative Pronoun"],
-  ["PRELS","PRELS ", "Substitutive Relative Pronoun"],
-  ["PRF","PRF ", "Reflexive Pronoun"],
-  ["PROAV","PROAV ", "Pronominal Adverb"],
-  ["PTKA","PTKA ","Particle with Adjective"],
-  ["PTKANT","PTKANT ", "Answering Particle"],
-  ["PTKNEG","PTKNEG ", "Negation Particle"],
-  ["PTKVZ","PTKVZ ", "Separated Verbal Particle"],
-  ["PTKZU","PTKZU ", "'zu' Particle"],
-  ["PWAT","PWAT ", "Attributive Interrogative Pronoun"],
-  ["PWAV","PWAV ", "Adverbial Interrogative Pronoun"],
-  ["PWS","PWS ", "Substitutive Interrogative Pronoun"],
-  ["TRUNC","TRUNC ","Truncated"],
-  ["VAFIN","VAFIN ", "Auxiliary Finite Verb"],
-  ["VAINF","VAINF ", "Auxiliary Infinite Verb"],
-  ["VAIMP","VAIMP ", "Auxiliary Finite Imperative Verb"],
-  ["VAPP","VAPP ", "Auxiliary Perfect Participle"],
-  ["VMFIN","VMFIN ", "Modal Finite Verb"],
-  ["VMINF","VMINF ", "Modal Infinite Verb"],
-  ["VMPP","VMPP ", "Modal Perfect Participle"],
-  ["VVFIN","VVFIN ","Finite Verb"],
-  ["VVIMP","VVIMP ", "Finite Imperative Verb"],
-  ["VVINF","VVINF ", "Infinite Verb"],
-  ["VVIZU","VVIZU ", "Infinite Verb with 'zu'"],
-  ["VVPP","VVPP ", "Perfect Participle"],
-  ["XY", "XY ", "Non-Word"]
-];
-
-var mateSttsArray = sttsArray.slice(0);
-mateSttsArray.push(
-  ["<root-POS>","<root-POS>","Root Part of Speech"]
-);
-
-
-var hintArray = {
-  "-" : [
-    ["Connexor",   "cnx/",     "Constituency, Lemma, Morphology, Part-of-Speech, Syntax"],
-    ["CoreNLP",    "corenlp/", "Named Entities"],
-    ["Mate",       "mate/",     "Lemma, Morphology, Part-of-Speech"],
-    ["OpenNLP",    "opennlp/", "Part-of-Speech"],
-    ["TreeTagger", "tt/",      "Lemma, Part-of-Speech"],
-    ["Xerox Parser", "xip/",   "Constituency, Lemma, Part-of-Speech"]
-  ],
-  "corenlp/" : [
-    ["Named Entity", "ne=" , "Combined"],
-    ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
-    ["Named Entity", "ne_hgc_175m_600=",    "ne_hgc_175m_600"]
-  ],
-  "corenlp/ne=" : namedEntities,
-  "corenlp/ne_dewac_175m_600=" : namedEntities,
-  "corenlp/ne_hgc_175m_600=" : namedEntities,
-  "cnx/" : [
-    ["Constituency", "c="],
-    ["Lemma", "l="],
-    ["Morphology", "m="],
-    ["Part-of-Speech", "p="],
-    ["Syntax", "syn="]
-  ],
-  "cnx/c=" : [
-    ["np", "np ", "Nominal Phrase"]
-  ],
-  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
-  "cnx/m=" : [
-    ["Abbr","Abbr ", "Nouns: Abbreviation"],
-    ["CMP","CMP ", "Adjective: Comparative"],
-    ["IMP", "IMP ", "Mood: Imperative"],
-    ["IND", "IND ", "Mood: Indicative"],
-    ["INF", "INF ", "Infinitive"],
-    ["ORD","ORD ", "Numeral: Ordinal"],
-    ["PAST", "PAST ", "Tense: past"],
-    ["PCP", "PCP ", "Participle"],
-    ["PERF", "PERF ", "Perfective Participle"],
-    ["PL","PL ", "Nouns: Plural"],
-    ["PRES", "PRES ", "Tense: present"],
-    ["PROG", "PROG ", "Progressive Participle"],
-    ["Prop","Prop ", "Nouns: Proper Noun"],
-    ["SUB", "SUB ", "Mood: Subjunctive"],
-    ["SUP","SUP ", "Adjective: Superlative"]
-  ],
-  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
-  "cnx/p=" : [
-    ["A", "A ", "Adjective"],
-    ["ADV", "ADV ", "Adverb"],
-    ["CC", "CC ", "Coordination Marker"],
-    ["CS", "CS ", "Clause Marker"],
-    ["DET", "DET ", "Determiner"],
-    ["INTERJ", "INTERJ ", "Interjection"],
-    ["N", "N ", "Noun"],
-    ["NUM", "NUM ", "Numeral"],
-    ["PREP", "PREP ", "Preposition"],
-    ["PRON", "PRON ", "Pro-Nominal"],
-    ["V", "V ", "Verb"]
-  ],
-  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/syntax.html
-  "cnx/syn=" : [
-    ["@ADVL", "@ADVL ", "Adverbial Head"],
-    ["@AUX", "@AUX ", "Auxiliary Verb"],
-    ["@CC", "@CC ", "Coordination"]
-    ["@MAIN", "@MAIN ", "Main Verb"],
-    ["@NH", "@NH ", "Nominal Head"],
-    ["@POSTMOD", "@POSTMOD ", "Postmodifier"],
-    ["@PREMARK", "@PREMARK ", "Preposed Marker"],
-    ["@PREMOD", "@POSTMOD ", "Premodifier"]
-  ],
-  "opennlp/" : [
-    ["Part-of-Speech", "p="]
-  ],
-  "opennlp/p=" : sttsArray,
-  "xip/" : [
-    ["Constituency", "c="],
-    // Inactive: ["Dependency", "d="],
-    ["Lemma", "l="],
-    ["Part-of-Speech", "p="],
-  ],
-  // "xip/c=" : [],
-  // Inactive: "xip/d=" : [],
-  // "xip/p=" : [],
-  "tt/" : [
-    ["Lemma", "l="],
-    ["Part-of-Speech", "p="]
-  ],
-  "tt/p=" : sttsArray,
-  "mate/" : [
-    // Inactive: "d" : ["d=", "Dependency"],
-    ["Lemma", "l="],
-    ["Morphology", "m="],
-    ["Part-of-Speech", "p="]
-  ],
-  // Inactive: mate/d=
-  "mate/p=" : mateSttsArray,
-  "mate/m=" : [
-    ["Case", "case:"],
-    ["Degree", "degree:"],
-    ["Gender", "gender:"],
-    ["Mood", "mood:"],
-    ["Number", "number:"],
-    ["Person", "person:"],
-    ["Tense","tense:"],
-    ["No type", "<no-type> "]
-  ],
-  "mate/m=case:" : [
-    ["acc", "acc ", "Accusative"],
-    ["dat","dat ", "Dative"],
-    ["gen", "gen ","Genitive"],
-    ["nom","nom ", "Nominative"],
-    ["*","* ", "Undefined"]
-  ],
-  "mate/m=degree:" : [
-    ["comp","comp ", "Comparative"],
-    ["pos","pos ", "Positive"],
-    ["sup","sup ", "Superative"]
-  ],
-  "mate/m=gender:" : [
-    ["fem", "fem ", "Feminium"],
-    ["masc", "masc ", "Masculinum"],
-    ["neut","neut ", "Neuter"],
-    ["*","* ","Undefined"]
-  ],
-  "mate/m=mood:" : [
-    ["imp","imp ", "Imperative"],
-    ["ind","ind ", "Indicative"],
-    ["subj","subj ", "Subjunctive"]
-  ],
-  "mate/m=number:" : [
-    ["pl","pl ","Plural"],
-    ["sg","sg ","Singular"],
-    ["*","* ","Undefined"]
-  ],
-  "mate/m=person:" : [
-    ["1","1 ", "First Person"],
-    ["2","2 ", "Second Person"],
-    ["3","3 ", "Third Person"]
-  ],
-  "mate/m=tense:" : [
-    ["past","past ", "Past"],
-    ["pres","pres ", "Present"]
-  ]
-};
-
-    </script>
   </head>
   <body>
     <header>
@@ -240,9 +19,5 @@
 	</div>
       </form>
     </header>
-    <script>
-KorAP.hintArray = hintArray;
-var input = KorAP.Hint.create();
-    </script>
   </body>
 </html>
diff --git a/dev/demo/hintdemo.js b/dev/demo/hintdemo.js
new file mode 100644
index 0000000..6c2303b
--- /dev/null
+++ b/dev/demo/hintdemo.js
@@ -0,0 +1,231 @@
+// http://www.nlpado.de/~sebastian/software/ner_german.shtml
+// http://www.cnts.ua.ac.be/conll2003/ner/
+var namedEntities = [
+  ["I-LOC",  "I-LOC ",  "Location"],
+  ["I-MISC", "I-MISC ", "Miscellaneous"],
+  ["I-ORG",  "I-ORG ",  "Organization"],
+  ["I-PER",  "I-PER ",  "Person"]
+];
+
+// http://www.ids-mannheim.de/cosmas2/projekt/referenz/stts/morph.html
+// http://nachhalt.sfb632.uni-potsdam.de/owl-docu/stts.html
+var sttsArray = [
+  // "$.", "$(", "$,"
+  ["ADJA","ADJA ", "Attributive Adjective"],
+  ["ADJD","ADJD ", "Predicative Adjective"],
+  ["ADV","ADV ", "Adverb"],
+  ["APPO","APPO ", "Postposition"],
+  ["APPR","APPR ", "Preposition"],
+  ["APPRART","APPRART ", "Preposition with Determiner"],
+  ["APZR","APZR ","Right Circumposition"],
+  ["ART","ART ", "Determiner"],
+  ["CARD","CARD ", "Cardinal Number"],
+  ["FM","FM ", "Foreign Material"],
+  ["ITJ","ITJ ", "Interjection"],
+  ["KOKOM","KOKOM ", "Comparison Particle"],
+  ["KON","KON ", "Coordinating Conjuncion"],
+  ["KOUI","KOUI ", "Subordinating Conjunction with 'zu'"],
+  ["KOUS","KOUS ", "Subordinating Conjunction with Sentence"],
+  ["NE","NE ", "Named Entity"],
+  ["NN","NN ", "Normal Nomina"],
+  ["PAV", "PAV ", "Pronominal Adverb"],
+  ["PDAT","PDAT ","Attributive Demonstrative Pronoun"],
+  ["PDS","PDS ", "Substitutive Demonstrative Pronoun"],
+  ["PIAT","PIAT ", "Attributive Indefinite Pronoun without Determiner"],
+  ["PIDAT","PIDAT ", "Attributive Indefinite Pronoun with Determiner"],
+  ["PIS","PIS ", "Substitutive Indefinite Pronoun"],
+  ["PPER","PPER ", "Personal Pronoun"],
+  ["PPOSAT","PPOSAT ", "Attributive Possessive Pronoun"],
+  ["PPOSS","PPOSS ", "Substitutive Possessive Pronoun"],
+  ["PRELAT","PRELAT ", "Attributive Relative Pronoun"],
+  ["PRELS","PRELS ", "Substitutive Relative Pronoun"],
+  ["PRF","PRF ", "Reflexive Pronoun"],
+  ["PROAV","PROAV ", "Pronominal Adverb"],
+  ["PTKA","PTKA ","Particle with Adjective"],
+  ["PTKANT","PTKANT ", "Answering Particle"],
+  ["PTKNEG","PTKNEG ", "Negation Particle"],
+  ["PTKVZ","PTKVZ ", "Separated Verbal Particle"],
+  ["PTKZU","PTKZU ", "'zu' Particle"],
+  ["PWAT","PWAT ", "Attributive Interrogative Pronoun"],
+  ["PWAV","PWAV ", "Adverbial Interrogative Pronoun"],
+  ["PWS","PWS ", "Substitutive Interrogative Pronoun"],
+  ["TRUNC","TRUNC ","Truncated"],
+  ["VAFIN","VAFIN ", "Auxiliary Finite Verb"],
+  ["VAINF","VAINF ", "Auxiliary Infinite Verb"],
+  ["VAIMP","VAIMP ", "Auxiliary Finite Imperative Verb"],
+  ["VAPP","VAPP ", "Auxiliary Perfect Participle"],
+  ["VMFIN","VMFIN ", "Modal Finite Verb"],
+  ["VMINF","VMINF ", "Modal Infinite Verb"],
+  ["VMPP","VMPP ", "Modal Perfect Participle"],
+  ["VVFIN","VVFIN ","Finite Verb"],
+  ["VVIMP","VVIMP ", "Finite Imperative Verb"],
+  ["VVINF","VVINF ", "Infinite Verb"],
+  ["VVIZU","VVIZU ", "Infinite Verb with 'zu'"],
+  ["VVPP","VVPP ", "Perfect Participle"],
+  ["XY", "XY ", "Non-Word"]
+];
+
+var mateSttsArray = sttsArray.slice(0);
+mateSttsArray.push(
+  ["<root-POS>","<root-POS>","Root Part of Speech"]
+);
+
+
+var hintArray = {
+  "-" : [
+    ["Connexor",   "cnx/",     "Constituency, Lemma, Morphology, Part-of-Speech, Syntax"],
+    ["CoreNLP",    "corenlp/", "Named Entities"],
+    ["Mate",       "mate/",     "Lemma, Morphology, Part-of-Speech"],
+    ["OpenNLP",    "opennlp/", "Part-of-Speech"],
+    ["TreeTagger", "tt/",      "Lemma, Part-of-Speech"],
+    ["Xerox Parser", "xip/",   "Constituency, Lemma, Part-of-Speech"]
+  ],
+  "corenlp/" : [
+    ["Named Entity", "ne=" , "Combined"],
+    ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
+    ["Named Entity", "ne_hgc_175m_600=",    "ne_hgc_175m_600"]
+  ],
+  "corenlp/ne=" : namedEntities,
+  "corenlp/ne_dewac_175m_600=" : namedEntities,
+  "corenlp/ne_hgc_175m_600=" : namedEntities,
+  "cnx/" : [
+    ["Constituency", "c="],
+    ["Lemma", "l="],
+    ["Morphology", "m="],
+    ["Part-of-Speech", "p="],
+    ["Syntax", "syn="]
+  ],
+  "cnx/c=" : [
+    ["np", "np ", "Nominal Phrase"]
+  ],
+  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+  "cnx/m=" : [
+    ["Abbr","Abbr ", "Nouns: Abbreviation"],
+    ["CMP","CMP ", "Adjective: Comparative"],
+    ["IMP", "IMP ", "Mood: Imperative"],
+    ["IND", "IND ", "Mood: Indicative"],
+    ["INF", "INF ", "Infinitive"],
+    ["ORD","ORD ", "Numeral: Ordinal"],
+    ["PAST", "PAST ", "Tense: past"],
+    ["PCP", "PCP ", "Participle"],
+    ["PERF", "PERF ", "Perfective Participle"],
+    ["PL","PL ", "Nouns: Plural"],
+    ["PRES", "PRES ", "Tense: present"],
+    ["PROG", "PROG ", "Progressive Participle"],
+    ["Prop","Prop ", "Nouns: Proper Noun"],
+    ["SUB", "SUB ", "Mood: Subjunctive"],
+    ["SUP","SUP ", "Adjective: Superlative"]
+  ],
+  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+  "cnx/p=" : [
+    ["A", "A ", "Adjective"],
+    ["ADV", "ADV ", "Adverb"],
+    ["CC", "CC ", "Coordination Marker"],
+    ["CS", "CS ", "Clause Marker"],
+    ["DET", "DET ", "Determiner"],
+    ["INTERJ", "INTERJ ", "Interjection"],
+    ["N", "N ", "Noun"],
+    ["NUM", "NUM ", "Numeral"],
+    ["PREP", "PREP ", "Preposition"],
+    ["PRON", "PRON ", "Pro-Nominal"],
+    ["V", "V ", "Verb"]
+  ],
+  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/syntax.html
+  "cnx/syn=" : [
+    ["@ADVL", "@ADVL ", "Adverbial Head"],
+    ["@AUX", "@AUX ", "Auxiliary Verb"],
+    ["@CC", "@CC ", "Coordination"]
+    ["@MAIN", "@MAIN ", "Main Verb"],
+    ["@NH", "@NH ", "Nominal Head"],
+    ["@POSTMOD", "@POSTMOD ", "Postmodifier"],
+    ["@PREMARK", "@PREMARK ", "Preposed Marker"],
+    ["@PREMOD", "@POSTMOD ", "Premodifier"]
+  ],
+  "opennlp/" : [
+    ["Part-of-Speech", "p="]
+  ],
+  "opennlp/p=" : sttsArray,
+  "xip/" : [
+    ["Constituency", "c="],
+    // Inactive: ["Dependency", "d="],
+    ["Lemma", "l="],
+    ["Part-of-Speech", "p="],
+  ],
+  // "xip/c=" : [],
+  // Inactive: "xip/d=" : [],
+  // "xip/p=" : [],
+  "tt/" : [
+    ["Lemma", "l="],
+    ["Part-of-Speech", "p="]
+  ],
+  "tt/p=" : sttsArray,
+  "mate/" : [
+    // Inactive: "d" : ["d=", "Dependency"],
+    ["Lemma", "l="],
+    ["Morphology", "m="],
+    ["Part-of-Speech", "p="]
+  ],
+  // Inactive: mate/d=
+  "mate/p=" : mateSttsArray,
+  "mate/m=" : [
+    ["Case", "case:"],
+    ["Degree", "degree:"],
+    ["Gender", "gender:"],
+    ["Mood", "mood:"],
+    ["Number", "number:"],
+    ["Person", "person:"],
+    ["Tense","tense:"],
+    ["No type", "<no-type> "]
+  ],
+  "mate/m=case:" : [
+    ["acc", "acc ", "Accusative"],
+    ["dat","dat ", "Dative"],
+    ["gen", "gen ","Genitive"],
+    ["nom","nom ", "Nominative"],
+    ["*","* ", "Undefined"]
+  ],
+  "mate/m=degree:" : [
+    ["comp","comp ", "Comparative"],
+    ["pos","pos ", "Positive"],
+    ["sup","sup ", "Superative"]
+  ],
+  "mate/m=gender:" : [
+    ["fem", "fem ", "Feminium"],
+    ["masc", "masc ", "Masculinum"],
+    ["neut","neut ", "Neuter"],
+    ["*","* ","Undefined"]
+  ],
+  "mate/m=mood:" : [
+    ["imp","imp ", "Imperative"],
+    ["ind","ind ", "Indicative"],
+    ["subj","subj ", "Subjunctive"]
+  ],
+  "mate/m=number:" : [
+    ["pl","pl ","Plural"],
+    ["sg","sg ","Singular"],
+    ["*","* ","Undefined"]
+  ],
+  "mate/m=person:" : [
+    ["1","1 ", "First Person"],
+    ["2","2 ", "Second Person"],
+    ["3","3 ", "Third Person"]
+  ],
+  "mate/m=tense:" : [
+    ["past","past ", "Past"],
+    ["pres","pres ", "Present"]
+  ]
+};
+
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
+});
+
+require(['hint','lib/domReady'], function (hintClass, domReady) {
+  KorAP.hintArray = hintArray;
+  domReady(function() {
+    hintClass.create();
+  });
+});
diff --git a/dev/demo/match.html b/dev/demo/match.html
index cb2e7ef..d586959 100644
--- a/dev/demo/match.html
+++ b/dev/demo/match.html
@@ -3,13 +3,9 @@
   <head>
     <title>Match demo</title>
     <meta charset="utf-8" />
-    <script src="../js/lib/dagre/dagre.min.js"></script>
-    <script src="../js/src/init.js"></script>
-    <script src="../js/src/menu.js"></script>
-    <script src="../js/src/match.js"></script>
+    <script data-main="matchdemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
-    <style type="text/css"
-	   rel="stylesheet">
+    <style type="text/css" rel="stylesheet">
 
 body {
   background-color: #ffa500;
@@ -42,159 +38,5 @@
 	</li>
       </ol>
     </div>
-
-    <script>
-var snippet = "<span title=\"cnx/l:meist\">" +
-  "  <span title=\"cnx/p:ADV\">" +
-  "    <span title=\"cnx/syn:@PREMOD\">" +
-  "      <span title=\"mate/l:meist\">" +
-  "        <span title=\"mate/p:ADV\">" +
-  "          <span title=\"opennlp/p:ADV\">meist</span>" +
-  "        </span>" +
-  "      </span>" +
-  "    </span>" +
-  "  </span>" +
-  "</span>" +
-  "<span title=\"cnx/l:deutlich\">" +
-  "  <span title=\"cnx/p:A\">" +
-  "    <span title=\"cnx/syn:@PREMOD\">" +
-  "      <span title=\"mate/l:deutlich\">" +
-  "        <span title=\"mate/m:degree:pos\">" +
-  "          <span title=\"mate/p:ADJD\">" +
-  "            <span title=\"opennlp/p:ADJD\">deutlich</span>" +
-  "          </span>" +
-  "        </span>" +
-  "      </span>" +
-  "    </span>" +
-  "  </span>" +
-  "</span>" +
-  "<span title=\"cnx/l:fähig\">" +
-  "  <span title=\"cnx/l:leistung\">" +
-  "    <span title=\"cnx/p:A\">" +
-  "      <span title=\"cnx/syn:@NH\">" +
-  "        <span title=\"mate/l:leistungsfähig\">" +
-  "          <span title=\"mate/m:degree:comp\">" +
-  "            <span title=\"mate/p:ADJD\">" +
-  "              <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
-  "            </span>" +
-  "          </span>" +
-  "        </span>" +
-  "      </span>" +
-  "    </span>" +
-  "  </span>" +
-  "</span>";
-
-var treeSnippet =
-  "<span class=\"context-left\"></span>" +
-  "<span class=\"match\">" +
-  "  <span title=\"xip/c:MC\">" +
-  "    <span title=\"xip/c:TOP\">" +
-  "      <span title=\"xip/c:PP\">" +
-  "        <span title=\"xip/c:PREP\">Mit</span>" +
-  "        <span title=\"xip/c:NP\">" +
-  "          <span title=\"xip/c:DET\">dieser</span>" +
-  "          <span title=\"xip/c:NPA\">" +
-  "            <span title=\"xip/c:NOUN\">Methode</span>" +
-  "          </span>" +
-  "        </span>" +
-  "      </span>" +
-  "      <span title=\"xip/c:VERB\">ist</span>" +
-  "      <span title=\"xip/c:NP\">" +
-  "        <span title=\"xip/c:PRON\">es</span>" +
-  "      </span>" +
-  "      <span title=\"xip/c:AP\">" +
-  "        <span title=\"xip/c:ADV\">nun</span>" +
-  "        <span title=\"xip/c:ADJ\">möglich</span>" +
-  "      </span>" +
-  "      <span title=\"xip/c:ADV\">z. B.</span>" +
-  "      <span title=\"xip/c:NPA\">" +
-  "        <span title=\"xip/c:NP\">" +
-  "          <span title=\"xip/c:NOUN\">Voice</span>" +
-  "        </span>" +
-  "      </span>" + "(" +
-  "      <span title=\"xip/c:INS\">" +
-  "        <span title=\"xip/c:NPA\">" +
-  "          <span title=\"xip/c:NP\">" +
-  "            <span title=\"xip/c:NOUN\">Sprache</span>" +
-  "          </span>" +
-  "        </span>" +
-  "      </span>" + ")" +
-  "      <span title=\"xip/c:VERB\">bevorzugt</span>" +
-  "      <span title=\"xip/c:PP\">" +
-  "        <span title=\"xip/c:PREP\">in</span>" +
-  "        <span title=\"xip/c:NP\">" +
-  "          <span title=\"xip/c:PRON\">der</span>" +
-  "        </span>" +
-  "        <span title=\"xip/c:NPA\">" +
-  "          <span title=\"xip/c:NP\">" +
-  "            <span title=\"xip/c:NOUN\">Bridge</span>" +
-  "          </span>" +
-  "        </span>" +
-  "      </span>" +
-  "      <span title=\"xip/c:INFC\">" +
-  "        <span title=\"xip/c:INS\">" +
-  "          <span title=\"xip/c:VERB\">weiterzugeben</span>" +
-  "        </span>" +
-  "      </span>" +
-  "    </span>" +
-  "  </span>" +
-  "</span>" +
-  "<span class=\"context-right\"></span>";
-
-// Parse and show the table
-// Override getMatchInfo API call
-KorAP.API.getMatchInfo = function(match, callObj) {
-  if (callObj["spans"] !== undefined && callObj["spans"] === true) {
-    return { "snippet": treeSnippet };
-  }
-  else {
-    return { "snippet": snippet };
-  }
-};
-
-KorAP.init();
-    </script>
-
-    <!--
-    <div class="matchinfo">
-      <div class="matchtable">
-	<table>
-	  <thead>
-            <tr>
-	      <th>Foundry</th>
-	      <th>Layer</th>
-	      <th>Ich</th>
-	      <th>Du</th>
-	      <th>Er</th>
-	    </tr>
-	  </thead>
-	  <tbody>
-	    <tr tabindex="0">
-	      <th>Hallo</th>
-	      <th>X</th>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	    </tr>
-	    <tr tabindex="0">
-	      <th>geht</th>
-	      <th>y</th>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	    </tr>
-	    <tr tabindex="0">
-	      <th>es</th>
-	      <th>z</th>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	      <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
-	    </tr>
-	  </tbody>
-	</table>
-      </div>
-    </div>
-    -->
-
   </body>
 </html>
diff --git a/dev/demo/matchdemo.js b/dev/demo/matchdemo.js
new file mode 100644
index 0000000..56bf675
--- /dev/null
+++ b/dev/demo/matchdemo.js
@@ -0,0 +1,117 @@
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
+});
+
+// Parse and show the table
+// Override getMatchInfo API call
+require(['init'], function () {
+
+var snippet = "<span title=\"cnx/l:meist\">" +
+  "  <span title=\"cnx/p:ADV\">" +
+  "    <span title=\"cnx/syn:@PREMOD\">" +
+  "      <span title=\"mate/l:meist\">" +
+  "        <span title=\"mate/p:ADV\">" +
+  "          <span title=\"opennlp/p:ADV\">meist</span>" +
+  "        </span>" +
+  "      </span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>" +
+  "<span title=\"cnx/l:deutlich\">" +
+  "  <span title=\"cnx/p:A\">" +
+  "    <span title=\"cnx/syn:@PREMOD\">" +
+  "      <span title=\"mate/l:deutlich\">" +
+  "        <span title=\"mate/m:degree:pos\">" +
+  "          <span title=\"mate/p:ADJD\">" +
+  "            <span title=\"opennlp/p:ADJD\">deutlich</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>" +
+  "<span title=\"cnx/l:fähig\">" +
+  "  <span title=\"cnx/l:leistung\">" +
+  "    <span title=\"cnx/p:A\">" +
+  "      <span title=\"cnx/syn:@NH\">" +
+  "        <span title=\"mate/l:leistungsfähig\">" +
+  "          <span title=\"mate/m:degree:comp\">" +
+  "            <span title=\"mate/p:ADJD\">" +
+  "              <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
+  "            </span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>";
+
+var treeSnippet =
+  "<span class=\"context-left\"></span>" +
+  "<span class=\"match\">" +
+  "  <span title=\"xip/c:MC\">" +
+  "    <span title=\"xip/c:TOP\">" +
+  "      <span title=\"xip/c:PP\">" +
+  "        <span title=\"xip/c:PREP\">Mit</span>" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:DET\">dieser</span>" +
+  "          <span title=\"xip/c:NPA\">" +
+  "            <span title=\"xip/c:NOUN\">Methode</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:VERB\">ist</span>" +
+  "      <span title=\"xip/c:NP\">" +
+  "        <span title=\"xip/c:PRON\">es</span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:AP\">" +
+  "        <span title=\"xip/c:ADV\">nun</span>" +
+  "        <span title=\"xip/c:ADJ\">möglich</span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:ADV\">z. B.</span>" +
+  "      <span title=\"xip/c:NPA\">" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:NOUN\">Voice</span>" +
+  "        </span>" +
+  "      </span>" + "(" +
+  "      <span title=\"xip/c:INS\">" +
+  "        <span title=\"xip/c:NPA\">" +
+  "          <span title=\"xip/c:NP\">" +
+  "            <span title=\"xip/c:NOUN\">Sprache</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" + ")" +
+  "      <span title=\"xip/c:VERB\">bevorzugt</span>" +
+  "      <span title=\"xip/c:PP\">" +
+  "        <span title=\"xip/c:PREP\">in</span>" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:PRON\">der</span>" +
+  "        </span>" +
+  "        <span title=\"xip/c:NPA\">" +
+  "          <span title=\"xip/c:NP\">" +
+  "            <span title=\"xip/c:NOUN\">Bridge</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:INFC\">" +
+  "        <span title=\"xip/c:INS\">" +
+  "          <span title=\"xip/c:VERB\">weiterzugeben</span>" +
+  "        </span>" +
+  "      </span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>" +
+  "<span class=\"context-right\"></span>";
+
+  KorAP.API.getMatchInfo = function(match, callObj, cb) {
+    if (callObj["spans"] !== undefined && callObj["spans"] === true) {
+      return cb({ "snippet": treeSnippet });
+    }
+    else {
+      return cb({ "snippet": snippet });
+    }
+  };
+});
diff --git a/dev/demo/menu.html b/dev/demo/menu.html
index 13f7ae9..f6d18ea 100644
--- a/dev/demo/menu.html
+++ b/dev/demo/menu.html
@@ -3,7 +3,7 @@
   <head>
     <title>Menu demo</title>
     <meta charset="utf-8" />
-    <script src="../js/src/menu.js"></script>
+    <script data-main="menudemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
     <style type="text/css" rel="stylesheet">
 .info {
@@ -28,77 +28,5 @@
 	<div id="pagination"><a rel="prev"><span><i class="fa fa-caret-left"></i></span></a><a rel="self"><span>1</span></a><a href="/kalamar?q=der+%5Bmate/m%3Dnumber:sg%5D&amp;ql=poliqarp&amp;p=2"><span>2</span></a><a href="/kalamar?q=der+%5Bmate/m%3Dnumber:sg%5D&amp;ql=poliqarp&amp;p=3"><span>3</span></a><span><i class="fa fa-ellipsis-h"></i></span><a href="/kalamar?q=der+%5Bmate/m%3Dnumber:sg%5D&amp;ql=poliqarp&amp;p=52230"><span>52230</span></a><a rel="next" href="/kalamar?q=der+%5Bmate/m%3Dnumber:sg%5D&amp;ql=poliqarp&amp;p=2"><span><i class="fa fa-caret-right"></i></span></a></div>
       </div>
     </main>
-
-    <script>
-KorAP.OwnMenuItem = {
-  create : function (params) {
-    return Object.create(KorAP.MenuItem).upgradeTo(KorAP.OwnMenuItem)._init(params);
-  },
-  content : function (content) {
-    if (arguments.length === 1) {
-      this._content = content;
-    };
-    return this._content;
-  },
-
-  // enter or click
-  onclick : function () {
-    console.log(this._name);
-  },
-
-  // right arrow
-  further : function () {
-    console.log("Further: " + this._name);
-  },
-  _init : function (params) {
-    if (params[0] === undefined)
-      throw new Error("Missing parameters");
-
-    this._name = params[0];
-    this._content = document.createTextNode(this._name);
-    this._lcField = ' ' + this.content().textContent.toLowerCase();
-
-    return this;
-  }
-};
-
-KorAP.OwnPrefix = {
-  create : function () {
-    return Object.create(KorAP.MenuPrefix)
-      .upgradeTo(KorAP.OwnPrefix)
-      ._init();
-  },
-  onclick : function () {
-    console.log('Prefix: ' + this.value());
-  }
-}
-
-KorAP.OwnMenu = {
-  create : function (params) {
-    return Object.create(KorAP.Menu)
-      .upgradeTo(KorAP.OwnMenu)
-      ._init(KorAP.OwnMenuItem, KorAP.OwnPrefix, params);
-  }
-};
-
-var menu = KorAP.OwnMenu.create([
-  ['Titel', 'title', 'string'],
-  ['Untertitel', 'subTitle', 'string'],
-  ['Veröffentlichungsdatum', 'pubDate', 'date'],
-  ['Länge', 'length', 'integer'],
-  ['Autor', 'author', 'string'],
-  ['Genre', 'genre', 'string'],
-  ['corpusID', 'corpusID', 'string'],
-  ['docID', 'docID', 'string'],
-  ['textID', 'textID', 'string']
-]);
-
-    document.getElementById('menu').appendChild(menu.element());
-
-    menu.limit(3);
-    menu.show('');
-    menu.focus();
-
-    </script>
   </body>
 </html>
diff --git a/dev/demo/menudemo.js b/dev/demo/menudemo.js
new file mode 100644
index 0000000..e089e89
--- /dev/null
+++ b/dev/demo/menudemo.js
@@ -0,0 +1,74 @@
+requirejs.config({
+  baseUrl: '../js/src'
+});
+
+require(['menu','menu/item', 'menu/prefix'], function (menuClass, itemClass, prefixClass) {
+  var OwnMenuItemClass = {
+    create : function (params) {
+      return Object.create(itemClass).upgradeTo(this)._init(params);
+    },
+    content : function (content) {
+      if (arguments.length === 1) {
+        this._content = content;
+      };
+      return this._content;
+    },
+
+    // enter or click
+    onclick : function () {
+      console.log(this._name);
+    },
+
+    // right arrow
+    further : function () {
+      console.log("Further: " + this._name);
+    },
+    _init : function (params) {
+      if (params[0] === undefined)
+	throw new Error("Missing parameters");
+
+      this._name = params[0];
+      this._content = document.createTextNode(this._name);
+      this._lcField = ' ' + this.content().textContent.toLowerCase();
+      
+      return this;
+    }
+  };
+
+  var OwnPrefixClass = {
+    create : function () {
+      return Object.create(prefixClass)
+	.upgradeTo(this)
+	._init();
+    },
+    onclick : function () {
+      console.log('Prefix: ' + this.value());
+    }
+  };
+
+  var OwnMenu = {
+    create : function (params) {
+      return Object.create(menuClass)
+      .upgradeTo(this)
+      ._init(OwnMenuItemClass, OwnPrefixClass, params);
+    }
+  };
+
+  var menu = OwnMenu.create([
+    ['Titel', 'title', 'string'],
+    ['Untertitel', 'subTitle', 'string'],
+    ['Veröffentlichungsdatum', 'pubDate', 'date'],
+    ['Länge', 'length', 'integer'],
+    ['Autor', 'author', 'string'],
+    ['Genre', 'genre', 'string'],
+    ['corpusID', 'corpusID', 'string'],
+    ['docID', 'docID', 'string'],
+    ['textID', 'textID', 'string']
+  ]);
+
+  document.getElementById('menu').appendChild(menu.element());
+
+  menu.limit(3);
+  menu.show('');
+  menu.focus();
+});
diff --git a/dev/demo/session.html b/dev/demo/session.html
index 034771c..5b4ae6b 100644
--- a/dev/demo/session.html
+++ b/dev/demo/session.html
@@ -3,37 +3,7 @@
   <head>
     <title>Cookie demo</title>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
-    <script src="../js/src/session.js"></script>
-    <script>
-
-var cookey;
-
-function add (val) {
-  var list = document.getElementById('number');
-  list.textContent += '-' + val;
-  cookey.set('n', list.textContent);
-};
-
-function removeCookie () {
-  cookey.clear();
-};
-
-document.addEventListener('DOMContentLoaded', function () {
-  cookey = KorAP.Session.create('peter');
-  document.getElementById('number').textContent = cookey.get('n') || '';
-
-  var elements =   document.getElementsByClassName('num');
-  for (var i = 0; i < elements.length; i++) {
-    elements[i].addEventListener(
-      'click',
-      function (e) {
-        add(this.textContent);
-      }
-    );
-  };
-});
-
-    </script>
+    <script data-main="sessiondemo.js" src="../js/lib/require.js" async="async"></script>
   </head>
   <body>
     <div id="number"></div>
diff --git a/dev/demo/sessiondemo.js b/dev/demo/sessiondemo.js
new file mode 100644
index 0000000..7fd9b73
--- /dev/null
+++ b/dev/demo/sessiondemo.js
@@ -0,0 +1,35 @@
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
+});
+
+var cookey;
+
+function add (val) {
+  var list = document.getElementById('number');
+  list.textContent += '-' + val;
+  cookey.set('n', list.textContent);
+};
+
+function removeCookie () {
+  cookey.clear();
+};
+
+define(['session', 'lib/domReady'], function (sessionClass, domReady) {
+  domReady(function () {
+    cookey = sessionClass.create('peter');
+    document.getElementById('number').textContent = cookey.get('n') || '';
+
+    var elements = document.getElementsByClassName('num');
+    for (var i = 0; i < elements.length; i++) {
+      elements[i].addEventListener(
+	'click',
+	function (e) {
+          add(this.textContent);
+	}
+      );
+    };
+  });
+})
diff --git a/dev/demo/vc.html b/dev/demo/vc.html
index 353b309..9eb7648 100644
--- a/dev/demo/vc.html
+++ b/dev/demo/vc.html
@@ -3,8 +3,7 @@
   <head>
     <title>Virtual Collection demo</title>
     <meta charset="utf-8" />
-    <script src="../js/src/menu.js"></script>
-    <script src="../js/src/vc.js"></script>
+    <script data-main="vcdemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
     <style type="text/css" rel="stylesheet">
 
@@ -28,79 +27,6 @@
     <div id="vc"></div>
     <div id="menu" class="vc"></div>
 
-    <script>
-    var json = {
-      "@type":"koral:docGroup",
-      "operation":"operation:or",
-      "operands":[
-        {
-          "@type":"koral:docGroup",
-          "operation":"operation:and",
-          "operands":[
-            {
-              "@type":"koral:doc",
-              "key":"Titel",
-              "value":"Der Birnbaum",
-              "match":"match:eq"
-            },
-            {
-              "@type":"koral:doc",
-              "key":"Veröffentlichungsort",
-              "value":"Mannheim",
-              "match":"match:eq"
-            },
-            {
-              "@type":"koral:docGroup",
-              "operation":"operation:or",
-              "operands":[
-                {
-                  "@type":"koral:doc",
-                  "key":"Untertitel",
-                  "value":"Aufzucht und Pflege",
-                  "match":"match:eq"
-                },
-                {
-                  "@type":"koral:doc",
-                  "key":"Untertitel",
-                  "value":"Gedichte",
-                  "match":"match:eq",
-                  "rewrites" : [
-                    {
-                      "@type": "koral:rewrite",
-                      "src" : "policy",
-                      "operation" : "operation:injection",
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "@type":"koral:doc",
-          "key":"Veröffentlichungsdatum",
-          "type":"type:date",
-          "value":"2015-03-05",
-          "match":"match:geq"
-        }
-      ]
-    };
-    KorAP.Locale.AND = 'und';
-    KorAP.Locale.OR  = 'oder';
-
-    var vc = KorAP.VirtualCollection.render(json);
-    document.getElementById('vc').appendChild(vc.element());
-
-    function showJSON() {
-      document.getElementById("json").innerHTML = JSON.stringify(vc.root().toJson());
-    };
-
-    function showQuery() {
-      document.getElementById("query").innerHTML = vc.root().toQuery();
-    };
-
-    </script>
-
     <hr />
 
     <p><a onclick="showJSON()" style="cursor:pointer">show JSON!</a></p>
diff --git a/dev/demo/vcdemo.js b/dev/demo/vcdemo.js
new file mode 100644
index 0000000..b96b16c
--- /dev/null
+++ b/dev/demo/vcdemo.js
@@ -0,0 +1,81 @@
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
+});
+
+var json = {
+  "@type":"koral:docGroup",
+  "operation":"operation:or",
+  "operands":[
+    {
+      "@type":"koral:docGroup",
+      "operation":"operation:and",
+      "operands":[
+        {
+          "@type":"koral:doc",
+          "key":"Titel",
+          "value":"Der Birnbaum",
+          "match":"match:eq"
+        },
+        {
+          "@type":"koral:doc",
+          "key":"Veröffentlichungsort",
+          "value":"Mannheim",
+          "match":"match:eq"
+        },
+        {
+          "@type":"koral:docGroup",
+          "operation":"operation:or",
+          "operands":[
+            {
+              "@type":"koral:doc",
+              "key":"Untertitel",
+              "value":"Aufzucht und Pflege",
+              "match":"match:eq"
+            },
+            {
+              "@type":"koral:doc",
+              "key":"Untertitel",
+              "value":"Gedichte",
+              "match":"match:eq",
+              "rewrites" : [
+                {
+                  "@type": "koral:rewrite",
+                  "src" : "policy",
+                  "operation" : "operation:injection",
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "@type":"koral:doc",
+      "key":"Veröffentlichungsdatum",
+      "type":"type:date",
+      "value":"2015-03-05",
+      "match":"match:geq"
+    }
+  ]
+};
+
+function showJSON() {
+  document.getElementById("json").innerHTML = JSON.stringify(vc.root().toJson());
+};
+
+function showQuery() {
+  document.getElementById("query").innerHTML = vc.root().toQuery();
+};
+
+require(['vc','lib/domReady'], function (vcClass, domReady) {
+  KorAP.Locale.AND = 'und';
+  KorAP.Locale.OR  = 'oder';
+
+  domReady(function() {
+    var vc = vcClass.render(json);
+    document.getElementById('vc').appendChild(vc.element());
+  });
+});
diff --git a/dev/js/lib/almond.js b/dev/js/lib/almond.js
new file mode 100644
index 0000000..2a06588
--- /dev/null
+++ b/dev/js/lib/almond.js
@@ -0,0 +1,430 @@
+/**
+ * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/almond for details
+ */
+//Going sloppy to avoid 'use strict' string cost, but strict practices should
+//be followed.
+/*jslint sloppy: true */
+/*global setTimeout: false */
+
+var requirejs, require, define;
+(function (undef) {
+    var main, req, makeMap, handlers,
+        defined = {},
+        waiting = {},
+        config = {},
+        defining = {},
+        hasOwn = Object.prototype.hasOwnProperty,
+        aps = [].slice,
+        jsSuffixRegExp = /\.js$/;
+
+    function hasProp(obj, prop) {
+        return hasOwn.call(obj, prop);
+    }
+
+    /**
+     * Given a relative module name, like ./something, normalize it to
+     * a real name that can be mapped to a path.
+     * @param {String} name the relative name
+     * @param {String} baseName a real name that the name arg is relative
+     * to.
+     * @returns {String} normalized name
+     */
+    function normalize(name, baseName) {
+        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
+            foundI, foundStarMap, starI, i, j, part,
+            baseParts = baseName && baseName.split("/"),
+            map = config.map,
+            starMap = (map && map['*']) || {};
+
+        //Adjust any relative paths.
+        if (name && name.charAt(0) === ".") {
+            //If have a base name, try to normalize against it,
+            //otherwise, assume it is a top-level require that will
+            //be relative to baseUrl in the end.
+            if (baseName) {
+                name = name.split('/');
+                lastIndex = name.length - 1;
+
+                // Node .js allowance:
+                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+                }
+
+                //Lop off the last part of baseParts, so that . matches the
+                //"directory" and not name of the baseName's module. For instance,
+                //baseName of "one/two/three", maps to "one/two/three.js", but we
+                //want the directory, "one/two" for this normalization.
+                name = baseParts.slice(0, baseParts.length - 1).concat(name);
+
+                //start trimDots
+                for (i = 0; i < name.length; i += 1) {
+                    part = name[i];
+                    if (part === ".") {
+                        name.splice(i, 1);
+                        i -= 1;
+                    } else if (part === "..") {
+                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {
+                            //End of the line. Keep at least one non-dot
+                            //path segment at the front so it can be mapped
+                            //correctly to disk. Otherwise, there is likely
+                            //no path mapping for a path starting with '..'.
+                            //This can still fail, but catches the most reasonable
+                            //uses of ..
+                            break;
+                        } else if (i > 0) {
+                            name.splice(i - 1, 2);
+                            i -= 2;
+                        }
+                    }
+                }
+                //end trimDots
+
+                name = name.join("/");
+            } else if (name.indexOf('./') === 0) {
+                // No baseName, so this is ID is resolved relative
+                // to baseUrl, pull off the leading dot.
+                name = name.substring(2);
+            }
+        }
+
+        //Apply map config if available.
+        if ((baseParts || starMap) && map) {
+            nameParts = name.split('/');
+
+            for (i = nameParts.length; i > 0; i -= 1) {
+                nameSegment = nameParts.slice(0, i).join("/");
+
+                if (baseParts) {
+                    //Find the longest baseName segment match in the config.
+                    //So, do joins on the biggest to smallest lengths of baseParts.
+                    for (j = baseParts.length; j > 0; j -= 1) {
+                        mapValue = map[baseParts.slice(0, j).join('/')];
+
+                        //baseName segment has  config, find if it has one for
+                        //this name.
+                        if (mapValue) {
+                            mapValue = mapValue[nameSegment];
+                            if (mapValue) {
+                                //Match, update name to the new value.
+                                foundMap = mapValue;
+                                foundI = i;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (foundMap) {
+                    break;
+                }
+
+                //Check for a star map match, but just hold on to it,
+                //if there is a shorter segment match later in a matching
+                //config, then favor over this star map.
+                if (!foundStarMap && starMap && starMap[nameSegment]) {
+                    foundStarMap = starMap[nameSegment];
+                    starI = i;
+                }
+            }
+
+            if (!foundMap && foundStarMap) {
+                foundMap = foundStarMap;
+                foundI = starI;
+            }
+
+            if (foundMap) {
+                nameParts.splice(0, foundI, foundMap);
+                name = nameParts.join('/');
+            }
+        }
+
+        return name;
+    }
+
+    function makeRequire(relName, forceSync) {
+        return function () {
+            //A version of a require function that passes a moduleName
+            //value for items that may need to
+            //look up paths relative to the moduleName
+            var args = aps.call(arguments, 0);
+
+            //If first arg is not require('string'), and there is only
+            //one arg, it is the array form without a callback. Insert
+            //a null so that the following concat is correct.
+            if (typeof args[0] !== 'string' && args.length === 1) {
+                args.push(null);
+            }
+            return req.apply(undef, args.concat([relName, forceSync]));
+        };
+    }
+
+    function makeNormalize(relName) {
+        return function (name) {
+            return normalize(name, relName);
+        };
+    }
+
+    function makeLoad(depName) {
+        return function (value) {
+            defined[depName] = value;
+        };
+    }
+
+    function callDep(name) {
+        if (hasProp(waiting, name)) {
+            var args = waiting[name];
+            delete waiting[name];
+            defining[name] = true;
+            main.apply(undef, args);
+        }
+
+        if (!hasProp(defined, name) && !hasProp(defining, name)) {
+            throw new Error('No ' + name);
+        }
+        return defined[name];
+    }
+
+    //Turns a plugin!resource to [plugin, resource]
+    //with the plugin being undefined if the name
+    //did not have a plugin prefix.
+    function splitPrefix(name) {
+        var prefix,
+            index = name ? name.indexOf('!') : -1;
+        if (index > -1) {
+            prefix = name.substring(0, index);
+            name = name.substring(index + 1, name.length);
+        }
+        return [prefix, name];
+    }
+
+    /**
+     * Makes a name map, normalizing the name, and using a plugin
+     * for normalization if necessary. Grabs a ref to plugin
+     * too, as an optimization.
+     */
+    makeMap = function (name, relName) {
+        var plugin,
+            parts = splitPrefix(name),
+            prefix = parts[0];
+
+        name = parts[1];
+
+        if (prefix) {
+            prefix = normalize(prefix, relName);
+            plugin = callDep(prefix);
+        }
+
+        //Normalize according
+        if (prefix) {
+            if (plugin && plugin.normalize) {
+                name = plugin.normalize(name, makeNormalize(relName));
+            } else {
+                name = normalize(name, relName);
+            }
+        } else {
+            name = normalize(name, relName);
+            parts = splitPrefix(name);
+            prefix = parts[0];
+            name = parts[1];
+            if (prefix) {
+                plugin = callDep(prefix);
+            }
+        }
+
+        //Using ridiculous property names for space reasons
+        return {
+            f: prefix ? prefix + '!' + name : name, //fullName
+            n: name,
+            pr: prefix,
+            p: plugin
+        };
+    };
+
+    function makeConfig(name) {
+        return function () {
+            return (config && config.config && config.config[name]) || {};
+        };
+    }
+
+    handlers = {
+        require: function (name) {
+            return makeRequire(name);
+        },
+        exports: function (name) {
+            var e = defined[name];
+            if (typeof e !== 'undefined') {
+                return e;
+            } else {
+                return (defined[name] = {});
+            }
+        },
+        module: function (name) {
+            return {
+                id: name,
+                uri: '',
+                exports: defined[name],
+                config: makeConfig(name)
+            };
+        }
+    };
+
+    main = function (name, deps, callback, relName) {
+        var cjsModule, depName, ret, map, i,
+            args = [],
+            callbackType = typeof callback,
+            usingExports;
+
+        //Use name if no relName
+        relName = relName || name;
+
+        //Call the callback to define the module, if necessary.
+        if (callbackType === 'undefined' || callbackType === 'function') {
+            //Pull out the defined dependencies and pass the ordered
+            //values to the callback.
+            //Default to [require, exports, module] if no deps
+            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
+            for (i = 0; i < deps.length; i += 1) {
+                map = makeMap(deps[i], relName);
+                depName = map.f;
+
+                //Fast path CommonJS standard dependencies.
+                if (depName === "require") {
+                    args[i] = handlers.require(name);
+                } else if (depName === "exports") {
+                    //CommonJS module spec 1.1
+                    args[i] = handlers.exports(name);
+                    usingExports = true;
+                } else if (depName === "module") {
+                    //CommonJS module spec 1.1
+                    cjsModule = args[i] = handlers.module(name);
+                } else if (hasProp(defined, depName) ||
+                           hasProp(waiting, depName) ||
+                           hasProp(defining, depName)) {
+                    args[i] = callDep(depName);
+                } else if (map.p) {
+                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
+                    args[i] = defined[depName];
+                } else {
+                    throw new Error(name + ' missing ' + depName);
+                }
+            }
+
+            ret = callback ? callback.apply(defined[name], args) : undefined;
+
+            if (name) {
+                //If setting exports via "module" is in play,
+                //favor that over return value and exports. After that,
+                //favor a non-undefined return value over exports use.
+                if (cjsModule && cjsModule.exports !== undef &&
+                        cjsModule.exports !== defined[name]) {
+                    defined[name] = cjsModule.exports;
+                } else if (ret !== undef || !usingExports) {
+                    //Use the return value from the function.
+                    defined[name] = ret;
+                }
+            }
+        } else if (name) {
+            //May just be an object definition for the module. Only
+            //worry about defining if have a module name.
+            defined[name] = callback;
+        }
+    };
+
+    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
+        if (typeof deps === "string") {
+            if (handlers[deps]) {
+                //callback in this case is really relName
+                return handlers[deps](callback);
+            }
+            //Just return the module wanted. In this scenario, the
+            //deps arg is the module name, and second arg (if passed)
+            //is just the relName.
+            //Normalize module name, if it contains . or ..
+            return callDep(makeMap(deps, callback).f);
+        } else if (!deps.splice) {
+            //deps is a config object, not an array.
+            config = deps;
+            if (config.deps) {
+                req(config.deps, config.callback);
+            }
+            if (!callback) {
+                return;
+            }
+
+            if (callback.splice) {
+                //callback is an array, which means it is a dependency list.
+                //Adjust args if there are dependencies
+                deps = callback;
+                callback = relName;
+                relName = null;
+            } else {
+                deps = undef;
+            }
+        }
+
+        //Support require(['a'])
+        callback = callback || function () {};
+
+        //If relName is a function, it is an errback handler,
+        //so remove it.
+        if (typeof relName === 'function') {
+            relName = forceSync;
+            forceSync = alt;
+        }
+
+        //Simulate async callback;
+        if (forceSync) {
+            main(undef, deps, callback, relName);
+        } else {
+            //Using a non-zero value because of concern for what old browsers
+            //do, and latest browsers "upgrade" to 4 if lower value is used:
+            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
+            //If want a value immediately, use require('id') instead -- something
+            //that works in almond on the global level, but not guaranteed and
+            //unlikely to work in other AMD implementations.
+            setTimeout(function () {
+                main(undef, deps, callback, relName);
+            }, 4);
+        }
+
+        return req;
+    };
+
+    /**
+     * Just drops the config on the floor, but returns req in case
+     * the config return value is used.
+     */
+    req.config = function (cfg) {
+        return req(cfg);
+    };
+
+    /**
+     * Expose module registry for debugging and tooling
+     */
+    requirejs._defined = defined;
+
+    define = function (name, deps, callback) {
+        if (typeof name !== 'string') {
+            throw new Error('See almond README: incorrect module build, no module name');
+        }
+
+        //This module may not have dependencies
+        if (!deps.splice) {
+            //deps is not an array, so probably means
+            //an object literal or factory function for
+            //the value. Adjust args.
+            callback = deps;
+            deps = [];
+        }
+
+        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
+            waiting[name] = [name, deps, callback];
+        }
+    };
+
+    define.amd = {
+        jQuery: true
+    };
+}());
diff --git a/dev/js/lib/dagre.js b/dev/js/lib/dagre.js
new file mode 100644
index 0000000..b62dde6
--- /dev/null
+++ b/dev/js/lib/dagre.js
@@ -0,0 +1,10825 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.dagre=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/*
+Copyright (c) 2012-2014 Chris Pettitt
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+module.exports = {
+  graphlib: require("./lib/graphlib"),
+
+  layout: require("./lib/layout"),
+  debug: require("./lib/debug"),
+  util: {
+    time: require("./lib/util").time,
+    notime: require("./lib/util").notime
+  },
+  version: require("./lib/version")
+};
+
+},{"./lib/debug":6,"./lib/graphlib":7,"./lib/layout":9,"./lib/util":29,"./lib/version":30}],2:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash"),
+    greedyFAS = require("./greedy-fas");
+
+module.exports = {
+  run: run,
+  undo: undo
+};
+
+function run(g) {
+  var fas = (g.graph().acyclicer === "greedy"
+                ? greedyFAS(g, weightFn(g))
+                : dfsFAS(g));
+  _.each(fas, function(e) {
+    var label = g.edge(e);
+    g.removeEdge(e);
+    label.forwardName = e.name;
+    label.reversed = true;
+    g.setEdge(e.w, e.v, label, _.uniqueId("rev"));
+  });
+
+  function weightFn(g) {
+    return function(e) {
+      return g.edge(e).weight;
+    };
+  }
+}
+
+function dfsFAS(g) {
+  var fas = [],
+      stack = {},
+      visited = {};
+
+  function dfs(v) {
+    if (_.has(visited, v)) {
+      return;
+    }
+    visited[v] = true;
+    stack[v] = true;
+    _.each(g.outEdges(v), function(e) {
+      if (_.has(stack, e.w)) {
+        fas.push(e);
+      } else {
+        dfs(e.w);
+      }
+    });
+    delete stack[v];
+  }
+
+  _.each(g.nodes(), dfs);
+  return fas;
+}
+
+function undo(g) {
+  _.each(g.edges(), function(e) {
+    var label = g.edge(e);
+    if (label.reversed) {
+      g.removeEdge(e);
+
+      var forwardName = label.forwardName;
+      delete label.reversed;
+      delete label.forwardName;
+      g.setEdge(e.w, e.v, label, forwardName);
+    }
+  });
+}
+
+},{"./greedy-fas":8,"./lodash":10}],3:[function(require,module,exports){
+var _ = require("./lodash"),
+    util = require("./util");
+
+module.exports = addBorderSegments;
+
+function addBorderSegments(g) {
+  function dfs(v) {
+    var children = g.children(v),
+        node = g.node(v);
+    if (children.length) {
+      _.each(children, dfs);
+    }
+
+    if (_.has(node, "minRank")) {
+      node.borderLeft = [];
+      node.borderRight = [];
+      for (var rank = node.minRank, maxRank = node.maxRank + 1;
+           rank < maxRank;
+           ++rank) {
+        addBorderNode(g, "borderLeft", "_bl", v, node, rank);
+        addBorderNode(g, "borderRight", "_br", v, node, rank);
+      }
+    }
+  }
+
+  _.each(g.children(), dfs);
+}
+
+function addBorderNode(g, prop, prefix, sg, sgNode, rank) {
+  var label = { width: 0, height: 0, rank: rank },
+      prev = sgNode[prop][rank - 1],
+      curr = util.addDummyNode(g, "border", label, prefix);
+  sgNode[prop][rank] = curr;
+  g.setParent(curr, sg);
+  if (prev) {
+    g.setEdge(prev, curr, { weight: 1 });
+  }
+}
+
+},{"./lodash":10,"./util":29}],4:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash");
+
+module.exports = {
+  adjust: adjust,
+  undo: undo
+};
+
+function adjust(g) {
+  var rankDir = g.graph().rankdir.toLowerCase();
+  if (rankDir === "lr" || rankDir === "rl") {
+    swapWidthHeight(g);
+  }
+}
+
+function undo(g) {
+  var rankDir = g.graph().rankdir.toLowerCase();
+  if (rankDir === "bt" || rankDir === "rl") {
+    reverseY(g);
+  }
+
+  if (rankDir === "lr" || rankDir === "rl") {
+    swapXY(g);
+    swapWidthHeight(g);
+  }
+}
+
+function swapWidthHeight(g) {
+  _.each(g.nodes(), function(v) { swapWidthHeightOne(g.node(v)); });
+  _.each(g.edges(), function(e) { swapWidthHeightOne(g.edge(e)); });
+}
+
+function swapWidthHeightOne(attrs) {
+  var w = attrs.width;
+  attrs.width = attrs.height;
+  attrs.height = w;
+}
+
+function reverseY(g) {
+  _.each(g.nodes(), function(v) { reverseYOne(g.node(v)); });
+
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    _.each(edge.points, reverseYOne);
+    if (_.has(edge, "y")) {
+      reverseYOne(edge);
+    }
+  });
+}
+
+function reverseYOne(attrs) {
+  attrs.y = -attrs.y;
+}
+
+function swapXY(g) {
+  _.each(g.nodes(), function(v) { swapXYOne(g.node(v)); });
+
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    _.each(edge.points, swapXYOne);
+    if (_.has(edge, "x")) {
+      swapXYOne(edge);
+    }
+  });
+}
+
+function swapXYOne(attrs) {
+  var x = attrs.x;
+  attrs.x = attrs.y;
+  attrs.y = x;
+}
+
+},{"./lodash":10}],5:[function(require,module,exports){
+/*
+ * Simple doubly linked list implementation derived from Cormen, et al.,
+ * "Introduction to Algorithms".
+ */
+
+module.exports = List;
+
+function List() {
+  var sentinel = {};
+  sentinel._next = sentinel._prev = sentinel;
+  this._sentinel = sentinel;
+}
+
+List.prototype.dequeue = function() {
+  var sentinel = this._sentinel,
+      entry = sentinel._prev;
+  if (entry !== sentinel) {
+    unlink(entry);
+    return entry;
+  }
+};
+
+List.prototype.enqueue = function(entry) {
+  var sentinel = this._sentinel;
+  if (entry._prev && entry._next) {
+    unlink(entry);
+  }
+  entry._next = sentinel._next;
+  sentinel._next._prev = entry;
+  sentinel._next = entry;
+  entry._prev = sentinel;
+};
+
+List.prototype.toString = function() {
+  var strs = [],
+      sentinel = this._sentinel,
+      curr = sentinel._prev;
+  while (curr !== sentinel) {
+    strs.push(JSON.stringify(curr, filterOutLinks));
+    curr = curr._prev;
+  }
+  return "[" + strs.join(", ") + "]";
+};
+
+function unlink(entry) {
+  entry._prev._next = entry._next;
+  entry._next._prev = entry._prev;
+  delete entry._next;
+  delete entry._prev;
+}
+
+function filterOutLinks(k, v) {
+  if (k !== "_next" && k !== "_prev") {
+    return v;
+  }
+}
+
+},{}],6:[function(require,module,exports){
+var _ = require("./lodash"),
+    util = require("./util"),
+    Graph = require("./graphlib").Graph;
+
+module.exports = {
+  debugOrdering: debugOrdering
+};
+
+/* istanbul ignore next */
+function debugOrdering(g) {
+  var layerMatrix = util.buildLayerMatrix(g);
+
+  var h = new Graph({ compound: true, multigraph: true }).setGraph({});
+
+  _.each(g.nodes(), function(v) {
+    h.setNode(v, { label: v });
+    h.setParent(v, "layer" + g.node(v).rank);
+  });
+
+  _.each(g.edges(), function(e) {
+    h.setEdge(e.v, e.w, {}, e.name);
+  });
+
+  _.each(layerMatrix, function(layer, i) {
+    var layerV = "layer" + i;
+    h.setNode(layerV, { rank: "same" });
+    _.reduce(layer, function(u, v) {
+      h.setEdge(u, v, { style: "invis" });
+      return v;
+    });
+  });
+
+  return h;
+}
+
+},{"./graphlib":7,"./lodash":10,"./util":29}],7:[function(require,module,exports){
+/* global window */
+
+var graphlib;
+
+if (require) {
+  try {
+    graphlib = require("graphlib");
+  } catch (e) {}
+}
+
+if (!graphlib) {
+  graphlib = window.graphlib;
+}
+
+module.exports = graphlib;
+
+},{"graphlib":31}],8:[function(require,module,exports){
+var _ = require("./lodash"),
+    Graph = require("./graphlib").Graph,
+    List = require("./data/list");
+
+/*
+ * A greedy heuristic for finding a feedback arc set for a graph. A feedback
+ * arc set is a set of edges that can be removed to make a graph acyclic.
+ * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and
+ * effective heuristic for the feedback arc set problem." This implementation
+ * adjusts that from the paper to allow for weighted edges.
+ */
+module.exports = greedyFAS;
+
+var DEFAULT_WEIGHT_FN = _.constant(1);
+
+function greedyFAS(g, weightFn) {
+  if (g.nodeCount() <= 1) {
+    return [];
+  }
+  var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN);
+  var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx);
+
+  // Expand multi-edges
+  return _.flatten(_.map(results, function(e) {
+    return g.outEdges(e.v, e.w);
+  }), true);
+}
+
+function doGreedyFAS(g, buckets, zeroIdx) {
+  var results = [],
+      sources = buckets[buckets.length - 1],
+      sinks = buckets[0];
+
+  var entry;
+  while (g.nodeCount()) {
+    while ((entry = sinks.dequeue()))   { removeNode(g, buckets, zeroIdx, entry); }
+    while ((entry = sources.dequeue())) { removeNode(g, buckets, zeroIdx, entry); }
+    if (g.nodeCount()) {
+      for (var i = buckets.length - 2; i > 0; --i) {
+        entry = buckets[i].dequeue();
+        if (entry) {
+          results = results.concat(removeNode(g, buckets, zeroIdx, entry, true));
+          break;
+        }
+      }
+    }
+  }
+
+  return results;
+}
+
+function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) {
+  var results = collectPredecessors ? [] : undefined;
+
+  _.each(g.inEdges(entry.v), function(edge) {
+    var weight = g.edge(edge),
+        uEntry = g.node(edge.v);
+
+    if (collectPredecessors) {
+      results.push({ v: edge.v, w: edge.w });
+    }
+
+    uEntry.out -= weight;
+    assignBucket(buckets, zeroIdx, uEntry);
+  });
+
+  _.each(g.outEdges(entry.v), function(edge) {
+    var weight = g.edge(edge),
+        w = edge.w,
+        wEntry = g.node(w);
+    wEntry["in"] -= weight;
+    assignBucket(buckets, zeroIdx, wEntry);
+  });
+
+  g.removeNode(entry.v);
+
+  return results;
+}
+
+function buildState(g, weightFn) {
+  var fasGraph = new Graph(),
+      maxIn = 0,
+      maxOut = 0;
+
+  _.each(g.nodes(), function(v) {
+    fasGraph.setNode(v, { v: v, "in": 0, out: 0 });
+  });
+
+  // Aggregate weights on nodes, but also sum the weights across multi-edges
+  // into a single edge for the fasGraph.
+  _.each(g.edges(), function(e) {
+    var prevWeight = fasGraph.edge(e.v, e.w) || 0,
+        weight = weightFn(e),
+        edgeWeight = prevWeight + weight;
+    fasGraph.setEdge(e.v, e.w, edgeWeight);
+    maxOut = Math.max(maxOut, fasGraph.node(e.v).out += weight);
+    maxIn  = Math.max(maxIn,  fasGraph.node(e.w)["in"]  += weight);
+  });
+
+  var buckets = _.range(maxOut + maxIn + 3).map(function() { return new List(); });
+  var zeroIdx = maxIn + 1;
+
+  _.each(fasGraph.nodes(), function(v) {
+    assignBucket(buckets, zeroIdx, fasGraph.node(v));
+  });
+
+  return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx };
+}
+
+function assignBucket(buckets, zeroIdx, entry) {
+  if (!entry.out) {
+    buckets[0].enqueue(entry);
+  } else if (!entry["in"]) {
+    buckets[buckets.length - 1].enqueue(entry);
+  } else {
+    buckets[entry.out - entry["in"] + zeroIdx].enqueue(entry);
+  }
+}
+
+},{"./data/list":5,"./graphlib":7,"./lodash":10}],9:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash"),
+    acyclic = require("./acyclic"),
+    normalize = require("./normalize"),
+    rank = require("./rank"),
+    normalizeRanks = require("./util").normalizeRanks,
+    parentDummyChains = require("./parent-dummy-chains"),
+    removeEmptyRanks = require("./util").removeEmptyRanks,
+    nestingGraph = require("./nesting-graph"),
+    addBorderSegments = require("./add-border-segments"),
+    coordinateSystem = require("./coordinate-system"),
+    order = require("./order"),
+    position = require("./position"),
+    util = require("./util"),
+    Graph = require("./graphlib").Graph;
+
+module.exports = layout;
+
+function layout(g, opts) {
+  var time = opts && opts.debugTiming ? util.time : util.notime;
+  time("layout", function() {
+    var layoutGraph = time("  buildLayoutGraph",
+                               function() { return buildLayoutGraph(g); });
+    time("  runLayout",        function() { runLayout(layoutGraph, time); });
+    time("  updateInputGraph", function() { updateInputGraph(g, layoutGraph); });
+  });
+}
+
+function runLayout(g, time) {
+  time("    makeSpaceForEdgeLabels", function() { makeSpaceForEdgeLabels(g); });
+  time("    removeSelfEdges",        function() { removeSelfEdges(g); });
+  time("    acyclic",                function() { acyclic.run(g); });
+  time("    nestingGraph.run",       function() { nestingGraph.run(g); });
+  time("    rank",                   function() { rank(util.asNonCompoundGraph(g)); });
+  time("    injectEdgeLabelProxies", function() { injectEdgeLabelProxies(g); });
+  time("    removeEmptyRanks",       function() { removeEmptyRanks(g); });
+  time("    nestingGraph.cleanup",   function() { nestingGraph.cleanup(g); });
+  time("    normalizeRanks",         function() { normalizeRanks(g); });
+  time("    assignRankMinMax",       function() { assignRankMinMax(g); });
+  time("    removeEdgeLabelProxies", function() { removeEdgeLabelProxies(g); });
+  time("    normalize.run",          function() { normalize.run(g); });
+  time("    parentDummyChains",      function() { parentDummyChains(g); });
+  time("    addBorderSegments",      function() { addBorderSegments(g); });
+  time("    order",                  function() { order(g); });
+  time("    insertSelfEdges",        function() { insertSelfEdges(g); });
+  time("    adjustCoordinateSystem", function() { coordinateSystem.adjust(g); });
+  time("    position",               function() { position(g); });
+  time("    positionSelfEdges",      function() { positionSelfEdges(g); });
+  time("    removeBorderNodes",      function() { removeBorderNodes(g); });
+  time("    normalize.undo",         function() { normalize.undo(g); });
+  time("    fixupEdgeLabelCoords",   function() { fixupEdgeLabelCoords(g); });
+  time("    undoCoordinateSystem",   function() { coordinateSystem.undo(g); });
+  time("    translateGraph",         function() { translateGraph(g); });
+  time("    assignNodeIntersects",   function() { assignNodeIntersects(g); });
+  time("    reversePoints",          function() { reversePointsForReversedEdges(g); });
+  time("    acyclic.undo",           function() { acyclic.undo(g); });
+}
+
+/*
+ * Copies final layout information from the layout graph back to the input
+ * graph. This process only copies whitelisted attributes from the layout graph
+ * to the input graph, so it serves as a good place to determine what
+ * attributes can influence layout.
+ */
+function updateInputGraph(inputGraph, layoutGraph) {
+  _.each(inputGraph.nodes(), function(v) {
+    var inputLabel = inputGraph.node(v),
+        layoutLabel = layoutGraph.node(v);
+
+    if (inputLabel) {
+      inputLabel.x = layoutLabel.x;
+      inputLabel.y = layoutLabel.y;
+
+      if (layoutGraph.children(v).length) {
+        inputLabel.width = layoutLabel.width;
+        inputLabel.height = layoutLabel.height;
+      }
+    }
+  });
+
+  _.each(inputGraph.edges(), function(e) {
+    var inputLabel = inputGraph.edge(e),
+        layoutLabel = layoutGraph.edge(e);
+
+    inputLabel.points = layoutLabel.points;
+    if (_.has(layoutLabel, "x")) {
+      inputLabel.x = layoutLabel.x;
+      inputLabel.y = layoutLabel.y;
+    }
+  });
+
+  inputGraph.graph().width = layoutGraph.graph().width;
+  inputGraph.graph().height = layoutGraph.graph().height;
+}
+
+var graphNumAttrs = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"],
+    graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: "tb" },
+    graphAttrs = ["acyclicer", "ranker", "rankdir", "align"],
+    nodeNumAttrs = ["width", "height"],
+    nodeDefaults = { width: 0, height: 0 },
+    edgeNumAttrs = ["minlen", "weight", "width", "height", "labeloffset"],
+    edgeDefaults = {
+      minlen: 1, weight: 1, width: 0, height: 0,
+      labeloffset: 10, labelpos: "r"
+    },
+    edgeAttrs = ["labelpos"];
+
+/*
+ * Constructs a new graph from the input graph, which can be used for layout.
+ * This process copies only whitelisted attributes from the input graph to the
+ * layout graph. Thus this function serves as a good place to determine what
+ * attributes can influence layout.
+ */
+function buildLayoutGraph(inputGraph) {
+  var g = new Graph({ multigraph: true, compound: true }),
+      graph = canonicalize(inputGraph.graph());
+
+  g.setGraph(_.merge({},
+    graphDefaults,
+    selectNumberAttrs(graph, graphNumAttrs),
+    _.pick(graph, graphAttrs)));
+
+  _.each(inputGraph.nodes(), function(v) {
+    var node = canonicalize(inputGraph.node(v));
+    g.setNode(v, _.defaults(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults));
+    g.setParent(v, inputGraph.parent(v));
+  });
+
+  _.each(inputGraph.edges(), function(e) {
+    var edge = canonicalize(inputGraph.edge(e));
+    g.setEdge(e, _.merge({},
+      edgeDefaults,
+      selectNumberAttrs(edge, edgeNumAttrs),
+      _.pick(edge, edgeAttrs)));
+  });
+
+  return g;
+}
+
+/*
+ * This idea comes from the Gansner paper: to account for edge labels in our
+ * layout we split each rank in half by doubling minlen and halving ranksep.
+ * Then we can place labels at these mid-points between nodes.
+ *
+ * We also add some minimal padding to the width to push the label for the edge
+ * away from the edge itself a bit.
+ */
+function makeSpaceForEdgeLabels(g) {
+  var graph = g.graph();
+  graph.ranksep /= 2;
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    edge.minlen *= 2;
+    if (edge.labelpos.toLowerCase() !== "c") {
+      if (graph.rankdir === "TB" || graph.rankdir === "BT") {
+        edge.width += edge.labeloffset;
+      } else {
+        edge.height += edge.labeloffset;
+      }
+    }
+  });
+}
+
+/*
+ * Creates temporary dummy nodes that capture the rank in which each edge's
+ * label is going to, if it has one of non-zero width and height. We do this
+ * so that we can safely remove empty ranks while preserving balance for the
+ * label's position.
+ */
+function injectEdgeLabelProxies(g) {
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    if (edge.width && edge.height) {
+      var v = g.node(e.v),
+          w = g.node(e.w),
+          label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e };
+      util.addDummyNode(g, "edge-proxy", label, "_ep");
+    }
+  });
+}
+
+function assignRankMinMax(g) {
+  var maxRank = 0;
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v);
+    if (node.borderTop) {
+      node.minRank = g.node(node.borderTop).rank;
+      node.maxRank = g.node(node.borderBottom).rank;
+      maxRank = _.max(maxRank, node.maxRank);
+    }
+  });
+  g.graph().maxRank = maxRank;
+}
+
+function removeEdgeLabelProxies(g) {
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v);
+    if (node.dummy === "edge-proxy") {
+      g.edge(node.e).labelRank = node.rank;
+      g.removeNode(v);
+    }
+  });
+}
+
+function translateGraph(g) {
+  var minX = Number.POSITIVE_INFINITY,
+      maxX = 0,
+      minY = Number.POSITIVE_INFINITY,
+      maxY = 0,
+      graphLabel = g.graph(),
+      marginX = graphLabel.marginx || 0,
+      marginY = graphLabel.marginy || 0;
+
+  function getExtremes(attrs) {
+    var x = attrs.x,
+        y = attrs.y,
+        w = attrs.width,
+        h = attrs.height;
+    minX = Math.min(minX, x - w / 2);
+    maxX = Math.max(maxX, x + w / 2);
+    minY = Math.min(minY, y - h / 2);
+    maxY = Math.max(maxY, y + h / 2);
+  }
+
+  _.each(g.nodes(), function(v) { getExtremes(g.node(v)); });
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    if (_.has(edge, "x")) {
+      getExtremes(edge);
+    }
+  });
+
+  minX -= marginX;
+  minY -= marginY;
+
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v);
+    node.x -= minX;
+    node.y -= minY;
+  });
+
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    _.each(edge.points, function(p) {
+      p.x -= minX;
+      p.y -= minY;
+    });
+    if (_.has(edge, "x")) { edge.x -= minX; }
+    if (_.has(edge, "y")) { edge.y -= minY; }
+  });
+
+  graphLabel.width = maxX - minX + marginX;
+  graphLabel.height = maxY - minY + marginY;
+}
+
+function assignNodeIntersects(g) {
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e),
+        nodeV = g.node(e.v),
+        nodeW = g.node(e.w),
+        p1, p2;
+    if (!edge.points) {
+      edge.points = [];
+      p1 = nodeW;
+      p2 = nodeV;
+    } else {
+      p1 = edge.points[0];
+      p2 = edge.points[edge.points.length - 1];
+    }
+    edge.points.unshift(util.intersectRect(nodeV, p1));
+    edge.points.push(util.intersectRect(nodeW, p2));
+  });
+}
+
+function fixupEdgeLabelCoords(g) {
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    if (_.has(edge, "x")) {
+      if (edge.labelpos === "l" || edge.labelpos === "r") {
+        edge.width -= edge.labeloffset;
+      }
+      switch (edge.labelpos) {
+        case "l": edge.x -= edge.width / 2 + edge.labeloffset; break;
+        case "r": edge.x += edge.width / 2 + edge.labeloffset; break;
+      }
+    }
+  });
+}
+
+function reversePointsForReversedEdges(g) {
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    if (edge.reversed) {
+      edge.points.reverse();
+    }
+  });
+}
+
+function removeBorderNodes(g) {
+  _.each(g.nodes(), function(v) {
+    if (g.children(v).length) {
+      var node = g.node(v),
+          t = g.node(node.borderTop),
+          b = g.node(node.borderBottom),
+          l = g.node(_.last(node.borderLeft)),
+          r = g.node(_.last(node.borderRight));
+
+      node.width = Math.abs(r.x - l.x);
+      node.height = Math.abs(b.y - t.y);
+      node.x = l.x + node.width / 2;
+      node.y = t.y + node.height / 2;
+    }
+  });
+
+  _.each(g.nodes(), function(v) {
+    if (g.node(v).dummy === "border") {
+      g.removeNode(v);
+    }
+  });
+}
+
+function removeSelfEdges(g) {
+  _.each(g.edges(), function(e) {
+    if (e.v === e.w) {
+      var node = g.node(e.v);
+      if (!node.selfEdges) {
+        node.selfEdges = [];
+      }
+      node.selfEdges.push({ e: e, label: g.edge(e) });
+      g.removeEdge(e);
+    }
+  });
+}
+
+function insertSelfEdges(g) {
+  var layers = util.buildLayerMatrix(g);
+  _.each(layers, function(layer) {
+    var orderShift = 0;
+    _.each(layer, function(v, i) {
+      var node = g.node(v);
+      node.order = i + orderShift;
+      _.each(node.selfEdges, function(selfEdge) {
+        util.addDummyNode(g, "selfedge", {
+          width: selfEdge.label.width,
+          height: selfEdge.label.height,
+          rank: node.rank,
+          order: i + (++orderShift),
+          e: selfEdge.e,
+          label: selfEdge.label
+        }, "_se");
+      });
+      delete node.selfEdges;
+    });
+  });
+}
+
+function positionSelfEdges(g) {
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v);
+    if (node.dummy === "selfedge") {
+      var selfNode = g.node(node.e.v),
+          x = selfNode.x + selfNode.width / 2,
+          y = selfNode.y,
+          dx = node.x - x,
+          dy = selfNode.height / 2;
+      g.setEdge(node.e, node.label);
+      g.removeNode(v);
+      node.label.points = [
+        { x: x + 2 * dx / 3, y: y - dy },
+        { x: x + 5 * dx / 6, y: y - dy },
+        { x: x +     dx    , y: y },
+        { x: x + 5 * dx / 6, y: y + dy },
+        { x: x + 2 * dx / 3, y: y + dy },
+      ];
+      node.label.x = node.x;
+      node.label.y = node.y;
+    }
+  });
+}
+
+function selectNumberAttrs(obj, attrs) {
+  return _.mapValues(_.pick(obj, attrs), Number);
+}
+
+function canonicalize(attrs) {
+  var newAttrs = {};
+  _.each(attrs, function(v, k) {
+    newAttrs[k.toLowerCase()] = v;
+  });
+  return newAttrs;
+}
+
+},{"./acyclic":2,"./add-border-segments":3,"./coordinate-system":4,"./graphlib":7,"./lodash":10,"./nesting-graph":11,"./normalize":12,"./order":17,"./parent-dummy-chains":22,"./position":24,"./rank":26,"./util":29}],10:[function(require,module,exports){
+/* global window */
+
+var lodash;
+
+if (require) {
+  try {
+    lodash = require("lodash");
+  } catch (e) {}
+}
+
+if (!lodash) {
+  lodash = window._;
+}
+
+module.exports = lodash;
+
+},{"lodash":51}],11:[function(require,module,exports){
+var _ = require("./lodash"),
+    util = require("./util");
+
+module.exports = {
+  run: run,
+  cleanup: cleanup
+};
+
+/*
+ * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs,
+ * adds appropriate edges to ensure that all cluster nodes are placed between
+ * these boundries, and ensures that the graph is connected.
+ *
+ * In addition we ensure, through the use of the minlen property, that nodes
+ * and subgraph border nodes to not end up on the same rank.
+ *
+ * Preconditions:
+ *
+ *    1. Input graph is a DAG
+ *    2. Nodes in the input graph has a minlen attribute
+ *
+ * Postconditions:
+ *
+ *    1. Input graph is connected.
+ *    2. Dummy nodes are added for the tops and bottoms of subgraphs.
+ *    3. The minlen attribute for nodes is adjusted to ensure nodes do not
+ *       get placed on the same rank as subgraph border nodes.
+ *
+ * The nesting graph idea comes from Sander, "Layout of Compound Directed
+ * Graphs."
+ */
+function run(g) {
+  var root = util.addDummyNode(g, "root", {}, "_root"),
+      depths = treeDepths(g),
+      height = _.max(depths) - 1,
+      nodeSep = 2 * height + 1;
+
+  g.graph().nestingRoot = root;
+
+  // Multiply minlen by nodeSep to align nodes on non-border ranks.
+  _.each(g.edges(), function(e) { g.edge(e).minlen *= nodeSep; });
+
+  // Calculate a weight that is sufficient to keep subgraphs vertically compact
+  var weight = sumWeights(g) + 1;
+
+  // Create border nodes and link them up
+  _.each(g.children(), function(child) {
+    dfs(g, root, nodeSep, weight, height, depths, child);
+  });
+
+  // Save the multiplier for node layers for later removal of empty border
+  // layers.
+  g.graph().nodeRankFactor = nodeSep;
+}
+
+function dfs(g, root, nodeSep, weight, height, depths, v) {
+  var children = g.children(v);
+  if (!children.length) {
+    if (v !== root) {
+      g.setEdge(root, v, { weight: 0, minlen: nodeSep });
+    }
+    return;
+  }
+
+  var top = util.addBorderNode(g, "_bt"),
+      bottom = util.addBorderNode(g, "_bb"),
+      label = g.node(v);
+
+  g.setParent(top, v);
+  label.borderTop = top;
+  g.setParent(bottom, v);
+  label.borderBottom = bottom;
+
+  _.each(children, function(child) {
+    dfs(g, root, nodeSep, weight, height, depths, child);
+
+    var childNode = g.node(child),
+        childTop = childNode.borderTop ? childNode.borderTop : child,
+        childBottom = childNode.borderBottom ? childNode.borderBottom : child,
+        thisWeight = childNode.borderTop ? weight : 2 * weight,
+        minlen = childTop !== childBottom ? 1 : height - depths[v] + 1;
+
+    g.setEdge(top, childTop, {
+      weight: thisWeight,
+      minlen: minlen,
+      nestingEdge: true
+    });
+
+    g.setEdge(childBottom, bottom, {
+      weight: thisWeight,
+      minlen: minlen,
+      nestingEdge: true
+    });
+  });
+
+  if (!g.parent(v)) {
+    g.setEdge(root, top, { weight: 0, minlen: height + depths[v] });
+  }
+}
+
+function treeDepths(g) {
+  var depths = {};
+  function dfs(v, depth) {
+    var children = g.children(v);
+    if (children && children.length) {
+      _.each(children, function(child) {
+        dfs(child, depth + 1);
+      });
+    }
+    depths[v] = depth;
+  }
+  _.each(g.children(), function(v) { dfs(v, 1); });
+  return depths;
+}
+
+function sumWeights(g) {
+  return _.reduce(g.edges(), function(acc, e) {
+    return acc + g.edge(e).weight;
+  }, 0);
+}
+
+function cleanup(g) {
+  var graphLabel = g.graph();
+  g.removeNode(graphLabel.nestingRoot);
+  delete graphLabel.nestingRoot;
+  _.each(g.edges(), function(e) {
+    var edge = g.edge(e);
+    if (edge.nestingEdge) {
+      g.removeEdge(e);
+    }
+  });
+}
+
+},{"./lodash":10,"./util":29}],12:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash"),
+    util = require("./util");
+
+module.exports = {
+  run: run,
+  undo: undo
+};
+
+/*
+ * Breaks any long edges in the graph into short segments that span 1 layer
+ * each. This operation is undoable with the denormalize function.
+ *
+ * Pre-conditions:
+ *
+ *    1. The input graph is a DAG.
+ *    2. Each node in the graph has a "rank" property.
+ *
+ * Post-condition:
+ *
+ *    1. All edges in the graph have a length of 1.
+ *    2. Dummy nodes are added where edges have been split into segments.
+ *    3. The graph is augmented with a "dummyChains" attribute which contains
+ *       the first dummy in each chain of dummy nodes produced.
+ */
+function run(g) {
+  g.graph().dummyChains = [];
+  _.each(g.edges(), function(edge) { normalizeEdge(g, edge); });
+}
+
+function normalizeEdge(g, e) {
+  var v = e.v,
+      vRank = g.node(v).rank,
+      w = e.w,
+      wRank = g.node(w).rank,
+      name = e.name,
+      edgeLabel = g.edge(e),
+      labelRank = edgeLabel.labelRank;
+
+  if (wRank === vRank + 1) return;
+
+  g.removeEdge(e);
+
+  var dummy, attrs, i;
+  for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) {
+    edgeLabel.points = [];
+    attrs = {
+      width: 0, height: 0,
+      edgeLabel: edgeLabel, edgeObj: e,
+      rank: vRank
+    };
+    dummy = util.addDummyNode(g, "edge", attrs, "_d");
+    if (vRank === labelRank) {
+      attrs.width = edgeLabel.width;
+      attrs.height = edgeLabel.height;
+      attrs.dummy = "edge-label";
+      attrs.labelpos = edgeLabel.labelpos;
+    }
+    g.setEdge(v, dummy, { weight: edgeLabel.weight }, name);
+    if (i === 0) {
+      g.graph().dummyChains.push(dummy);
+    }
+    v = dummy;
+  }
+
+  g.setEdge(v, w, { weight: edgeLabel.weight }, name);
+}
+
+function undo(g) {
+  _.each(g.graph().dummyChains, function(v) {
+    var node = g.node(v),
+        origLabel = node.edgeLabel,
+        w;
+    g.setEdge(node.edgeObj, origLabel);
+    while (node.dummy) {
+      w = g.successors(v)[0];
+      g.removeNode(v);
+      origLabel.points.push({ x: node.x, y: node.y });
+      if (node.dummy === "edge-label") {
+        origLabel.x = node.x;
+        origLabel.y = node.y;
+        origLabel.width = node.width;
+        origLabel.height = node.height;
+      }
+      v = w;
+      node = g.node(v);
+    }
+  });
+}
+
+},{"./lodash":10,"./util":29}],13:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = addSubgraphConstraints;
+
+function addSubgraphConstraints(g, cg, vs) {
+  var prev = {},
+      rootPrev;
+
+  _.each(vs, function(v) {
+    var child = g.parent(v),
+        parent,
+        prevChild;
+    while (child) {
+      parent = g.parent(child);
+      if (parent) {
+        prevChild = prev[parent];
+        prev[parent] = child;
+      } else {
+        prevChild = rootPrev;
+        rootPrev = child;
+      }
+      if (prevChild && prevChild !== child) {
+        cg.setEdge(prevChild, child);
+        return;
+      }
+      child = parent;
+    }
+  });
+
+  /*
+  function dfs(v) {
+    var children = v ? g.children(v) : g.children();
+    if (children.length) {
+      var min = Number.POSITIVE_INFINITY,
+          subgraphs = [];
+      _.each(children, function(child) {
+        var childMin = dfs(child);
+        if (g.children(child).length) {
+          subgraphs.push({ v: child, order: childMin });
+        }
+        min = Math.min(min, childMin);
+      });
+      _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) {
+        cg.setEdge(prev.v, curr.v);
+        return curr;
+      });
+      return min;
+    }
+    return g.node(v).order;
+  }
+  dfs(undefined);
+  */
+}
+
+},{"../lodash":10}],14:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = barycenter;
+
+function barycenter(g, movable) {
+  return _.map(movable, function(v) {
+    var inV = g.inEdges(v);
+    if (!inV.length) {
+      return { v: v };
+    } else {
+      var result = _.reduce(inV, function(acc, e) {
+        var edge = g.edge(e),
+            nodeU = g.node(e.v);
+        return {
+          sum: acc.sum + (edge.weight * nodeU.order),
+          weight: acc.weight + edge.weight
+        };
+      }, { sum: 0, weight: 0 });
+
+      return {
+        v: v,
+        barycenter: result.sum / result.weight,
+        weight: result.weight
+      };
+    }
+  });
+}
+
+
+},{"../lodash":10}],15:[function(require,module,exports){
+var _ = require("../lodash"),
+    Graph = require("../graphlib").Graph;
+
+module.exports = buildLayerGraph;
+
+/*
+ * Constructs a graph that can be used to sort a layer of nodes. The graph will
+ * contain all base and subgraph nodes from the request layer in their original
+ * hierarchy and any edges that are incident on these nodes and are of the type
+ * requested by the "relationship" parameter.
+ *
+ * Nodes from the requested rank that do not have parents are assigned a root
+ * node in the output graph, which is set in the root graph attribute. This
+ * makes it easy to walk the hierarchy of movable nodes during ordering.
+ *
+ * Pre-conditions:
+ *
+ *    1. Input graph is a DAG
+ *    2. Base nodes in the input graph have a rank attribute
+ *    3. Subgraph nodes in the input graph has minRank and maxRank attributes
+ *    4. Edges have an assigned weight
+ *
+ * Post-conditions:
+ *
+ *    1. Output graph has all nodes in the movable rank with preserved
+ *       hierarchy.
+ *    2. Root nodes in the movable layer are made children of the node
+ *       indicated by the root attribute of the graph.
+ *    3. Non-movable nodes incident on movable nodes, selected by the
+ *       relationship parameter, are included in the graph (without hierarchy).
+ *    4. Edges incident on movable nodes, selected by the relationship
+ *       parameter, are added to the output graph.
+ *    5. The weights for copied edges are aggregated as need, since the output
+ *       graph is not a multi-graph.
+ */
+function buildLayerGraph(g, rank, relationship) {
+  var root = createRootNode(g),
+      result = new Graph({ compound: true }).setGraph({ root: root })
+                  .setDefaultNodeLabel(function(v) { return g.node(v); });
+
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v),
+        parent = g.parent(v);
+
+    if (node.rank === rank || node.minRank <= rank && rank <= node.maxRank) {
+      result.setNode(v);
+      result.setParent(v, parent || root);
+
+      // This assumes we have only short edges!
+      _.each(g[relationship](v), function(e) {
+        var u = e.v === v ? e.w : e.v,
+            edge = result.edge(u, v),
+            weight = !_.isUndefined(edge) ? edge.weight : 0;
+        result.setEdge(u, v, { weight: g.edge(e).weight + weight });
+      });
+
+      if (_.has(node, "minRank")) {
+        result.setNode(v, {
+          borderLeft: node.borderLeft[rank],
+          borderRight: node.borderRight[rank]
+        });
+      }
+    }
+  });
+
+  return result;
+}
+
+function createRootNode(g) {
+  var v;
+  while (g.hasNode((v = _.uniqueId("_root"))));
+  return v;
+}
+
+},{"../graphlib":7,"../lodash":10}],16:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash");
+
+module.exports = crossCount;
+
+/*
+ * A function that takes a layering (an array of layers, each with an array of
+ * ordererd nodes) and a graph and returns a weighted crossing count.
+ *
+ * Pre-conditions:
+ *
+ *    1. Input graph must be simple (not a multigraph), directed, and include
+ *       only simple edges.
+ *    2. Edges in the input graph must have assigned weights.
+ *
+ * Post-conditions:
+ *
+ *    1. The graph and layering matrix are left unchanged.
+ *
+ * This algorithm is derived from Barth, et al., "Bilayer Cross Counting."
+ */
+function crossCount(g, layering) {
+  var cc = 0;
+  for (var i = 1; i < layering.length; ++i) {
+    cc += twoLayerCrossCount(g, layering[i-1], layering[i]);
+  }
+  return cc;
+}
+
+function twoLayerCrossCount(g, northLayer, southLayer) {
+  // Sort all of the edges between the north and south layers by their position
+  // in the north layer and then the south. Map these edges to the position of
+  // their head in the south layer.
+  var southPos = _.zipObject(southLayer,
+                             _.map(southLayer, function (v, i) { return i; }));
+  var southEntries = _.flatten(_.map(northLayer, function(v) {
+    return _.chain(g.outEdges(v))
+            .map(function(e) {
+              return { pos: southPos[e.w], weight: g.edge(e).weight };
+            })
+            .sortBy("pos")
+            .value();
+  }), true);
+
+  // Build the accumulator tree
+  var firstIndex = 1;
+  while (firstIndex < southLayer.length) firstIndex <<= 1;
+  var treeSize = 2 * firstIndex - 1;
+  firstIndex -= 1;
+  var tree = _.map(new Array(treeSize), function() { return 0; });
+
+  // Calculate the weighted crossings
+  var cc = 0;
+  _.each(southEntries.forEach(function(entry) {
+    var index = entry.pos + firstIndex;
+    tree[index] += entry.weight;
+    var weightSum = 0;
+    while (index > 0) {
+      if (index % 2) {
+        weightSum += tree[index + 1];
+      }
+      index = (index - 1) >> 1;
+      tree[index] += entry.weight;
+    }
+    cc += entry.weight * weightSum;
+  }));
+
+  return cc;
+}
+
+},{"../lodash":10}],17:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash"),
+    initOrder = require("./init-order"),
+    crossCount = require("./cross-count"),
+    sortSubgraph = require("./sort-subgraph"),
+    buildLayerGraph = require("./build-layer-graph"),
+    addSubgraphConstraints = require("./add-subgraph-constraints"),
+    Graph = require("../graphlib").Graph,
+    util = require("../util");
+
+module.exports = order;
+
+/*
+ * Applies heuristics to minimize edge crossings in the graph and sets the best
+ * order solution as an order attribute on each node.
+ *
+ * Pre-conditions:
+ *
+ *    1. Graph must be DAG
+ *    2. Graph nodes must be objects with a "rank" attribute
+ *    3. Graph edges must have the "weight" attribute
+ *
+ * Post-conditions:
+ *
+ *    1. Graph nodes will have an "order" attribute based on the results of the
+ *       algorithm.
+ */
+function order(g) {
+  var maxRank = util.maxRank(g),
+      downLayerGraphs = buildLayerGraphs(g, _.range(1, maxRank + 1), "inEdges"),
+      upLayerGraphs = buildLayerGraphs(g, _.range(maxRank - 1, -1, -1), "outEdges");
+
+  var layering = initOrder(g);
+  assignOrder(g, layering);
+
+  var bestCC = Number.POSITIVE_INFINITY,
+      best;
+
+  for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) {
+    sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2);
+
+    layering = util.buildLayerMatrix(g);
+    var cc = crossCount(g, layering);
+    if (cc < bestCC) {
+      lastBest = 0;
+      best = _.cloneDeep(layering);
+      bestCC = cc;
+    }
+  }
+
+  assignOrder(g, best);
+}
+
+function buildLayerGraphs(g, ranks, relationship) {
+  return _.map(ranks, function(rank) {
+    return buildLayerGraph(g, rank, relationship);
+  });
+}
+
+function sweepLayerGraphs(layerGraphs, biasRight) {
+  var cg = new Graph();
+  _.each(layerGraphs, function(lg) {
+    var root = lg.graph().root;
+    var sorted = sortSubgraph(lg, root, cg, biasRight);
+    _.each(sorted.vs, function(v, i) {
+      lg.node(v).order = i;
+    });
+    addSubgraphConstraints(lg, cg, sorted.vs);
+  });
+}
+
+function assignOrder(g, layering) {
+  _.each(layering, function(layer) {
+    _.each(layer, function(v, i) {
+      g.node(v).order = i;
+    });
+  });
+}
+
+},{"../graphlib":7,"../lodash":10,"../util":29,"./add-subgraph-constraints":13,"./build-layer-graph":15,"./cross-count":16,"./init-order":18,"./sort-subgraph":20}],18:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash");
+
+module.exports = initOrder;
+
+/*
+ * Assigns an initial order value for each node by performing a DFS search
+ * starting from nodes in the first rank. Nodes are assigned an order in their
+ * rank as they are first visited.
+ *
+ * This approach comes from Gansner, et al., "A Technique for Drawing Directed
+ * Graphs."
+ *
+ * Returns a layering matrix with an array per layer and each layer sorted by
+ * the order of its nodes.
+ */
+function initOrder(g) {
+  var visited = {},
+      simpleNodes = _.filter(g.nodes(), function(v) {
+        return !g.children(v).length;
+      }),
+      maxRank = _.max(_.map(simpleNodes, function(v) { return g.node(v).rank; })),
+      layers = _.map(_.range(maxRank + 1), function() { return []; });
+
+  function dfs(v) {
+    if (_.has(visited, v)) return;
+    visited[v] = true;
+    var node = g.node(v);
+    layers[node.rank].push(v);
+    _.each(g.successors(v), dfs);
+  }
+
+  var orderedVs = _.sortBy(simpleNodes, function(v) { return g.node(v).rank; });
+  _.each(orderedVs, dfs);
+
+  return layers;
+}
+
+},{"../lodash":10}],19:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash");
+
+module.exports = resolveConflicts;
+
+/*
+ * Given a list of entries of the form {v, barycenter, weight} and a
+ * constraint graph this function will resolve any conflicts between the
+ * constraint graph and the barycenters for the entries. If the barycenters for
+ * an entry would violate a constraint in the constraint graph then we coalesce
+ * the nodes in the conflict into a new node that respects the contraint and
+ * aggregates barycenter and weight information.
+ *
+ * This implementation is based on the description in Forster, "A Fast and
+ * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it
+ * differs in some specific details.
+ *
+ * Pre-conditions:
+ *
+ *    1. Each entry has the form {v, barycenter, weight}, or if the node has
+ *       no barycenter, then {v}.
+ *
+ * Returns:
+ *
+ *    A new list of entries of the form {vs, i, barycenter, weight}. The list
+ *    `vs` may either be a singleton or it may be an aggregation of nodes
+ *    ordered such that they do not violate constraints from the constraint
+ *    graph. The property `i` is the lowest original index of any of the
+ *    elements in `vs`.
+ */
+function resolveConflicts(entries, cg) {
+  var mappedEntries = {};
+  _.each(entries, function(entry, i) {
+    var tmp = mappedEntries[entry.v] = {
+      indegree: 0,
+      "in": [],
+      out: [],
+      vs: [entry.v],
+      i: i
+    };
+    if (!_.isUndefined(entry.barycenter)) {
+      tmp.barycenter = entry.barycenter;
+      tmp.weight = entry.weight;
+    }
+  });
+
+  _.each(cg.edges(), function(e) {
+    var entryV = mappedEntries[e.v],
+        entryW = mappedEntries[e.w];
+    if (!_.isUndefined(entryV) && !_.isUndefined(entryW)) {
+      entryW.indegree++;
+      entryV.out.push(mappedEntries[e.w]);
+    }
+  });
+
+  var sourceSet = _.filter(mappedEntries, function(entry) {
+    return !entry.indegree;
+  });
+
+  return doResolveConflicts(sourceSet);
+}
+
+function doResolveConflicts(sourceSet) {
+  var entries = [];
+
+  function handleIn(vEntry) {
+    return function(uEntry) {
+      if (uEntry.merged) {
+        return;
+      }
+      if (_.isUndefined(uEntry.barycenter) ||
+          _.isUndefined(vEntry.barycenter) ||
+          uEntry.barycenter >= vEntry.barycenter) {
+        mergeEntries(vEntry, uEntry);
+      }
+    };
+  }
+
+  function handleOut(vEntry) {
+    return function(wEntry) {
+      wEntry["in"].push(vEntry);
+      if (--wEntry.indegree === 0) {
+        sourceSet.push(wEntry);
+      }
+    };
+  }
+
+  while (sourceSet.length) {
+    var entry = sourceSet.pop();
+    entries.push(entry);
+    _.each(entry["in"].reverse(), handleIn(entry));
+    _.each(entry.out, handleOut(entry));
+  }
+
+  return _.chain(entries)
+          .filter(function(entry) { return !entry.merged; })
+          .map(function(entry) {
+            return _.pick(entry, ["vs", "i", "barycenter", "weight"]);
+          })
+          .value();
+}
+
+function mergeEntries(target, source) {
+  var sum = 0,
+      weight = 0;
+
+  if (target.weight) {
+    sum += target.barycenter * target.weight;
+    weight += target.weight;
+  }
+
+  if (source.weight) {
+    sum += source.barycenter * source.weight;
+    weight += source.weight;
+  }
+
+  target.vs = source.vs.concat(target.vs);
+  target.barycenter = sum / weight;
+  target.weight = weight;
+  target.i = Math.min(source.i, target.i);
+  source.merged = true;
+}
+
+},{"../lodash":10}],20:[function(require,module,exports){
+var _ = require("../lodash"),
+    barycenter = require("./barycenter"),
+    resolveConflicts = require("./resolve-conflicts"),
+    sort = require("./sort");
+
+module.exports = sortSubgraph;
+
+function sortSubgraph(g, v, cg, biasRight) {
+  var movable = g.children(v),
+      node = g.node(v),
+      bl = node ? node.borderLeft : undefined,
+      br = node ? node.borderRight: undefined,
+      subgraphs = {};
+
+  if (bl) {
+    movable = _.filter(movable, function(w) {
+      return w !== bl && w !== br;
+    });
+  }
+
+  var barycenters = barycenter(g, movable);
+  _.each(barycenters, function(entry) {
+    if (g.children(entry.v).length) {
+      var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight);
+      subgraphs[entry.v] = subgraphResult;
+      if (_.has(subgraphResult, "barycenter")) {
+        mergeBarycenters(entry, subgraphResult);
+      }
+    }
+  });
+
+  var entries = resolveConflicts(barycenters, cg);
+  expandSubgraphs(entries, subgraphs);
+
+  var result = sort(entries, biasRight);
+
+  if (bl) {
+    result.vs = _.flatten([bl, result.vs, br], true);
+    if (g.predecessors(bl).length) {
+      var blPred = g.node(g.predecessors(bl)[0]),
+          brPred = g.node(g.predecessors(br)[0]);
+      if (!_.has(result, "barycenter")) {
+        result.barycenter = 0;
+        result.weight = 0;
+      }
+      result.barycenter = (result.barycenter * result.weight +
+                           blPred.order + brPred.order) / (result.weight + 2);
+      result.weight += 2;
+    }
+  }
+
+  return result;
+}
+
+function expandSubgraphs(entries, subgraphs) {
+  _.each(entries, function(entry) {
+    entry.vs = _.flatten(entry.vs.map(function(v) {
+      if (subgraphs[v]) {
+        return subgraphs[v].vs;
+      }
+      return v;
+    }), true);
+  });
+}
+
+function mergeBarycenters(target, other) {
+  if (!_.isUndefined(target.barycenter)) {
+    target.barycenter = (target.barycenter * target.weight +
+                         other.barycenter * other.weight) /
+                        (target.weight + other.weight);
+    target.weight += other.weight;
+  } else {
+    target.barycenter = other.barycenter;
+    target.weight = other.weight;
+  }
+}
+
+},{"../lodash":10,"./barycenter":14,"./resolve-conflicts":19,"./sort":21}],21:[function(require,module,exports){
+var _ = require("../lodash"),
+    util = require("../util");
+
+module.exports = sort;
+
+function sort(entries, biasRight) {
+  var parts = util.partition(entries, function(entry) {
+    return _.has(entry, "barycenter");
+  });
+  var sortable = parts.lhs,
+      unsortable = _.sortBy(parts.rhs, function(entry) { return -entry.i; }),
+      vs = [],
+      sum = 0,
+      weight = 0,
+      vsIndex = 0;
+
+  sortable.sort(compareWithBias(!!biasRight));
+
+  vsIndex = consumeUnsortable(vs, unsortable, vsIndex);
+
+  _.each(sortable, function (entry) {
+    vsIndex += entry.vs.length;
+    vs.push(entry.vs);
+    sum += entry.barycenter * entry.weight;
+    weight += entry.weight;
+    vsIndex = consumeUnsortable(vs, unsortable, vsIndex);
+  });
+
+  var result = { vs: _.flatten(vs, true) };
+  if (weight) {
+    result.barycenter = sum / weight;
+    result.weight = weight;
+  }
+  return result;
+}
+
+function consumeUnsortable(vs, unsortable, index) {
+  var last;
+  while (unsortable.length && (last = _.last(unsortable)).i <= index) {
+    unsortable.pop();
+    vs.push(last.vs);
+    index++;
+  }
+  return index;
+}
+
+function compareWithBias(bias) {
+  return function(entryV, entryW) {
+    if (entryV.barycenter < entryW.barycenter) {
+      return -1;
+    } else if (entryV.barycenter > entryW.barycenter) {
+      return 1;
+    }
+
+    return !bias ? entryV.i - entryW.i : entryW.i - entryV.i;
+  };
+}
+
+},{"../lodash":10,"../util":29}],22:[function(require,module,exports){
+var _ = require("./lodash");
+
+module.exports = parentDummyChains;
+
+function parentDummyChains(g) {
+  var postorderNums = postorder(g);
+
+  _.each(g.graph().dummyChains, function(v) {
+    var node = g.node(v),
+        edgeObj = node.edgeObj,
+        pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w),
+        path = pathData.path,
+        lca = pathData.lca,
+        pathIdx = 0,
+        pathV = path[pathIdx],
+        ascending = true;
+
+    while (v !== edgeObj.w) {
+      node = g.node(v);
+
+      if (ascending) {
+        while ((pathV = path[pathIdx]) !== lca &&
+               g.node(pathV).maxRank < node.rank) {
+          pathIdx++;
+        }
+
+        if (pathV === lca) {
+          ascending = false;
+        }
+      }
+
+      if (!ascending) {
+        while (pathIdx < path.length - 1 &&
+               g.node(pathV = path[pathIdx + 1]).minRank <= node.rank) {
+          pathIdx++;
+        }
+        pathV = path[pathIdx];
+      }
+
+      g.setParent(v, pathV);
+      v = g.successors(v)[0];
+    }
+  });
+}
+
+// Find a path from v to w through the lowest common ancestor (LCA). Return the
+// full path and the LCA.
+function findPath(g, postorderNums, v, w) {
+  var vPath = [],
+      wPath = [],
+      low = Math.min(postorderNums[v].low, postorderNums[w].low),
+      lim = Math.max(postorderNums[v].lim, postorderNums[w].lim),
+      parent,
+      lca;
+
+  // Traverse up from v to find the LCA
+  parent = v;
+  do {
+    parent = g.parent(parent);
+    vPath.push(parent);
+  } while (parent &&
+           (postorderNums[parent].low > low || lim > postorderNums[parent].lim));
+  lca = parent;
+
+  // Traverse from w to LCA
+  parent = w;
+  while ((parent = g.parent(parent)) !== lca) {
+    wPath.push(parent);
+  }
+
+  return { path: vPath.concat(wPath.reverse()), lca: lca };
+}
+
+function postorder(g) {
+  var result = {},
+      lim = 0;
+
+  function dfs(v) {
+    var low = lim;
+    _.each(g.children(v), dfs);
+    result[v] = { low: low, lim: lim++ };
+  }
+  _.each(g.children(), dfs);
+
+  return result;
+}
+
+},{"./lodash":10}],23:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash"),
+    Graph = require("../graphlib").Graph,
+    util = require("../util");
+
+/*
+ * This module provides coordinate assignment based on Brandes and Köpf, "Fast
+ * and Simple Horizontal Coordinate Assignment."
+ */
+
+module.exports = {
+  positionX: positionX,
+  findType1Conflicts: findType1Conflicts,
+  findType2Conflicts: findType2Conflicts,
+  addConflict: addConflict,
+  hasConflict: hasConflict,
+  verticalAlignment: verticalAlignment,
+  horizontalCompaction: horizontalCompaction,
+  alignCoordinates: alignCoordinates,
+  findSmallestWidthAlignment: findSmallestWidthAlignment,
+  balance: balance
+};
+
+/*
+ * Marks all edges in the graph with a type-1 conflict with the "type1Conflict"
+ * property. A type-1 conflict is one where a non-inner segment crosses an
+ * inner segment. An inner segment is an edge with both incident nodes marked
+ * with the "dummy" property.
+ *
+ * This algorithm scans layer by layer, starting with the second, for type-1
+ * conflicts between the current layer and the previous layer. For each layer
+ * it scans the nodes from left to right until it reaches one that is incident
+ * on an inner segment. It then scans predecessors to determine if they have
+ * edges that cross that inner segment. At the end a final scan is done for all
+ * nodes on the current rank to see if they cross the last visited inner
+ * segment.
+ *
+ * This algorithm (safely) assumes that a dummy node will only be incident on a
+ * single node in the layers being scanned.
+ */
+function findType1Conflicts(g, layering) {
+  var conflicts = {};
+
+  function visitLayer(prevLayer, layer) {
+    var
+      // last visited node in the previous layer that is incident on an inner
+      // segment.
+      k0 = 0,
+      // Tracks the last node in this layer scanned for crossings with a type-1
+      // segment.
+      scanPos = 0,
+      prevLayerLength = prevLayer.length,
+      lastNode = _.last(layer);
+
+    _.each(layer, function(v, i) {
+      var w = findOtherInnerSegmentNode(g, v),
+          k1 = w ? g.node(w).order : prevLayerLength;
+
+      if (w || v === lastNode) {
+        _.each(layer.slice(scanPos, i +1), function(scanNode) {
+          _.each(g.predecessors(scanNode), function(u) {
+            var uLabel = g.node(u),
+                uPos = uLabel.order;
+            if ((uPos < k0 || k1 < uPos) &&
+                !(uLabel.dummy && g.node(scanNode).dummy)) {
+              addConflict(conflicts, u, scanNode);
+            }
+          });
+        });
+        scanPos = i + 1;
+        k0 = k1;
+      }
+    });
+
+    return layer;
+  }
+
+  _.reduce(layering, visitLayer);
+  return conflicts;
+}
+
+function findType2Conflicts(g, layering) {
+  var conflicts = {};
+
+  function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) {
+    var v;
+    _.each(_.range(southPos, southEnd), function(i) {
+      v = south[i];
+      if (g.node(v).dummy) {
+        _.each(g.predecessors(v), function(u) {
+          var uNode = g.node(u);
+          if (uNode.dummy &&
+              (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) {
+            addConflict(conflicts, u, v);
+          }
+        });
+      }
+    });
+  }
+
+
+  function visitLayer(north, south) {
+    var prevNorthPos = -1,
+        nextNorthPos,
+        southPos = 0;
+
+    _.each(south, function(v, southLookahead) {
+      if (g.node(v).dummy === "border") {
+        var predecessors = g.predecessors(v);
+        if (predecessors.length) {
+          nextNorthPos = g.node(predecessors[0]).order;
+          scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos);
+          southPos = southLookahead;
+          prevNorthPos = nextNorthPos;
+        }
+      }
+      scan(south, southPos, south.length, nextNorthPos, north.length);
+    });
+
+    return south;
+  }
+
+  _.reduce(layering, visitLayer);
+  return conflicts;
+}
+
+function findOtherInnerSegmentNode(g, v) {
+  if (g.node(v).dummy) {
+    return _.find(g.predecessors(v), function(u) {
+      return g.node(u).dummy;
+    });
+  }
+}
+
+function addConflict(conflicts, v, w) {
+  if (v > w) {
+    var tmp = v;
+    v = w;
+    w = tmp;
+  }
+
+  var conflictsV = conflicts[v];
+  if (!conflictsV) {
+    conflicts[v] = conflictsV = {};
+  }
+  conflictsV[w] = true;
+}
+
+function hasConflict(conflicts, v, w) {
+  if (v > w) {
+    var tmp = v;
+    v = w;
+    w = tmp;
+  }
+  return _.has(conflicts[v], w);
+}
+
+/*
+ * Try to align nodes into vertical "blocks" where possible. This algorithm
+ * attempts to align a node with one of its median neighbors. If the edge
+ * connecting a neighbor is a type-1 conflict then we ignore that possibility.
+ * If a previous node has already formed a block with a node after the node
+ * we're trying to form a block with, we also ignore that possibility - our
+ * blocks would be split in that scenario.
+ */
+function verticalAlignment(g, layering, conflicts, neighborFn) {
+  var root = {},
+      align = {},
+      pos = {};
+
+  // We cache the position here based on the layering because the graph and
+  // layering may be out of sync. The layering matrix is manipulated to
+  // generate different extreme alignments.
+  _.each(layering, function(layer) {
+    _.each(layer, function(v, order) {
+      root[v] = v;
+      align[v] = v;
+      pos[v] = order;
+    });
+  });
+
+  _.each(layering, function(layer) {
+    var prevIdx = -1;
+    _.each(layer, function(v) {
+      var ws = neighborFn(v);
+      if (ws.length) {
+        ws = _.sortBy(ws, function(w) { return pos[w]; });
+        var mp = (ws.length - 1) / 2;
+        for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) {
+          var w = ws[i];
+          if (align[v] === v &&
+              prevIdx < pos[w] &&
+              !hasConflict(conflicts, v, w)) {
+            align[w] = v;
+            align[v] = root[v] = root[w];
+            prevIdx = pos[w];
+          }
+        }
+      }
+    });
+  });
+
+  return { root: root, align: align };
+}
+
+function horizontalCompaction(g, layering, root, align, reverseSep) {
+  // This portion of the algorithm differs from BK due to a number of problems.
+  // Instead of their algorithm we construct a new block graph and do two
+  // sweeps. The first sweep places blocks with the smallest possible
+  // coordinates. The second sweep removes unused space by moving blocks to the
+  // greatest coordinates without violating separation.
+  var xs = {},
+      blockG = buildBlockGraph(g, layering, root, reverseSep);
+
+  // First pass, assign smallest coordinates via DFS
+  var visited = {};
+  function pass1(v) {
+    if (!_.has(visited, v)) {
+      visited[v] = true;
+      xs[v] = _.reduce(blockG.inEdges(v), function(max, e) {
+        pass1(e.v);
+        return Math.max(max, xs[e.v] + blockG.edge(e));
+      }, 0);
+    }
+  }
+  _.each(blockG.nodes(), pass1);
+
+  function pass2(v) {
+    if (visited[v] !== 2) {
+      visited[v]++;
+      var min = _.reduce(blockG.outEdges(v), function(min, e) {
+        pass2(e.w);
+        return Math.min(min, xs[e.w] - blockG.edge(e));
+      }, Number.POSITIVE_INFINITY);
+      if (min !== Number.POSITIVE_INFINITY) {
+        xs[v] = Math.max(xs[v], min);
+      }
+    }
+  }
+  _.each(blockG.nodes(), pass2);
+
+
+  // Assign x coordinates to all nodes
+  _.each(align, function(v) {
+    xs[v] = xs[root[v]];
+  });
+
+  return xs;
+}
+
+
+function buildBlockGraph(g, layering, root, reverseSep) {
+  var blockGraph = new Graph(),
+      graphLabel = g.graph(),
+      sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep);
+
+  _.each(layering, function(layer) {
+    var u;
+    _.each(layer, function(v) {
+      var vRoot = root[v];
+      blockGraph.setNode(vRoot);
+      if (u) {
+        var uRoot = root[u],
+            prevMax = blockGraph.edge(uRoot, vRoot);
+        blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0));
+      }
+      u = v;
+    });
+  });
+
+  return blockGraph;
+}
+
+/*
+ * Returns the alignment that has the smallest width of the given alignments.
+ */
+function findSmallestWidthAlignment(g, xss) {
+  return _.min(xss, function(xs) {
+    var min = _.min(xs, function(x, v) { return x - width(g, v) / 2; }),
+        max = _.max(xs, function(x, v) { return x + width(g, v) / 2; });
+    return max - min;
+  });
+}
+
+/*
+ * Align the coordinates of each of the layout alignments such that
+ * left-biased alignments have their minimum coordinate at the same point as
+ * the minimum coordinate of the smallest width alignment and right-biased
+ * alignments have their maximum coordinate at the same point as the maximum
+ * coordinate of the smallest width alignment.
+ */
+function alignCoordinates(xss, alignTo) {
+  var alignToMin = _.min(alignTo),
+      alignToMax = _.max(alignTo);
+
+  _.each(["u", "d"], function(vert) {
+    _.each(["l", "r"], function(horiz) {
+      var alignment = vert + horiz,
+          xs = xss[alignment],
+          delta;
+      if (xs === alignTo) return;
+
+      delta = horiz === "l" ? alignToMin - _.min(xs) : alignToMax - _.max(xs);
+
+      if (delta) {
+        xss[alignment] = _.mapValues(xs, function(x) { return x + delta; });
+      }
+    });
+  });
+}
+
+function balance(xss, align) {
+  return _.mapValues(xss.ul, function(ignore, v) {
+    if (align) {
+      return xss[align.toLowerCase()][v];
+    } else {
+      var xs = _.sortBy(_.pluck(xss, v));
+      return (xs[1] + xs[2]) / 2;
+    }
+  });
+}
+
+function positionX(g) {
+  var layering = util.buildLayerMatrix(g),
+      conflicts = _.merge(findType1Conflicts(g, layering),
+                          findType2Conflicts(g, layering));
+
+  var xss = {},
+      adjustedLayering;
+  _.each(["u", "d"], function(vert) {
+    adjustedLayering = vert === "u" ? layering : _.values(layering).reverse();
+    _.each(["l", "r"], function(horiz) {
+      if (horiz === "r") {
+        adjustedLayering = _.map(adjustedLayering, function(inner) {
+          return _.values(inner).reverse();
+        });
+      }
+
+      var neighborFn = _.bind(vert === "u" ? g.predecessors : g.successors, g);
+      var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn);
+      var xs = horizontalCompaction(g, adjustedLayering,
+                                    align.root, align.align,
+                                    horiz === "r");
+      if (horiz === "r") {
+        xs = _.mapValues(xs, function(x) { return -x; });
+      }
+      xss[vert + horiz] = xs;
+    });
+  });
+
+  var smallestWidth = findSmallestWidthAlignment(g, xss);
+  alignCoordinates(xss, smallestWidth);
+  return balance(xss, g.graph().align);
+}
+
+function sep(nodeSep, edgeSep, reverseSep) {
+  return function(g, v, w) {
+    var vLabel = g.node(v),
+        wLabel = g.node(w),
+        sum = 0,
+        delta;
+
+    sum += vLabel.width / 2;
+    if (_.has(vLabel, "labelpos")) {
+      switch (vLabel.labelpos.toLowerCase()) {
+        case "l": delta = -vLabel.width / 2; break;
+        case "r": delta = vLabel.width / 2; break;
+      }
+    }
+    if (delta) {
+      sum += reverseSep ? delta : -delta;
+    }
+    delta = 0;
+
+    sum += (vLabel.dummy ? edgeSep : nodeSep) / 2;
+    sum += (wLabel.dummy ? edgeSep : nodeSep) / 2;
+
+    sum += wLabel.width / 2;
+    if (_.has(wLabel, "labelpos")) {
+      switch (wLabel.labelpos.toLowerCase()) {
+        case "l": delta = wLabel.width / 2; break;
+        case "r": delta = -wLabel.width / 2; break;
+      }
+    }
+    if (delta) {
+      sum += reverseSep ? delta : -delta;
+    }
+    delta = 0;
+
+    return sum;
+  };
+}
+
+function width(g, v) {
+  return g.node(v).width;
+}
+
+},{"../graphlib":7,"../lodash":10,"../util":29}],24:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash"),
+    util = require("../util"),
+    positionX = require("./bk").positionX;
+
+module.exports = position;
+
+function position(g) {
+  g = util.asNonCompoundGraph(g);
+
+  positionY(g);
+  _.each(positionX(g), function(x, v) {
+    g.node(v).x = x;
+  });
+}
+
+function positionY(g) {
+  var layering = util.buildLayerMatrix(g),
+      rankSep = g.graph().ranksep,
+      prevY = 0;
+  _.each(layering, function(layer) {
+    var maxHeight = _.max(_.map(layer, function(v) { return g.node(v).height; }));
+    _.each(layer, function(v) {
+      g.node(v).y = prevY + maxHeight / 2;
+    });
+    prevY += maxHeight + rankSep;
+  });
+}
+
+
+},{"../lodash":10,"../util":29,"./bk":23}],25:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash"),
+    Graph = require("../graphlib").Graph,
+    slack = require("./util").slack;
+
+module.exports = feasibleTree;
+
+/*
+ * Constructs a spanning tree with tight edges and adjusted the input node's
+ * ranks to achieve this. A tight edge is one that is has a length that matches
+ * its "minlen" attribute.
+ *
+ * The basic structure for this function is derived from Gansner, et al., "A
+ * Technique for Drawing Directed Graphs."
+ *
+ * Pre-conditions:
+ *
+ *    1. Graph must be a DAG.
+ *    2. Graph must be connected.
+ *    3. Graph must have at least one node.
+ *    5. Graph nodes must have been previously assigned a "rank" property that
+ *       respects the "minlen" property of incident edges.
+ *    6. Graph edges must have a "minlen" property.
+ *
+ * Post-conditions:
+ *
+ *    - Graph nodes will have their rank adjusted to ensure that all edges are
+ *      tight.
+ *
+ * Returns a tree (undirected graph) that is constructed using only "tight"
+ * edges.
+ */
+function feasibleTree(g) {
+  var t = new Graph({ directed: false });
+
+  // Choose arbitrary node from which to start our tree
+  var start = g.nodes()[0],
+      size = g.nodeCount();
+  t.setNode(start, {});
+
+  var edge, delta;
+  while (tightTree(t, g) < size) {
+    edge = findMinSlackEdge(t, g);
+    delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge);
+    shiftRanks(t, g, delta);
+  }
+
+  return t;
+}
+
+/*
+ * Finds a maximal tree of tight edges and returns the number of nodes in the
+ * tree.
+ */
+function tightTree(t, g) {
+  function dfs(v) {
+    _.each(g.nodeEdges(v), function(e) {
+      var edgeV = e.v,
+          w = (v === edgeV) ? e.w : edgeV;
+      if (!t.hasNode(w) && !slack(g, e)) {
+        t.setNode(w, {});
+        t.setEdge(v, w, {});
+        dfs(w);
+      }
+    });
+  }
+
+  _.each(t.nodes(), dfs);
+  return t.nodeCount();
+}
+
+/*
+ * Finds the edge with the smallest slack that is incident on tree and returns
+ * it.
+ */
+function findMinSlackEdge(t, g) {
+  return _.min(g.edges(), function(e) {
+    if (t.hasNode(e.v) !== t.hasNode(e.w)) {
+      return slack(g, e);
+    }
+  });
+}
+
+function shiftRanks(t, g, delta) {
+  _.each(t.nodes(), function(v) {
+    g.node(v).rank += delta;
+  });
+}
+
+},{"../graphlib":7,"../lodash":10,"./util":28}],26:[function(require,module,exports){
+"use strict";
+
+var rankUtil = require("./util"),
+    longestPath = rankUtil.longestPath,
+    feasibleTree = require("./feasible-tree"),
+    networkSimplex = require("./network-simplex");
+
+module.exports = rank;
+
+/*
+ * Assigns a rank to each node in the input graph that respects the "minlen"
+ * constraint specified on edges between nodes.
+ *
+ * This basic structure is derived from Gansner, et al., "A Technique for
+ * Drawing Directed Graphs."
+ *
+ * Pre-conditions:
+ *
+ *    1. Graph must be a connected DAG
+ *    2. Graph nodes must be objects
+ *    3. Graph edges must have "weight" and "minlen" attributes
+ *
+ * Post-conditions:
+ *
+ *    1. Graph nodes will have a "rank" attribute based on the results of the
+ *       algorithm. Ranks can start at any index (including negative), we'll
+ *       fix them up later.
+ */
+function rank(g) {
+  switch(g.graph().ranker) {
+    case "network-simplex": networkSimplexRanker(g); break;
+    case "tight-tree": tightTreeRanker(g); break;
+    case "longest-path": longestPathRanker(g); break;
+    default: networkSimplexRanker(g);
+  }
+}
+
+// A fast and simple ranker, but results are far from optimal.
+var longestPathRanker = longestPath;
+
+function tightTreeRanker(g) {
+  longestPath(g);
+  feasibleTree(g);
+}
+
+function networkSimplexRanker(g) {
+  networkSimplex(g);
+}
+
+},{"./feasible-tree":25,"./network-simplex":27,"./util":28}],27:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash"),
+    feasibleTree = require("./feasible-tree"),
+    slack = require("./util").slack,
+    initRank = require("./util").longestPath,
+    preorder = require("../graphlib").alg.preorder,
+    postorder = require("../graphlib").alg.postorder,
+    simplify = require("../util").simplify;
+
+module.exports = networkSimplex;
+
+// Expose some internals for testing purposes
+networkSimplex.initLowLimValues = initLowLimValues;
+networkSimplex.initCutValues = initCutValues;
+networkSimplex.calcCutValue = calcCutValue;
+networkSimplex.leaveEdge = leaveEdge;
+networkSimplex.enterEdge = enterEdge;
+networkSimplex.exchangeEdges = exchangeEdges;
+
+/*
+ * The network simplex algorithm assigns ranks to each node in the input graph
+ * and iteratively improves the ranking to reduce the length of edges.
+ *
+ * Preconditions:
+ *
+ *    1. The input graph must be a DAG.
+ *    2. All nodes in the graph must have an object value.
+ *    3. All edges in the graph must have "minlen" and "weight" attributes.
+ *
+ * Postconditions:
+ *
+ *    1. All nodes in the graph will have an assigned "rank" attribute that has
+ *       been optimized by the network simplex algorithm. Ranks start at 0.
+ *
+ *
+ * A rough sketch of the algorithm is as follows:
+ *
+ *    1. Assign initial ranks to each node. We use the longest path algorithm,
+ *       which assigns ranks to the lowest position possible. In general this
+ *       leads to very wide bottom ranks and unnecessarily long edges.
+ *    2. Construct a feasible tight tree. A tight tree is one such that all
+ *       edges in the tree have no slack (difference between length of edge
+ *       and minlen for the edge). This by itself greatly improves the assigned
+ *       rankings by shorting edges.
+ *    3. Iteratively find edges that have negative cut values. Generally a
+ *       negative cut value indicates that the edge could be removed and a new
+ *       tree edge could be added to produce a more compact graph.
+ *
+ * Much of the algorithms here are derived from Gansner, et al., "A Technique
+ * for Drawing Directed Graphs." The structure of the file roughly follows the
+ * structure of the overall algorithm.
+ */
+function networkSimplex(g) {
+  g = simplify(g);
+  initRank(g);
+  var t = feasibleTree(g);
+  initLowLimValues(t);
+  initCutValues(t, g);
+
+  var e, f;
+  while ((e = leaveEdge(t))) {
+    f = enterEdge(t, g, e);
+    exchangeEdges(t, g, e, f);
+  }
+}
+
+/*
+ * Initializes cut values for all edges in the tree.
+ */
+function initCutValues(t, g) {
+  var vs = postorder(t, t.nodes());
+  vs = vs.slice(0, vs.length - 1);
+  _.each(vs, function(v) {
+    assignCutValue(t, g, v);
+  });
+}
+
+function assignCutValue(t, g, child) {
+  var childLab = t.node(child),
+      parent = childLab.parent;
+  t.edge(child, parent).cutvalue = calcCutValue(t, g, child);
+}
+
+/*
+ * Given the tight tree, its graph, and a child in the graph calculate and
+ * return the cut value for the edge between the child and its parent.
+ */
+function calcCutValue(t, g, child) {
+  var childLab = t.node(child),
+      parent = childLab.parent,
+      // True if the child is on the tail end of the edge in the directed graph
+      childIsTail = true,
+      // The graph's view of the tree edge we're inspecting
+      graphEdge = g.edge(child, parent),
+      // The accumulated cut value for the edge between this node and its parent
+      cutValue = 0;
+
+  if (!graphEdge) {
+    childIsTail = false;
+    graphEdge = g.edge(parent, child);
+  }
+
+  cutValue = graphEdge.weight;
+
+  _.each(g.nodeEdges(child), function(e) {
+    var isOutEdge = e.v === child,
+        other = isOutEdge ? e.w : e.v;
+
+    if (other !== parent) {
+      var pointsToHead = isOutEdge === childIsTail,
+          otherWeight = g.edge(e).weight;
+
+      cutValue += pointsToHead ? otherWeight : -otherWeight;
+      if (isTreeEdge(t, child, other)) {
+        var otherCutValue = t.edge(child, other).cutvalue;
+        cutValue += pointsToHead ? -otherCutValue : otherCutValue;
+      }
+    }
+  });
+
+  return cutValue;
+}
+
+function initLowLimValues(tree, root) {
+  if (arguments.length < 2) {
+    root = tree.nodes()[0];
+  }
+  dfsAssignLowLim(tree, {}, 1, root);
+}
+
+function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
+  var low = nextLim,
+      label = tree.node(v);
+
+  visited[v] = true;
+  _.each(tree.neighbors(v), function(w) {
+    if (!_.has(visited, w)) {
+      nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v);
+    }
+  });
+
+  label.low = low;
+  label.lim = nextLim++;
+  if (parent) {
+    label.parent = parent;
+  } else {
+    // TODO should be able to remove this when we incrementally update low lim
+    delete label.parent;
+  }
+
+  return nextLim;
+}
+
+function leaveEdge(tree) {
+  return _.find(tree.edges(), function(e) {
+    return tree.edge(e).cutvalue < 0;
+  });
+}
+
+function enterEdge(t, g, edge) {
+  var v = edge.v,
+      w = edge.w;
+
+  // For the rest of this function we assume that v is the tail and w is the
+  // head, so if we don't have this edge in the graph we should flip it to
+  // match the correct orientation.
+  if (!g.hasEdge(v, w)) {
+    v = edge.w;
+    w = edge.v;
+  }
+
+  var vLabel = t.node(v),
+      wLabel = t.node(w),
+      tailLabel = vLabel,
+      flip = false;
+
+  // If the root is in the tail of the edge then we need to flip the logic that
+  // checks for the head and tail nodes in the candidates function below.
+  if (vLabel.lim > wLabel.lim) {
+    tailLabel = wLabel;
+    flip = true;
+  }
+
+  var candidates = _.filter(g.edges(), function(edge) {
+    return flip === isDescendant(t, t.node(edge.v), tailLabel) &&
+           flip !== isDescendant(t, t.node(edge.w), tailLabel);
+  });
+
+  return _.min(candidates, function(edge) { return slack(g, edge); });
+}
+
+function exchangeEdges(t, g, e, f) {
+  var v = e.v,
+      w = e.w;
+  t.removeEdge(v, w);
+  t.setEdge(f.v, f.w, {});
+  initLowLimValues(t);
+  initCutValues(t, g);
+  updateRanks(t, g);
+}
+
+function updateRanks(t, g) {
+  var root = _.find(t.nodes(), function(v) { return !g.node(v).parent; }),
+      vs = preorder(t, root);
+  vs = vs.slice(1);
+  _.each(vs, function(v) {
+    var parent = t.node(v).parent,
+        edge = g.edge(v, parent),
+        flipped = false;
+
+    if (!edge) {
+      edge = g.edge(parent, v);
+      flipped = true;
+    }
+
+    g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen);
+  });
+}
+
+/*
+ * Returns true if the edge is in the tree.
+ */
+function isTreeEdge(tree, u, v) {
+  return tree.hasEdge(u, v);
+}
+
+/*
+ * Returns true if the specified node is descendant of the root node per the
+ * assigned low and lim attributes in the tree.
+ */
+function isDescendant(tree, vLabel, rootLabel) {
+  return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim;
+}
+
+},{"../graphlib":7,"../lodash":10,"../util":29,"./feasible-tree":25,"./util":28}],28:[function(require,module,exports){
+"use strict";
+
+var _ = require("../lodash");
+
+module.exports = {
+  longestPath: longestPath,
+  slack: slack
+};
+
+/*
+ * Initializes ranks for the input graph using the longest path algorithm. This
+ * algorithm scales well and is fast in practice, it yields rather poor
+ * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom
+ * ranks wide and leaving edges longer than necessary. However, due to its
+ * speed, this algorithm is good for getting an initial ranking that can be fed
+ * into other algorithms.
+ *
+ * This algorithm does not normalize layers because it will be used by other
+ * algorithms in most cases. If using this algorithm directly, be sure to
+ * run normalize at the end.
+ *
+ * Pre-conditions:
+ *
+ *    1. Input graph is a DAG.
+ *    2. Input graph node labels can be assigned properties.
+ *
+ * Post-conditions:
+ *
+ *    1. Each node will be assign an (unnormalized) "rank" property.
+ */
+function longestPath(g) {
+  var visited = {};
+
+  function dfs(v) {
+    var label = g.node(v);
+    if (_.has(visited, v)) {
+      return label.rank;
+    }
+    visited[v] = true;
+
+    var rank = _.min(_.map(g.outEdges(v), function(e) {
+      return dfs(e.w) - g.edge(e).minlen;
+    }));
+
+    if (rank === Number.POSITIVE_INFINITY) {
+      rank = 0;
+    }
+
+    return (label.rank = rank);
+  }
+
+  _.each(g.sources(), dfs);
+}
+
+/*
+ * Returns the amount of slack for the given edge. The slack is defined as the
+ * difference between the length of the edge and its minimum length.
+ */
+function slack(g, e) {
+  return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen;
+}
+
+},{"../lodash":10}],29:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash"),
+    Graph = require("./graphlib").Graph;
+
+module.exports = {
+  addDummyNode: addDummyNode,
+  simplify: simplify,
+  asNonCompoundGraph: asNonCompoundGraph,
+  successorWeights: successorWeights,
+  predecessorWeights: predecessorWeights,
+  intersectRect: intersectRect,
+  buildLayerMatrix: buildLayerMatrix,
+  normalizeRanks: normalizeRanks,
+  removeEmptyRanks: removeEmptyRanks,
+  addBorderNode: addBorderNode,
+  maxRank: maxRank,
+  partition: partition,
+  time: time,
+  notime: notime
+};
+
+/*
+ * Adds a dummy node to the graph and return v.
+ */
+function addDummyNode(g, type, attrs, name) {
+  var v;
+  do {
+    v = _.uniqueId(name);
+  } while (g.hasNode(v));
+
+  attrs.dummy = type;
+  g.setNode(v, attrs);
+  return v;
+}
+
+/*
+ * Returns a new graph with only simple edges. Handles aggregation of data
+ * associated with multi-edges.
+ */
+function simplify(g) {
+  var simplified = new Graph().setGraph(g.graph());
+  _.each(g.nodes(), function(v) { simplified.setNode(v, g.node(v)); });
+  _.each(g.edges(), function(e) {
+    var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 },
+        label = g.edge(e);
+    simplified.setEdge(e.v, e.w, {
+      weight: simpleLabel.weight + label.weight,
+      minlen: Math.max(simpleLabel.minlen, label.minlen)
+    });
+  });
+  return simplified;
+}
+
+function asNonCompoundGraph(g) {
+  var simplified = new Graph({ multigraph: g.isMultigraph() }).setGraph(g.graph());
+  _.each(g.nodes(), function(v) {
+    if (!g.children(v).length) {
+      simplified.setNode(v, g.node(v));
+    }
+  });
+  _.each(g.edges(), function(e) {
+    simplified.setEdge(e, g.edge(e));
+  });
+  return simplified;
+}
+
+function successorWeights(g) {
+  var weightMap = _.map(g.nodes(), function(v) {
+    var sucs = {};
+    _.each(g.outEdges(v), function(e) {
+      sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight;
+    });
+    return sucs;
+  });
+  return _.zipObject(g.nodes(), weightMap);
+}
+
+function predecessorWeights(g) {
+  var weightMap = _.map(g.nodes(), function(v) {
+    var preds = {};
+    _.each(g.inEdges(v), function(e) {
+      preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight;
+    });
+    return preds;
+  });
+  return _.zipObject(g.nodes(), weightMap);
+}
+
+/*
+ * Finds where a line starting at point ({x, y}) would intersect a rectangle
+ * ({x, y, width, height}) if it were pointing at the rectangle's center.
+ */
+function intersectRect(rect, point) {
+  var x = rect.x;
+  var y = rect.y;
+
+  // Rectangle intersection algorithm from:
+  // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
+  var dx = point.x - x;
+  var dy = point.y - y;
+  var w = rect.width / 2;
+  var h = rect.height / 2;
+
+  if (!dx && !dy) {
+    throw new Error("Not possible to find intersection inside of the rectangle");
+  }
+
+  var sx, sy;
+  if (Math.abs(dy) * w > Math.abs(dx) * h) {
+    // Intersection is top or bottom of rect.
+    if (dy < 0) {
+      h = -h;
+    }
+    sx = h * dx / dy;
+    sy = h;
+  } else {
+    // Intersection is left or right of rect.
+    if (dx < 0) {
+      w = -w;
+    }
+    sx = w;
+    sy = w * dy / dx;
+  }
+
+  return { x: x + sx, y: y + sy };
+}
+
+/*
+ * Given a DAG with each node assigned "rank" and "order" properties, this
+ * function will produce a matrix with the ids of each node.
+ */
+function buildLayerMatrix(g) {
+  var layering = _.map(_.range(maxRank(g) + 1), function() { return []; });
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v),
+        rank = node.rank;
+    if (!_.isUndefined(rank)) {
+      layering[rank][node.order] = v;
+    }
+  });
+  return layering;
+}
+
+/*
+ * Adjusts the ranks for all nodes in the graph such that all nodes v have
+ * rank(v) >= 0 and at least one node w has rank(w) = 0.
+ */
+function normalizeRanks(g) {
+  var min = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; }));
+  _.each(g.nodes(), function(v) {
+    var node = g.node(v);
+    if (_.has(node, "rank")) {
+      node.rank -= min;
+    }
+  });
+}
+
+function removeEmptyRanks(g) {
+  // Ranks may not start at 0, so we need to offset them
+  var offset = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; }));
+
+  var layers = [];
+  _.each(g.nodes(), function(v) {
+    var rank = g.node(v).rank - offset;
+    if (!_.has(layers, rank)) {
+      layers[rank] = [];
+    }
+    layers[rank].push(v);
+  });
+
+  var delta = 0,
+      nodeRankFactor = g.graph().nodeRankFactor;
+  _.each(layers, function(vs, i) {
+    if (_.isUndefined(vs) && i % nodeRankFactor !== 0) {
+      --delta;
+    } else if (delta) {
+      _.each(vs, function(v) { g.node(v).rank += delta; });
+    }
+  });
+}
+
+function addBorderNode(g, prefix, rank, order) {
+  var node = {
+    width: 0,
+    height: 0
+  };
+  if (arguments.length >= 4) {
+    node.rank = rank;
+    node.order = order;
+  }
+  return addDummyNode(g, "border", node, prefix);
+}
+
+function maxRank(g) {
+  return _.max(_.map(g.nodes(), function(v) {
+    var rank = g.node(v).rank;
+    if (!_.isUndefined(rank)) {
+      return rank;
+    }
+  }));
+}
+
+/*
+ * Partition a collection into two groups: `lhs` and `rhs`. If the supplied
+ * function returns true for an entry it goes into `lhs`. Otherwise it goes
+ * into `rhs.
+ */
+function partition(collection, fn) {
+  var result = { lhs: [], rhs: [] };
+  _.each(collection, function(value) {
+    if (fn(value)) {
+      result.lhs.push(value);
+    } else {
+      result.rhs.push(value);
+    }
+  });
+  return result;
+}
+
+/*
+ * Returns a new function that wraps `fn` with a timer. The wrapper logs the
+ * time it takes to execute the function.
+ */
+function time(name, fn) {
+  var start = _.now();
+  try {
+    return fn();
+  } finally {
+    console.log(name + " time: " + (_.now() - start) + "ms");
+  }
+}
+
+function notime(name, fn) {
+  return fn();
+}
+
+},{"./graphlib":7,"./lodash":10}],30:[function(require,module,exports){
+module.exports = "0.7.1";
+
+},{}],31:[function(require,module,exports){
+/**
+ * Copyright (c) 2014, Chris Pettitt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its 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.
+ */
+
+var lib = require("./lib");
+
+module.exports = {
+  Graph: lib.Graph,
+  json: require("./lib/json"),
+  alg: require("./lib/alg"),
+  version: lib.version
+};
+
+},{"./lib":47,"./lib/alg":38,"./lib/json":48}],32:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = components;
+
+function components(g) {
+  var visited = {},
+      cmpts = [],
+      cmpt;
+
+  function dfs(v) {
+    if (_.has(visited, v)) return;
+    visited[v] = true;
+    cmpt.push(v);
+    _.each(g.successors(v), dfs);
+    _.each(g.predecessors(v), dfs);
+  }
+
+  _.each(g.nodes(), function(v) {
+    cmpt = [];
+    dfs(v);
+    if (cmpt.length) {
+      cmpts.push(cmpt);
+    }
+  });
+
+  return cmpts;
+}
+
+},{"../lodash":49}],33:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = dfs;
+
+/*
+ * A helper that preforms a pre- or post-order traversal on the input graph
+ * and returns the nodes in the order they were visited. This algorithm treats
+ * the input as undirected.
+ *
+ * Order must be one of "pre" or "post".
+ */
+function dfs(g, vs, order) {
+  if (!_.isArray(vs)) {
+    vs = [vs];
+  }
+
+  var acc = [],
+      visited = {};
+  _.each(vs, function(v) {
+    if (!g.hasNode(v)) {
+      throw new Error("Graph does not have node: " + v);
+    }
+
+    doDfs(g, v, order === "post", visited, acc);
+  });
+  return acc;
+}
+
+function doDfs(g, v, postorder, visited, acc) {
+  if (!_.has(visited, v)) {
+    visited[v] = true;
+
+    if (!postorder) { acc.push(v); }
+    _.each(g.neighbors(v), function(w) {
+      doDfs(g, w, postorder, visited, acc);
+    });
+    if (postorder) { acc.push(v); }
+  }
+}
+
+},{"../lodash":49}],34:[function(require,module,exports){
+var dijkstra = require("./dijkstra"),
+    _ = require("../lodash");
+
+module.exports = dijkstraAll;
+
+function dijkstraAll(g, weightFunc, edgeFunc) {
+  return _.transform(g.nodes(), function(acc, v) {
+    acc[v] = dijkstra(g, v, weightFunc, edgeFunc);
+  }, {});
+}
+
+},{"../lodash":49,"./dijkstra":35}],35:[function(require,module,exports){
+var _ = require("../lodash"),
+    PriorityQueue = require("../data/priority-queue");
+
+module.exports = dijkstra;
+
+var DEFAULT_WEIGHT_FUNC = _.constant(1);
+
+function dijkstra(g, source, weightFn, edgeFn) {
+  return runDijkstra(g, String(source),
+                     weightFn || DEFAULT_WEIGHT_FUNC,
+                     edgeFn || function(v) { return g.outEdges(v); });
+}
+
+function runDijkstra(g, source, weightFn, edgeFn) {
+  var results = {},
+      pq = new PriorityQueue(),
+      v, vEntry;
+
+  var updateNeighbors = function(edge) {
+    var w = edge.v !== v ? edge.v : edge.w,
+        wEntry = results[w],
+        weight = weightFn(edge),
+        distance = vEntry.distance + weight;
+
+    if (weight < 0) {
+      throw new Error("dijkstra does not allow negative edge weights. " +
+                      "Bad edge: " + edge + " Weight: " + weight);
+    }
+
+    if (distance < wEntry.distance) {
+      wEntry.distance = distance;
+      wEntry.predecessor = v;
+      pq.decrease(w, distance);
+    }
+  };
+
+  g.nodes().forEach(function(v) {
+    var distance = v === source ? 0 : Number.POSITIVE_INFINITY;
+    results[v] = { distance: distance };
+    pq.add(v, distance);
+  });
+
+  while (pq.size() > 0) {
+    v = pq.removeMin();
+    vEntry = results[v];
+    if (vEntry.distance === Number.POSITIVE_INFINITY) {
+      break;
+    }
+
+    edgeFn(v).forEach(updateNeighbors);
+  }
+
+  return results;
+}
+
+},{"../data/priority-queue":45,"../lodash":49}],36:[function(require,module,exports){
+var _ = require("../lodash"),
+    tarjan = require("./tarjan");
+
+module.exports = findCycles;
+
+function findCycles(g) {
+  return _.filter(tarjan(g), function(cmpt) { return cmpt.length > 1; });
+}
+
+},{"../lodash":49,"./tarjan":43}],37:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = floydWarshall;
+
+var DEFAULT_WEIGHT_FUNC = _.constant(1);
+
+function floydWarshall(g, weightFn, edgeFn) {
+  return runFloydWarshall(g,
+                          weightFn || DEFAULT_WEIGHT_FUNC,
+                          edgeFn || function(v) { return g.outEdges(v); });
+}
+
+function runFloydWarshall(g, weightFn, edgeFn) {
+  var results = {},
+      nodes = g.nodes();
+
+  nodes.forEach(function(v) {
+    results[v] = {};
+    results[v][v] = { distance: 0 };
+    nodes.forEach(function(w) {
+      if (v !== w) {
+        results[v][w] = { distance: Number.POSITIVE_INFINITY };
+      }
+    });
+    edgeFn(v).forEach(function(edge) {
+      var w = edge.v === v ? edge.w : edge.v,
+          d = weightFn(edge);
+      results[v][w] = { distance: d, predecessor: v };
+    });
+  });
+
+  nodes.forEach(function(k) {
+    var rowK = results[k];
+    nodes.forEach(function(i) {
+      var rowI = results[i];
+      nodes.forEach(function(j) {
+        var ik = rowI[k];
+        var kj = rowK[j];
+        var ij = rowI[j];
+        var altDistance = ik.distance + kj.distance;
+        if (altDistance < ij.distance) {
+          ij.distance = altDistance;
+          ij.predecessor = kj.predecessor;
+        }
+      });
+    });
+  });
+
+  return results;
+}
+
+},{"../lodash":49}],38:[function(require,module,exports){
+module.exports = {
+  components: require("./components"),
+  dijkstra: require("./dijkstra"),
+  dijkstraAll: require("./dijkstra-all"),
+  findCycles: require("./find-cycles"),
+  floydWarshall: require("./floyd-warshall"),
+  isAcyclic: require("./is-acyclic"),
+  postorder: require("./postorder"),
+  preorder: require("./preorder"),
+  prim: require("./prim"),
+  tarjan: require("./tarjan"),
+  topsort: require("./topsort")
+};
+
+},{"./components":32,"./dijkstra":35,"./dijkstra-all":34,"./find-cycles":36,"./floyd-warshall":37,"./is-acyclic":39,"./postorder":40,"./preorder":41,"./prim":42,"./tarjan":43,"./topsort":44}],39:[function(require,module,exports){
+var topsort = require("./topsort");
+
+module.exports = isAcyclic;
+
+function isAcyclic(g) {
+  try {
+    topsort(g);
+  } catch (e) {
+    if (e instanceof topsort.CycleException) {
+      return false;
+    }
+    throw e;
+  }
+  return true;
+}
+
+},{"./topsort":44}],40:[function(require,module,exports){
+var dfs = require("./dfs");
+
+module.exports = postorder;
+
+function postorder(g, vs) {
+  return dfs(g, vs, "post");
+}
+
+},{"./dfs":33}],41:[function(require,module,exports){
+var dfs = require("./dfs");
+
+module.exports = preorder;
+
+function preorder(g, vs) {
+  return dfs(g, vs, "pre");
+}
+
+},{"./dfs":33}],42:[function(require,module,exports){
+var _ = require("../lodash"),
+    Graph = require("../graph"),
+    PriorityQueue = require("../data/priority-queue");
+
+module.exports = prim;
+
+function prim(g, weightFunc) {
+  var result = new Graph(),
+      parents = {},
+      pq = new PriorityQueue(),
+      v;
+
+  function updateNeighbors(edge) {
+    var w = edge.v === v ? edge.w : edge.v,
+        pri = pq.priority(w);
+    if (pri !== undefined) {
+      var edgeWeight = weightFunc(edge);
+      if (edgeWeight < pri) {
+        parents[w] = v;
+        pq.decrease(w, edgeWeight);
+      }
+    }
+  }
+
+  if (g.nodeCount() === 0) {
+    return result;
+  }
+
+  _.each(g.nodes(), function(v) {
+    pq.add(v, Number.POSITIVE_INFINITY);
+    result.setNode(v);
+  });
+
+  // Start from an arbitrary node
+  pq.decrease(g.nodes()[0], 0);
+
+  var init = false;
+  while (pq.size() > 0) {
+    v = pq.removeMin();
+    if (_.has(parents, v)) {
+      result.setEdge(v, parents[v]);
+    } else if (init) {
+      throw new Error("Input graph is not connected: " + g);
+    } else {
+      init = true;
+    }
+
+    g.nodeEdges(v).forEach(updateNeighbors);
+  }
+
+  return result;
+}
+
+},{"../data/priority-queue":45,"../graph":46,"../lodash":49}],43:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = tarjan;
+
+function tarjan(g) {
+  var index = 0,
+      stack = [],
+      visited = {}, // node id -> { onStack, lowlink, index }
+      results = [];
+
+  function dfs(v) {
+    var entry = visited[v] = {
+      onStack: true,
+      lowlink: index,
+      index: index++
+    };
+    stack.push(v);
+
+    g.successors(v).forEach(function(w) {
+      if (!_.has(visited, w)) {
+        dfs(w);
+        entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink);
+      } else if (visited[w].onStack) {
+        entry.lowlink = Math.min(entry.lowlink, visited[w].index);
+      }
+    });
+
+    if (entry.lowlink === entry.index) {
+      var cmpt = [],
+          w;
+      do {
+        w = stack.pop();
+        visited[w].onStack = false;
+        cmpt.push(w);
+      } while (v !== w);
+      results.push(cmpt);
+    }
+  }
+
+  g.nodes().forEach(function(v) {
+    if (!_.has(visited, v)) {
+      dfs(v);
+    }
+  });
+
+  return results;
+}
+
+},{"../lodash":49}],44:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = topsort;
+topsort.CycleException = CycleException;
+
+function topsort(g) {
+  var visited = {},
+      stack = {},
+      results = [];
+
+  function visit(node) {
+    if (_.has(stack, node)) {
+      throw new CycleException();
+    }
+
+    if (!_.has(visited, node)) {
+      stack[node] = true;
+      visited[node] = true;
+      _.each(g.predecessors(node), visit);
+      delete stack[node];
+      results.push(node);
+    }
+  }
+
+  _.each(g.sinks(), visit);
+
+  if (_.size(visited) !== g.nodeCount()) {
+    throw new CycleException();
+  }
+
+  return results;
+}
+
+function CycleException() {}
+
+},{"../lodash":49}],45:[function(require,module,exports){
+var _ = require("../lodash");
+
+module.exports = PriorityQueue;
+
+/**
+ * A min-priority queue data structure. This algorithm is derived from Cormen,
+ * et al., "Introduction to Algorithms". The basic idea of a min-priority
+ * queue is that you can efficiently (in O(1) time) get the smallest key in
+ * the queue. Adding and removing elements takes O(log n) time. A key can
+ * have its priority decreased in O(log n) time.
+ */
+function PriorityQueue() {
+  this._arr = [];
+  this._keyIndices = {};
+}
+
+/**
+ * Returns the number of elements in the queue. Takes `O(1)` time.
+ */
+PriorityQueue.prototype.size = function() {
+  return this._arr.length;
+};
+
+/**
+ * Returns the keys that are in the queue. Takes `O(n)` time.
+ */
+PriorityQueue.prototype.keys = function() {
+  return this._arr.map(function(x) { return x.key; });
+};
+
+/**
+ * Returns `true` if **key** is in the queue and `false` if not.
+ */
+PriorityQueue.prototype.has = function(key) {
+  return _.has(this._keyIndices, key);
+};
+
+/**
+ * Returns the priority for **key**. If **key** is not present in the queue
+ * then this function returns `undefined`. Takes `O(1)` time.
+ *
+ * @param {Object} key
+ */
+PriorityQueue.prototype.priority = function(key) {
+  var index = this._keyIndices[key];
+  if (index !== undefined) {
+    return this._arr[index].priority;
+  }
+};
+
+/**
+ * Returns the key for the minimum element in this queue. If the queue is
+ * empty this function throws an Error. Takes `O(1)` time.
+ */
+PriorityQueue.prototype.min = function() {
+  if (this.size() === 0) {
+    throw new Error("Queue underflow");
+  }
+  return this._arr[0].key;
+};
+
+/**
+ * Inserts a new key into the priority queue. If the key already exists in
+ * the queue this function returns `false`; otherwise it will return `true`.
+ * Takes `O(n)` time.
+ *
+ * @param {Object} key the key to add
+ * @param {Number} priority the initial priority for the key
+ */
+PriorityQueue.prototype.add = function(key, priority) {
+  var keyIndices = this._keyIndices;
+  key = String(key);
+  if (!_.has(keyIndices, key)) {
+    var arr = this._arr;
+    var index = arr.length;
+    keyIndices[key] = index;
+    arr.push({key: key, priority: priority});
+    this._decrease(index);
+    return true;
+  }
+  return false;
+};
+
+/**
+ * Removes and returns the smallest key in the queue. Takes `O(log n)` time.
+ */
+PriorityQueue.prototype.removeMin = function() {
+  this._swap(0, this._arr.length - 1);
+  var min = this._arr.pop();
+  delete this._keyIndices[min.key];
+  this._heapify(0);
+  return min.key;
+};
+
+/**
+ * Decreases the priority for **key** to **priority**. If the new priority is
+ * greater than the previous priority, this function will throw an Error.
+ *
+ * @param {Object} key the key for which to raise priority
+ * @param {Number} priority the new priority for the key
+ */
+PriorityQueue.prototype.decrease = function(key, priority) {
+  var index = this._keyIndices[key];
+  if (priority > this._arr[index].priority) {
+    throw new Error("New priority is greater than current priority. " +
+        "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority);
+  }
+  this._arr[index].priority = priority;
+  this._decrease(index);
+};
+
+PriorityQueue.prototype._heapify = function(i) {
+  var arr = this._arr;
+  var l = 2 * i,
+      r = l + 1,
+      largest = i;
+  if (l < arr.length) {
+    largest = arr[l].priority < arr[largest].priority ? l : largest;
+    if (r < arr.length) {
+      largest = arr[r].priority < arr[largest].priority ? r : largest;
+    }
+    if (largest !== i) {
+      this._swap(i, largest);
+      this._heapify(largest);
+    }
+  }
+};
+
+PriorityQueue.prototype._decrease = function(index) {
+  var arr = this._arr;
+  var priority = arr[index].priority;
+  var parent;
+  while (index !== 0) {
+    parent = index >> 1;
+    if (arr[parent].priority < priority) {
+      break;
+    }
+    this._swap(index, parent);
+    index = parent;
+  }
+};
+
+PriorityQueue.prototype._swap = function(i, j) {
+  var arr = this._arr;
+  var keyIndices = this._keyIndices;
+  var origArrI = arr[i];
+  var origArrJ = arr[j];
+  arr[i] = origArrJ;
+  arr[j] = origArrI;
+  keyIndices[origArrJ.key] = i;
+  keyIndices[origArrI.key] = j;
+};
+
+},{"../lodash":49}],46:[function(require,module,exports){
+"use strict";
+
+var _ = require("./lodash");
+
+module.exports = Graph;
+
+var DEFAULT_EDGE_NAME = "\x00",
+    GRAPH_NODE = "\x00",
+    EDGE_KEY_DELIM = "\x01";
+
+// Implementation notes:
+//
+//  * Node id query functions should return string ids for the nodes
+//  * Edge id query functions should return an "edgeObj", edge object, that is
+//    composed of enough information to uniquely identify an edge: {v, w, name}.
+//  * Internally we use an "edgeId", a stringified form of the edgeObj, to
+//    reference edges. This is because we need a performant way to look these
+//    edges up and, object properties, which have string keys, are the closest
+//    we're going to get to a performant hashtable in JavaScript.
+
+function Graph(opts) {
+  this._isDirected = _.has(opts, "directed") ? opts.directed : true;
+  this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false;
+  this._isCompound = _.has(opts, "compound") ? opts.compound : false;
+
+  // Label for the graph itself
+  this._label = undefined;
+
+  // Defaults to be set when creating a new node
+  this._defaultNodeLabelFn = _.constant(undefined);
+
+  // Defaults to be set when creating a new edge
+  this._defaultEdgeLabelFn = _.constant(undefined);
+
+  // v -> label
+  this._nodes = {};
+
+  if (this._isCompound) {
+    // v -> parent
+    this._parent = {};
+
+    // v -> children
+    this._children = {};
+    this._children[GRAPH_NODE] = {};
+  }
+
+  // v -> edgeObj
+  this._in = {};
+
+  // u -> v -> Number
+  this._preds = {};
+
+  // v -> edgeObj
+  this._out = {};
+
+  // v -> w -> Number
+  this._sucs = {};
+
+  // e -> edgeObj
+  this._edgeObjs = {};
+
+  // e -> label
+  this._edgeLabels = {};
+}
+
+/* Number of nodes in the graph. Should only be changed by the implementation. */
+Graph.prototype._nodeCount = 0;
+
+/* Number of edges in the graph. Should only be changed by the implementation. */
+Graph.prototype._edgeCount = 0;
+
+
+/* === Graph functions ========= */
+
+Graph.prototype.isDirected = function() {
+  return this._isDirected;
+};
+
+Graph.prototype.isMultigraph = function() {
+  return this._isMultigraph;
+};
+
+Graph.prototype.isCompound = function() {
+  return this._isCompound;
+};
+
+Graph.prototype.setGraph = function(label) {
+  this._label = label;
+  return this;
+};
+
+Graph.prototype.graph = function() {
+  return this._label;
+};
+
+
+/* === Node functions ========== */
+
+Graph.prototype.setDefaultNodeLabel = function(newDefault) {
+  if (!_.isFunction(newDefault)) {
+    newDefault = _.constant(newDefault);
+  }
+  this._defaultNodeLabelFn = newDefault;
+  return this;
+};
+
+Graph.prototype.nodeCount = function() {
+  return this._nodeCount;
+};
+
+Graph.prototype.nodes = function() {
+  return _.keys(this._nodes);
+};
+
+Graph.prototype.sources = function() {
+  return _.filter(this.nodes(), function(v) {
+    return _.isEmpty(this._in[v]);
+  }, this);
+};
+
+Graph.prototype.sinks = function() {
+  return _.filter(this.nodes(), function(v) {
+    return _.isEmpty(this._out[v]);
+  }, this);
+};
+
+Graph.prototype.setNodes = function(vs, value) {
+  var args = arguments;
+  _.each(vs, function(v) {
+    if (args.length > 1) {
+      this.setNode(v, value);
+    } else {
+      this.setNode(v);
+    }
+  }, this);
+  return this;
+};
+
+Graph.prototype.setNode = function(v, value) {
+  if (_.has(this._nodes, v)) {
+    if (arguments.length > 1) {
+      this._nodes[v] = value;
+    }
+    return this;
+  }
+
+  this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v);
+  if (this._isCompound) {
+    this._parent[v] = GRAPH_NODE;
+    this._children[v] = {};
+    this._children[GRAPH_NODE][v] = true;
+  }
+  this._in[v] = {};
+  this._preds[v] = {};
+  this._out[v] = {};
+  this._sucs[v] = {};
+  ++this._nodeCount;
+  return this;
+};
+
+Graph.prototype.node = function(v) {
+  return this._nodes[v];
+};
+
+Graph.prototype.hasNode = function(v) {
+  return _.has(this._nodes, v);
+};
+
+Graph.prototype.removeNode =  function(v) {
+  var self = this;
+  if (_.has(this._nodes, v)) {
+    var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); };
+    delete this._nodes[v];
+    if (this._isCompound) {
+      this._removeFromParentsChildList(v);
+      delete this._parent[v];
+      _.each(this.children(v), function(child) {
+        this.setParent(child);
+      }, this);
+      delete this._children[v];
+    }
+    _.each(_.keys(this._in[v]), removeEdge);
+    delete this._in[v];
+    delete this._preds[v];
+    _.each(_.keys(this._out[v]), removeEdge);
+    delete this._out[v];
+    delete this._sucs[v];
+    --this._nodeCount;
+  }
+  return this;
+};
+
+Graph.prototype.setParent = function(v, parent) {
+  if (!this._isCompound) {
+    throw new Error("Cannot set parent in a non-compound graph");
+  }
+
+  if (_.isUndefined(parent)) {
+    parent = GRAPH_NODE;
+  } else {
+    for (var ancestor = parent;
+         !_.isUndefined(ancestor);
+         ancestor = this.parent(ancestor)) {
+      if (ancestor === v) {
+        throw new Error("Setting " + parent+ " as parent of " + v +
+                        " would create create a cycle");
+      }
+    }
+
+    this.setNode(parent);
+  }
+
+  this.setNode(v);
+  this._removeFromParentsChildList(v);
+  this._parent[v] = parent;
+  this._children[parent][v] = true;
+  return this;
+};
+
+Graph.prototype._removeFromParentsChildList = function(v) {
+  delete this._children[this._parent[v]][v];
+};
+
+Graph.prototype.parent = function(v) {
+  if (this._isCompound) {
+    var parent = this._parent[v];
+    if (parent !== GRAPH_NODE) {
+      return parent;
+    }
+  }
+};
+
+Graph.prototype.children = function(v) {
+  if (_.isUndefined(v)) {
+    v = GRAPH_NODE;
+  }
+
+  if (this._isCompound) {
+    var children = this._children[v];
+    if (children) {
+      return _.keys(children);
+    }
+  } else if (v === GRAPH_NODE) {
+    return this.nodes();
+  } else if (this.hasNode(v)) {
+    return [];
+  }
+};
+
+Graph.prototype.predecessors = function(v) {
+  var predsV = this._preds[v];
+  if (predsV) {
+    return _.keys(predsV);
+  }
+};
+
+Graph.prototype.successors = function(v) {
+  var sucsV = this._sucs[v];
+  if (sucsV) {
+    return _.keys(sucsV);
+  }
+};
+
+Graph.prototype.neighbors = function(v) {
+  var preds = this.predecessors(v);
+  if (preds) {
+    return _.union(preds, this.successors(v));
+  }
+};
+
+/* === Edge functions ========== */
+
+Graph.prototype.setDefaultEdgeLabel = function(newDefault) {
+  if (!_.isFunction(newDefault)) {
+    newDefault = _.constant(newDefault);
+  }
+  this._defaultEdgeLabelFn = newDefault;
+  return this;
+};
+
+Graph.prototype.edgeCount = function() {
+  return this._edgeCount;
+};
+
+Graph.prototype.edges = function() {
+  return _.values(this._edgeObjs);
+};
+
+Graph.prototype.setPath = function(vs, value) {
+  var self = this,
+      args = arguments;
+  _.reduce(vs, function(v, w) {
+    if (args.length > 1) {
+      self.setEdge(v, w, value);
+    } else {
+      self.setEdge(v, w);
+    }
+    return w;
+  });
+  return this;
+};
+
+/*
+ * setEdge(v, w, [value, [name]])
+ * setEdge({ v, w, [name] }, [value])
+ */
+Graph.prototype.setEdge = function() {
+  var v, w, name, value,
+      valueSpecified = false;
+
+  if (_.isPlainObject(arguments[0])) {
+    v = arguments[0].v;
+    w = arguments[0].w;
+    name = arguments[0].name;
+    if (arguments.length === 2) {
+      value = arguments[1];
+      valueSpecified = true;
+    }
+  } else {
+    v = arguments[0];
+    w = arguments[1];
+    name = arguments[3];
+    if (arguments.length > 2) {
+      value = arguments[2];
+      valueSpecified = true;
+    }
+  }
+
+  v = "" + v;
+  w = "" + w;
+  if (!_.isUndefined(name)) {
+    name = "" + name;
+  }
+
+  var e = edgeArgsToId(this._isDirected, v, w, name);
+  if (_.has(this._edgeLabels, e)) {
+    if (valueSpecified) {
+      this._edgeLabels[e] = value;
+    }
+    return this;
+  }
+
+  if (!_.isUndefined(name) && !this._isMultigraph) {
+    throw new Error("Cannot set a named edge when isMultigraph = false");
+  }
+
+  // It didn't exist, so we need to create it.
+  // First ensure the nodes exist.
+  this.setNode(v);
+  this.setNode(w);
+
+  this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name);
+
+  var edgeObj = edgeArgsToObj(this._isDirected, v, w, name);
+  // Ensure we add undirected edges in a consistent way.
+  v = edgeObj.v;
+  w = edgeObj.w;
+
+  Object.freeze(edgeObj);
+  this._edgeObjs[e] = edgeObj;
+  incrementOrInitEntry(this._preds[w], v);
+  incrementOrInitEntry(this._sucs[v], w);
+  this._in[w][e] = edgeObj;
+  this._out[v][e] = edgeObj;
+  this._edgeCount++;
+  return this;
+};
+
+Graph.prototype.edge = function(v, w, name) {
+  var e = (arguments.length === 1
+            ? edgeObjToId(this._isDirected, arguments[0])
+            : edgeArgsToId(this._isDirected, v, w, name));
+  return this._edgeLabels[e];
+};
+
+Graph.prototype.hasEdge = function(v, w, name) {
+  var e = (arguments.length === 1
+            ? edgeObjToId(this._isDirected, arguments[0])
+            : edgeArgsToId(this._isDirected, v, w, name));
+  return _.has(this._edgeLabels, e);
+};
+
+Graph.prototype.removeEdge = function(v, w, name) {
+  var e = (arguments.length === 1
+            ? edgeObjToId(this._isDirected, arguments[0])
+            : edgeArgsToId(this._isDirected, v, w, name)),
+      edge = this._edgeObjs[e];
+  if (edge) {
+    v = edge.v;
+    w = edge.w;
+    delete this._edgeLabels[e];
+    delete this._edgeObjs[e];
+    decrementOrRemoveEntry(this._preds[w], v);
+    decrementOrRemoveEntry(this._sucs[v], w);
+    delete this._in[w][e];
+    delete this._out[v][e];
+    this._edgeCount--;
+  }
+  return this;
+};
+
+Graph.prototype.inEdges = function(v, u) {
+  var inV = this._in[v];
+  if (inV) {
+    var edges = _.values(inV);
+    if (!u) {
+      return edges;
+    }
+    return _.filter(edges, function(edge) { return edge.v === u; });
+  }
+};
+
+Graph.prototype.outEdges = function(v, w) {
+  var outV = this._out[v];
+  if (outV) {
+    var edges = _.values(outV);
+    if (!w) {
+      return edges;
+    }
+    return _.filter(edges, function(edge) { return edge.w === w; });
+  }
+};
+
+Graph.prototype.nodeEdges = function(v, w) {
+  var inEdges = this.inEdges(v, w);
+  if (inEdges) {
+    return inEdges.concat(this.outEdges(v, w));
+  }
+};
+
+function incrementOrInitEntry(map, k) {
+  if (_.has(map, k)) {
+    map[k]++;
+  } else {
+    map[k] = 1;
+  }
+}
+
+function decrementOrRemoveEntry(map, k) {
+  if (!--map[k]) { delete map[k]; }
+}
+
+function edgeArgsToId(isDirected, v, w, name) {
+  if (!isDirected && v > w) {
+    var tmp = v;
+    v = w;
+    w = tmp;
+  }
+  return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM +
+             (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name);
+}
+
+function edgeArgsToObj(isDirected, v, w, name) {
+  if (!isDirected && v > w) {
+    var tmp = v;
+    v = w;
+    w = tmp;
+  }
+  var edgeObj =  { v: v, w: w };
+  if (name) {
+    edgeObj.name = name;
+  }
+  return edgeObj;
+}
+
+function edgeObjToId(isDirected, edgeObj) {
+  return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);
+}
+
+},{"./lodash":49}],47:[function(require,module,exports){
+// Includes only the "core" of graphlib
+module.exports = {
+  Graph: require("./graph"),
+  version: require("./version")
+};
+
+},{"./graph":46,"./version":50}],48:[function(require,module,exports){
+var _ = require("./lodash"),
+    Graph = require("./graph");
+
+module.exports = {
+  write: write,
+  read: read
+};
+
+function write(g) {
+  var json = {
+    options: {
+      directed: g.isDirected(),
+      multigraph: g.isMultigraph(),
+      compound: g.isCompound()
+    },
+    nodes: writeNodes(g),
+    edges: writeEdges(g)
+  };
+  if (!_.isUndefined(g.graph())) {
+    json.value = _.clone(g.graph());
+  }
+  return json;
+}
+
+function writeNodes(g) {
+  return _.map(g.nodes(), function(v) {
+    var nodeValue = g.node(v),
+        parent = g.parent(v),
+        node = { v: v };
+    if (!_.isUndefined(nodeValue)) {
+      node.value = nodeValue;
+    }
+    if (!_.isUndefined(parent)) {
+      node.parent = parent;
+    }
+    return node;
+  });
+}
+
+function writeEdges(g) {
+  return _.map(g.edges(), function(e) {
+    var edgeValue = g.edge(e),
+        edge = { v: e.v, w: e.w };
+    if (!_.isUndefined(e.name)) {
+      edge.name = e.name;
+    }
+    if (!_.isUndefined(edgeValue)) {
+      edge.value = edgeValue;
+    }
+    return edge;
+  });
+}
+
+function read(json) {
+  var g = new Graph(json.options).setGraph(json.value);
+  _.each(json.nodes, function(entry) {
+    g.setNode(entry.v, entry.value);
+    if (entry.parent) {
+      g.setParent(entry.v, entry.parent);
+    }
+  });
+  _.each(json.edges, function(entry) {
+    g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value);
+  });
+  return g;
+}
+
+},{"./graph":46,"./lodash":49}],49:[function(require,module,exports){
+module.exports=require(10)
+},{"/Users/cpettitt/projects/dagre/lib/lodash.js":10,"lodash":51}],50:[function(require,module,exports){
+module.exports = '1.0.1';
+
+},{}],51:[function(require,module,exports){
+(function (global){
+/**
+ * @license
+ * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
+ * Build: `lodash modern -o ./dist/lodash.js`
+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
+ * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license <http://lodash.com/license>
+ */
+;(function() {
+
+  /** Used as a safe reference for `undefined` in pre ES5 environments */
+  var undefined;
+
+  /** Used to pool arrays and objects used internally */
+  var arrayPool = [],
+      objectPool = [];
+
+  /** Used to generate unique IDs */
+  var idCounter = 0;
+
+  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
+  var keyPrefix = +new Date + '';
+
+  /** Used as the size when optimizations are enabled for large arrays */
+  var largeArraySize = 75;
+
+  /** Used as the max size of the `arrayPool` and `objectPool` */
+  var maxPoolSize = 40;
+
+  /** Used to detect and test whitespace */
+  var whitespace = (
+    // whitespace
+    ' \t\x0B\f\xA0\ufeff' +
+
+    // line terminators
+    '\n\r\u2028\u2029' +
+
+    // unicode category "Zs" space separators
+    '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
+  );
+
+  /** Used to match empty string literals in compiled template source */
+  var reEmptyStringLeading = /\b__p \+= '';/g,
+      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
+      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
+
+  /**
+   * Used to match ES6 template delimiters
+   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
+   */
+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
+
+  /** Used to match regexp flags from their coerced string values */
+  var reFlags = /\w*$/;
+
+  /** Used to detected named functions */
+  var reFuncName = /^\s*function[ \n\r\t]+\w/;
+
+  /** Used to match "interpolate" template delimiters */
+  var reInterpolate = /<%=([\s\S]+?)%>/g;
+
+  /** Used to match leading whitespace and zeros to be removed */
+  var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
+
+  /** Used to ensure capturing order of template delimiters */
+  var reNoMatch = /($^)/;
+
+  /** Used to detect functions containing a `this` reference */
+  var reThis = /\bthis\b/;
+
+  /** Used to match unescaped characters in compiled string literals */
+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
+
+  /** Used to assign default `context` object properties */
+  var contextProps = [
+    'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
+    'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
+    'parseInt', 'setTimeout'
+  ];
+
+  /** Used to make template sourceURLs easier to identify */
+  var templateCounter = 0;
+
+  /** `Object#toString` result shortcuts */
+  var argsClass = '[object Arguments]',
+      arrayClass = '[object Array]',
+      boolClass = '[object Boolean]',
+      dateClass = '[object Date]',
+      funcClass = '[object Function]',
+      numberClass = '[object Number]',
+      objectClass = '[object Object]',
+      regexpClass = '[object RegExp]',
+      stringClass = '[object String]';
+
+  /** Used to identify object classifications that `_.clone` supports */
+  var cloneableClasses = {};
+  cloneableClasses[funcClass] = false;
+  cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
+  cloneableClasses[boolClass] = cloneableClasses[dateClass] =
+  cloneableClasses[numberClass] = cloneableClasses[objectClass] =
+  cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
+
+  /** Used as an internal `_.debounce` options object */
+  var debounceOptions = {
+    'leading': false,
+    'maxWait': 0,
+    'trailing': false
+  };
+
+  /** Used as the property descriptor for `__bindData__` */
+  var descriptor = {
+    'configurable': false,
+    'enumerable': false,
+    'value': null,
+    'writable': false
+  };
+
+  /** Used to determine if values are of the language type Object */
+  var objectTypes = {
+    'boolean': false,
+    'function': true,
+    'object': true,
+    'number': false,
+    'string': false,
+    'undefined': false
+  };
+
+  /** Used to escape characters for inclusion in compiled string literals */
+  var stringEscapes = {
+    '\\': '\\',
+    "'": "'",
+    '\n': 'n',
+    '\r': 'r',
+    '\t': 't',
+    '\u2028': 'u2028',
+    '\u2029': 'u2029'
+  };
+
+  /** Used as a reference to the global object */
+  var root = (objectTypes[typeof window] && window) || this;
+
+  /** Detect free variable `exports` */
+  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
+
+  /** Detect free variable `module` */
+  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
+
+  /** Detect the popular CommonJS extension `module.exports` */
+  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
+
+  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
+  var freeGlobal = objectTypes[typeof global] && global;
+  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
+    root = freeGlobal;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * The base implementation of `_.indexOf` without support for binary searches
+   * or `fromIndex` constraints.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @param {*} value The value to search for.
+   * @param {number} [fromIndex=0] The index to search from.
+   * @returns {number} Returns the index of the matched value or `-1`.
+   */
+  function baseIndexOf(array, value, fromIndex) {
+    var index = (fromIndex || 0) - 1,
+        length = array ? array.length : 0;
+
+    while (++index < length) {
+      if (array[index] === value) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * An implementation of `_.contains` for cache objects that mimics the return
+   * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
+   *
+   * @private
+   * @param {Object} cache The cache object to inspect.
+   * @param {*} value The value to search for.
+   * @returns {number} Returns `0` if `value` is found, else `-1`.
+   */
+  function cacheIndexOf(cache, value) {
+    var type = typeof value;
+    cache = cache.cache;
+
+    if (type == 'boolean' || value == null) {
+      return cache[value] ? 0 : -1;
+    }
+    if (type != 'number' && type != 'string') {
+      type = 'object';
+    }
+    var key = type == 'number' ? value : keyPrefix + value;
+    cache = (cache = cache[type]) && cache[key];
+
+    return type == 'object'
+      ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
+      : (cache ? 0 : -1);
+  }
+
+  /**
+   * Adds a given value to the corresponding cache object.
+   *
+   * @private
+   * @param {*} value The value to add to the cache.
+   */
+  function cachePush(value) {
+    var cache = this.cache,
+        type = typeof value;
+
+    if (type == 'boolean' || value == null) {
+      cache[value] = true;
+    } else {
+      if (type != 'number' && type != 'string') {
+        type = 'object';
+      }
+      var key = type == 'number' ? value : keyPrefix + value,
+          typeCache = cache[type] || (cache[type] = {});
+
+      if (type == 'object') {
+        (typeCache[key] || (typeCache[key] = [])).push(value);
+      } else {
+        typeCache[key] = true;
+      }
+    }
+  }
+
+  /**
+   * Used by `_.max` and `_.min` as the default callback when a given
+   * collection is a string value.
+   *
+   * @private
+   * @param {string} value The character to inspect.
+   * @returns {number} Returns the code unit of given character.
+   */
+  function charAtCallback(value) {
+    return value.charCodeAt(0);
+  }
+
+  /**
+   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
+   * them in ascending order.
+   *
+   * @private
+   * @param {Object} a The object to compare to `b`.
+   * @param {Object} b The object to compare to `a`.
+   * @returns {number} Returns the sort order indicator of `1` or `-1`.
+   */
+  function compareAscending(a, b) {
+    var ac = a.criteria,
+        bc = b.criteria,
+        index = -1,
+        length = ac.length;
+
+    while (++index < length) {
+      var value = ac[index],
+          other = bc[index];
+
+      if (value !== other) {
+        if (value > other || typeof value == 'undefined') {
+          return 1;
+        }
+        if (value < other || typeof other == 'undefined') {
+          return -1;
+        }
+      }
+    }
+    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+    // that causes it, under certain circumstances, to return the same value for
+    // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
+    //
+    // This also ensures a stable sort in V8 and other engines.
+    // See http://code.google.com/p/v8/issues/detail?id=90
+    return a.index - b.index;
+  }
+
+  /**
+   * Creates a cache object to optimize linear searches of large arrays.
+   *
+   * @private
+   * @param {Array} [array=[]] The array to search.
+   * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
+   */
+  function createCache(array) {
+    var index = -1,
+        length = array.length,
+        first = array[0],
+        mid = array[(length / 2) | 0],
+        last = array[length - 1];
+
+    if (first && typeof first == 'object' &&
+        mid && typeof mid == 'object' && last && typeof last == 'object') {
+      return false;
+    }
+    var cache = getObject();
+    cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
+
+    var result = getObject();
+    result.array = array;
+    result.cache = cache;
+    result.push = cachePush;
+
+    while (++index < length) {
+      result.push(array[index]);
+    }
+    return result;
+  }
+
+  /**
+   * Used by `template` to escape characters for inclusion in compiled
+   * string literals.
+   *
+   * @private
+   * @param {string} match The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  function escapeStringChar(match) {
+    return '\\' + stringEscapes[match];
+  }
+
+  /**
+   * Gets an array from the array pool or creates a new one if the pool is empty.
+   *
+   * @private
+   * @returns {Array} The array from the pool.
+   */
+  function getArray() {
+    return arrayPool.pop() || [];
+  }
+
+  /**
+   * Gets an object from the object pool or creates a new one if the pool is empty.
+   *
+   * @private
+   * @returns {Object} The object from the pool.
+   */
+  function getObject() {
+    return objectPool.pop() || {
+      'array': null,
+      'cache': null,
+      'criteria': null,
+      'false': false,
+      'index': 0,
+      'null': false,
+      'number': null,
+      'object': null,
+      'push': null,
+      'string': null,
+      'true': false,
+      'undefined': false,
+      'value': null
+    };
+  }
+
+  /**
+   * Releases the given array back to the array pool.
+   *
+   * @private
+   * @param {Array} [array] The array to release.
+   */
+  function releaseArray(array) {
+    array.length = 0;
+    if (arrayPool.length < maxPoolSize) {
+      arrayPool.push(array);
+    }
+  }
+
+  /**
+   * Releases the given object back to the object pool.
+   *
+   * @private
+   * @param {Object} [object] The object to release.
+   */
+  function releaseObject(object) {
+    var cache = object.cache;
+    if (cache) {
+      releaseObject(cache);
+    }
+    object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
+    if (objectPool.length < maxPoolSize) {
+      objectPool.push(object);
+    }
+  }
+
+  /**
+   * Slices the `collection` from the `start` index up to, but not including,
+   * the `end` index.
+   *
+   * Note: This function is used instead of `Array#slice` to support node lists
+   * in IE < 9 and to ensure dense arrays are returned.
+   *
+   * @private
+   * @param {Array|Object|string} collection The collection to slice.
+   * @param {number} start The start index.
+   * @param {number} end The end index.
+   * @returns {Array} Returns the new array.
+   */
+  function slice(array, start, end) {
+    start || (start = 0);
+    if (typeof end == 'undefined') {
+      end = array ? array.length : 0;
+    }
+    var index = -1,
+        length = end - start || 0,
+        result = Array(length < 0 ? 0 : length);
+
+    while (++index < length) {
+      result[index] = array[start + index];
+    }
+    return result;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Create a new `lodash` function using the given context object.
+   *
+   * @static
+   * @memberOf _
+   * @category Utilities
+   * @param {Object} [context=root] The context object.
+   * @returns {Function} Returns the `lodash` function.
+   */
+  function runInContext(context) {
+    // Avoid issues with some ES3 environments that attempt to use values, named
+    // after built-in constructors like `Object`, for the creation of literals.
+    // ES5 clears this up by stating that literals must use built-in constructors.
+    // See http://es5.github.io/#x11.1.5.
+    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
+
+    /** Native constructor references */
+    var Array = context.Array,
+        Boolean = context.Boolean,
+        Date = context.Date,
+        Function = context.Function,
+        Math = context.Math,
+        Number = context.Number,
+        Object = context.Object,
+        RegExp = context.RegExp,
+        String = context.String,
+        TypeError = context.TypeError;
+
+    /**
+     * Used for `Array` method references.
+     *
+     * Normally `Array.prototype` would suffice, however, using an array literal
+     * avoids issues in Narwhal.
+     */
+    var arrayRef = [];
+
+    /** Used for native method references */
+    var objectProto = Object.prototype;
+
+    /** Used to restore the original `_` reference in `noConflict` */
+    var oldDash = context._;
+
+    /** Used to resolve the internal [[Class]] of values */
+    var toString = objectProto.toString;
+
+    /** Used to detect if a method is native */
+    var reNative = RegExp('^' +
+      String(toString)
+        .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+        .replace(/toString| for [^\]]+/g, '.*?') + '$'
+    );
+
+    /** Native method shortcuts */
+    var ceil = Math.ceil,
+        clearTimeout = context.clearTimeout,
+        floor = Math.floor,
+        fnToString = Function.prototype.toString,
+        getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
+        hasOwnProperty = objectProto.hasOwnProperty,
+        push = arrayRef.push,
+        setTimeout = context.setTimeout,
+        splice = arrayRef.splice,
+        unshift = arrayRef.unshift;
+
+    /** Used to set meta data on functions */
+    var defineProperty = (function() {
+      // IE 8 only accepts DOM elements
+      try {
+        var o = {},
+            func = isNative(func = Object.defineProperty) && func,
+            result = func(o, o, o) && func;
+      } catch(e) { }
+      return result;
+    }());
+
+    /* Native method shortcuts for methods with the same name as other `lodash` methods */
+    var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
+        nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
+        nativeIsFinite = context.isFinite,
+        nativeIsNaN = context.isNaN,
+        nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
+        nativeMax = Math.max,
+        nativeMin = Math.min,
+        nativeParseInt = context.parseInt,
+        nativeRandom = Math.random;
+
+    /** Used to lookup a built-in constructor by [[Class]] */
+    var ctorByClass = {};
+    ctorByClass[arrayClass] = Array;
+    ctorByClass[boolClass] = Boolean;
+    ctorByClass[dateClass] = Date;
+    ctorByClass[funcClass] = Function;
+    ctorByClass[objectClass] = Object;
+    ctorByClass[numberClass] = Number;
+    ctorByClass[regexpClass] = RegExp;
+    ctorByClass[stringClass] = String;
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates a `lodash` object which wraps the given value to enable intuitive
+     * method chaining.
+     *
+     * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
+     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
+     * and `unshift`
+     *
+     * Chaining is supported in custom builds as long as the `value` method is
+     * implicitly or explicitly included in the build.
+     *
+     * The chainable wrapper functions are:
+     * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
+     * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
+     * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
+     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
+     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
+     * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
+     * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
+     * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
+     * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
+     * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
+     * and `zip`
+     *
+     * The non-chainable wrapper functions are:
+     * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
+     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
+     * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+     * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
+     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
+     * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
+     * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
+     * `template`, `unescape`, `uniqueId`, and `value`
+     *
+     * The wrapper functions `first` and `last` return wrapped values when `n` is
+     * provided, otherwise they return unwrapped values.
+     *
+     * Explicit chaining can be enabled by using the `_.chain` method.
+     *
+     * @name _
+     * @constructor
+     * @category Chaining
+     * @param {*} value The value to wrap in a `lodash` instance.
+     * @returns {Object} Returns a `lodash` instance.
+     * @example
+     *
+     * var wrapped = _([1, 2, 3]);
+     *
+     * // returns an unwrapped value
+     * wrapped.reduce(function(sum, num) {
+     *   return sum + num;
+     * });
+     * // => 6
+     *
+     * // returns a wrapped value
+     * var squares = wrapped.map(function(num) {
+     *   return num * num;
+     * });
+     *
+     * _.isArray(squares);
+     * // => false
+     *
+     * _.isArray(squares.value());
+     * // => true
+     */
+    function lodash(value) {
+      // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
+      return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
+       ? value
+       : new lodashWrapper(value);
+    }
+
+    /**
+     * A fast path for creating `lodash` wrapper objects.
+     *
+     * @private
+     * @param {*} value The value to wrap in a `lodash` instance.
+     * @param {boolean} chainAll A flag to enable chaining for all methods
+     * @returns {Object} Returns a `lodash` instance.
+     */
+    function lodashWrapper(value, chainAll) {
+      this.__chain__ = !!chainAll;
+      this.__wrapped__ = value;
+    }
+    // ensure `new lodashWrapper` is an instance of `lodash`
+    lodashWrapper.prototype = lodash.prototype;
+
+    /**
+     * An object used to flag environments features.
+     *
+     * @static
+     * @memberOf _
+     * @type Object
+     */
+    var support = lodash.support = {};
+
+    /**
+     * Detect if functions can be decompiled by `Function#toString`
+     * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
+     *
+     * @memberOf _.support
+     * @type boolean
+     */
+    support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
+
+    /**
+     * Detect if `Function#name` is supported (all but IE).
+     *
+     * @memberOf _.support
+     * @type boolean
+     */
+    support.funcNames = typeof Function.name == 'string';
+
+    /**
+     * By default, the template delimiters used by Lo-Dash are similar to those in
+     * embedded Ruby (ERB). Change the following template settings to use alternative
+     * delimiters.
+     *
+     * @static
+     * @memberOf _
+     * @type Object
+     */
+    lodash.templateSettings = {
+
+      /**
+       * Used to detect `data` property values to be HTML-escaped.
+       *
+       * @memberOf _.templateSettings
+       * @type RegExp
+       */
+      'escape': /<%-([\s\S]+?)%>/g,
+
+      /**
+       * Used to detect code to be evaluated.
+       *
+       * @memberOf _.templateSettings
+       * @type RegExp
+       */
+      'evaluate': /<%([\s\S]+?)%>/g,
+
+      /**
+       * Used to detect `data` property values to inject.
+       *
+       * @memberOf _.templateSettings
+       * @type RegExp
+       */
+      'interpolate': reInterpolate,
+
+      /**
+       * Used to reference the data object in the template text.
+       *
+       * @memberOf _.templateSettings
+       * @type string
+       */
+      'variable': '',
+
+      /**
+       * Used to import variables into the compiled template.
+       *
+       * @memberOf _.templateSettings
+       * @type Object
+       */
+      'imports': {
+
+        /**
+         * A reference to the `lodash` function.
+         *
+         * @memberOf _.templateSettings.imports
+         * @type Function
+         */
+        '_': lodash
+      }
+    };
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * The base implementation of `_.bind` that creates the bound function and
+     * sets its meta data.
+     *
+     * @private
+     * @param {Array} bindData The bind data array.
+     * @returns {Function} Returns the new bound function.
+     */
+    function baseBind(bindData) {
+      var func = bindData[0],
+          partialArgs = bindData[2],
+          thisArg = bindData[4];
+
+      function bound() {
+        // `Function#bind` spec
+        // http://es5.github.io/#x15.3.4.5
+        if (partialArgs) {
+          // avoid `arguments` object deoptimizations by using `slice` instead
+          // of `Array.prototype.slice.call` and not assigning `arguments` to a
+          // variable as a ternary expression
+          var args = slice(partialArgs);
+          push.apply(args, arguments);
+        }
+        // mimic the constructor's `return` behavior
+        // http://es5.github.io/#x13.2.2
+        if (this instanceof bound) {
+          // ensure `new bound` is an instance of `func`
+          var thisBinding = baseCreate(func.prototype),
+              result = func.apply(thisBinding, args || arguments);
+          return isObject(result) ? result : thisBinding;
+        }
+        return func.apply(thisArg, args || arguments);
+      }
+      setBindData(bound, bindData);
+      return bound;
+    }
+
+    /**
+     * The base implementation of `_.clone` without argument juggling or support
+     * for `thisArg` binding.
+     *
+     * @private
+     * @param {*} value The value to clone.
+     * @param {boolean} [isDeep=false] Specify a deep clone.
+     * @param {Function} [callback] The function to customize cloning values.
+     * @param {Array} [stackA=[]] Tracks traversed source objects.
+     * @param {Array} [stackB=[]] Associates clones with source counterparts.
+     * @returns {*} Returns the cloned value.
+     */
+    function baseClone(value, isDeep, callback, stackA, stackB) {
+      if (callback) {
+        var result = callback(value);
+        if (typeof result != 'undefined') {
+          return result;
+        }
+      }
+      // inspect [[Class]]
+      var isObj = isObject(value);
+      if (isObj) {
+        var className = toString.call(value);
+        if (!cloneableClasses[className]) {
+          return value;
+        }
+        var ctor = ctorByClass[className];
+        switch (className) {
+          case boolClass:
+          case dateClass:
+            return new ctor(+value);
+
+          case numberClass:
+          case stringClass:
+            return new ctor(value);
+
+          case regexpClass:
+            result = ctor(value.source, reFlags.exec(value));
+            result.lastIndex = value.lastIndex;
+            return result;
+        }
+      } else {
+        return value;
+      }
+      var isArr = isArray(value);
+      if (isDeep) {
+        // check for circular references and return corresponding clone
+        var initedStack = !stackA;
+        stackA || (stackA = getArray());
+        stackB || (stackB = getArray());
+
+        var length = stackA.length;
+        while (length--) {
+          if (stackA[length] == value) {
+            return stackB[length];
+          }
+        }
+        result = isArr ? ctor(value.length) : {};
+      }
+      else {
+        result = isArr ? slice(value) : assign({}, value);
+      }
+      // add array properties assigned by `RegExp#exec`
+      if (isArr) {
+        if (hasOwnProperty.call(value, 'index')) {
+          result.index = value.index;
+        }
+        if (hasOwnProperty.call(value, 'input')) {
+          result.input = value.input;
+        }
+      }
+      // exit for shallow clone
+      if (!isDeep) {
+        return result;
+      }
+      // add the source value to the stack of traversed objects
+      // and associate it with its clone
+      stackA.push(value);
+      stackB.push(result);
+
+      // recursively populate clone (susceptible to call stack limits)
+      (isArr ? forEach : forOwn)(value, function(objValue, key) {
+        result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
+      });
+
+      if (initedStack) {
+        releaseArray(stackA);
+        releaseArray(stackB);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.create` without support for assigning
+     * properties to the created object.
+     *
+     * @private
+     * @param {Object} prototype The object to inherit from.
+     * @returns {Object} Returns the new object.
+     */
+    function baseCreate(prototype, properties) {
+      return isObject(prototype) ? nativeCreate(prototype) : {};
+    }
+    // fallback for browsers without `Object.create`
+    if (!nativeCreate) {
+      baseCreate = (function() {
+        function Object() {}
+        return function(prototype) {
+          if (isObject(prototype)) {
+            Object.prototype = prototype;
+            var result = new Object;
+            Object.prototype = null;
+          }
+          return result || context.Object();
+        };
+      }());
+    }
+
+    /**
+     * The base implementation of `_.createCallback` without support for creating
+     * "_.pluck" or "_.where" style callbacks.
+     *
+     * @private
+     * @param {*} [func=identity] The value to convert to a callback.
+     * @param {*} [thisArg] The `this` binding of the created callback.
+     * @param {number} [argCount] The number of arguments the callback accepts.
+     * @returns {Function} Returns a callback function.
+     */
+    function baseCreateCallback(func, thisArg, argCount) {
+      if (typeof func != 'function') {
+        return identity;
+      }
+      // exit early for no `thisArg` or already bound by `Function#bind`
+      if (typeof thisArg == 'undefined' || !('prototype' in func)) {
+        return func;
+      }
+      var bindData = func.__bindData__;
+      if (typeof bindData == 'undefined') {
+        if (support.funcNames) {
+          bindData = !func.name;
+        }
+        bindData = bindData || !support.funcDecomp;
+        if (!bindData) {
+          var source = fnToString.call(func);
+          if (!support.funcNames) {
+            bindData = !reFuncName.test(source);
+          }
+          if (!bindData) {
+            // checks if `func` references the `this` keyword and stores the result
+            bindData = reThis.test(source);
+            setBindData(func, bindData);
+          }
+        }
+      }
+      // exit early if there are no `this` references or `func` is bound
+      if (bindData === false || (bindData !== true && bindData[1] & 1)) {
+        return func;
+      }
+      switch (argCount) {
+        case 1: return function(value) {
+          return func.call(thisArg, value);
+        };
+        case 2: return function(a, b) {
+          return func.call(thisArg, a, b);
+        };
+        case 3: return function(value, index, collection) {
+          return func.call(thisArg, value, index, collection);
+        };
+        case 4: return function(accumulator, value, index, collection) {
+          return func.call(thisArg, accumulator, value, index, collection);
+        };
+      }
+      return bind(func, thisArg);
+    }
+
+    /**
+     * The base implementation of `createWrapper` that creates the wrapper and
+     * sets its meta data.
+     *
+     * @private
+     * @param {Array} bindData The bind data array.
+     * @returns {Function} Returns the new function.
+     */
+    function baseCreateWrapper(bindData) {
+      var func = bindData[0],
+          bitmask = bindData[1],
+          partialArgs = bindData[2],
+          partialRightArgs = bindData[3],
+          thisArg = bindData[4],
+          arity = bindData[5];
+
+      var isBind = bitmask & 1,
+          isBindKey = bitmask & 2,
+          isCurry = bitmask & 4,
+          isCurryBound = bitmask & 8,
+          key = func;
+
+      function bound() {
+        var thisBinding = isBind ? thisArg : this;
+        if (partialArgs) {
+          var args = slice(partialArgs);
+          push.apply(args, arguments);
+        }
+        if (partialRightArgs || isCurry) {
+          args || (args = slice(arguments));
+          if (partialRightArgs) {
+            push.apply(args, partialRightArgs);
+          }
+          if (isCurry && args.length < arity) {
+            bitmask |= 16 & ~32;
+            return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
+          }
+        }
+        args || (args = arguments);
+        if (isBindKey) {
+          func = thisBinding[key];
+        }
+        if (this instanceof bound) {
+          thisBinding = baseCreate(func.prototype);
+          var result = func.apply(thisBinding, args);
+          return isObject(result) ? result : thisBinding;
+        }
+        return func.apply(thisBinding, args);
+      }
+      setBindData(bound, bindData);
+      return bound;
+    }
+
+    /**
+     * The base implementation of `_.difference` that accepts a single array
+     * of values to exclude.
+     *
+     * @private
+     * @param {Array} array The array to process.
+     * @param {Array} [values] The array of values to exclude.
+     * @returns {Array} Returns a new array of filtered values.
+     */
+    function baseDifference(array, values) {
+      var index = -1,
+          indexOf = getIndexOf(),
+          length = array ? array.length : 0,
+          isLarge = length >= largeArraySize && indexOf === baseIndexOf,
+          result = [];
+
+      if (isLarge) {
+        var cache = createCache(values);
+        if (cache) {
+          indexOf = cacheIndexOf;
+          values = cache;
+        } else {
+          isLarge = false;
+        }
+      }
+      while (++index < length) {
+        var value = array[index];
+        if (indexOf(values, value) < 0) {
+          result.push(value);
+        }
+      }
+      if (isLarge) {
+        releaseObject(values);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.flatten` without support for callback
+     * shorthands or `thisArg` binding.
+     *
+     * @private
+     * @param {Array} array The array to flatten.
+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
+     * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
+     * @param {number} [fromIndex=0] The index to start from.
+     * @returns {Array} Returns a new flattened array.
+     */
+    function baseFlatten(array, isShallow, isStrict, fromIndex) {
+      var index = (fromIndex || 0) - 1,
+          length = array ? array.length : 0,
+          result = [];
+
+      while (++index < length) {
+        var value = array[index];
+
+        if (value && typeof value == 'object' && typeof value.length == 'number'
+            && (isArray(value) || isArguments(value))) {
+          // recursively flatten arrays (susceptible to call stack limits)
+          if (!isShallow) {
+            value = baseFlatten(value, isShallow, isStrict);
+          }
+          var valIndex = -1,
+              valLength = value.length,
+              resIndex = result.length;
+
+          result.length += valLength;
+          while (++valIndex < valLength) {
+            result[resIndex++] = value[valIndex];
+          }
+        } else if (!isStrict) {
+          result.push(value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.isEqual`, without support for `thisArg` binding,
+     * that allows partial "_.where" style comparisons.
+     *
+     * @private
+     * @param {*} a The value to compare.
+     * @param {*} b The other value to compare.
+     * @param {Function} [callback] The function to customize comparing values.
+     * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
+     * @param {Array} [stackA=[]] Tracks traversed `a` objects.
+     * @param {Array} [stackB=[]] Tracks traversed `b` objects.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     */
+    function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
+      // used to indicate that when comparing objects, `a` has at least the properties of `b`
+      if (callback) {
+        var result = callback(a, b);
+        if (typeof result != 'undefined') {
+          return !!result;
+        }
+      }
+      // exit early for identical values
+      if (a === b) {
+        // treat `+0` vs. `-0` as not equal
+        return a !== 0 || (1 / a == 1 / b);
+      }
+      var type = typeof a,
+          otherType = typeof b;
+
+      // exit early for unlike primitive values
+      if (a === a &&
+          !(a && objectTypes[type]) &&
+          !(b && objectTypes[otherType])) {
+        return false;
+      }
+      // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
+      // http://es5.github.io/#x15.3.4.4
+      if (a == null || b == null) {
+        return a === b;
+      }
+      // compare [[Class]] names
+      var className = toString.call(a),
+          otherClass = toString.call(b);
+
+      if (className == argsClass) {
+        className = objectClass;
+      }
+      if (otherClass == argsClass) {
+        otherClass = objectClass;
+      }
+      if (className != otherClass) {
+        return false;
+      }
+      switch (className) {
+        case boolClass:
+        case dateClass:
+          // coerce dates and booleans to numbers, dates to milliseconds and booleans
+          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
+          return +a == +b;
+
+        case numberClass:
+          // treat `NaN` vs. `NaN` as equal
+          return (a != +a)
+            ? b != +b
+            // but treat `+0` vs. `-0` as not equal
+            : (a == 0 ? (1 / a == 1 / b) : a == +b);
+
+        case regexpClass:
+        case stringClass:
+          // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
+          // treat string primitives and their corresponding object instances as equal
+          return a == String(b);
+      }
+      var isArr = className == arrayClass;
+      if (!isArr) {
+        // unwrap any `lodash` wrapped values
+        var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
+            bWrapped = hasOwnProperty.call(b, '__wrapped__');
+
+        if (aWrapped || bWrapped) {
+          return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
+        }
+        // exit for functions and DOM nodes
+        if (className != objectClass) {
+          return false;
+        }
+        // in older versions of Opera, `arguments` objects have `Array` constructors
+        var ctorA = a.constructor,
+            ctorB = b.constructor;
+
+        // non `Object` object instances with different constructors are not equal
+        if (ctorA != ctorB &&
+              !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
+              ('constructor' in a && 'constructor' in b)
+            ) {
+          return false;
+        }
+      }
+      // assume cyclic structures are equal
+      // the algorithm for detecting cyclic structures is adapted from ES 5.1
+      // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
+      var initedStack = !stackA;
+      stackA || (stackA = getArray());
+      stackB || (stackB = getArray());
+
+      var length = stackA.length;
+      while (length--) {
+        if (stackA[length] == a) {
+          return stackB[length] == b;
+        }
+      }
+      var size = 0;
+      result = true;
+
+      // add `a` and `b` to the stack of traversed objects
+      stackA.push(a);
+      stackB.push(b);
+
+      // recursively compare objects and arrays (susceptible to call stack limits)
+      if (isArr) {
+        // compare lengths to determine if a deep comparison is necessary
+        length = a.length;
+        size = b.length;
+        result = size == length;
+
+        if (result || isWhere) {
+          // deep compare the contents, ignoring non-numeric properties
+          while (size--) {
+            var index = length,
+                value = b[size];
+
+            if (isWhere) {
+              while (index--) {
+                if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
+                  break;
+                }
+              }
+            } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
+              break;
+            }
+          }
+        }
+      }
+      else {
+        // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
+        // which, in this case, is more costly
+        forIn(b, function(value, key, b) {
+          if (hasOwnProperty.call(b, key)) {
+            // count the number of properties.
+            size++;
+            // deep compare each property value.
+            return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
+          }
+        });
+
+        if (result && !isWhere) {
+          // ensure both objects have the same number of properties
+          forIn(a, function(value, key, a) {
+            if (hasOwnProperty.call(a, key)) {
+              // `size` will be `-1` if `a` has more properties than `b`
+              return (result = --size > -1);
+            }
+          });
+        }
+      }
+      stackA.pop();
+      stackB.pop();
+
+      if (initedStack) {
+        releaseArray(stackA);
+        releaseArray(stackB);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.merge` without argument juggling or support
+     * for `thisArg` binding.
+     *
+     * @private
+     * @param {Object} object The destination object.
+     * @param {Object} source The source object.
+     * @param {Function} [callback] The function to customize merging properties.
+     * @param {Array} [stackA=[]] Tracks traversed source objects.
+     * @param {Array} [stackB=[]] Associates values with source counterparts.
+     */
+    function baseMerge(object, source, callback, stackA, stackB) {
+      (isArray(source) ? forEach : forOwn)(source, function(source, key) {
+        var found,
+            isArr,
+            result = source,
+            value = object[key];
+
+        if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
+          // avoid merging previously merged cyclic sources
+          var stackLength = stackA.length;
+          while (stackLength--) {
+            if ((found = stackA[stackLength] == source)) {
+              value = stackB[stackLength];
+              break;
+            }
+          }
+          if (!found) {
+            var isShallow;
+            if (callback) {
+              result = callback(value, source);
+              if ((isShallow = typeof result != 'undefined')) {
+                value = result;
+              }
+            }
+            if (!isShallow) {
+              value = isArr
+                ? (isArray(value) ? value : [])
+                : (isPlainObject(value) ? value : {});
+            }
+            // add `source` and associated `value` to the stack of traversed objects
+            stackA.push(source);
+            stackB.push(value);
+
+            // recursively merge objects and arrays (susceptible to call stack limits)
+            if (!isShallow) {
+              baseMerge(value, source, callback, stackA, stackB);
+            }
+          }
+        }
+        else {
+          if (callback) {
+            result = callback(value, source);
+            if (typeof result == 'undefined') {
+              result = source;
+            }
+          }
+          if (typeof result != 'undefined') {
+            value = result;
+          }
+        }
+        object[key] = value;
+      });
+    }
+
+    /**
+     * The base implementation of `_.random` without argument juggling or support
+     * for returning floating-point numbers.
+     *
+     * @private
+     * @param {number} min The minimum possible value.
+     * @param {number} max The maximum possible value.
+     * @returns {number} Returns a random number.
+     */
+    function baseRandom(min, max) {
+      return min + floor(nativeRandom() * (max - min + 1));
+    }
+
+    /**
+     * The base implementation of `_.uniq` without support for callback shorthands
+     * or `thisArg` binding.
+     *
+     * @private
+     * @param {Array} array The array to process.
+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
+     * @param {Function} [callback] The function called per iteration.
+     * @returns {Array} Returns a duplicate-value-free array.
+     */
+    function baseUniq(array, isSorted, callback) {
+      var index = -1,
+          indexOf = getIndexOf(),
+          length = array ? array.length : 0,
+          result = [];
+
+      var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
+          seen = (callback || isLarge) ? getArray() : result;
+
+      if (isLarge) {
+        var cache = createCache(seen);
+        indexOf = cacheIndexOf;
+        seen = cache;
+      }
+      while (++index < length) {
+        var value = array[index],
+            computed = callback ? callback(value, index, array) : value;
+
+        if (isSorted
+              ? !index || seen[seen.length - 1] !== computed
+              : indexOf(seen, computed) < 0
+            ) {
+          if (callback || isLarge) {
+            seen.push(computed);
+          }
+          result.push(value);
+        }
+      }
+      if (isLarge) {
+        releaseArray(seen.array);
+        releaseObject(seen);
+      } else if (callback) {
+        releaseArray(seen);
+      }
+      return result;
+    }
+
+    /**
+     * Creates a function that aggregates a collection, creating an object composed
+     * of keys generated from the results of running each element of the collection
+     * through a callback. The given `setter` function sets the keys and values
+     * of the composed object.
+     *
+     * @private
+     * @param {Function} setter The setter function.
+     * @returns {Function} Returns the new aggregator function.
+     */
+    function createAggregator(setter) {
+      return function(collection, callback, thisArg) {
+        var result = {};
+        callback = lodash.createCallback(callback, thisArg, 3);
+
+        var index = -1,
+            length = collection ? collection.length : 0;
+
+        if (typeof length == 'number') {
+          while (++index < length) {
+            var value = collection[index];
+            setter(result, value, callback(value, index, collection), collection);
+          }
+        } else {
+          forOwn(collection, function(value, key, collection) {
+            setter(result, value, callback(value, key, collection), collection);
+          });
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Creates a function that, when called, either curries or invokes `func`
+     * with an optional `this` binding and partially applied arguments.
+     *
+     * @private
+     * @param {Function|string} func The function or method name to reference.
+     * @param {number} bitmask The bitmask of method flags to compose.
+     *  The bitmask may be composed of the following flags:
+     *  1 - `_.bind`
+     *  2 - `_.bindKey`
+     *  4 - `_.curry`
+     *  8 - `_.curry` (bound)
+     *  16 - `_.partial`
+     *  32 - `_.partialRight`
+     * @param {Array} [partialArgs] An array of arguments to prepend to those
+     *  provided to the new function.
+     * @param {Array} [partialRightArgs] An array of arguments to append to those
+     *  provided to the new function.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @param {number} [arity] The arity of `func`.
+     * @returns {Function} Returns the new function.
+     */
+    function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
+      var isBind = bitmask & 1,
+          isBindKey = bitmask & 2,
+          isCurry = bitmask & 4,
+          isCurryBound = bitmask & 8,
+          isPartial = bitmask & 16,
+          isPartialRight = bitmask & 32;
+
+      if (!isBindKey && !isFunction(func)) {
+        throw new TypeError;
+      }
+      if (isPartial && !partialArgs.length) {
+        bitmask &= ~16;
+        isPartial = partialArgs = false;
+      }
+      if (isPartialRight && !partialRightArgs.length) {
+        bitmask &= ~32;
+        isPartialRight = partialRightArgs = false;
+      }
+      var bindData = func && func.__bindData__;
+      if (bindData && bindData !== true) {
+        // clone `bindData`
+        bindData = slice(bindData);
+        if (bindData[2]) {
+          bindData[2] = slice(bindData[2]);
+        }
+        if (bindData[3]) {
+          bindData[3] = slice(bindData[3]);
+        }
+        // set `thisBinding` is not previously bound
+        if (isBind && !(bindData[1] & 1)) {
+          bindData[4] = thisArg;
+        }
+        // set if previously bound but not currently (subsequent curried functions)
+        if (!isBind && bindData[1] & 1) {
+          bitmask |= 8;
+        }
+        // set curried arity if not yet set
+        if (isCurry && !(bindData[1] & 4)) {
+          bindData[5] = arity;
+        }
+        // append partial left arguments
+        if (isPartial) {
+          push.apply(bindData[2] || (bindData[2] = []), partialArgs);
+        }
+        // append partial right arguments
+        if (isPartialRight) {
+          unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
+        }
+        // merge flags
+        bindData[1] |= bitmask;
+        return createWrapper.apply(null, bindData);
+      }
+      // fast path for `_.bind`
+      var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
+      return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
+    }
+
+    /**
+     * Used by `escape` to convert characters to HTML entities.
+     *
+     * @private
+     * @param {string} match The matched character to escape.
+     * @returns {string} Returns the escaped character.
+     */
+    function escapeHtmlChar(match) {
+      return htmlEscapes[match];
+    }
+
+    /**
+     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
+     * customized, this method returns the custom method, otherwise it returns
+     * the `baseIndexOf` function.
+     *
+     * @private
+     * @returns {Function} Returns the "indexOf" function.
+     */
+    function getIndexOf() {
+      var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
+      return result;
+    }
+
+    /**
+     * Checks if `value` is a native function.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
+     */
+    function isNative(value) {
+      return typeof value == 'function' && reNative.test(value);
+    }
+
+    /**
+     * Sets `this` binding data on a given function.
+     *
+     * @private
+     * @param {Function} func The function to set data on.
+     * @param {Array} value The data array to set.
+     */
+    var setBindData = !defineProperty ? noop : function(func, value) {
+      descriptor.value = value;
+      defineProperty(func, '__bindData__', descriptor);
+    };
+
+    /**
+     * A fallback implementation of `isPlainObject` which checks if a given value
+     * is an object created by the `Object` constructor, assuming objects created
+     * by the `Object` constructor have no inherited enumerable properties and that
+     * there are no `Object.prototype` extensions.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+     */
+    function shimIsPlainObject(value) {
+      var ctor,
+          result;
+
+      // avoid non Object objects, `arguments` objects, and DOM elements
+      if (!(value && toString.call(value) == objectClass) ||
+          (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
+        return false;
+      }
+      // In most environments an object's own properties are iterated before
+      // its inherited properties. If the last iterated property is an object's
+      // own property then there are no inherited enumerable properties.
+      forIn(value, function(value, key) {
+        result = key;
+      });
+      return typeof result == 'undefined' || hasOwnProperty.call(value, result);
+    }
+
+    /**
+     * Used by `unescape` to convert HTML entities to characters.
+     *
+     * @private
+     * @param {string} match The matched character to unescape.
+     * @returns {string} Returns the unescaped character.
+     */
+    function unescapeHtmlChar(match) {
+      return htmlUnescapes[match];
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Checks if `value` is an `arguments` object.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
+     * @example
+     *
+     * (function() { return _.isArguments(arguments); })(1, 2, 3);
+     * // => true
+     *
+     * _.isArguments([1, 2, 3]);
+     * // => false
+     */
+    function isArguments(value) {
+      return value && typeof value == 'object' && typeof value.length == 'number' &&
+        toString.call(value) == argsClass || false;
+    }
+
+    /**
+     * Checks if `value` is an array.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
+     * @example
+     *
+     * (function() { return _.isArray(arguments); })();
+     * // => false
+     *
+     * _.isArray([1, 2, 3]);
+     * // => true
+     */
+    var isArray = nativeIsArray || function(value) {
+      return value && typeof value == 'object' && typeof value.length == 'number' &&
+        toString.call(value) == arrayClass || false;
+    };
+
+    /**
+     * A fallback implementation of `Object.keys` which produces an array of the
+     * given object's own enumerable property names.
+     *
+     * @private
+     * @type Function
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns an array of property names.
+     */
+    var shimKeys = function(object) {
+      var index, iterable = object, result = [];
+      if (!iterable) return result;
+      if (!(objectTypes[typeof object])) return result;
+        for (index in iterable) {
+          if (hasOwnProperty.call(iterable, index)) {
+            result.push(index);
+          }
+        }
+      return result
+    };
+
+    /**
+     * Creates an array composed of the own enumerable property names of an object.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns an array of property names.
+     * @example
+     *
+     * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
+     * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
+     */
+    var keys = !nativeKeys ? shimKeys : function(object) {
+      if (!isObject(object)) {
+        return [];
+      }
+      return nativeKeys(object);
+    };
+
+    /**
+     * Used to convert characters to HTML entities:
+     *
+     * Though the `>` character is escaped for symmetry, characters like `>` and `/`
+     * don't require escaping in HTML and have no special meaning unless they're part
+     * of a tag or an unquoted attribute value.
+     * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
+     */
+    var htmlEscapes = {
+      '&': '&amp;',
+      '<': '&lt;',
+      '>': '&gt;',
+      '"': '&quot;',
+      "'": '&#39;'
+    };
+
+    /** Used to convert HTML entities to characters */
+    var htmlUnescapes = invert(htmlEscapes);
+
+    /** Used to match HTML entities and HTML characters */
+    var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
+        reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Assigns own enumerable properties of source object(s) to the destination
+     * object. Subsequent sources will overwrite property assignments of previous
+     * sources. If a callback is provided it will be executed to produce the
+     * assigned values. The callback is bound to `thisArg` and invoked with two
+     * arguments; (objectValue, sourceValue).
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @alias extend
+     * @category Objects
+     * @param {Object} object The destination object.
+     * @param {...Object} [source] The source objects.
+     * @param {Function} [callback] The function to customize assigning values.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns the destination object.
+     * @example
+     *
+     * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
+     * // => { 'name': 'fred', 'employer': 'slate' }
+     *
+     * var defaults = _.partialRight(_.assign, function(a, b) {
+     *   return typeof a == 'undefined' ? b : a;
+     * });
+     *
+     * var object = { 'name': 'barney' };
+     * defaults(object, { 'name': 'fred', 'employer': 'slate' });
+     * // => { 'name': 'barney', 'employer': 'slate' }
+     */
+    var assign = function(object, source, guard) {
+      var index, iterable = object, result = iterable;
+      if (!iterable) return result;
+      var args = arguments,
+          argsIndex = 0,
+          argsLength = typeof guard == 'number' ? 2 : args.length;
+      if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
+        var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
+      } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
+        callback = args[--argsLength];
+      }
+      while (++argsIndex < argsLength) {
+        iterable = args[argsIndex];
+        if (iterable && objectTypes[typeof iterable]) {
+        var ownIndex = -1,
+            ownProps = objectTypes[typeof iterable] && keys(iterable),
+            length = ownProps ? ownProps.length : 0;
+
+        while (++ownIndex < length) {
+          index = ownProps[ownIndex];
+          result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
+        }
+        }
+      }
+      return result
+    };
+
+    /**
+     * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
+     * be cloned, otherwise they will be assigned by reference. If a callback
+     * is provided it will be executed to produce the cloned values. If the
+     * callback returns `undefined` cloning will be handled by the method instead.
+     * The callback is bound to `thisArg` and invoked with one argument; (value).
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to clone.
+     * @param {boolean} [isDeep=false] Specify a deep clone.
+     * @param {Function} [callback] The function to customize cloning values.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the cloned value.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * var shallow = _.clone(characters);
+     * shallow[0] === characters[0];
+     * // => true
+     *
+     * var deep = _.clone(characters, true);
+     * deep[0] === characters[0];
+     * // => false
+     *
+     * _.mixin({
+     *   'clone': _.partialRight(_.clone, function(value) {
+     *     return _.isElement(value) ? value.cloneNode(false) : undefined;
+     *   })
+     * });
+     *
+     * var clone = _.clone(document.body);
+     * clone.childNodes.length;
+     * // => 0
+     */
+    function clone(value, isDeep, callback, thisArg) {
+      // allows working with "Collections" methods without using their `index`
+      // and `collection` arguments for `isDeep` and `callback`
+      if (typeof isDeep != 'boolean' && isDeep != null) {
+        thisArg = callback;
+        callback = isDeep;
+        isDeep = false;
+      }
+      return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
+    }
+
+    /**
+     * Creates a deep clone of `value`. If a callback is provided it will be
+     * executed to produce the cloned values. If the callback returns `undefined`
+     * cloning will be handled by the method instead. The callback is bound to
+     * `thisArg` and invoked with one argument; (value).
+     *
+     * Note: This method is loosely based on the structured clone algorithm. Functions
+     * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
+     * objects created by constructors other than `Object` are cloned to plain `Object` objects.
+     * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to deep clone.
+     * @param {Function} [callback] The function to customize cloning values.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the deep cloned value.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * var deep = _.cloneDeep(characters);
+     * deep[0] === characters[0];
+     * // => false
+     *
+     * var view = {
+     *   'label': 'docs',
+     *   'node': element
+     * };
+     *
+     * var clone = _.cloneDeep(view, function(value) {
+     *   return _.isElement(value) ? value.cloneNode(true) : undefined;
+     * });
+     *
+     * clone.node == view.node;
+     * // => false
+     */
+    function cloneDeep(value, callback, thisArg) {
+      return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
+    }
+
+    /**
+     * Creates an object that inherits from the given `prototype` object. If a
+     * `properties` object is provided its own enumerable properties are assigned
+     * to the created object.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} prototype The object to inherit from.
+     * @param {Object} [properties] The properties to assign to the object.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * function Shape() {
+     *   this.x = 0;
+     *   this.y = 0;
+     * }
+     *
+     * function Circle() {
+     *   Shape.call(this);
+     * }
+     *
+     * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
+     *
+     * var circle = new Circle;
+     * circle instanceof Circle;
+     * // => true
+     *
+     * circle instanceof Shape;
+     * // => true
+     */
+    function create(prototype, properties) {
+      var result = baseCreate(prototype);
+      return properties ? assign(result, properties) : result;
+    }
+
+    /**
+     * Assigns own enumerable properties of source object(s) to the destination
+     * object for all destination properties that resolve to `undefined`. Once a
+     * property is set, additional defaults of the same property will be ignored.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Objects
+     * @param {Object} object The destination object.
+     * @param {...Object} [source] The source objects.
+     * @param- {Object} [guard] Allows working with `_.reduce` without using its
+     *  `key` and `object` arguments as sources.
+     * @returns {Object} Returns the destination object.
+     * @example
+     *
+     * var object = { 'name': 'barney' };
+     * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
+     * // => { 'name': 'barney', 'employer': 'slate' }
+     */
+    var defaults = function(object, source, guard) {
+      var index, iterable = object, result = iterable;
+      if (!iterable) return result;
+      var args = arguments,
+          argsIndex = 0,
+          argsLength = typeof guard == 'number' ? 2 : args.length;
+      while (++argsIndex < argsLength) {
+        iterable = args[argsIndex];
+        if (iterable && objectTypes[typeof iterable]) {
+        var ownIndex = -1,
+            ownProps = objectTypes[typeof iterable] && keys(iterable),
+            length = ownProps ? ownProps.length : 0;
+
+        while (++ownIndex < length) {
+          index = ownProps[ownIndex];
+          if (typeof result[index] == 'undefined') result[index] = iterable[index];
+        }
+        }
+      }
+      return result
+    };
+
+    /**
+     * This method is like `_.findIndex` except that it returns the key of the
+     * first element that passes the callback check, instead of the element itself.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to search.
+     * @param {Function|Object|string} [callback=identity] The function called per
+     *  iteration. If a property name or object is provided it will be used to
+     *  create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
+     * @example
+     *
+     * var characters = {
+     *   'barney': {  'age': 36, 'blocked': false },
+     *   'fred': {    'age': 40, 'blocked': true },
+     *   'pebbles': { 'age': 1,  'blocked': false }
+     * };
+     *
+     * _.findKey(characters, function(chr) {
+     *   return chr.age < 40;
+     * });
+     * // => 'barney' (property order is not guaranteed across environments)
+     *
+     * // using "_.where" callback shorthand
+     * _.findKey(characters, { 'age': 1 });
+     * // => 'pebbles'
+     *
+     * // using "_.pluck" callback shorthand
+     * _.findKey(characters, 'blocked');
+     * // => 'fred'
+     */
+    function findKey(object, callback, thisArg) {
+      var result;
+      callback = lodash.createCallback(callback, thisArg, 3);
+      forOwn(object, function(value, key, object) {
+        if (callback(value, key, object)) {
+          result = key;
+          return false;
+        }
+      });
+      return result;
+    }
+
+    /**
+     * This method is like `_.findKey` except that it iterates over elements
+     * of a `collection` in the opposite order.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to search.
+     * @param {Function|Object|string} [callback=identity] The function called per
+     *  iteration. If a property name or object is provided it will be used to
+     *  create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
+     * @example
+     *
+     * var characters = {
+     *   'barney': {  'age': 36, 'blocked': true },
+     *   'fred': {    'age': 40, 'blocked': false },
+     *   'pebbles': { 'age': 1,  'blocked': true }
+     * };
+     *
+     * _.findLastKey(characters, function(chr) {
+     *   return chr.age < 40;
+     * });
+     * // => returns `pebbles`, assuming `_.findKey` returns `barney`
+     *
+     * // using "_.where" callback shorthand
+     * _.findLastKey(characters, { 'age': 40 });
+     * // => 'fred'
+     *
+     * // using "_.pluck" callback shorthand
+     * _.findLastKey(characters, 'blocked');
+     * // => 'pebbles'
+     */
+    function findLastKey(object, callback, thisArg) {
+      var result;
+      callback = lodash.createCallback(callback, thisArg, 3);
+      forOwnRight(object, function(value, key, object) {
+        if (callback(value, key, object)) {
+          result = key;
+          return false;
+        }
+      });
+      return result;
+    }
+
+    /**
+     * Iterates over own and inherited enumerable properties of an object,
+     * executing the callback for each property. The callback is bound to `thisArg`
+     * and invoked with three arguments; (value, key, object). Callbacks may exit
+     * iteration early by explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Objects
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * function Shape() {
+     *   this.x = 0;
+     *   this.y = 0;
+     * }
+     *
+     * Shape.prototype.move = function(x, y) {
+     *   this.x += x;
+     *   this.y += y;
+     * };
+     *
+     * _.forIn(new Shape, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
+     */
+    var forIn = function(collection, callback, thisArg) {
+      var index, iterable = collection, result = iterable;
+      if (!iterable) return result;
+      if (!objectTypes[typeof iterable]) return result;
+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
+        for (index in iterable) {
+          if (callback(iterable[index], index, collection) === false) return result;
+        }
+      return result
+    };
+
+    /**
+     * This method is like `_.forIn` except that it iterates over elements
+     * of a `collection` in the opposite order.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * function Shape() {
+     *   this.x = 0;
+     *   this.y = 0;
+     * }
+     *
+     * Shape.prototype.move = function(x, y) {
+     *   this.x += x;
+     *   this.y += y;
+     * };
+     *
+     * _.forInRight(new Shape, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
+     */
+    function forInRight(object, callback, thisArg) {
+      var pairs = [];
+
+      forIn(object, function(value, key) {
+        pairs.push(key, value);
+      });
+
+      var length = pairs.length;
+      callback = baseCreateCallback(callback, thisArg, 3);
+      while (length--) {
+        if (callback(pairs[length--], pairs[length], object) === false) {
+          break;
+        }
+      }
+      return object;
+    }
+
+    /**
+     * Iterates over own enumerable properties of an object, executing the callback
+     * for each property. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, key, object). Callbacks may exit iteration early by
+     * explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Objects
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
+     *   console.log(key);
+     * });
+     * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
+     */
+    var forOwn = function(collection, callback, thisArg) {
+      var index, iterable = collection, result = iterable;
+      if (!iterable) return result;
+      if (!objectTypes[typeof iterable]) return result;
+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
+        var ownIndex = -1,
+            ownProps = objectTypes[typeof iterable] && keys(iterable),
+            length = ownProps ? ownProps.length : 0;
+
+        while (++ownIndex < length) {
+          index = ownProps[ownIndex];
+          if (callback(iterable[index], index, collection) === false) return result;
+        }
+      return result
+    };
+
+    /**
+     * This method is like `_.forOwn` except that it iterates over elements
+     * of a `collection` in the opposite order.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
+     *   console.log(key);
+     * });
+     * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
+     */
+    function forOwnRight(object, callback, thisArg) {
+      var props = keys(object),
+          length = props.length;
+
+      callback = baseCreateCallback(callback, thisArg, 3);
+      while (length--) {
+        var key = props[length];
+        if (callback(object[key], key, object) === false) {
+          break;
+        }
+      }
+      return object;
+    }
+
+    /**
+     * Creates a sorted array of property names of all enumerable properties,
+     * own and inherited, of `object` that have function values.
+     *
+     * @static
+     * @memberOf _
+     * @alias methods
+     * @category Objects
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns an array of property names that have function values.
+     * @example
+     *
+     * _.functions(_);
+     * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
+     */
+    function functions(object) {
+      var result = [];
+      forIn(object, function(value, key) {
+        if (isFunction(value)) {
+          result.push(key);
+        }
+      });
+      return result.sort();
+    }
+
+    /**
+     * Checks if the specified property name exists as a direct property of `object`,
+     * instead of an inherited property.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to inspect.
+     * @param {string} key The name of the property to check.
+     * @returns {boolean} Returns `true` if key is a direct property, else `false`.
+     * @example
+     *
+     * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
+     * // => true
+     */
+    function has(object, key) {
+      return object ? hasOwnProperty.call(object, key) : false;
+    }
+
+    /**
+     * Creates an object composed of the inverted keys and values of the given object.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to invert.
+     * @returns {Object} Returns the created inverted object.
+     * @example
+     *
+     * _.invert({ 'first': 'fred', 'second': 'barney' });
+     * // => { 'fred': 'first', 'barney': 'second' }
+     */
+    function invert(object) {
+      var index = -1,
+          props = keys(object),
+          length = props.length,
+          result = {};
+
+      while (++index < length) {
+        var key = props[index];
+        result[object[key]] = key;
+      }
+      return result;
+    }
+
+    /**
+     * Checks if `value` is a boolean value.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
+     * @example
+     *
+     * _.isBoolean(null);
+     * // => false
+     */
+    function isBoolean(value) {
+      return value === true || value === false ||
+        value && typeof value == 'object' && toString.call(value) == boolClass || false;
+    }
+
+    /**
+     * Checks if `value` is a date.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
+     * @example
+     *
+     * _.isDate(new Date);
+     * // => true
+     */
+    function isDate(value) {
+      return value && typeof value == 'object' && toString.call(value) == dateClass || false;
+    }
+
+    /**
+     * Checks if `value` is a DOM element.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
+     * @example
+     *
+     * _.isElement(document.body);
+     * // => true
+     */
+    function isElement(value) {
+      return value && value.nodeType === 1 || false;
+    }
+
+    /**
+     * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
+     * length of `0` and objects with no own enumerable properties are considered
+     * "empty".
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Array|Object|string} value The value to inspect.
+     * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
+     * @example
+     *
+     * _.isEmpty([1, 2, 3]);
+     * // => false
+     *
+     * _.isEmpty({});
+     * // => true
+     *
+     * _.isEmpty('');
+     * // => true
+     */
+    function isEmpty(value) {
+      var result = true;
+      if (!value) {
+        return result;
+      }
+      var className = toString.call(value),
+          length = value.length;
+
+      if ((className == arrayClass || className == stringClass || className == argsClass ) ||
+          (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
+        return !length;
+      }
+      forOwn(value, function() {
+        return (result = false);
+      });
+      return result;
+    }
+
+    /**
+     * Performs a deep comparison between two values to determine if they are
+     * equivalent to each other. If a callback is provided it will be executed
+     * to compare values. If the callback returns `undefined` comparisons will
+     * be handled by the method instead. The callback is bound to `thisArg` and
+     * invoked with two arguments; (a, b).
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} a The value to compare.
+     * @param {*} b The other value to compare.
+     * @param {Function} [callback] The function to customize comparing values.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     * @example
+     *
+     * var object = { 'name': 'fred' };
+     * var copy = { 'name': 'fred' };
+     *
+     * object == copy;
+     * // => false
+     *
+     * _.isEqual(object, copy);
+     * // => true
+     *
+     * var words = ['hello', 'goodbye'];
+     * var otherWords = ['hi', 'goodbye'];
+     *
+     * _.isEqual(words, otherWords, function(a, b) {
+     *   var reGreet = /^(?:hello|hi)$/i,
+     *       aGreet = _.isString(a) && reGreet.test(a),
+     *       bGreet = _.isString(b) && reGreet.test(b);
+     *
+     *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
+     * });
+     * // => true
+     */
+    function isEqual(a, b, callback, thisArg) {
+      return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
+    }
+
+    /**
+     * Checks if `value` is, or can be coerced to, a finite number.
+     *
+     * Note: This is not the same as native `isFinite` which will return true for
+     * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
+     * @example
+     *
+     * _.isFinite(-101);
+     * // => true
+     *
+     * _.isFinite('10');
+     * // => true
+     *
+     * _.isFinite(true);
+     * // => false
+     *
+     * _.isFinite('');
+     * // => false
+     *
+     * _.isFinite(Infinity);
+     * // => false
+     */
+    function isFinite(value) {
+      return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
+    }
+
+    /**
+     * Checks if `value` is a function.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
+     * @example
+     *
+     * _.isFunction(_);
+     * // => true
+     */
+    function isFunction(value) {
+      return typeof value == 'function';
+    }
+
+    /**
+     * Checks if `value` is the language type of Object.
+     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
+     * @example
+     *
+     * _.isObject({});
+     * // => true
+     *
+     * _.isObject([1, 2, 3]);
+     * // => true
+     *
+     * _.isObject(1);
+     * // => false
+     */
+    function isObject(value) {
+      // check if the value is the ECMAScript language type of Object
+      // http://es5.github.io/#x8
+      // and avoid a V8 bug
+      // http://code.google.com/p/v8/issues/detail?id=2291
+      return !!(value && objectTypes[typeof value]);
+    }
+
+    /**
+     * Checks if `value` is `NaN`.
+     *
+     * Note: This is not the same as native `isNaN` which will return `true` for
+     * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
+     * @example
+     *
+     * _.isNaN(NaN);
+     * // => true
+     *
+     * _.isNaN(new Number(NaN));
+     * // => true
+     *
+     * isNaN(undefined);
+     * // => true
+     *
+     * _.isNaN(undefined);
+     * // => false
+     */
+    function isNaN(value) {
+      // `NaN` as a primitive is the only value that is not equal to itself
+      // (perform the [[Class]] check first to avoid errors with some host objects in IE)
+      return isNumber(value) && value != +value;
+    }
+
+    /**
+     * Checks if `value` is `null`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
+     * @example
+     *
+     * _.isNull(null);
+     * // => true
+     *
+     * _.isNull(undefined);
+     * // => false
+     */
+    function isNull(value) {
+      return value === null;
+    }
+
+    /**
+     * Checks if `value` is a number.
+     *
+     * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
+     * @example
+     *
+     * _.isNumber(8.4 * 5);
+     * // => true
+     */
+    function isNumber(value) {
+      return typeof value == 'number' ||
+        value && typeof value == 'object' && toString.call(value) == numberClass || false;
+    }
+
+    /**
+     * Checks if `value` is an object created by the `Object` constructor.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+     * @example
+     *
+     * function Shape() {
+     *   this.x = 0;
+     *   this.y = 0;
+     * }
+     *
+     * _.isPlainObject(new Shape);
+     * // => false
+     *
+     * _.isPlainObject([1, 2, 3]);
+     * // => false
+     *
+     * _.isPlainObject({ 'x': 0, 'y': 0 });
+     * // => true
+     */
+    var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
+      if (!(value && toString.call(value) == objectClass)) {
+        return false;
+      }
+      var valueOf = value.valueOf,
+          objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
+
+      return objProto
+        ? (value == objProto || getPrototypeOf(value) == objProto)
+        : shimIsPlainObject(value);
+    };
+
+    /**
+     * Checks if `value` is a regular expression.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
+     * @example
+     *
+     * _.isRegExp(/fred/);
+     * // => true
+     */
+    function isRegExp(value) {
+      return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
+    }
+
+    /**
+     * Checks if `value` is a string.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
+     * @example
+     *
+     * _.isString('fred');
+     * // => true
+     */
+    function isString(value) {
+      return typeof value == 'string' ||
+        value && typeof value == 'object' && toString.call(value) == stringClass || false;
+    }
+
+    /**
+     * Checks if `value` is `undefined`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
+     * @example
+     *
+     * _.isUndefined(void 0);
+     * // => true
+     */
+    function isUndefined(value) {
+      return typeof value == 'undefined';
+    }
+
+    /**
+     * Creates an object with the same keys as `object` and values generated by
+     * running each own enumerable property of `object` through the callback.
+     * The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, key, object).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new object with values of the results of each `callback` execution.
+     * @example
+     *
+     * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
+     * // => { 'a': 3, 'b': 6, 'c': 9 }
+     *
+     * var characters = {
+     *   'fred': { 'name': 'fred', 'age': 40 },
+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
+     * };
+     *
+     * // using "_.pluck" callback shorthand
+     * _.mapValues(characters, 'age');
+     * // => { 'fred': 40, 'pebbles': 1 }
+     */
+    function mapValues(object, callback, thisArg) {
+      var result = {};
+      callback = lodash.createCallback(callback, thisArg, 3);
+
+      forOwn(object, function(value, key, object) {
+        result[key] = callback(value, key, object);
+      });
+      return result;
+    }
+
+    /**
+     * Recursively merges own enumerable properties of the source object(s), that
+     * don't resolve to `undefined` into the destination object. Subsequent sources
+     * will overwrite property assignments of previous sources. If a callback is
+     * provided it will be executed to produce the merged values of the destination
+     * and source properties. If the callback returns `undefined` merging will
+     * be handled by the method instead. The callback is bound to `thisArg` and
+     * invoked with two arguments; (objectValue, sourceValue).
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The destination object.
+     * @param {...Object} [source] The source objects.
+     * @param {Function} [callback] The function to customize merging properties.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns the destination object.
+     * @example
+     *
+     * var names = {
+     *   'characters': [
+     *     { 'name': 'barney' },
+     *     { 'name': 'fred' }
+     *   ]
+     * };
+     *
+     * var ages = {
+     *   'characters': [
+     *     { 'age': 36 },
+     *     { 'age': 40 }
+     *   ]
+     * };
+     *
+     * _.merge(names, ages);
+     * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
+     *
+     * var food = {
+     *   'fruits': ['apple'],
+     *   'vegetables': ['beet']
+     * };
+     *
+     * var otherFood = {
+     *   'fruits': ['banana'],
+     *   'vegetables': ['carrot']
+     * };
+     *
+     * _.merge(food, otherFood, function(a, b) {
+     *   return _.isArray(a) ? a.concat(b) : undefined;
+     * });
+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
+     */
+    function merge(object) {
+      var args = arguments,
+          length = 2;
+
+      if (!isObject(object)) {
+        return object;
+      }
+      // allows working with `_.reduce` and `_.reduceRight` without using
+      // their `index` and `collection` arguments
+      if (typeof args[2] != 'number') {
+        length = args.length;
+      }
+      if (length > 3 && typeof args[length - 2] == 'function') {
+        var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
+      } else if (length > 2 && typeof args[length - 1] == 'function') {
+        callback = args[--length];
+      }
+      var sources = slice(arguments, 1, length),
+          index = -1,
+          stackA = getArray(),
+          stackB = getArray();
+
+      while (++index < length) {
+        baseMerge(object, sources[index], callback, stackA, stackB);
+      }
+      releaseArray(stackA);
+      releaseArray(stackB);
+      return object;
+    }
+
+    /**
+     * Creates a shallow clone of `object` excluding the specified properties.
+     * Property names may be specified as individual arguments or as arrays of
+     * property names. If a callback is provided it will be executed for each
+     * property of `object` omitting the properties the callback returns truey
+     * for. The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, key, object).
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The source object.
+     * @param {Function|...string|string[]} [callback] The properties to omit or the
+     *  function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns an object without the omitted properties.
+     * @example
+     *
+     * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
+     * // => { 'name': 'fred' }
+     *
+     * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
+     *   return typeof value == 'number';
+     * });
+     * // => { 'name': 'fred' }
+     */
+    function omit(object, callback, thisArg) {
+      var result = {};
+      if (typeof callback != 'function') {
+        var props = [];
+        forIn(object, function(value, key) {
+          props.push(key);
+        });
+        props = baseDifference(props, baseFlatten(arguments, true, false, 1));
+
+        var index = -1,
+            length = props.length;
+
+        while (++index < length) {
+          var key = props[index];
+          result[key] = object[key];
+        }
+      } else {
+        callback = lodash.createCallback(callback, thisArg, 3);
+        forIn(object, function(value, key, object) {
+          if (!callback(value, key, object)) {
+            result[key] = value;
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Creates a two dimensional array of an object's key-value pairs,
+     * i.e. `[[key1, value1], [key2, value2]]`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns new array of key-value pairs.
+     * @example
+     *
+     * _.pairs({ 'barney': 36, 'fred': 40 });
+     * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
+     */
+    function pairs(object) {
+      var index = -1,
+          props = keys(object),
+          length = props.length,
+          result = Array(length);
+
+      while (++index < length) {
+        var key = props[index];
+        result[index] = [key, object[key]];
+      }
+      return result;
+    }
+
+    /**
+     * Creates a shallow clone of `object` composed of the specified properties.
+     * Property names may be specified as individual arguments or as arrays of
+     * property names. If a callback is provided it will be executed for each
+     * property of `object` picking the properties the callback returns truey
+     * for. The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, key, object).
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The source object.
+     * @param {Function|...string|string[]} [callback] The function called per
+     *  iteration or property names to pick, specified as individual property
+     *  names or arrays of property names.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns an object composed of the picked properties.
+     * @example
+     *
+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
+     * // => { 'name': 'fred' }
+     *
+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
+     *   return key.charAt(0) != '_';
+     * });
+     * // => { 'name': 'fred' }
+     */
+    function pick(object, callback, thisArg) {
+      var result = {};
+      if (typeof callback != 'function') {
+        var index = -1,
+            props = baseFlatten(arguments, true, false, 1),
+            length = isObject(object) ? props.length : 0;
+
+        while (++index < length) {
+          var key = props[index];
+          if (key in object) {
+            result[key] = object[key];
+          }
+        }
+      } else {
+        callback = lodash.createCallback(callback, thisArg, 3);
+        forIn(object, function(value, key, object) {
+          if (callback(value, key, object)) {
+            result[key] = value;
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * An alternative to `_.reduce` this method transforms `object` to a new
+     * `accumulator` object which is the result of running each of its own
+     * enumerable properties through a callback, with each callback execution
+     * potentially mutating the `accumulator` object. The callback is bound to
+     * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
+     * Callbacks may exit iteration early by explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Array|Object} object The object to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [accumulator] The custom accumulator value.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the accumulated value.
+     * @example
+     *
+     * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
+     *   num *= num;
+     *   if (num % 2) {
+     *     return result.push(num) < 3;
+     *   }
+     * });
+     * // => [1, 9, 25]
+     *
+     * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
+     *   result[key] = num * 3;
+     * });
+     * // => { 'a': 3, 'b': 6, 'c': 9 }
+     */
+    function transform(object, callback, accumulator, thisArg) {
+      var isArr = isArray(object);
+      if (accumulator == null) {
+        if (isArr) {
+          accumulator = [];
+        } else {
+          var ctor = object && object.constructor,
+              proto = ctor && ctor.prototype;
+
+          accumulator = baseCreate(proto);
+        }
+      }
+      if (callback) {
+        callback = lodash.createCallback(callback, thisArg, 4);
+        (isArr ? forEach : forOwn)(object, function(value, index, object) {
+          return callback(accumulator, value, index, object);
+        });
+      }
+      return accumulator;
+    }
+
+    /**
+     * Creates an array composed of the own enumerable property values of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @category Objects
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns an array of property values.
+     * @example
+     *
+     * _.values({ 'one': 1, 'two': 2, 'three': 3 });
+     * // => [1, 2, 3] (property order is not guaranteed across environments)
+     */
+    function values(object) {
+      var index = -1,
+          props = keys(object),
+          length = props.length,
+          result = Array(length);
+
+      while (++index < length) {
+        result[index] = object[props[index]];
+      }
+      return result;
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates an array of elements from the specified indexes, or keys, of the
+     * `collection`. Indexes may be specified as individual arguments or as arrays
+     * of indexes.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
+     *   to retrieve, specified as individual indexes or arrays of indexes.
+     * @returns {Array} Returns a new array of elements corresponding to the
+     *  provided indexes.
+     * @example
+     *
+     * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
+     * // => ['a', 'c', 'e']
+     *
+     * _.at(['fred', 'barney', 'pebbles'], 0, 2);
+     * // => ['fred', 'pebbles']
+     */
+    function at(collection) {
+      var args = arguments,
+          index = -1,
+          props = baseFlatten(args, true, false, 1),
+          length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
+          result = Array(length);
+
+      while(++index < length) {
+        result[index] = collection[props[index]];
+      }
+      return result;
+    }
+
+    /**
+     * Checks if a given value is present in a collection using strict equality
+     * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
+     * offset from the end of the collection.
+     *
+     * @static
+     * @memberOf _
+     * @alias include
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {*} target The value to check for.
+     * @param {number} [fromIndex=0] The index to search from.
+     * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
+     * @example
+     *
+     * _.contains([1, 2, 3], 1);
+     * // => true
+     *
+     * _.contains([1, 2, 3], 1, 2);
+     * // => false
+     *
+     * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
+     * // => true
+     *
+     * _.contains('pebbles', 'eb');
+     * // => true
+     */
+    function contains(collection, target, fromIndex) {
+      var index = -1,
+          indexOf = getIndexOf(),
+          length = collection ? collection.length : 0,
+          result = false;
+
+      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
+      if (isArray(collection)) {
+        result = indexOf(collection, target, fromIndex) > -1;
+      } else if (typeof length == 'number') {
+        result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
+      } else {
+        forOwn(collection, function(value) {
+          if (++index >= fromIndex) {
+            return !(result = value === target);
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of `collection` through the callback. The corresponding value
+     * of each key is the number of times the key was returned by the callback.
+     * The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
+     * // => { '4': 1, '6': 2 }
+     *
+     * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
+     * // => { '4': 1, '6': 2 }
+     *
+     * _.countBy(['one', 'two', 'three'], 'length');
+     * // => { '3': 2, '5': 1 }
+     */
+    var countBy = createAggregator(function(result, value, key) {
+      (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
+    });
+
+    /**
+     * Checks if the given callback returns truey value for **all** elements of
+     * a collection. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias all
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {boolean} Returns `true` if all elements passed the callback check,
+     *  else `false`.
+     * @example
+     *
+     * _.every([true, 1, null, 'yes']);
+     * // => false
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.every(characters, 'age');
+     * // => true
+     *
+     * // using "_.where" callback shorthand
+     * _.every(characters, { 'age': 36 });
+     * // => false
+     */
+    function every(collection, callback, thisArg) {
+      var result = true;
+      callback = lodash.createCallback(callback, thisArg, 3);
+
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      if (typeof length == 'number') {
+        while (++index < length) {
+          if (!(result = !!callback(collection[index], index, collection))) {
+            break;
+          }
+        }
+      } else {
+        forOwn(collection, function(value, index, collection) {
+          return (result = !!callback(value, index, collection));
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Iterates over elements of a collection, returning an array of all elements
+     * the callback returns truey for. The callback is bound to `thisArg` and
+     * invoked with three arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias select
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new array of elements that passed the callback check.
+     * @example
+     *
+     * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
+     * // => [2, 4, 6]
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.filter(characters, 'blocked');
+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
+     *
+     * // using "_.where" callback shorthand
+     * _.filter(characters, { 'age': 36 });
+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
+     */
+    function filter(collection, callback, thisArg) {
+      var result = [];
+      callback = lodash.createCallback(callback, thisArg, 3);
+
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      if (typeof length == 'number') {
+        while (++index < length) {
+          var value = collection[index];
+          if (callback(value, index, collection)) {
+            result.push(value);
+          }
+        }
+      } else {
+        forOwn(collection, function(value, index, collection) {
+          if (callback(value, index, collection)) {
+            result.push(value);
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Iterates over elements of a collection, returning the first element that
+     * the callback returns truey for. The callback is bound to `thisArg` and
+     * invoked with three arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias detect, findWhere
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the found element, else `undefined`.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
+     * ];
+     *
+     * _.find(characters, function(chr) {
+     *   return chr.age < 40;
+     * });
+     * // => { 'name': 'barney', 'age': 36, 'blocked': false }
+     *
+     * // using "_.where" callback shorthand
+     * _.find(characters, { 'age': 1 });
+     * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
+     *
+     * // using "_.pluck" callback shorthand
+     * _.find(characters, 'blocked');
+     * // => { 'name': 'fred', 'age': 40, 'blocked': true }
+     */
+    function find(collection, callback, thisArg) {
+      callback = lodash.createCallback(callback, thisArg, 3);
+
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      if (typeof length == 'number') {
+        while (++index < length) {
+          var value = collection[index];
+          if (callback(value, index, collection)) {
+            return value;
+          }
+        }
+      } else {
+        var result;
+        forOwn(collection, function(value, index, collection) {
+          if (callback(value, index, collection)) {
+            result = value;
+            return false;
+          }
+        });
+        return result;
+      }
+    }
+
+    /**
+     * This method is like `_.find` except that it iterates over elements
+     * of a `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the found element, else `undefined`.
+     * @example
+     *
+     * _.findLast([1, 2, 3, 4], function(num) {
+     *   return num % 2 == 1;
+     * });
+     * // => 3
+     */
+    function findLast(collection, callback, thisArg) {
+      var result;
+      callback = lodash.createCallback(callback, thisArg, 3);
+      forEachRight(collection, function(value, index, collection) {
+        if (callback(value, index, collection)) {
+          result = value;
+          return false;
+        }
+      });
+      return result;
+    }
+
+    /**
+     * Iterates over elements of a collection, executing the callback for each
+     * element. The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, index|key, collection). Callbacks may exit iteration early by
+     * explicitly returning `false`.
+     *
+     * Note: As with other "Collections" methods, objects with a `length` property
+     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
+     * may be used for object iteration.
+     *
+     * @static
+     * @memberOf _
+     * @alias each
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array|Object|string} Returns `collection`.
+     * @example
+     *
+     * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
+     * // => logs each number and returns '1,2,3'
+     *
+     * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
+     * // => logs each number and returns the object (property order is not guaranteed across environments)
+     */
+    function forEach(collection, callback, thisArg) {
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
+      if (typeof length == 'number') {
+        while (++index < length) {
+          if (callback(collection[index], index, collection) === false) {
+            break;
+          }
+        }
+      } else {
+        forOwn(collection, callback);
+      }
+      return collection;
+    }
+
+    /**
+     * This method is like `_.forEach` except that it iterates over elements
+     * of a `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @alias eachRight
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array|Object|string} Returns `collection`.
+     * @example
+     *
+     * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
+     * // => logs each number from right to left and returns '3,2,1'
+     */
+    function forEachRight(collection, callback, thisArg) {
+      var length = collection ? collection.length : 0;
+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
+      if (typeof length == 'number') {
+        while (length--) {
+          if (callback(collection[length], length, collection) === false) {
+            break;
+          }
+        }
+      } else {
+        var props = keys(collection);
+        length = props.length;
+        forOwn(collection, function(value, key, collection) {
+          key = props ? props[--length] : --length;
+          return callback(collection[key], key, collection);
+        });
+      }
+      return collection;
+    }
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of a collection through the callback. The corresponding value
+     * of each key is an array of the elements responsible for generating the key.
+     * The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
+     * // => { '4': [4.2], '6': [6.1, 6.4] }
+     *
+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
+     * // => { '4': [4.2], '6': [6.1, 6.4] }
+     *
+     * // using "_.pluck" callback shorthand
+     * _.groupBy(['one', 'two', 'three'], 'length');
+     * // => { '3': ['one', 'two'], '5': ['three'] }
+     */
+    var groupBy = createAggregator(function(result, value, key) {
+      (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
+    });
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of the collection through the given callback. The corresponding
+     * value of each key is the last element responsible for generating the key.
+     * The callback is bound to `thisArg` and invoked with three arguments;
+     * (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * var keys = [
+     *   { 'dir': 'left', 'code': 97 },
+     *   { 'dir': 'right', 'code': 100 }
+     * ];
+     *
+     * _.indexBy(keys, 'dir');
+     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+     *
+     * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+     *
+     * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+     */
+    var indexBy = createAggregator(function(result, value, key) {
+      result[key] = value;
+    });
+
+    /**
+     * Invokes the method named by `methodName` on each element in the `collection`
+     * returning an array of the results of each invoked method. Additional arguments
+     * will be provided to each invoked method. If `methodName` is a function it
+     * will be invoked for, and `this` bound to, each element in the `collection`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|string} methodName The name of the method to invoke or
+     *  the function invoked per iteration.
+     * @param {...*} [arg] Arguments to invoke the method with.
+     * @returns {Array} Returns a new array of the results of each invoked method.
+     * @example
+     *
+     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
+     * // => [[1, 5, 7], [1, 2, 3]]
+     *
+     * _.invoke([123, 456], String.prototype.split, '');
+     * // => [['1', '2', '3'], ['4', '5', '6']]
+     */
+    function invoke(collection, methodName) {
+      var args = slice(arguments, 2),
+          index = -1,
+          isFunc = typeof methodName == 'function',
+          length = collection ? collection.length : 0,
+          result = Array(typeof length == 'number' ? length : 0);
+
+      forEach(collection, function(value) {
+        result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
+      });
+      return result;
+    }
+
+    /**
+     * Creates an array of values by running each element in the collection
+     * through the callback. The callback is bound to `thisArg` and invoked with
+     * three arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias collect
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new array of the results of each `callback` execution.
+     * @example
+     *
+     * _.map([1, 2, 3], function(num) { return num * 3; });
+     * // => [3, 6, 9]
+     *
+     * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
+     * // => [3, 6, 9] (property order is not guaranteed across environments)
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.map(characters, 'name');
+     * // => ['barney', 'fred']
+     */
+    function map(collection, callback, thisArg) {
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      callback = lodash.createCallback(callback, thisArg, 3);
+      if (typeof length == 'number') {
+        var result = Array(length);
+        while (++index < length) {
+          result[index] = callback(collection[index], index, collection);
+        }
+      } else {
+        result = [];
+        forOwn(collection, function(value, key, collection) {
+          result[++index] = callback(value, key, collection);
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Retrieves the maximum value of a collection. If the collection is empty or
+     * falsey `-Infinity` is returned. If a callback is provided it will be executed
+     * for each value in the collection to generate the criterion by which the value
+     * is ranked. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, index, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the maximum value.
+     * @example
+     *
+     * _.max([4, 2, 8, 6]);
+     * // => 8
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * _.max(characters, function(chr) { return chr.age; });
+     * // => { 'name': 'fred', 'age': 40 };
+     *
+     * // using "_.pluck" callback shorthand
+     * _.max(characters, 'age');
+     * // => { 'name': 'fred', 'age': 40 };
+     */
+    function max(collection, callback, thisArg) {
+      var computed = -Infinity,
+          result = computed;
+
+      // allows working with functions like `_.map` without using
+      // their `index` argument as a callback
+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
+        callback = null;
+      }
+      if (callback == null && isArray(collection)) {
+        var index = -1,
+            length = collection.length;
+
+        while (++index < length) {
+          var value = collection[index];
+          if (value > result) {
+            result = value;
+          }
+        }
+      } else {
+        callback = (callback == null && isString(collection))
+          ? charAtCallback
+          : lodash.createCallback(callback, thisArg, 3);
+
+        forEach(collection, function(value, index, collection) {
+          var current = callback(value, index, collection);
+          if (current > computed) {
+            computed = current;
+            result = value;
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Retrieves the minimum value of a collection. If the collection is empty or
+     * falsey `Infinity` is returned. If a callback is provided it will be executed
+     * for each value in the collection to generate the criterion by which the value
+     * is ranked. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, index, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the minimum value.
+     * @example
+     *
+     * _.min([4, 2, 8, 6]);
+     * // => 2
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * _.min(characters, function(chr) { return chr.age; });
+     * // => { 'name': 'barney', 'age': 36 };
+     *
+     * // using "_.pluck" callback shorthand
+     * _.min(characters, 'age');
+     * // => { 'name': 'barney', 'age': 36 };
+     */
+    function min(collection, callback, thisArg) {
+      var computed = Infinity,
+          result = computed;
+
+      // allows working with functions like `_.map` without using
+      // their `index` argument as a callback
+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
+        callback = null;
+      }
+      if (callback == null && isArray(collection)) {
+        var index = -1,
+            length = collection.length;
+
+        while (++index < length) {
+          var value = collection[index];
+          if (value < result) {
+            result = value;
+          }
+        }
+      } else {
+        callback = (callback == null && isString(collection))
+          ? charAtCallback
+          : lodash.createCallback(callback, thisArg, 3);
+
+        forEach(collection, function(value, index, collection) {
+          var current = callback(value, index, collection);
+          if (current < computed) {
+            computed = current;
+            result = value;
+          }
+        });
+      }
+      return result;
+    }
+
+    /**
+     * Retrieves the value of a specified property from all elements in the collection.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {string} property The name of the property to pluck.
+     * @returns {Array} Returns a new array of property values.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * _.pluck(characters, 'name');
+     * // => ['barney', 'fred']
+     */
+    var pluck = map;
+
+    /**
+     * Reduces a collection to a value which is the accumulated result of running
+     * each element in the collection through the callback, where each successive
+     * callback execution consumes the return value of the previous execution. If
+     * `accumulator` is not provided the first element of the collection will be
+     * used as the initial `accumulator` value. The callback is bound to `thisArg`
+     * and invoked with four arguments; (accumulator, value, index|key, collection).
+     *
+     * @static
+     * @memberOf _
+     * @alias foldl, inject
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [accumulator] Initial value of the accumulator.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the accumulated value.
+     * @example
+     *
+     * var sum = _.reduce([1, 2, 3], function(sum, num) {
+     *   return sum + num;
+     * });
+     * // => 6
+     *
+     * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
+     *   result[key] = num * 3;
+     *   return result;
+     * }, {});
+     * // => { 'a': 3, 'b': 6, 'c': 9 }
+     */
+    function reduce(collection, callback, accumulator, thisArg) {
+      if (!collection) return accumulator;
+      var noaccum = arguments.length < 3;
+      callback = lodash.createCallback(callback, thisArg, 4);
+
+      var index = -1,
+          length = collection.length;
+
+      if (typeof length == 'number') {
+        if (noaccum) {
+          accumulator = collection[++index];
+        }
+        while (++index < length) {
+          accumulator = callback(accumulator, collection[index], index, collection);
+        }
+      } else {
+        forOwn(collection, function(value, index, collection) {
+          accumulator = noaccum
+            ? (noaccum = false, value)
+            : callback(accumulator, value, index, collection)
+        });
+      }
+      return accumulator;
+    }
+
+    /**
+     * This method is like `_.reduce` except that it iterates over elements
+     * of a `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @alias foldr
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function} [callback=identity] The function called per iteration.
+     * @param {*} [accumulator] Initial value of the accumulator.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the accumulated value.
+     * @example
+     *
+     * var list = [[0, 1], [2, 3], [4, 5]];
+     * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
+     * // => [4, 5, 2, 3, 0, 1]
+     */
+    function reduceRight(collection, callback, accumulator, thisArg) {
+      var noaccum = arguments.length < 3;
+      callback = lodash.createCallback(callback, thisArg, 4);
+      forEachRight(collection, function(value, index, collection) {
+        accumulator = noaccum
+          ? (noaccum = false, value)
+          : callback(accumulator, value, index, collection);
+      });
+      return accumulator;
+    }
+
+    /**
+     * The opposite of `_.filter` this method returns the elements of a
+     * collection that the callback does **not** return truey for.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new array of elements that failed the callback check.
+     * @example
+     *
+     * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
+     * // => [1, 3, 5]
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.reject(characters, 'blocked');
+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
+     *
+     * // using "_.where" callback shorthand
+     * _.reject(characters, { 'age': 36 });
+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
+     */
+    function reject(collection, callback, thisArg) {
+      callback = lodash.createCallback(callback, thisArg, 3);
+      return filter(collection, function(value, index, collection) {
+        return !callback(value, index, collection);
+      });
+    }
+
+    /**
+     * Retrieves a random element or `n` random elements from a collection.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to sample.
+     * @param {number} [n] The number of elements to sample.
+     * @param- {Object} [guard] Allows working with functions like `_.map`
+     *  without using their `index` arguments as `n`.
+     * @returns {Array} Returns the random sample(s) of `collection`.
+     * @example
+     *
+     * _.sample([1, 2, 3, 4]);
+     * // => 2
+     *
+     * _.sample([1, 2, 3, 4], 2);
+     * // => [3, 1]
+     */
+    function sample(collection, n, guard) {
+      if (collection && typeof collection.length != 'number') {
+        collection = values(collection);
+      }
+      if (n == null || guard) {
+        return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
+      }
+      var result = shuffle(collection);
+      result.length = nativeMin(nativeMax(0, n), result.length);
+      return result;
+    }
+
+    /**
+     * Creates an array of shuffled values, using a version of the Fisher-Yates
+     * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to shuffle.
+     * @returns {Array} Returns a new shuffled collection.
+     * @example
+     *
+     * _.shuffle([1, 2, 3, 4, 5, 6]);
+     * // => [4, 1, 6, 3, 5, 2]
+     */
+    function shuffle(collection) {
+      var index = -1,
+          length = collection ? collection.length : 0,
+          result = Array(typeof length == 'number' ? length : 0);
+
+      forEach(collection, function(value) {
+        var rand = baseRandom(0, ++index);
+        result[index] = result[rand];
+        result[rand] = value;
+      });
+      return result;
+    }
+
+    /**
+     * Gets the size of the `collection` by returning `collection.length` for arrays
+     * and array-like objects or the number of own enumerable properties for objects.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to inspect.
+     * @returns {number} Returns `collection.length` or number of own enumerable properties.
+     * @example
+     *
+     * _.size([1, 2]);
+     * // => 2
+     *
+     * _.size({ 'one': 1, 'two': 2, 'three': 3 });
+     * // => 3
+     *
+     * _.size('pebbles');
+     * // => 7
+     */
+    function size(collection) {
+      var length = collection ? collection.length : 0;
+      return typeof length == 'number' ? length : keys(collection).length;
+    }
+
+    /**
+     * Checks if the callback returns a truey value for **any** element of a
+     * collection. The function returns as soon as it finds a passing value and
+     * does not iterate over the entire collection. The callback is bound to
+     * `thisArg` and invoked with three arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias any
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {boolean} Returns `true` if any element passed the callback check,
+     *  else `false`.
+     * @example
+     *
+     * _.some([null, 0, 'yes', false], Boolean);
+     * // => true
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.some(characters, 'blocked');
+     * // => true
+     *
+     * // using "_.where" callback shorthand
+     * _.some(characters, { 'age': 1 });
+     * // => false
+     */
+    function some(collection, callback, thisArg) {
+      var result;
+      callback = lodash.createCallback(callback, thisArg, 3);
+
+      var index = -1,
+          length = collection ? collection.length : 0;
+
+      if (typeof length == 'number') {
+        while (++index < length) {
+          if ((result = callback(collection[index], index, collection))) {
+            break;
+          }
+        }
+      } else {
+        forOwn(collection, function(value, index, collection) {
+          return !(result = callback(value, index, collection));
+        });
+      }
+      return !!result;
+    }
+
+    /**
+     * Creates an array of elements, sorted in ascending order by the results of
+     * running each element in a collection through the callback. This method
+     * performs a stable sort, that is, it will preserve the original sort order
+     * of equal elements. The callback is bound to `thisArg` and invoked with
+     * three arguments; (value, index|key, collection).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an array of property names is provided for `callback` the collection
+     * will be sorted by each property value.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Array|Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new array of sorted elements.
+     * @example
+     *
+     * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
+     * // => [3, 1, 2]
+     *
+     * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
+     * // => [3, 1, 2]
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'age': 36 },
+     *   { 'name': 'fred',    'age': 40 },
+     *   { 'name': 'barney',  'age': 26 },
+     *   { 'name': 'fred',    'age': 30 }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.map(_.sortBy(characters, 'age'), _.values);
+     * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
+     *
+     * // sorting by multiple properties
+     * _.map(_.sortBy(characters, ['name', 'age']), _.values);
+     * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
+     */
+    function sortBy(collection, callback, thisArg) {
+      var index = -1,
+          isArr = isArray(callback),
+          length = collection ? collection.length : 0,
+          result = Array(typeof length == 'number' ? length : 0);
+
+      if (!isArr) {
+        callback = lodash.createCallback(callback, thisArg, 3);
+      }
+      forEach(collection, function(value, key, collection) {
+        var object = result[++index] = getObject();
+        if (isArr) {
+          object.criteria = map(callback, function(key) { return value[key]; });
+        } else {
+          (object.criteria = getArray())[0] = callback(value, key, collection);
+        }
+        object.index = index;
+        object.value = value;
+      });
+
+      length = result.length;
+      result.sort(compareAscending);
+      while (length--) {
+        var object = result[length];
+        result[length] = object.value;
+        if (!isArr) {
+          releaseArray(object.criteria);
+        }
+        releaseObject(object);
+      }
+      return result;
+    }
+
+    /**
+     * Converts the `collection` to an array.
+     *
+     * @static
+     * @memberOf _
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to convert.
+     * @returns {Array} Returns the new converted array.
+     * @example
+     *
+     * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
+     * // => [2, 3, 4]
+     */
+    function toArray(collection) {
+      if (collection && typeof collection.length == 'number') {
+        return slice(collection);
+      }
+      return values(collection);
+    }
+
+    /**
+     * Performs a deep comparison of each element in a `collection` to the given
+     * `properties` object, returning an array of all elements that have equivalent
+     * property values.
+     *
+     * @static
+     * @memberOf _
+     * @type Function
+     * @category Collections
+     * @param {Array|Object|string} collection The collection to iterate over.
+     * @param {Object} props The object of property values to filter by.
+     * @returns {Array} Returns a new array of elements that have the given properties.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
+     * ];
+     *
+     * _.where(characters, { 'age': 36 });
+     * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
+     *
+     * _.where(characters, { 'pets': ['dino'] });
+     * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
+     */
+    var where = filter;
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates an array with all falsey values removed. The values `false`, `null`,
+     * `0`, `""`, `undefined`, and `NaN` are all falsey.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to compact.
+     * @returns {Array} Returns a new array of filtered values.
+     * @example
+     *
+     * _.compact([0, 1, false, 2, '', 3]);
+     * // => [1, 2, 3]
+     */
+    function compact(array) {
+      var index = -1,
+          length = array ? array.length : 0,
+          result = [];
+
+      while (++index < length) {
+        var value = array[index];
+        if (value) {
+          result.push(value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Creates an array excluding all values of the provided arrays using strict
+     * equality for comparisons, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to process.
+     * @param {...Array} [values] The arrays of values to exclude.
+     * @returns {Array} Returns a new array of filtered values.
+     * @example
+     *
+     * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
+     * // => [1, 3, 4]
+     */
+    function difference(array) {
+      return baseDifference(array, baseFlatten(arguments, true, true, 1));
+    }
+
+    /**
+     * This method is like `_.find` except that it returns the index of the first
+     * element that passes the callback check, instead of the element itself.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to search.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {number} Returns the index of the found element, else `-1`.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
+     * ];
+     *
+     * _.findIndex(characters, function(chr) {
+     *   return chr.age < 20;
+     * });
+     * // => 2
+     *
+     * // using "_.where" callback shorthand
+     * _.findIndex(characters, { 'age': 36 });
+     * // => 0
+     *
+     * // using "_.pluck" callback shorthand
+     * _.findIndex(characters, 'blocked');
+     * // => 1
+     */
+    function findIndex(array, callback, thisArg) {
+      var index = -1,
+          length = array ? array.length : 0;
+
+      callback = lodash.createCallback(callback, thisArg, 3);
+      while (++index < length) {
+        if (callback(array[index], index, array)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * This method is like `_.findIndex` except that it iterates over elements
+     * of a `collection` from right to left.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to search.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {number} Returns the index of the found element, else `-1`.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'age': 36, 'blocked': true },
+     *   { 'name': 'fred',    'age': 40, 'blocked': false },
+     *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
+     * ];
+     *
+     * _.findLastIndex(characters, function(chr) {
+     *   return chr.age > 30;
+     * });
+     * // => 1
+     *
+     * // using "_.where" callback shorthand
+     * _.findLastIndex(characters, { 'age': 36 });
+     * // => 0
+     *
+     * // using "_.pluck" callback shorthand
+     * _.findLastIndex(characters, 'blocked');
+     * // => 2
+     */
+    function findLastIndex(array, callback, thisArg) {
+      var length = array ? array.length : 0;
+      callback = lodash.createCallback(callback, thisArg, 3);
+      while (length--) {
+        if (callback(array[length], length, array)) {
+          return length;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * Gets the first element or first `n` elements of an array. If a callback
+     * is provided elements at the beginning of the array are returned as long
+     * as the callback returns truey. The callback is bound to `thisArg` and
+     * invoked with three arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias head, take
+     * @category Arrays
+     * @param {Array} array The array to query.
+     * @param {Function|Object|number|string} [callback] The function called
+     *  per element or the number of elements to return. If a property name or
+     *  object is provided it will be used to create a "_.pluck" or "_.where"
+     *  style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the first element(s) of `array`.
+     * @example
+     *
+     * _.first([1, 2, 3]);
+     * // => 1
+     *
+     * _.first([1, 2, 3], 2);
+     * // => [1, 2]
+     *
+     * _.first([1, 2, 3], function(num) {
+     *   return num < 3;
+     * });
+     * // => [1, 2]
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
+     *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.first(characters, 'blocked');
+     * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
+     *
+     * // using "_.where" callback shorthand
+     * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
+     * // => ['barney', 'fred']
+     */
+    function first(array, callback, thisArg) {
+      var n = 0,
+          length = array ? array.length : 0;
+
+      if (typeof callback != 'number' && callback != null) {
+        var index = -1;
+        callback = lodash.createCallback(callback, thisArg, 3);
+        while (++index < length && callback(array[index], index, array)) {
+          n++;
+        }
+      } else {
+        n = callback;
+        if (n == null || thisArg) {
+          return array ? array[0] : undefined;
+        }
+      }
+      return slice(array, 0, nativeMin(nativeMax(0, n), length));
+    }
+
+    /**
+     * Flattens a nested array (the nesting can be to any depth). If `isShallow`
+     * is truey, the array will only be flattened a single level. If a callback
+     * is provided each element of the array is passed through the callback before
+     * flattening. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to flatten.
+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new flattened array.
+     * @example
+     *
+     * _.flatten([1, [2], [3, [[4]]]]);
+     * // => [1, 2, 3, 4];
+     *
+     * _.flatten([1, [2], [3, [[4]]]], true);
+     * // => [1, 2, 3, [[4]]];
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.flatten(characters, 'pets');
+     * // => ['hoppy', 'baby puss', 'dino']
+     */
+    function flatten(array, isShallow, callback, thisArg) {
+      // juggle arguments
+      if (typeof isShallow != 'boolean' && isShallow != null) {
+        thisArg = callback;
+        callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
+        isShallow = false;
+      }
+      if (callback != null) {
+        array = map(array, callback, thisArg);
+      }
+      return baseFlatten(array, isShallow);
+    }
+
+    /**
+     * Gets the index at which the first occurrence of `value` is found using
+     * strict equality for comparisons, i.e. `===`. If the array is already sorted
+     * providing `true` for `fromIndex` will run a faster binary search.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to search.
+     * @param {*} value The value to search for.
+     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
+     *  to perform a binary search on a sorted array.
+     * @returns {number} Returns the index of the matched value or `-1`.
+     * @example
+     *
+     * _.indexOf([1, 2, 3, 1, 2, 3], 2);
+     * // => 1
+     *
+     * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
+     * // => 4
+     *
+     * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
+     * // => 2
+     */
+    function indexOf(array, value, fromIndex) {
+      if (typeof fromIndex == 'number') {
+        var length = array ? array.length : 0;
+        fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
+      } else if (fromIndex) {
+        var index = sortedIndex(array, value);
+        return array[index] === value ? index : -1;
+      }
+      return baseIndexOf(array, value, fromIndex);
+    }
+
+    /**
+     * Gets all but the last element or last `n` elements of an array. If a
+     * callback is provided elements at the end of the array are excluded from
+     * the result as long as the callback returns truey. The callback is bound
+     * to `thisArg` and invoked with three arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to query.
+     * @param {Function|Object|number|string} [callback=1] The function called
+     *  per element or the number of elements to exclude. If a property name or
+     *  object is provided it will be used to create a "_.pluck" or "_.where"
+     *  style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a slice of `array`.
+     * @example
+     *
+     * _.initial([1, 2, 3]);
+     * // => [1, 2]
+     *
+     * _.initial([1, 2, 3], 2);
+     * // => [1]
+     *
+     * _.initial([1, 2, 3], function(num) {
+     *   return num > 1;
+     * });
+     * // => [1]
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.initial(characters, 'blocked');
+     * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
+     *
+     * // using "_.where" callback shorthand
+     * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
+     * // => ['barney', 'fred']
+     */
+    function initial(array, callback, thisArg) {
+      var n = 0,
+          length = array ? array.length : 0;
+
+      if (typeof callback != 'number' && callback != null) {
+        var index = length;
+        callback = lodash.createCallback(callback, thisArg, 3);
+        while (index-- && callback(array[index], index, array)) {
+          n++;
+        }
+      } else {
+        n = (callback == null || thisArg) ? 1 : callback || n;
+      }
+      return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
+    }
+
+    /**
+     * Creates an array of unique values present in all provided arrays using
+     * strict equality for comparisons, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {...Array} [array] The arrays to inspect.
+     * @returns {Array} Returns an array of shared values.
+     * @example
+     *
+     * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
+     * // => [1, 2]
+     */
+    function intersection() {
+      var args = [],
+          argsIndex = -1,
+          argsLength = arguments.length,
+          caches = getArray(),
+          indexOf = getIndexOf(),
+          trustIndexOf = indexOf === baseIndexOf,
+          seen = getArray();
+
+      while (++argsIndex < argsLength) {
+        var value = arguments[argsIndex];
+        if (isArray(value) || isArguments(value)) {
+          args.push(value);
+          caches.push(trustIndexOf && value.length >= largeArraySize &&
+            createCache(argsIndex ? args[argsIndex] : seen));
+        }
+      }
+      var array = args[0],
+          index = -1,
+          length = array ? array.length : 0,
+          result = [];
+
+      outer:
+      while (++index < length) {
+        var cache = caches[0];
+        value = array[index];
+
+        if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
+          argsIndex = argsLength;
+          (cache || seen).push(value);
+          while (--argsIndex) {
+            cache = caches[argsIndex];
+            if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
+              continue outer;
+            }
+          }
+          result.push(value);
+        }
+      }
+      while (argsLength--) {
+        cache = caches[argsLength];
+        if (cache) {
+          releaseObject(cache);
+        }
+      }
+      releaseArray(caches);
+      releaseArray(seen);
+      return result;
+    }
+
+    /**
+     * Gets the last element or last `n` elements of an array. If a callback is
+     * provided elements at the end of the array are returned as long as the
+     * callback returns truey. The callback is bound to `thisArg` and invoked
+     * with three arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to query.
+     * @param {Function|Object|number|string} [callback] The function called
+     *  per element or the number of elements to return. If a property name or
+     *  object is provided it will be used to create a "_.pluck" or "_.where"
+     *  style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {*} Returns the last element(s) of `array`.
+     * @example
+     *
+     * _.last([1, 2, 3]);
+     * // => 3
+     *
+     * _.last([1, 2, 3], 2);
+     * // => [2, 3]
+     *
+     * _.last([1, 2, 3], function(num) {
+     *   return num > 1;
+     * });
+     * // => [2, 3]
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.pluck(_.last(characters, 'blocked'), 'name');
+     * // => ['fred', 'pebbles']
+     *
+     * // using "_.where" callback shorthand
+     * _.last(characters, { 'employer': 'na' });
+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
+     */
+    function last(array, callback, thisArg) {
+      var n = 0,
+          length = array ? array.length : 0;
+
+      if (typeof callback != 'number' && callback != null) {
+        var index = length;
+        callback = lodash.createCallback(callback, thisArg, 3);
+        while (index-- && callback(array[index], index, array)) {
+          n++;
+        }
+      } else {
+        n = callback;
+        if (n == null || thisArg) {
+          return array ? array[length - 1] : undefined;
+        }
+      }
+      return slice(array, nativeMax(0, length - n));
+    }
+
+    /**
+     * Gets the index at which the last occurrence of `value` is found using strict
+     * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
+     * as the offset from the end of the collection.
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to search.
+     * @param {*} value The value to search for.
+     * @param {number} [fromIndex=array.length-1] The index to search from.
+     * @returns {number} Returns the index of the matched value or `-1`.
+     * @example
+     *
+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
+     * // => 4
+     *
+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
+     * // => 1
+     */
+    function lastIndexOf(array, value, fromIndex) {
+      var index = array ? array.length : 0;
+      if (typeof fromIndex == 'number') {
+        index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
+      }
+      while (index--) {
+        if (array[index] === value) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * Removes all provided values from the given array using strict equality for
+     * comparisons, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to modify.
+     * @param {...*} [value] The values to remove.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = [1, 2, 3, 1, 2, 3];
+     * _.pull(array, 2, 3);
+     * console.log(array);
+     * // => [1, 1]
+     */
+    function pull(array) {
+      var args = arguments,
+          argsIndex = 0,
+          argsLength = args.length,
+          length = array ? array.length : 0;
+
+      while (++argsIndex < argsLength) {
+        var index = -1,
+            value = args[argsIndex];
+        while (++index < length) {
+          if (array[index] === value) {
+            splice.call(array, index--, 1);
+            length--;
+          }
+        }
+      }
+      return array;
+    }
+
+    /**
+     * Creates an array of numbers (positive and/or negative) progressing from
+     * `start` up to but not including `end`. If `start` is less than `stop` a
+     * zero-length range is created unless a negative `step` is specified.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {number} [start=0] The start of the range.
+     * @param {number} end The end of the range.
+     * @param {number} [step=1] The value to increment or decrement by.
+     * @returns {Array} Returns a new range array.
+     * @example
+     *
+     * _.range(4);
+     * // => [0, 1, 2, 3]
+     *
+     * _.range(1, 5);
+     * // => [1, 2, 3, 4]
+     *
+     * _.range(0, 20, 5);
+     * // => [0, 5, 10, 15]
+     *
+     * _.range(0, -4, -1);
+     * // => [0, -1, -2, -3]
+     *
+     * _.range(1, 4, 0);
+     * // => [1, 1, 1]
+     *
+     * _.range(0);
+     * // => []
+     */
+    function range(start, end, step) {
+      start = +start || 0;
+      step = typeof step == 'number' ? step : (+step || 1);
+
+      if (end == null) {
+        end = start;
+        start = 0;
+      }
+      // use `Array(length)` so engines like Chakra and V8 avoid slower modes
+      // http://youtu.be/XAqIpGU8ZZk#t=17m25s
+      var index = -1,
+          length = nativeMax(0, ceil((end - start) / (step || 1))),
+          result = Array(length);
+
+      while (++index < length) {
+        result[index] = start;
+        start += step;
+      }
+      return result;
+    }
+
+    /**
+     * Removes all elements from an array that the callback returns truey for
+     * and returns an array of removed elements. The callback is bound to `thisArg`
+     * and invoked with three arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to modify.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a new array of removed elements.
+     * @example
+     *
+     * var array = [1, 2, 3, 4, 5, 6];
+     * var evens = _.remove(array, function(num) { return num % 2 == 0; });
+     *
+     * console.log(array);
+     * // => [1, 3, 5]
+     *
+     * console.log(evens);
+     * // => [2, 4, 6]
+     */
+    function remove(array, callback, thisArg) {
+      var index = -1,
+          length = array ? array.length : 0,
+          result = [];
+
+      callback = lodash.createCallback(callback, thisArg, 3);
+      while (++index < length) {
+        var value = array[index];
+        if (callback(value, index, array)) {
+          result.push(value);
+          splice.call(array, index--, 1);
+          length--;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The opposite of `_.initial` this method gets all but the first element or
+     * first `n` elements of an array. If a callback function is provided elements
+     * at the beginning of the array are excluded from the result as long as the
+     * callback returns truey. The callback is bound to `thisArg` and invoked
+     * with three arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias drop, tail
+     * @category Arrays
+     * @param {Array} array The array to query.
+     * @param {Function|Object|number|string} [callback=1] The function called
+     *  per element or the number of elements to exclude. If a property name or
+     *  object is provided it will be used to create a "_.pluck" or "_.where"
+     *  style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a slice of `array`.
+     * @example
+     *
+     * _.rest([1, 2, 3]);
+     * // => [2, 3]
+     *
+     * _.rest([1, 2, 3], 2);
+     * // => [3]
+     *
+     * _.rest([1, 2, 3], function(num) {
+     *   return num < 3;
+     * });
+     * // => [3]
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
+     *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
+     *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
+     * ];
+     *
+     * // using "_.pluck" callback shorthand
+     * _.pluck(_.rest(characters, 'blocked'), 'name');
+     * // => ['fred', 'pebbles']
+     *
+     * // using "_.where" callback shorthand
+     * _.rest(characters, { 'employer': 'slate' });
+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
+     */
+    function rest(array, callback, thisArg) {
+      if (typeof callback != 'number' && callback != null) {
+        var n = 0,
+            index = -1,
+            length = array ? array.length : 0;
+
+        callback = lodash.createCallback(callback, thisArg, 3);
+        while (++index < length && callback(array[index], index, array)) {
+          n++;
+        }
+      } else {
+        n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
+      }
+      return slice(array, n);
+    }
+
+    /**
+     * Uses a binary search to determine the smallest index at which a value
+     * should be inserted into a given sorted array in order to maintain the sort
+     * order of the array. If a callback is provided it will be executed for
+     * `value` and each element of `array` to compute their sort ranking. The
+     * callback is bound to `thisArg` and invoked with one argument; (value).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to inspect.
+     * @param {*} value The value to evaluate.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * _.sortedIndex([20, 30, 50], 40);
+     * // => 2
+     *
+     * // using "_.pluck" callback shorthand
+     * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
+     * // => 2
+     *
+     * var dict = {
+     *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
+     * };
+     *
+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
+     *   return dict.wordToNumber[word];
+     * });
+     * // => 2
+     *
+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
+     *   return this.wordToNumber[word];
+     * }, dict);
+     * // => 2
+     */
+    function sortedIndex(array, value, callback, thisArg) {
+      var low = 0,
+          high = array ? array.length : low;
+
+      // explicitly reference `identity` for better inlining in Firefox
+      callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
+      value = callback(value);
+
+      while (low < high) {
+        var mid = (low + high) >>> 1;
+        (callback(array[mid]) < value)
+          ? low = mid + 1
+          : high = mid;
+      }
+      return low;
+    }
+
+    /**
+     * Creates an array of unique values, in order, of the provided arrays using
+     * strict equality for comparisons, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {...Array} [array] The arrays to inspect.
+     * @returns {Array} Returns an array of combined values.
+     * @example
+     *
+     * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
+     * // => [1, 2, 3, 5, 4]
+     */
+    function union() {
+      return baseUniq(baseFlatten(arguments, true, true));
+    }
+
+    /**
+     * Creates a duplicate-value-free version of an array using strict equality
+     * for comparisons, i.e. `===`. If the array is sorted, providing
+     * `true` for `isSorted` will use a faster algorithm. If a callback is provided
+     * each element of `array` is passed through the callback before uniqueness
+     * is computed. The callback is bound to `thisArg` and invoked with three
+     * arguments; (value, index, array).
+     *
+     * If a property name is provided for `callback` the created "_.pluck" style
+     * callback will return the property value of the given element.
+     *
+     * If an object is provided for `callback` the created "_.where" style callback
+     * will return `true` for elements that have the properties of the given object,
+     * else `false`.
+     *
+     * @static
+     * @memberOf _
+     * @alias unique
+     * @category Arrays
+     * @param {Array} array The array to process.
+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
+     * @param {Function|Object|string} [callback=identity] The function called
+     *  per iteration. If a property name or object is provided it will be used
+     *  to create a "_.pluck" or "_.where" style callback, respectively.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns a duplicate-value-free array.
+     * @example
+     *
+     * _.uniq([1, 2, 1, 3, 1]);
+     * // => [1, 2, 3]
+     *
+     * _.uniq([1, 1, 2, 2, 3], true);
+     * // => [1, 2, 3]
+     *
+     * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
+     * // => ['A', 'b', 'C']
+     *
+     * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
+     * // => [1, 2.5, 3]
+     *
+     * // using "_.pluck" callback shorthand
+     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }, { 'x': 2 }]
+     */
+    function uniq(array, isSorted, callback, thisArg) {
+      // juggle arguments
+      if (typeof isSorted != 'boolean' && isSorted != null) {
+        thisArg = callback;
+        callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
+        isSorted = false;
+      }
+      if (callback != null) {
+        callback = lodash.createCallback(callback, thisArg, 3);
+      }
+      return baseUniq(array, isSorted, callback);
+    }
+
+    /**
+     * Creates an array excluding all provided values using strict equality for
+     * comparisons, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {Array} array The array to filter.
+     * @param {...*} [value] The values to exclude.
+     * @returns {Array} Returns a new array of filtered values.
+     * @example
+     *
+     * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
+     * // => [2, 3, 4]
+     */
+    function without(array) {
+      return baseDifference(array, slice(arguments, 1));
+    }
+
+    /**
+     * Creates an array that is the symmetric difference of the provided arrays.
+     * See http://en.wikipedia.org/wiki/Symmetric_difference.
+     *
+     * @static
+     * @memberOf _
+     * @category Arrays
+     * @param {...Array} [array] The arrays to inspect.
+     * @returns {Array} Returns an array of values.
+     * @example
+     *
+     * _.xor([1, 2, 3], [5, 2, 1, 4]);
+     * // => [3, 5, 4]
+     *
+     * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
+     * // => [1, 4, 5]
+     */
+    function xor() {
+      var index = -1,
+          length = arguments.length;
+
+      while (++index < length) {
+        var array = arguments[index];
+        if (isArray(array) || isArguments(array)) {
+          var result = result
+            ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
+            : array;
+        }
+      }
+      return result || [];
+    }
+
+    /**
+     * Creates an array of grouped elements, the first of which contains the first
+     * elements of the given arrays, the second of which contains the second
+     * elements of the given arrays, and so on.
+     *
+     * @static
+     * @memberOf _
+     * @alias unzip
+     * @category Arrays
+     * @param {...Array} [array] Arrays to process.
+     * @returns {Array} Returns a new array of grouped elements.
+     * @example
+     *
+     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
+     * // => [['fred', 30, true], ['barney', 40, false]]
+     */
+    function zip() {
+      var array = arguments.length > 1 ? arguments : arguments[0],
+          index = -1,
+          length = array ? max(pluck(array, 'length')) : 0,
+          result = Array(length < 0 ? 0 : length);
+
+      while (++index < length) {
+        result[index] = pluck(array, index);
+      }
+      return result;
+    }
+
+    /**
+     * Creates an object composed from arrays of `keys` and `values`. Provide
+     * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
+     * or two arrays, one of `keys` and one of corresponding `values`.
+     *
+     * @static
+     * @memberOf _
+     * @alias object
+     * @category Arrays
+     * @param {Array} keys The array of keys.
+     * @param {Array} [values=[]] The array of values.
+     * @returns {Object} Returns an object composed of the given keys and
+     *  corresponding values.
+     * @example
+     *
+     * _.zipObject(['fred', 'barney'], [30, 40]);
+     * // => { 'fred': 30, 'barney': 40 }
+     */
+    function zipObject(keys, values) {
+      var index = -1,
+          length = keys ? keys.length : 0,
+          result = {};
+
+      if (!values && length && !isArray(keys[0])) {
+        values = [];
+      }
+      while (++index < length) {
+        var key = keys[index];
+        if (values) {
+          result[key] = values[index];
+        } else if (key) {
+          result[key[0]] = key[1];
+        }
+      }
+      return result;
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates a function that executes `func`, with  the `this` binding and
+     * arguments of the created function, only after being called `n` times.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {number} n The number of times the function must be called before
+     *  `func` is executed.
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new restricted function.
+     * @example
+     *
+     * var saves = ['profile', 'settings'];
+     *
+     * var done = _.after(saves.length, function() {
+     *   console.log('Done saving!');
+     * });
+     *
+     * _.forEach(saves, function(type) {
+     *   asyncSave({ 'type': type, 'complete': done });
+     * });
+     * // => logs 'Done saving!', after all saves have completed
+     */
+    function after(n, func) {
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      return function() {
+        if (--n < 1) {
+          return func.apply(this, arguments);
+        }
+      };
+    }
+
+    /**
+     * Creates a function that, when called, invokes `func` with the `this`
+     * binding of `thisArg` and prepends any additional `bind` arguments to those
+     * provided to the bound function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to bind.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @param {...*} [arg] Arguments to be partially applied.
+     * @returns {Function} Returns the new bound function.
+     * @example
+     *
+     * var func = function(greeting) {
+     *   return greeting + ' ' + this.name;
+     * };
+     *
+     * func = _.bind(func, { 'name': 'fred' }, 'hi');
+     * func();
+     * // => 'hi fred'
+     */
+    function bind(func, thisArg) {
+      return arguments.length > 2
+        ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
+        : createWrapper(func, 1, null, null, thisArg);
+    }
+
+    /**
+     * Binds methods of an object to the object itself, overwriting the existing
+     * method. Method names may be specified as individual arguments or as arrays
+     * of method names. If no method names are provided all the function properties
+     * of `object` will be bound.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Object} object The object to bind and assign the bound methods to.
+     * @param {...string} [methodName] The object method names to
+     *  bind, specified as individual method names or arrays of method names.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var view = {
+     *   'label': 'docs',
+     *   'onClick': function() { console.log('clicked ' + this.label); }
+     * };
+     *
+     * _.bindAll(view);
+     * jQuery('#docs').on('click', view.onClick);
+     * // => logs 'clicked docs', when the button is clicked
+     */
+    function bindAll(object) {
+      var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
+          index = -1,
+          length = funcs.length;
+
+      while (++index < length) {
+        var key = funcs[index];
+        object[key] = createWrapper(object[key], 1, null, null, object);
+      }
+      return object;
+    }
+
+    /**
+     * Creates a function that, when called, invokes the method at `object[key]`
+     * and prepends any additional `bindKey` arguments to those provided to the bound
+     * function. This method differs from `_.bind` by allowing bound functions to
+     * reference methods that will be redefined or don't yet exist.
+     * See http://michaux.ca/articles/lazy-function-definition-pattern.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Object} object The object the method belongs to.
+     * @param {string} key The key of the method.
+     * @param {...*} [arg] Arguments to be partially applied.
+     * @returns {Function} Returns the new bound function.
+     * @example
+     *
+     * var object = {
+     *   'name': 'fred',
+     *   'greet': function(greeting) {
+     *     return greeting + ' ' + this.name;
+     *   }
+     * };
+     *
+     * var func = _.bindKey(object, 'greet', 'hi');
+     * func();
+     * // => 'hi fred'
+     *
+     * object.greet = function(greeting) {
+     *   return greeting + 'ya ' + this.name + '!';
+     * };
+     *
+     * func();
+     * // => 'hiya fred!'
+     */
+    function bindKey(object, key) {
+      return arguments.length > 2
+        ? createWrapper(key, 19, slice(arguments, 2), null, object)
+        : createWrapper(key, 3, null, null, object);
+    }
+
+    /**
+     * Creates a function that is the composition of the provided functions,
+     * where each function consumes the return value of the function that follows.
+     * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
+     * Each function is executed with the `this` binding of the composed function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {...Function} [func] Functions to compose.
+     * @returns {Function} Returns the new composed function.
+     * @example
+     *
+     * var realNameMap = {
+     *   'pebbles': 'penelope'
+     * };
+     *
+     * var format = function(name) {
+     *   name = realNameMap[name.toLowerCase()] || name;
+     *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
+     * };
+     *
+     * var greet = function(formatted) {
+     *   return 'Hiya ' + formatted + '!';
+     * };
+     *
+     * var welcome = _.compose(greet, format);
+     * welcome('pebbles');
+     * // => 'Hiya Penelope!'
+     */
+    function compose() {
+      var funcs = arguments,
+          length = funcs.length;
+
+      while (length--) {
+        if (!isFunction(funcs[length])) {
+          throw new TypeError;
+        }
+      }
+      return function() {
+        var args = arguments,
+            length = funcs.length;
+
+        while (length--) {
+          args = [funcs[length].apply(this, args)];
+        }
+        return args[0];
+      };
+    }
+
+    /**
+     * Creates a function which accepts one or more arguments of `func` that when
+     * invoked either executes `func` returning its result, if all `func` arguments
+     * have been provided, or returns a function that accepts one or more of the
+     * remaining `func` arguments, and so on. The arity of `func` can be specified
+     * if `func.length` is not sufficient.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to curry.
+     * @param {number} [arity=func.length] The arity of `func`.
+     * @returns {Function} Returns the new curried function.
+     * @example
+     *
+     * var curried = _.curry(function(a, b, c) {
+     *   console.log(a + b + c);
+     * });
+     *
+     * curried(1)(2)(3);
+     * // => 6
+     *
+     * curried(1, 2)(3);
+     * // => 6
+     *
+     * curried(1, 2, 3);
+     * // => 6
+     */
+    function curry(func, arity) {
+      arity = typeof arity == 'number' ? arity : (+arity || func.length);
+      return createWrapper(func, 4, null, null, null, arity);
+    }
+
+    /**
+     * Creates a function that will delay the execution of `func` until after
+     * `wait` milliseconds have elapsed since the last time it was invoked.
+     * Provide an options object to indicate that `func` should be invoked on
+     * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
+     * to the debounced function will return the result of the last `func` call.
+     *
+     * Note: If `leading` and `trailing` options are `true` `func` will be called
+     * on the trailing edge of the timeout only if the the debounced function is
+     * invoked more than once during the `wait` timeout.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to debounce.
+     * @param {number} wait The number of milliseconds to delay.
+     * @param {Object} [options] The options object.
+     * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
+     * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
+     * @returns {Function} Returns the new debounced function.
+     * @example
+     *
+     * // avoid costly calculations while the window size is in flux
+     * var lazyLayout = _.debounce(calculateLayout, 150);
+     * jQuery(window).on('resize', lazyLayout);
+     *
+     * // execute `sendMail` when the click event is fired, debouncing subsequent calls
+     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
+     *   'leading': true,
+     *   'trailing': false
+     * });
+     *
+     * // ensure `batchLog` is executed once after 1 second of debounced calls
+     * var source = new EventSource('/stream');
+     * source.addEventListener('message', _.debounce(batchLog, 250, {
+     *   'maxWait': 1000
+     * }, false);
+     */
+    function debounce(func, wait, options) {
+      var args,
+          maxTimeoutId,
+          result,
+          stamp,
+          thisArg,
+          timeoutId,
+          trailingCall,
+          lastCalled = 0,
+          maxWait = false,
+          trailing = true;
+
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      wait = nativeMax(0, wait) || 0;
+      if (options === true) {
+        var leading = true;
+        trailing = false;
+      } else if (isObject(options)) {
+        leading = options.leading;
+        maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
+        trailing = 'trailing' in options ? options.trailing : trailing;
+      }
+      var delayed = function() {
+        var remaining = wait - (now() - stamp);
+        if (remaining <= 0) {
+          if (maxTimeoutId) {
+            clearTimeout(maxTimeoutId);
+          }
+          var isCalled = trailingCall;
+          maxTimeoutId = timeoutId = trailingCall = undefined;
+          if (isCalled) {
+            lastCalled = now();
+            result = func.apply(thisArg, args);
+            if (!timeoutId && !maxTimeoutId) {
+              args = thisArg = null;
+            }
+          }
+        } else {
+          timeoutId = setTimeout(delayed, remaining);
+        }
+      };
+
+      var maxDelayed = function() {
+        if (timeoutId) {
+          clearTimeout(timeoutId);
+        }
+        maxTimeoutId = timeoutId = trailingCall = undefined;
+        if (trailing || (maxWait !== wait)) {
+          lastCalled = now();
+          result = func.apply(thisArg, args);
+          if (!timeoutId && !maxTimeoutId) {
+            args = thisArg = null;
+          }
+        }
+      };
+
+      return function() {
+        args = arguments;
+        stamp = now();
+        thisArg = this;
+        trailingCall = trailing && (timeoutId || !leading);
+
+        if (maxWait === false) {
+          var leadingCall = leading && !timeoutId;
+        } else {
+          if (!maxTimeoutId && !leading) {
+            lastCalled = stamp;
+          }
+          var remaining = maxWait - (stamp - lastCalled),
+              isCalled = remaining <= 0;
+
+          if (isCalled) {
+            if (maxTimeoutId) {
+              maxTimeoutId = clearTimeout(maxTimeoutId);
+            }
+            lastCalled = stamp;
+            result = func.apply(thisArg, args);
+          }
+          else if (!maxTimeoutId) {
+            maxTimeoutId = setTimeout(maxDelayed, remaining);
+          }
+        }
+        if (isCalled && timeoutId) {
+          timeoutId = clearTimeout(timeoutId);
+        }
+        else if (!timeoutId && wait !== maxWait) {
+          timeoutId = setTimeout(delayed, wait);
+        }
+        if (leadingCall) {
+          isCalled = true;
+          result = func.apply(thisArg, args);
+        }
+        if (isCalled && !timeoutId && !maxTimeoutId) {
+          args = thisArg = null;
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Defers executing the `func` function until the current call stack has cleared.
+     * Additional arguments will be provided to `func` when it is invoked.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to defer.
+     * @param {...*} [arg] Arguments to invoke the function with.
+     * @returns {number} Returns the timer id.
+     * @example
+     *
+     * _.defer(function(text) { console.log(text); }, 'deferred');
+     * // logs 'deferred' after one or more milliseconds
+     */
+    function defer(func) {
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      var args = slice(arguments, 1);
+      return setTimeout(function() { func.apply(undefined, args); }, 1);
+    }
+
+    /**
+     * Executes the `func` function after `wait` milliseconds. Additional arguments
+     * will be provided to `func` when it is invoked.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay execution.
+     * @param {...*} [arg] Arguments to invoke the function with.
+     * @returns {number} Returns the timer id.
+     * @example
+     *
+     * _.delay(function(text) { console.log(text); }, 1000, 'later');
+     * // => logs 'later' after one second
+     */
+    function delay(func, wait) {
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      var args = slice(arguments, 2);
+      return setTimeout(function() { func.apply(undefined, args); }, wait);
+    }
+
+    /**
+     * Creates a function that memoizes the result of `func`. If `resolver` is
+     * provided it will be used to determine the cache key for storing the result
+     * based on the arguments provided to the memoized function. By default, the
+     * first argument provided to the memoized function is used as the cache key.
+     * The `func` is executed with the `this` binding of the memoized function.
+     * The result cache is exposed as the `cache` property on the memoized function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to have its output memoized.
+     * @param {Function} [resolver] A function used to resolve the cache key.
+     * @returns {Function} Returns the new memoizing function.
+     * @example
+     *
+     * var fibonacci = _.memoize(function(n) {
+     *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
+     * });
+     *
+     * fibonacci(9)
+     * // => 34
+     *
+     * var data = {
+     *   'fred': { 'name': 'fred', 'age': 40 },
+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
+     * };
+     *
+     * // modifying the result cache
+     * var get = _.memoize(function(name) { return data[name]; }, _.identity);
+     * get('pebbles');
+     * // => { 'name': 'pebbles', 'age': 1 }
+     *
+     * get.cache.pebbles.name = 'penelope';
+     * get('pebbles');
+     * // => { 'name': 'penelope', 'age': 1 }
+     */
+    function memoize(func, resolver) {
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      var memoized = function() {
+        var cache = memoized.cache,
+            key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
+
+        return hasOwnProperty.call(cache, key)
+          ? cache[key]
+          : (cache[key] = func.apply(this, arguments));
+      }
+      memoized.cache = {};
+      return memoized;
+    }
+
+    /**
+     * Creates a function that is restricted to execute `func` once. Repeat calls to
+     * the function will return the value of the first call. The `func` is executed
+     * with the `this` binding of the created function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new restricted function.
+     * @example
+     *
+     * var initialize = _.once(createApplication);
+     * initialize();
+     * initialize();
+     * // `initialize` executes `createApplication` once
+     */
+    function once(func) {
+      var ran,
+          result;
+
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      return function() {
+        if (ran) {
+          return result;
+        }
+        ran = true;
+        result = func.apply(this, arguments);
+
+        // clear the `func` variable so the function may be garbage collected
+        func = null;
+        return result;
+      };
+    }
+
+    /**
+     * Creates a function that, when called, invokes `func` with any additional
+     * `partial` arguments prepended to those provided to the new function. This
+     * method is similar to `_.bind` except it does **not** alter the `this` binding.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to partially apply arguments to.
+     * @param {...*} [arg] Arguments to be partially applied.
+     * @returns {Function} Returns the new partially applied function.
+     * @example
+     *
+     * var greet = function(greeting, name) { return greeting + ' ' + name; };
+     * var hi = _.partial(greet, 'hi');
+     * hi('fred');
+     * // => 'hi fred'
+     */
+    function partial(func) {
+      return createWrapper(func, 16, slice(arguments, 1));
+    }
+
+    /**
+     * This method is like `_.partial` except that `partial` arguments are
+     * appended to those provided to the new function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to partially apply arguments to.
+     * @param {...*} [arg] Arguments to be partially applied.
+     * @returns {Function} Returns the new partially applied function.
+     * @example
+     *
+     * var defaultsDeep = _.partialRight(_.merge, _.defaults);
+     *
+     * var options = {
+     *   'variable': 'data',
+     *   'imports': { 'jq': $ }
+     * };
+     *
+     * defaultsDeep(options, _.templateSettings);
+     *
+     * options.variable
+     * // => 'data'
+     *
+     * options.imports
+     * // => { '_': _, 'jq': $ }
+     */
+    function partialRight(func) {
+      return createWrapper(func, 32, null, slice(arguments, 1));
+    }
+
+    /**
+     * Creates a function that, when executed, will only call the `func` function
+     * at most once per every `wait` milliseconds. Provide an options object to
+     * indicate that `func` should be invoked on the leading and/or trailing edge
+     * of the `wait` timeout. Subsequent calls to the throttled function will
+     * return the result of the last `func` call.
+     *
+     * Note: If `leading` and `trailing` options are `true` `func` will be called
+     * on the trailing edge of the timeout only if the the throttled function is
+     * invoked more than once during the `wait` timeout.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {Function} func The function to throttle.
+     * @param {number} wait The number of milliseconds to throttle executions to.
+     * @param {Object} [options] The options object.
+     * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
+     * @returns {Function} Returns the new throttled function.
+     * @example
+     *
+     * // avoid excessively updating the position while scrolling
+     * var throttled = _.throttle(updatePosition, 100);
+     * jQuery(window).on('scroll', throttled);
+     *
+     * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
+     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
+     *   'trailing': false
+     * }));
+     */
+    function throttle(func, wait, options) {
+      var leading = true,
+          trailing = true;
+
+      if (!isFunction(func)) {
+        throw new TypeError;
+      }
+      if (options === false) {
+        leading = false;
+      } else if (isObject(options)) {
+        leading = 'leading' in options ? options.leading : leading;
+        trailing = 'trailing' in options ? options.trailing : trailing;
+      }
+      debounceOptions.leading = leading;
+      debounceOptions.maxWait = wait;
+      debounceOptions.trailing = trailing;
+
+      return debounce(func, wait, debounceOptions);
+    }
+
+    /**
+     * Creates a function that provides `value` to the wrapper function as its
+     * first argument. Additional arguments provided to the function are appended
+     * to those provided to the wrapper function. The wrapper is executed with
+     * the `this` binding of the created function.
+     *
+     * @static
+     * @memberOf _
+     * @category Functions
+     * @param {*} value The value to wrap.
+     * @param {Function} wrapper The wrapper function.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var p = _.wrap(_.escape, function(func, text) {
+     *   return '<p>' + func(text) + '</p>';
+     * });
+     *
+     * p('Fred, Wilma, & Pebbles');
+     * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
+     */
+    function wrap(value, wrapper) {
+      return createWrapper(wrapper, 16, [value]);
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates a function that returns `value`.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {*} value The value to return from the new function.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var object = { 'name': 'fred' };
+     * var getter = _.constant(object);
+     * getter() === object;
+     * // => true
+     */
+    function constant(value) {
+      return function() {
+        return value;
+      };
+    }
+
+    /**
+     * Produces a callback bound to an optional `thisArg`. If `func` is a property
+     * name the created callback will return the property value for a given element.
+     * If `func` is an object the created callback will return `true` for elements
+     * that contain the equivalent object properties, otherwise it will return `false`.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {*} [func=identity] The value to convert to a callback.
+     * @param {*} [thisArg] The `this` binding of the created callback.
+     * @param {number} [argCount] The number of arguments the callback accepts.
+     * @returns {Function} Returns a callback function.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * // wrap to create custom callback shorthands
+     * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
+     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
+     *   return !match ? func(callback, thisArg) : function(object) {
+     *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
+     *   };
+     * });
+     *
+     * _.filter(characters, 'age__gt38');
+     * // => [{ 'name': 'fred', 'age': 40 }]
+     */
+    function createCallback(func, thisArg, argCount) {
+      var type = typeof func;
+      if (func == null || type == 'function') {
+        return baseCreateCallback(func, thisArg, argCount);
+      }
+      // handle "_.pluck" style callback shorthands
+      if (type != 'object') {
+        return property(func);
+      }
+      var props = keys(func),
+          key = props[0],
+          a = func[key];
+
+      // handle "_.where" style callback shorthands
+      if (props.length == 1 && a === a && !isObject(a)) {
+        // fast path the common case of providing an object with a single
+        // property containing a primitive value
+        return function(object) {
+          var b = object[key];
+          return a === b && (a !== 0 || (1 / a == 1 / b));
+        };
+      }
+      return function(object) {
+        var length = props.length,
+            result = false;
+
+        while (length--) {
+          if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
+            break;
+          }
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
+     * corresponding HTML entities.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} string The string to escape.
+     * @returns {string} Returns the escaped string.
+     * @example
+     *
+     * _.escape('Fred, Wilma, & Pebbles');
+     * // => 'Fred, Wilma, &amp; Pebbles'
+     */
+    function escape(string) {
+      return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
+    }
+
+    /**
+     * This method returns the first argument provided to it.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {*} value Any value.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * var object = { 'name': 'fred' };
+     * _.identity(object) === object;
+     * // => true
+     */
+    function identity(value) {
+      return value;
+    }
+
+    /**
+     * Adds function properties of a source object to the destination object.
+     * If `object` is a function methods will be added to its prototype as well.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {Function|Object} [object=lodash] object The destination object.
+     * @param {Object} source The object of functions to add.
+     * @param {Object} [options] The options object.
+     * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
+     * @example
+     *
+     * function capitalize(string) {
+     *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
+     * }
+     *
+     * _.mixin({ 'capitalize': capitalize });
+     * _.capitalize('fred');
+     * // => 'Fred'
+     *
+     * _('fred').capitalize().value();
+     * // => 'Fred'
+     *
+     * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
+     * _('fred').capitalize();
+     * // => 'Fred'
+     */
+    function mixin(object, source, options) {
+      var chain = true,
+          methodNames = source && functions(source);
+
+      if (!source || (!options && !methodNames.length)) {
+        if (options == null) {
+          options = source;
+        }
+        ctor = lodashWrapper;
+        source = object;
+        object = lodash;
+        methodNames = functions(source);
+      }
+      if (options === false) {
+        chain = false;
+      } else if (isObject(options) && 'chain' in options) {
+        chain = options.chain;
+      }
+      var ctor = object,
+          isFunc = isFunction(ctor);
+
+      forEach(methodNames, function(methodName) {
+        var func = object[methodName] = source[methodName];
+        if (isFunc) {
+          ctor.prototype[methodName] = function() {
+            var chainAll = this.__chain__,
+                value = this.__wrapped__,
+                args = [value];
+
+            push.apply(args, arguments);
+            var result = func.apply(object, args);
+            if (chain || chainAll) {
+              if (value === result && isObject(result)) {
+                return this;
+              }
+              result = new ctor(result);
+              result.__chain__ = chainAll;
+            }
+            return result;
+          };
+        }
+      });
+    }
+
+    /**
+     * Reverts the '_' variable to its previous value and returns a reference to
+     * the `lodash` function.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @returns {Function} Returns the `lodash` function.
+     * @example
+     *
+     * var lodash = _.noConflict();
+     */
+    function noConflict() {
+      context._ = oldDash;
+      return this;
+    }
+
+    /**
+     * A no-operation function.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @example
+     *
+     * var object = { 'name': 'fred' };
+     * _.noop(object) === undefined;
+     * // => true
+     */
+    function noop() {
+      // no operation performed
+    }
+
+    /**
+     * Gets the number of milliseconds that have elapsed since the Unix epoch
+     * (1 January 1970 00:00:00 UTC).
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @example
+     *
+     * var stamp = _.now();
+     * _.defer(function() { console.log(_.now() - stamp); });
+     * // => logs the number of milliseconds it took for the deferred function to be called
+     */
+    var now = isNative(now = Date.now) && now || function() {
+      return new Date().getTime();
+    };
+
+    /**
+     * Converts the given value into an integer of the specified radix.
+     * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
+     * `value` is a hexadecimal, in which case a `radix` of `16` is used.
+     *
+     * Note: This method avoids differences in native ES3 and ES5 `parseInt`
+     * implementations. See http://es5.github.io/#E.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} value The value to parse.
+     * @param {number} [radix] The radix used to interpret the value to parse.
+     * @returns {number} Returns the new integer value.
+     * @example
+     *
+     * _.parseInt('08');
+     * // => 8
+     */
+    var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
+      // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
+      return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
+    };
+
+    /**
+     * Creates a "_.pluck" style function, which returns the `key` value of a
+     * given object.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} key The name of the property to retrieve.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'fred',   'age': 40 },
+     *   { 'name': 'barney', 'age': 36 }
+     * ];
+     *
+     * var getName = _.property('name');
+     *
+     * _.map(characters, getName);
+     * // => ['barney', 'fred']
+     *
+     * _.sortBy(characters, getName);
+     * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
+     */
+    function property(key) {
+      return function(object) {
+        return object[key];
+      };
+    }
+
+    /**
+     * Produces a random number between `min` and `max` (inclusive). If only one
+     * argument is provided a number between `0` and the given number will be
+     * returned. If `floating` is truey or either `min` or `max` are floats a
+     * floating-point number will be returned instead of an integer.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {number} [min=0] The minimum possible value.
+     * @param {number} [max=1] The maximum possible value.
+     * @param {boolean} [floating=false] Specify returning a floating-point number.
+     * @returns {number} Returns a random number.
+     * @example
+     *
+     * _.random(0, 5);
+     * // => an integer between 0 and 5
+     *
+     * _.random(5);
+     * // => also an integer between 0 and 5
+     *
+     * _.random(5, true);
+     * // => a floating-point number between 0 and 5
+     *
+     * _.random(1.2, 5.2);
+     * // => a floating-point number between 1.2 and 5.2
+     */
+    function random(min, max, floating) {
+      var noMin = min == null,
+          noMax = max == null;
+
+      if (floating == null) {
+        if (typeof min == 'boolean' && noMax) {
+          floating = min;
+          min = 1;
+        }
+        else if (!noMax && typeof max == 'boolean') {
+          floating = max;
+          noMax = true;
+        }
+      }
+      if (noMin && noMax) {
+        max = 1;
+      }
+      min = +min || 0;
+      if (noMax) {
+        max = min;
+        min = 0;
+      } else {
+        max = +max || 0;
+      }
+      if (floating || min % 1 || max % 1) {
+        var rand = nativeRandom();
+        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
+      }
+      return baseRandom(min, max);
+    }
+
+    /**
+     * Resolves the value of property `key` on `object`. If `key` is a function
+     * it will be invoked with the `this` binding of `object` and its result returned,
+     * else the property value is returned. If `object` is falsey then `undefined`
+     * is returned.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {Object} object The object to inspect.
+     * @param {string} key The name of the property to resolve.
+     * @returns {*} Returns the resolved value.
+     * @example
+     *
+     * var object = {
+     *   'cheese': 'crumpets',
+     *   'stuff': function() {
+     *     return 'nonsense';
+     *   }
+     * };
+     *
+     * _.result(object, 'cheese');
+     * // => 'crumpets'
+     *
+     * _.result(object, 'stuff');
+     * // => 'nonsense'
+     */
+    function result(object, key) {
+      if (object) {
+        var value = object[key];
+        return isFunction(value) ? object[key]() : value;
+      }
+    }
+
+    /**
+     * A micro-templating method that handles arbitrary delimiters, preserves
+     * whitespace, and correctly escapes quotes within interpolated code.
+     *
+     * Note: In the development build, `_.template` utilizes sourceURLs for easier
+     * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
+     *
+     * For more information on precompiling templates see:
+     * http://lodash.com/custom-builds
+     *
+     * For more information on Chrome extension sandboxes see:
+     * http://developer.chrome.com/stable/extensions/sandboxingEval.html
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} text The template text.
+     * @param {Object} data The data object used to populate the text.
+     * @param {Object} [options] The options object.
+     * @param {RegExp} [options.escape] The "escape" delimiter.
+     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
+     * @param {Object} [options.imports] An object to import into the template as local variables.
+     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
+     * @param {string} [sourceURL] The sourceURL of the template's compiled source.
+     * @param {string} [variable] The data object variable name.
+     * @returns {Function|string} Returns a compiled function when no `data` object
+     *  is given, else it returns the interpolated text.
+     * @example
+     *
+     * // using the "interpolate" delimiter to create a compiled template
+     * var compiled = _.template('hello <%= name %>');
+     * compiled({ 'name': 'fred' });
+     * // => 'hello fred'
+     *
+     * // using the "escape" delimiter to escape HTML in data property values
+     * _.template('<b><%- value %></b>', { 'value': '<script>' });
+     * // => '<b>&lt;script&gt;</b>'
+     *
+     * // using the "evaluate" delimiter to generate HTML
+     * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
+     * _.template(list, { 'people': ['fred', 'barney'] });
+     * // => '<li>fred</li><li>barney</li>'
+     *
+     * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
+     * _.template('hello ${ name }', { 'name': 'pebbles' });
+     * // => 'hello pebbles'
+     *
+     * // using the internal `print` function in "evaluate" delimiters
+     * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
+     * // => 'hello barney!'
+     *
+     * // using a custom template delimiters
+     * _.templateSettings = {
+     *   'interpolate': /{{([\s\S]+?)}}/g
+     * };
+     *
+     * _.template('hello {{ name }}!', { 'name': 'mustache' });
+     * // => 'hello mustache!'
+     *
+     * // using the `imports` option to import jQuery
+     * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
+     * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
+     * // => '<li>fred</li><li>barney</li>'
+     *
+     * // using the `sourceURL` option to specify a custom sourceURL for the template
+     * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
+     * compiled(data);
+     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
+     *
+     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
+     * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
+     * compiled.source;
+     * // => function(data) {
+     *   var __t, __p = '', __e = _.escape;
+     *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
+     *   return __p;
+     * }
+     *
+     * // using the `source` property to inline compiled templates for meaningful
+     * // line numbers in error messages and a stack trace
+     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
+     *   var JST = {\
+     *     "main": ' + _.template(mainText).source + '\
+     *   };\
+     * ');
+     */
+    function template(text, data, options) {
+      // based on John Resig's `tmpl` implementation
+      // http://ejohn.org/blog/javascript-micro-templating/
+      // and Laura Doktorova's doT.js
+      // https://github.com/olado/doT
+      var settings = lodash.templateSettings;
+      text = String(text || '');
+
+      // avoid missing dependencies when `iteratorTemplate` is not defined
+      options = defaults({}, options, settings);
+
+      var imports = defaults({}, options.imports, settings.imports),
+          importsKeys = keys(imports),
+          importsValues = values(imports);
+
+      var isEvaluating,
+          index = 0,
+          interpolate = options.interpolate || reNoMatch,
+          source = "__p += '";
+
+      // compile the regexp to match each delimiter
+      var reDelimiters = RegExp(
+        (options.escape || reNoMatch).source + '|' +
+        interpolate.source + '|' +
+        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
+        (options.evaluate || reNoMatch).source + '|$'
+      , 'g');
+
+      text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
+        interpolateValue || (interpolateValue = esTemplateValue);
+
+        // escape characters that cannot be included in string literals
+        source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
+
+        // replace delimiters with snippets
+        if (escapeValue) {
+          source += "' +\n__e(" + escapeValue + ") +\n'";
+        }
+        if (evaluateValue) {
+          isEvaluating = true;
+          source += "';\n" + evaluateValue + ";\n__p += '";
+        }
+        if (interpolateValue) {
+          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
+        }
+        index = offset + match.length;
+
+        // the JS engine embedded in Adobe products requires returning the `match`
+        // string in order to produce the correct `offset` value
+        return match;
+      });
+
+      source += "';\n";
+
+      // if `variable` is not specified, wrap a with-statement around the generated
+      // code to add the data object to the top of the scope chain
+      var variable = options.variable,
+          hasVariable = variable;
+
+      if (!hasVariable) {
+        variable = 'obj';
+        source = 'with (' + variable + ') {\n' + source + '\n}\n';
+      }
+      // cleanup code by stripping empty strings
+      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
+        .replace(reEmptyStringMiddle, '$1')
+        .replace(reEmptyStringTrailing, '$1;');
+
+      // frame code as the function body
+      source = 'function(' + variable + ') {\n' +
+        (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
+        "var __t, __p = '', __e = _.escape" +
+        (isEvaluating
+          ? ', __j = Array.prototype.join;\n' +
+            "function print() { __p += __j.call(arguments, '') }\n"
+          : ';\n'
+        ) +
+        source +
+        'return __p\n}';
+
+      // Use a sourceURL for easier debugging.
+      // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
+      var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
+
+      try {
+        var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
+      } catch(e) {
+        e.source = source;
+        throw e;
+      }
+      if (data) {
+        return result(data);
+      }
+      // provide the compiled function's source by its `toString` method, in
+      // supported environments, or the `source` property as a convenience for
+      // inlining compiled templates during the build process
+      result.source = source;
+      return result;
+    }
+
+    /**
+     * Executes the callback `n` times, returning an array of the results
+     * of each callback execution. The callback is bound to `thisArg` and invoked
+     * with one argument; (index).
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {number} n The number of times to execute the callback.
+     * @param {Function} callback The function called per iteration.
+     * @param {*} [thisArg] The `this` binding of `callback`.
+     * @returns {Array} Returns an array of the results of each `callback` execution.
+     * @example
+     *
+     * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
+     * // => [3, 6, 4]
+     *
+     * _.times(3, function(n) { mage.castSpell(n); });
+     * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
+     *
+     * _.times(3, function(n) { this.cast(n); }, mage);
+     * // => also calls `mage.castSpell(n)` three times
+     */
+    function times(n, callback, thisArg) {
+      n = (n = +n) > -1 ? n : 0;
+      var index = -1,
+          result = Array(n);
+
+      callback = baseCreateCallback(callback, thisArg, 1);
+      while (++index < n) {
+        result[index] = callback(index);
+      }
+      return result;
+    }
+
+    /**
+     * The inverse of `_.escape` this method converts the HTML entities
+     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
+     * corresponding characters.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} string The string to unescape.
+     * @returns {string} Returns the unescaped string.
+     * @example
+     *
+     * _.unescape('Fred, Barney &amp; Pebbles');
+     * // => 'Fred, Barney & Pebbles'
+     */
+    function unescape(string) {
+      return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
+    }
+
+    /**
+     * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
+     *
+     * @static
+     * @memberOf _
+     * @category Utilities
+     * @param {string} [prefix] The value to prefix the ID with.
+     * @returns {string} Returns the unique ID.
+     * @example
+     *
+     * _.uniqueId('contact_');
+     * // => 'contact_104'
+     *
+     * _.uniqueId();
+     * // => '105'
+     */
+    function uniqueId(prefix) {
+      var id = ++idCounter;
+      return String(prefix == null ? '' : prefix) + id;
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * Creates a `lodash` object that wraps the given value with explicit
+     * method chaining enabled.
+     *
+     * @static
+     * @memberOf _
+     * @category Chaining
+     * @param {*} value The value to wrap.
+     * @returns {Object} Returns the wrapper object.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney',  'age': 36 },
+     *   { 'name': 'fred',    'age': 40 },
+     *   { 'name': 'pebbles', 'age': 1 }
+     * ];
+     *
+     * var youngest = _.chain(characters)
+     *     .sortBy('age')
+     *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
+     *     .first()
+     *     .value();
+     * // => 'pebbles is 1'
+     */
+    function chain(value) {
+      value = new lodashWrapper(value);
+      value.__chain__ = true;
+      return value;
+    }
+
+    /**
+     * Invokes `interceptor` with the `value` as the first argument and then
+     * returns `value`. The purpose of this method is to "tap into" a method
+     * chain in order to perform operations on intermediate results within
+     * the chain.
+     *
+     * @static
+     * @memberOf _
+     * @category Chaining
+     * @param {*} value The value to provide to `interceptor`.
+     * @param {Function} interceptor The function to invoke.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * _([1, 2, 3, 4])
+     *  .tap(function(array) { array.pop(); })
+     *  .reverse()
+     *  .value();
+     * // => [3, 2, 1]
+     */
+    function tap(value, interceptor) {
+      interceptor(value);
+      return value;
+    }
+
+    /**
+     * Enables explicit method chaining on the wrapper object.
+     *
+     * @name chain
+     * @memberOf _
+     * @category Chaining
+     * @returns {*} Returns the wrapper object.
+     * @example
+     *
+     * var characters = [
+     *   { 'name': 'barney', 'age': 36 },
+     *   { 'name': 'fred',   'age': 40 }
+     * ];
+     *
+     * // without explicit chaining
+     * _(characters).first();
+     * // => { 'name': 'barney', 'age': 36 }
+     *
+     * // with explicit chaining
+     * _(characters).chain()
+     *   .first()
+     *   .pick('age')
+     *   .value();
+     * // => { 'age': 36 }
+     */
+    function wrapperChain() {
+      this.__chain__ = true;
+      return this;
+    }
+
+    /**
+     * Produces the `toString` result of the wrapped value.
+     *
+     * @name toString
+     * @memberOf _
+     * @category Chaining
+     * @returns {string} Returns the string result.
+     * @example
+     *
+     * _([1, 2, 3]).toString();
+     * // => '1,2,3'
+     */
+    function wrapperToString() {
+      return String(this.__wrapped__);
+    }
+
+    /**
+     * Extracts the wrapped value.
+     *
+     * @name valueOf
+     * @memberOf _
+     * @alias value
+     * @category Chaining
+     * @returns {*} Returns the wrapped value.
+     * @example
+     *
+     * _([1, 2, 3]).valueOf();
+     * // => [1, 2, 3]
+     */
+    function wrapperValueOf() {
+      return this.__wrapped__;
+    }
+
+    /*--------------------------------------------------------------------------*/
+
+    // add functions that return wrapped values when chaining
+    lodash.after = after;
+    lodash.assign = assign;
+    lodash.at = at;
+    lodash.bind = bind;
+    lodash.bindAll = bindAll;
+    lodash.bindKey = bindKey;
+    lodash.chain = chain;
+    lodash.compact = compact;
+    lodash.compose = compose;
+    lodash.constant = constant;
+    lodash.countBy = countBy;
+    lodash.create = create;
+    lodash.createCallback = createCallback;
+    lodash.curry = curry;
+    lodash.debounce = debounce;
+    lodash.defaults = defaults;
+    lodash.defer = defer;
+    lodash.delay = delay;
+    lodash.difference = difference;
+    lodash.filter = filter;
+    lodash.flatten = flatten;
+    lodash.forEach = forEach;
+    lodash.forEachRight = forEachRight;
+    lodash.forIn = forIn;
+    lodash.forInRight = forInRight;
+    lodash.forOwn = forOwn;
+    lodash.forOwnRight = forOwnRight;
+    lodash.functions = functions;
+    lodash.groupBy = groupBy;
+    lodash.indexBy = indexBy;
+    lodash.initial = initial;
+    lodash.intersection = intersection;
+    lodash.invert = invert;
+    lodash.invoke = invoke;
+    lodash.keys = keys;
+    lodash.map = map;
+    lodash.mapValues = mapValues;
+    lodash.max = max;
+    lodash.memoize = memoize;
+    lodash.merge = merge;
+    lodash.min = min;
+    lodash.omit = omit;
+    lodash.once = once;
+    lodash.pairs = pairs;
+    lodash.partial = partial;
+    lodash.partialRight = partialRight;
+    lodash.pick = pick;
+    lodash.pluck = pluck;
+    lodash.property = property;
+    lodash.pull = pull;
+    lodash.range = range;
+    lodash.reject = reject;
+    lodash.remove = remove;
+    lodash.rest = rest;
+    lodash.shuffle = shuffle;
+    lodash.sortBy = sortBy;
+    lodash.tap = tap;
+    lodash.throttle = throttle;
+    lodash.times = times;
+    lodash.toArray = toArray;
+    lodash.transform = transform;
+    lodash.union = union;
+    lodash.uniq = uniq;
+    lodash.values = values;
+    lodash.where = where;
+    lodash.without = without;
+    lodash.wrap = wrap;
+    lodash.xor = xor;
+    lodash.zip = zip;
+    lodash.zipObject = zipObject;
+
+    // add aliases
+    lodash.collect = map;
+    lodash.drop = rest;
+    lodash.each = forEach;
+    lodash.eachRight = forEachRight;
+    lodash.extend = assign;
+    lodash.methods = functions;
+    lodash.object = zipObject;
+    lodash.select = filter;
+    lodash.tail = rest;
+    lodash.unique = uniq;
+    lodash.unzip = zip;
+
+    // add functions to `lodash.prototype`
+    mixin(lodash);
+
+    /*--------------------------------------------------------------------------*/
+
+    // add functions that return unwrapped values when chaining
+    lodash.clone = clone;
+    lodash.cloneDeep = cloneDeep;
+    lodash.contains = contains;
+    lodash.escape = escape;
+    lodash.every = every;
+    lodash.find = find;
+    lodash.findIndex = findIndex;
+    lodash.findKey = findKey;
+    lodash.findLast = findLast;
+    lodash.findLastIndex = findLastIndex;
+    lodash.findLastKey = findLastKey;
+    lodash.has = has;
+    lodash.identity = identity;
+    lodash.indexOf = indexOf;
+    lodash.isArguments = isArguments;
+    lodash.isArray = isArray;
+    lodash.isBoolean = isBoolean;
+    lodash.isDate = isDate;
+    lodash.isElement = isElement;
+    lodash.isEmpty = isEmpty;
+    lodash.isEqual = isEqual;
+    lodash.isFinite = isFinite;
+    lodash.isFunction = isFunction;
+    lodash.isNaN = isNaN;
+    lodash.isNull = isNull;
+    lodash.isNumber = isNumber;
+    lodash.isObject = isObject;
+    lodash.isPlainObject = isPlainObject;
+    lodash.isRegExp = isRegExp;
+    lodash.isString = isString;
+    lodash.isUndefined = isUndefined;
+    lodash.lastIndexOf = lastIndexOf;
+    lodash.mixin = mixin;
+    lodash.noConflict = noConflict;
+    lodash.noop = noop;
+    lodash.now = now;
+    lodash.parseInt = parseInt;
+    lodash.random = random;
+    lodash.reduce = reduce;
+    lodash.reduceRight = reduceRight;
+    lodash.result = result;
+    lodash.runInContext = runInContext;
+    lodash.size = size;
+    lodash.some = some;
+    lodash.sortedIndex = sortedIndex;
+    lodash.template = template;
+    lodash.unescape = unescape;
+    lodash.uniqueId = uniqueId;
+
+    // add aliases
+    lodash.all = every;
+    lodash.any = some;
+    lodash.detect = find;
+    lodash.findWhere = find;
+    lodash.foldl = reduce;
+    lodash.foldr = reduceRight;
+    lodash.include = contains;
+    lodash.inject = reduce;
+
+    mixin(function() {
+      var source = {}
+      forOwn(lodash, function(func, methodName) {
+        if (!lodash.prototype[methodName]) {
+          source[methodName] = func;
+        }
+      });
+      return source;
+    }(), false);
+
+    /*--------------------------------------------------------------------------*/
+
+    // add functions capable of returning wrapped and unwrapped values when chaining
+    lodash.first = first;
+    lodash.last = last;
+    lodash.sample = sample;
+
+    // add aliases
+    lodash.take = first;
+    lodash.head = first;
+
+    forOwn(lodash, function(func, methodName) {
+      var callbackable = methodName !== 'sample';
+      if (!lodash.prototype[methodName]) {
+        lodash.prototype[methodName]= function(n, guard) {
+          var chainAll = this.__chain__,
+              result = func(this.__wrapped__, n, guard);
+
+          return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
+            ? result
+            : new lodashWrapper(result, chainAll);
+        };
+      }
+    });
+
+    /*--------------------------------------------------------------------------*/
+
+    /**
+     * The semantic version number.
+     *
+     * @static
+     * @memberOf _
+     * @type string
+     */
+    lodash.VERSION = '2.4.1';
+
+    // add "Chaining" functions to the wrapper
+    lodash.prototype.chain = wrapperChain;
+    lodash.prototype.toString = wrapperToString;
+    lodash.prototype.value = wrapperValueOf;
+    lodash.prototype.valueOf = wrapperValueOf;
+
+    // add `Array` functions that return unwrapped values
+    forEach(['join', 'pop', 'shift'], function(methodName) {
+      var func = arrayRef[methodName];
+      lodash.prototype[methodName] = function() {
+        var chainAll = this.__chain__,
+            result = func.apply(this.__wrapped__, arguments);
+
+        return chainAll
+          ? new lodashWrapper(result, chainAll)
+          : result;
+      };
+    });
+
+    // add `Array` functions that return the existing wrapped value
+    forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
+      var func = arrayRef[methodName];
+      lodash.prototype[methodName] = function() {
+        func.apply(this.__wrapped__, arguments);
+        return this;
+      };
+    });
+
+    // add `Array` functions that return new wrapped values
+    forEach(['concat', 'slice', 'splice'], function(methodName) {
+      var func = arrayRef[methodName];
+      lodash.prototype[methodName] = function() {
+        return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
+      };
+    });
+
+    return lodash;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // expose Lo-Dash
+  var _ = runInContext();
+
+  // some AMD build optimizers like r.js check for condition patterns like the following:
+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+    // Expose Lo-Dash to the global object even when an AMD loader is present in
+    // case Lo-Dash is loaded with a RequireJS shim config.
+    // See http://requirejs.org/docs/api.html#config-shim
+    root._ = _;
+
+    // define as an anonymous module so, through path mapping, it can be
+    // referenced as the "underscore" module
+    define(function() {
+      return _;
+    });
+  }
+  // check for `exports` after `define` in case a build optimizer adds an `exports` object
+  else if (freeExports && freeModule) {
+    // in Node.js or RingoJS
+    if (moduleExports) {
+      (freeModule.exports = _)._ = _;
+    }
+    // in Narwhal or Rhino -require
+    else {
+      freeExports._ = _;
+    }
+  }
+  else {
+    // in a browser or Rhino
+    root._ = _;
+  }
+}.call(this));
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}]},{},[1])(1)
+});
\ No newline at end of file
diff --git a/dev/js/lib/domReady.js b/dev/js/lib/domReady.js
new file mode 100644
index 0000000..2b54122
--- /dev/null
+++ b/dev/js/lib/domReady.js
@@ -0,0 +1,129 @@
+/**
+ * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/requirejs/domReady for details
+ */
+/*jslint */
+/*global require: false, define: false, requirejs: false,
+  window: false, clearInterval: false, document: false,
+  self: false, setInterval: false */
+
+
+define(function () {
+    'use strict';
+
+    var isTop, testDiv, scrollIntervalId,
+        isBrowser = typeof window !== "undefined" && window.document,
+        isPageLoaded = !isBrowser,
+        doc = isBrowser ? document : null,
+        readyCalls = [];
+
+    function runCallbacks(callbacks) {
+        var i;
+        for (i = 0; i < callbacks.length; i += 1) {
+            callbacks[i](doc);
+        }
+    }
+
+    function callReady() {
+        var callbacks = readyCalls;
+
+        if (isPageLoaded) {
+            //Call the DOM ready callbacks
+            if (callbacks.length) {
+                readyCalls = [];
+                runCallbacks(callbacks);
+            }
+        }
+    }
+
+    /**
+     * Sets the page as loaded.
+     */
+    function pageLoaded() {
+        if (!isPageLoaded) {
+            isPageLoaded = true;
+            if (scrollIntervalId) {
+                clearInterval(scrollIntervalId);
+            }
+
+            callReady();
+        }
+    }
+
+    if (isBrowser) {
+        if (document.addEventListener) {
+            //Standards. Hooray! Assumption here that if standards based,
+            //it knows about DOMContentLoaded.
+            document.addEventListener("DOMContentLoaded", pageLoaded, false);
+            window.addEventListener("load", pageLoaded, false);
+        } else if (window.attachEvent) {
+            window.attachEvent("onload", pageLoaded);
+
+            testDiv = document.createElement('div');
+            try {
+                isTop = window.frameElement === null;
+            } catch (e) {}
+
+            //DOMContentLoaded approximation that uses a doScroll, as found by
+            //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,
+            //but modified by other contributors, including jdalton
+            if (testDiv.doScroll && isTop && window.external) {
+                scrollIntervalId = setInterval(function () {
+                    try {
+                        testDiv.doScroll();
+                        pageLoaded();
+                    } catch (e) {}
+                }, 30);
+            }
+        }
+
+        //Check if document already complete, and if so, just trigger page load
+        //listeners. Latest webkit browsers also use "interactive", and
+        //will fire the onDOMContentLoaded before "interactive" but not after
+        //entering "interactive" or "complete". More details:
+        //http://dev.w3.org/html5/spec/the-end.html#the-end
+        //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded
+        //Hmm, this is more complicated on further use, see "firing too early"
+        //bug: https://github.com/requirejs/domReady/issues/1
+        //so removing the || document.readyState === "interactive" test.
+        //There is still a window.onload binding that should get fired if
+        //DOMContentLoaded is missed.
+        if (document.readyState === "complete") {
+            pageLoaded();
+        }
+    }
+
+    /** START OF PUBLIC API **/
+
+    /**
+     * Registers a callback for DOM ready. If DOM is already ready, the
+     * callback is called immediately.
+     * @param {Function} callback
+     */
+    function domReady(callback) {
+        if (isPageLoaded) {
+            callback(doc);
+        } else {
+            readyCalls.push(callback);
+        }
+        return domReady;
+    }
+
+    domReady.version = '2.0.1';
+
+    /**
+     * Loader Plugin API method
+     */
+    domReady.load = function (name, req, onLoad, config) {
+        if (config.isBuild) {
+            onLoad(null);
+        } else {
+            domReady(onLoad);
+        }
+    };
+
+    /** END OF PUBLIC API **/
+
+    return domReady;
+});
diff --git a/dev/js/lib/require.js b/dev/js/lib/require.js
new file mode 100644
index 0000000..babfa9a
--- /dev/null
+++ b/dev/js/lib/require.js
@@ -0,0 +1,2083 @@
+/** vim: et:ts=4:sw=4:sts=4
+ * @license RequireJS 2.1.17 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+//Not using strict: uneven strict support in browsers, #392, and causes
+//problems with requirejs.exec()/transpiler plugins that may not be strict.
+/*jslint regexp: true, nomen: true, sloppy: true */
+/*global window, navigator, document, importScripts, setTimeout, opera */
+
+var requirejs, require, define;
+(function (global) {
+    var req, s, head, baseElement, dataMain, src,
+        interactiveScript, currentlyAddingScript, mainScript, subPath,
+        version = '2.1.17',
+        commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
+        cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
+        jsSuffixRegExp = /\.js$/,
+        currDirRegExp = /^\.\//,
+        op = Object.prototype,
+        ostring = op.toString,
+        hasOwn = op.hasOwnProperty,
+        ap = Array.prototype,
+        apsp = ap.splice,
+        isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
+        isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
+        //PS3 indicates loaded and complete, but need to wait for complete
+        //specifically. Sequence is 'loading', 'loaded', execution,
+        // then 'complete'. The UA check is unfortunate, but not sure how
+        //to feature test w/o causing perf issues.
+        readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
+                      /^complete$/ : /^(complete|loaded)$/,
+        defContextName = '_',
+        //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
+        isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
+        contexts = {},
+        cfg = {},
+        globalDefQueue = [],
+        useInteractive = false;
+
+    function isFunction(it) {
+        return ostring.call(it) === '[object Function]';
+    }
+
+    function isArray(it) {
+        return ostring.call(it) === '[object Array]';
+    }
+
+    /**
+     * Helper function for iterating over an array. If the func returns
+     * a true value, it will break out of the loop.
+     */
+    function each(ary, func) {
+        if (ary) {
+            var i;
+            for (i = 0; i < ary.length; i += 1) {
+                if (ary[i] && func(ary[i], i, ary)) {
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper function for iterating over an array backwards. If the func
+     * returns a true value, it will break out of the loop.
+     */
+    function eachReverse(ary, func) {
+        if (ary) {
+            var i;
+            for (i = ary.length - 1; i > -1; i -= 1) {
+                if (ary[i] && func(ary[i], i, ary)) {
+                    break;
+                }
+            }
+        }
+    }
+
+    function hasProp(obj, prop) {
+        return hasOwn.call(obj, prop);
+    }
+
+    function getOwn(obj, prop) {
+        return hasProp(obj, prop) && obj[prop];
+    }
+
+    /**
+     * Cycles over properties in an object and calls a function for each
+     * property value. If the function returns a truthy value, then the
+     * iteration is stopped.
+     */
+    function eachProp(obj, func) {
+        var prop;
+        for (prop in obj) {
+            if (hasProp(obj, prop)) {
+                if (func(obj[prop], prop)) {
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Simple function to mix in properties from source into target,
+     * but only if target does not already have a property of the same name.
+     */
+    function mixin(target, source, force, deepStringMixin) {
+        if (source) {
+            eachProp(source, function (value, prop) {
+                if (force || !hasProp(target, prop)) {
+                    if (deepStringMixin && typeof value === 'object' && value &&
+                        !isArray(value) && !isFunction(value) &&
+                        !(value instanceof RegExp)) {
+
+                        if (!target[prop]) {
+                            target[prop] = {};
+                        }
+                        mixin(target[prop], value, force, deepStringMixin);
+                    } else {
+                        target[prop] = value;
+                    }
+                }
+            });
+        }
+        return target;
+    }
+
+    //Similar to Function.prototype.bind, but the 'this' object is specified
+    //first, since it is easier to read/figure out what 'this' will be.
+    function bind(obj, fn) {
+        return function () {
+            return fn.apply(obj, arguments);
+        };
+    }
+
+    function scripts() {
+        return document.getElementsByTagName('script');
+    }
+
+    function defaultOnError(err) {
+        throw err;
+    }
+
+    //Allow getting a global that is expressed in
+    //dot notation, like 'a.b.c'.
+    function getGlobal(value) {
+        if (!value) {
+            return value;
+        }
+        var g = global;
+        each(value.split('.'), function (part) {
+            g = g[part];
+        });
+        return g;
+    }
+
+    /**
+     * Constructs an error with a pointer to an URL with more information.
+     * @param {String} id the error ID that maps to an ID on a web page.
+     * @param {String} message human readable error.
+     * @param {Error} [err] the original error, if there is one.
+     *
+     * @returns {Error}
+     */
+    function makeError(id, msg, err, requireModules) {
+        var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
+        e.requireType = id;
+        e.requireModules = requireModules;
+        if (err) {
+            e.originalError = err;
+        }
+        return e;
+    }
+
+    if (typeof define !== 'undefined') {
+        //If a define is already in play via another AMD loader,
+        //do not overwrite.
+        return;
+    }
+
+    if (typeof requirejs !== 'undefined') {
+        if (isFunction(requirejs)) {
+            //Do not overwrite an existing requirejs instance.
+            return;
+        }
+        cfg = requirejs;
+        requirejs = undefined;
+    }
+
+    //Allow for a require config object
+    if (typeof require !== 'undefined' && !isFunction(require)) {
+        //assume it is a config object.
+        cfg = require;
+        require = undefined;
+    }
+
+    function newContext(contextName) {
+        var inCheckLoaded, Module, context, handlers,
+            checkLoadedTimeoutId,
+            config = {
+                //Defaults. Do not set a default for map
+                //config to speed up normalize(), which
+                //will run faster if there is no default.
+                waitSeconds: 7,
+                baseUrl: './',
+                paths: {},
+                bundles: {},
+                pkgs: {},
+                shim: {},
+                config: {}
+            },
+            registry = {},
+            //registry of just enabled modules, to speed
+            //cycle breaking code when lots of modules
+            //are registered, but not activated.
+            enabledRegistry = {},
+            undefEvents = {},
+            defQueue = [],
+            defined = {},
+            urlFetched = {},
+            bundlesMap = {},
+            requireCounter = 1,
+            unnormalizedCounter = 1;
+
+        /**
+         * Trims the . and .. from an array of path segments.
+         * It will keep a leading path segment if a .. will become
+         * the first path segment, to help with module name lookups,
+         * which act like paths, but can be remapped. But the end result,
+         * all paths that use this function should look normalized.
+         * NOTE: this method MODIFIES the input array.
+         * @param {Array} ary the array of path segments.
+         */
+        function trimDots(ary) {
+            var i, part;
+            for (i = 0; i < ary.length; i++) {
+                part = ary[i];
+                if (part === '.') {
+                    ary.splice(i, 1);
+                    i -= 1;
+                } else if (part === '..') {
+                    // If at the start, or previous value is still ..,
+                    // keep them so that when converted to a path it may
+                    // still work when converted to a path, even though
+                    // as an ID it is less than ideal. In larger point
+                    // releases, may be better to just kick out an error.
+                    if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') {
+                        continue;
+                    } else if (i > 0) {
+                        ary.splice(i - 1, 2);
+                        i -= 2;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Given a relative module name, like ./something, normalize it to
+         * a real name that can be mapped to a path.
+         * @param {String} name the relative name
+         * @param {String} baseName a real name that the name arg is relative
+         * to.
+         * @param {Boolean} applyMap apply the map config to the value. Should
+         * only be done if this normalization is for a dependency ID.
+         * @returns {String} normalized name
+         */
+        function normalize(name, baseName, applyMap) {
+            var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
+                foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
+                baseParts = (baseName && baseName.split('/')),
+                map = config.map,
+                starMap = map && map['*'];
+
+            //Adjust any relative paths.
+            if (name) {
+                name = name.split('/');
+                lastIndex = name.length - 1;
+
+                // If wanting node ID compatibility, strip .js from end
+                // of IDs. Have to do this here, and not in nameToUrl
+                // because node allows either .js or non .js to map
+                // to same file.
+                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+                }
+
+                // Starts with a '.' so need the baseName
+                if (name[0].charAt(0) === '.' && baseParts) {
+                    //Convert baseName to array, and lop off the last part,
+                    //so that . matches that 'directory' and not name of the baseName's
+                    //module. For instance, baseName of 'one/two/three', maps to
+                    //'one/two/three.js', but we want the directory, 'one/two' for
+                    //this normalization.
+                    normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
+                    name = normalizedBaseParts.concat(name);
+                }
+
+                trimDots(name);
+                name = name.join('/');
+            }
+
+            //Apply map config if available.
+            if (applyMap && map && (baseParts || starMap)) {
+                nameParts = name.split('/');
+
+                outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
+                    nameSegment = nameParts.slice(0, i).join('/');
+
+                    if (baseParts) {
+                        //Find the longest baseName segment match in the config.
+                        //So, do joins on the biggest to smallest lengths of baseParts.
+                        for (j = baseParts.length; j > 0; j -= 1) {
+                            mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
+
+                            //baseName segment has config, find if it has one for
+                            //this name.
+                            if (mapValue) {
+                                mapValue = getOwn(mapValue, nameSegment);
+                                if (mapValue) {
+                                    //Match, update name to the new value.
+                                    foundMap = mapValue;
+                                    foundI = i;
+                                    break outerLoop;
+                                }
+                            }
+                        }
+                    }
+
+                    //Check for a star map match, but just hold on to it,
+                    //if there is a shorter segment match later in a matching
+                    //config, then favor over this star map.
+                    if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
+                        foundStarMap = getOwn(starMap, nameSegment);
+                        starI = i;
+                    }
+                }
+
+                if (!foundMap && foundStarMap) {
+                    foundMap = foundStarMap;
+                    foundI = starI;
+                }
+
+                if (foundMap) {
+                    nameParts.splice(0, foundI, foundMap);
+                    name = nameParts.join('/');
+                }
+            }
+
+            // If the name points to a package's name, use
+            // the package main instead.
+            pkgMain = getOwn(config.pkgs, name);
+
+            return pkgMain ? pkgMain : name;
+        }
+
+        function removeScript(name) {
+            if (isBrowser) {
+                each(scripts(), function (scriptNode) {
+                    if (scriptNode.getAttribute('data-requiremodule') === name &&
+                            scriptNode.getAttribute('data-requirecontext') === context.contextName) {
+                        scriptNode.parentNode.removeChild(scriptNode);
+                        return true;
+                    }
+                });
+            }
+        }
+
+        function hasPathFallback(id) {
+            var pathConfig = getOwn(config.paths, id);
+            if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
+                //Pop off the first array value, since it failed, and
+                //retry
+                pathConfig.shift();
+                context.require.undef(id);
+
+                //Custom require that does not do map translation, since
+                //ID is "absolute", already mapped/resolved.
+                context.makeRequire(null, {
+                    skipMap: true
+                })([id]);
+
+                return true;
+            }
+        }
+
+        //Turns a plugin!resource to [plugin, resource]
+        //with the plugin being undefined if the name
+        //did not have a plugin prefix.
+        function splitPrefix(name) {
+            var prefix,
+                index = name ? name.indexOf('!') : -1;
+            if (index > -1) {
+                prefix = name.substring(0, index);
+                name = name.substring(index + 1, name.length);
+            }
+            return [prefix, name];
+        }
+
+        /**
+         * Creates a module mapping that includes plugin prefix, module
+         * name, and path. If parentModuleMap is provided it will
+         * also normalize the name via require.normalize()
+         *
+         * @param {String} name the module name
+         * @param {String} [parentModuleMap] parent module map
+         * for the module name, used to resolve relative names.
+         * @param {Boolean} isNormalized: is the ID already normalized.
+         * This is true if this call is done for a define() module ID.
+         * @param {Boolean} applyMap: apply the map config to the ID.
+         * Should only be true if this map is for a dependency.
+         *
+         * @returns {Object}
+         */
+        function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
+            var url, pluginModule, suffix, nameParts,
+                prefix = null,
+                parentName = parentModuleMap ? parentModuleMap.name : null,
+                originalName = name,
+                isDefine = true,
+                normalizedName = '';
+
+            //If no name, then it means it is a require call, generate an
+            //internal name.
+            if (!name) {
+                isDefine = false;
+                name = '_@r' + (requireCounter += 1);
+            }
+
+            nameParts = splitPrefix(name);
+            prefix = nameParts[0];
+            name = nameParts[1];
+
+            if (prefix) {
+                prefix = normalize(prefix, parentName, applyMap);
+                pluginModule = getOwn(defined, prefix);
+            }
+
+            //Account for relative paths if there is a base name.
+            if (name) {
+                if (prefix) {
+                    if (pluginModule && pluginModule.normalize) {
+                        //Plugin is loaded, use its normalize method.
+                        normalizedName = pluginModule.normalize(name, function (name) {
+                            return normalize(name, parentName, applyMap);
+                        });
+                    } else {
+                        // If nested plugin references, then do not try to
+                        // normalize, as it will not normalize correctly. This
+                        // places a restriction on resourceIds, and the longer
+                        // term solution is not to normalize until plugins are
+                        // loaded and all normalizations to allow for async
+                        // loading of a loader plugin. But for now, fixes the
+                        // common uses. Details in #1131
+                        normalizedName = name.indexOf('!') === -1 ?
+                                         normalize(name, parentName, applyMap) :
+                                         name;
+                    }
+                } else {
+                    //A regular module.
+                    normalizedName = normalize(name, parentName, applyMap);
+
+                    //Normalized name may be a plugin ID due to map config
+                    //application in normalize. The map config values must
+                    //already be normalized, so do not need to redo that part.
+                    nameParts = splitPrefix(normalizedName);
+                    prefix = nameParts[0];
+                    normalizedName = nameParts[1];
+                    isNormalized = true;
+
+                    url = context.nameToUrl(normalizedName);
+                }
+            }
+
+            //If the id is a plugin id that cannot be determined if it needs
+            //normalization, stamp it with a unique ID so two matching relative
+            //ids that may conflict can be separate.
+            suffix = prefix && !pluginModule && !isNormalized ?
+                     '_unnormalized' + (unnormalizedCounter += 1) :
+                     '';
+
+            return {
+                prefix: prefix,
+                name: normalizedName,
+                parentMap: parentModuleMap,
+                unnormalized: !!suffix,
+                url: url,
+                originalName: originalName,
+                isDefine: isDefine,
+                id: (prefix ?
+                        prefix + '!' + normalizedName :
+                        normalizedName) + suffix
+            };
+        }
+
+        function getModule(depMap) {
+            var id = depMap.id,
+                mod = getOwn(registry, id);
+
+            if (!mod) {
+                mod = registry[id] = new context.Module(depMap);
+            }
+
+            return mod;
+        }
+
+        function on(depMap, name, fn) {
+            var id = depMap.id,
+                mod = getOwn(registry, id);
+
+            if (hasProp(defined, id) &&
+                    (!mod || mod.defineEmitComplete)) {
+                if (name === 'defined') {
+                    fn(defined[id]);
+                }
+            } else {
+                mod = getModule(depMap);
+                if (mod.error && name === 'error') {
+                    fn(mod.error);
+                } else {
+                    mod.on(name, fn);
+                }
+            }
+        }
+
+        function onError(err, errback) {
+            var ids = err.requireModules,
+                notified = false;
+
+            if (errback) {
+                errback(err);
+            } else {
+                each(ids, function (id) {
+                    var mod = getOwn(registry, id);
+                    if (mod) {
+                        //Set error on module, so it skips timeout checks.
+                        mod.error = err;
+                        if (mod.events.error) {
+                            notified = true;
+                            mod.emit('error', err);
+                        }
+                    }
+                });
+
+                if (!notified) {
+                    req.onError(err);
+                }
+            }
+        }
+
+        /**
+         * Internal method to transfer globalQueue items to this context's
+         * defQueue.
+         */
+        function takeGlobalQueue() {
+            //Push all the globalDefQueue items into the context's defQueue
+            if (globalDefQueue.length) {
+                //Array splice in the values since the context code has a
+                //local var ref to defQueue, so cannot just reassign the one
+                //on context.
+                apsp.apply(defQueue,
+                           [defQueue.length, 0].concat(globalDefQueue));
+                globalDefQueue = [];
+            }
+        }
+
+        handlers = {
+            'require': function (mod) {
+                if (mod.require) {
+                    return mod.require;
+                } else {
+                    return (mod.require = context.makeRequire(mod.map));
+                }
+            },
+            'exports': function (mod) {
+                mod.usingExports = true;
+                if (mod.map.isDefine) {
+                    if (mod.exports) {
+                        return (defined[mod.map.id] = mod.exports);
+                    } else {
+                        return (mod.exports = defined[mod.map.id] = {});
+                    }
+                }
+            },
+            'module': function (mod) {
+                if (mod.module) {
+                    return mod.module;
+                } else {
+                    return (mod.module = {
+                        id: mod.map.id,
+                        uri: mod.map.url,
+                        config: function () {
+                            return  getOwn(config.config, mod.map.id) || {};
+                        },
+                        exports: mod.exports || (mod.exports = {})
+                    });
+                }
+            }
+        };
+
+        function cleanRegistry(id) {
+            //Clean up machinery used for waiting modules.
+            delete registry[id];
+            delete enabledRegistry[id];
+        }
+
+        function breakCycle(mod, traced, processed) {
+            var id = mod.map.id;
+
+            if (mod.error) {
+                mod.emit('error', mod.error);
+            } else {
+                traced[id] = true;
+                each(mod.depMaps, function (depMap, i) {
+                    var depId = depMap.id,
+                        dep = getOwn(registry, depId);
+
+                    //Only force things that have not completed
+                    //being defined, so still in the registry,
+                    //and only if it has not been matched up
+                    //in the module already.
+                    if (dep && !mod.depMatched[i] && !processed[depId]) {
+                        if (getOwn(traced, depId)) {
+                            mod.defineDep(i, defined[depId]);
+                            mod.check(); //pass false?
+                        } else {
+                            breakCycle(dep, traced, processed);
+                        }
+                    }
+                });
+                processed[id] = true;
+            }
+        }
+
+        function checkLoaded() {
+            var err, usingPathFallback,
+                waitInterval = config.waitSeconds * 1000,
+                //It is possible to disable the wait interval by using waitSeconds of 0.
+                expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
+                noLoads = [],
+                reqCalls = [],
+                stillLoading = false,
+                needCycleCheck = true;
+
+            //Do not bother if this call was a result of a cycle break.
+            if (inCheckLoaded) {
+                return;
+            }
+
+            inCheckLoaded = true;
+
+            //Figure out the state of all the modules.
+            eachProp(enabledRegistry, function (mod) {
+                var map = mod.map,
+                    modId = map.id;
+
+                //Skip things that are not enabled or in error state.
+                if (!mod.enabled) {
+                    return;
+                }
+
+                if (!map.isDefine) {
+                    reqCalls.push(mod);
+                }
+
+                if (!mod.error) {
+                    //If the module should be executed, and it has not
+                    //been inited and time is up, remember it.
+                    if (!mod.inited && expired) {
+                        if (hasPathFallback(modId)) {
+                            usingPathFallback = true;
+                            stillLoading = true;
+                        } else {
+                            noLoads.push(modId);
+                            removeScript(modId);
+                        }
+                    } else if (!mod.inited && mod.fetched && map.isDefine) {
+                        stillLoading = true;
+                        if (!map.prefix) {
+                            //No reason to keep looking for unfinished
+                            //loading. If the only stillLoading is a
+                            //plugin resource though, keep going,
+                            //because it may be that a plugin resource
+                            //is waiting on a non-plugin cycle.
+                            return (needCycleCheck = false);
+                        }
+                    }
+                }
+            });
+
+            if (expired && noLoads.length) {
+                //If wait time expired, throw error of unloaded modules.
+                err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
+                err.contextName = context.contextName;
+                return onError(err);
+            }
+
+            //Not expired, check for a cycle.
+            if (needCycleCheck) {
+                each(reqCalls, function (mod) {
+                    breakCycle(mod, {}, {});
+                });
+            }
+
+            //If still waiting on loads, and the waiting load is something
+            //other than a plugin resource, or there are still outstanding
+            //scripts, then just try back later.
+            if ((!expired || usingPathFallback) && stillLoading) {
+                //Something is still waiting to load. Wait for it, but only
+                //if a timeout is not already in effect.
+                if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
+                    checkLoadedTimeoutId = setTimeout(function () {
+                        checkLoadedTimeoutId = 0;
+                        checkLoaded();
+                    }, 50);
+                }
+            }
+
+            inCheckLoaded = false;
+        }
+
+        Module = function (map) {
+            this.events = getOwn(undefEvents, map.id) || {};
+            this.map = map;
+            this.shim = getOwn(config.shim, map.id);
+            this.depExports = [];
+            this.depMaps = [];
+            this.depMatched = [];
+            this.pluginMaps = {};
+            this.depCount = 0;
+
+            /* this.exports this.factory
+               this.depMaps = [],
+               this.enabled, this.fetched
+            */
+        };
+
+        Module.prototype = {
+            init: function (depMaps, factory, errback, options) {
+                options = options || {};
+
+                //Do not do more inits if already done. Can happen if there
+                //are multiple define calls for the same module. That is not
+                //a normal, common case, but it is also not unexpected.
+                if (this.inited) {
+                    return;
+                }
+
+                this.factory = factory;
+
+                if (errback) {
+                    //Register for errors on this module.
+                    this.on('error', errback);
+                } else if (this.events.error) {
+                    //If no errback already, but there are error listeners
+                    //on this module, set up an errback to pass to the deps.
+                    errback = bind(this, function (err) {
+                        this.emit('error', err);
+                    });
+                }
+
+                //Do a copy of the dependency array, so that
+                //source inputs are not modified. For example
+                //"shim" deps are passed in here directly, and
+                //doing a direct modification of the depMaps array
+                //would affect that config.
+                this.depMaps = depMaps && depMaps.slice(0);
+
+                this.errback = errback;
+
+                //Indicate this module has be initialized
+                this.inited = true;
+
+                this.ignore = options.ignore;
+
+                //Could have option to init this module in enabled mode,
+                //or could have been previously marked as enabled. However,
+                //the dependencies are not known until init is called. So
+                //if enabled previously, now trigger dependencies as enabled.
+                if (options.enabled || this.enabled) {
+                    //Enable this module and dependencies.
+                    //Will call this.check()
+                    this.enable();
+                } else {
+                    this.check();
+                }
+            },
+
+            defineDep: function (i, depExports) {
+                //Because of cycles, defined callback for a given
+                //export can be called more than once.
+                if (!this.depMatched[i]) {
+                    this.depMatched[i] = true;
+                    this.depCount -= 1;
+                    this.depExports[i] = depExports;
+                }
+            },
+
+            fetch: function () {
+                if (this.fetched) {
+                    return;
+                }
+                this.fetched = true;
+
+                context.startTime = (new Date()).getTime();
+
+                var map = this.map;
+
+                //If the manager is for a plugin managed resource,
+                //ask the plugin to load it now.
+                if (this.shim) {
+                    context.makeRequire(this.map, {
+                        enableBuildCallback: true
+                    })(this.shim.deps || [], bind(this, function () {
+                        return map.prefix ? this.callPlugin() : this.load();
+                    }));
+                } else {
+                    //Regular dependency.
+                    return map.prefix ? this.callPlugin() : this.load();
+                }
+            },
+
+            load: function () {
+                var url = this.map.url;
+
+                //Regular dependency.
+                if (!urlFetched[url]) {
+                    urlFetched[url] = true;
+                    context.load(this.map.id, url);
+                }
+            },
+
+            /**
+             * Checks if the module is ready to define itself, and if so,
+             * define it.
+             */
+            check: function () {
+                if (!this.enabled || this.enabling) {
+                    return;
+                }
+
+                var err, cjsModule,
+                    id = this.map.id,
+                    depExports = this.depExports,
+                    exports = this.exports,
+                    factory = this.factory;
+
+                if (!this.inited) {
+                    this.fetch();
+                } else if (this.error) {
+                    this.emit('error', this.error);
+                } else if (!this.defining) {
+                    //The factory could trigger another require call
+                    //that would result in checking this module to
+                    //define itself again. If already in the process
+                    //of doing that, skip this work.
+                    this.defining = true;
+
+                    if (this.depCount < 1 && !this.defined) {
+                        if (isFunction(factory)) {
+                            //If there is an error listener, favor passing
+                            //to that instead of throwing an error. However,
+                            //only do it for define()'d  modules. require
+                            //errbacks should not be called for failures in
+                            //their callbacks (#699). However if a global
+                            //onError is set, use that.
+                            if ((this.events.error && this.map.isDefine) ||
+                                req.onError !== defaultOnError) {
+                                try {
+                                    exports = context.execCb(id, factory, depExports, exports);
+                                } catch (e) {
+                                    err = e;
+                                }
+                            } else {
+                                exports = context.execCb(id, factory, depExports, exports);
+                            }
+
+                            // Favor return value over exports. If node/cjs in play,
+                            // then will not have a return value anyway. Favor
+                            // module.exports assignment over exports object.
+                            if (this.map.isDefine && exports === undefined) {
+                                cjsModule = this.module;
+                                if (cjsModule) {
+                                    exports = cjsModule.exports;
+                                } else if (this.usingExports) {
+                                    //exports already set the defined value.
+                                    exports = this.exports;
+                                }
+                            }
+
+                            if (err) {
+                                err.requireMap = this.map;
+                                err.requireModules = this.map.isDefine ? [this.map.id] : null;
+                                err.requireType = this.map.isDefine ? 'define' : 'require';
+                                return onError((this.error = err));
+                            }
+
+                        } else {
+                            //Just a literal value
+                            exports = factory;
+                        }
+
+                        this.exports = exports;
+
+                        if (this.map.isDefine && !this.ignore) {
+                            defined[id] = exports;
+
+                            if (req.onResourceLoad) {
+                                req.onResourceLoad(context, this.map, this.depMaps);
+                            }
+                        }
+
+                        //Clean up
+                        cleanRegistry(id);
+
+                        this.defined = true;
+                    }
+
+                    //Finished the define stage. Allow calling check again
+                    //to allow define notifications below in the case of a
+                    //cycle.
+                    this.defining = false;
+
+                    if (this.defined && !this.defineEmitted) {
+                        this.defineEmitted = true;
+                        this.emit('defined', this.exports);
+                        this.defineEmitComplete = true;
+                    }
+
+                }
+            },
+
+            callPlugin: function () {
+                var map = this.map,
+                    id = map.id,
+                    //Map already normalized the prefix.
+                    pluginMap = makeModuleMap(map.prefix);
+
+                //Mark this as a dependency for this plugin, so it
+                //can be traced for cycles.
+                this.depMaps.push(pluginMap);
+
+                on(pluginMap, 'defined', bind(this, function (plugin) {
+                    var load, normalizedMap, normalizedMod,
+                        bundleId = getOwn(bundlesMap, this.map.id),
+                        name = this.map.name,
+                        parentName = this.map.parentMap ? this.map.parentMap.name : null,
+                        localRequire = context.makeRequire(map.parentMap, {
+                            enableBuildCallback: true
+                        });
+
+                    //If current map is not normalized, wait for that
+                    //normalized name to load instead of continuing.
+                    if (this.map.unnormalized) {
+                        //Normalize the ID if the plugin allows it.
+                        if (plugin.normalize) {
+                            name = plugin.normalize(name, function (name) {
+                                return normalize(name, parentName, true);
+                            }) || '';
+                        }
+
+                        //prefix and name should already be normalized, no need
+                        //for applying map config again either.
+                        normalizedMap = makeModuleMap(map.prefix + '!' + name,
+                                                      this.map.parentMap);
+                        on(normalizedMap,
+                            'defined', bind(this, function (value) {
+                                this.init([], function () { return value; }, null, {
+                                    enabled: true,
+                                    ignore: true
+                                });
+                            }));
+
+                        normalizedMod = getOwn(registry, normalizedMap.id);
+                        if (normalizedMod) {
+                            //Mark this as a dependency for this plugin, so it
+                            //can be traced for cycles.
+                            this.depMaps.push(normalizedMap);
+
+                            if (this.events.error) {
+                                normalizedMod.on('error', bind(this, function (err) {
+                                    this.emit('error', err);
+                                }));
+                            }
+                            normalizedMod.enable();
+                        }
+
+                        return;
+                    }
+
+                    //If a paths config, then just load that file instead to
+                    //resolve the plugin, as it is built into that paths layer.
+                    if (bundleId) {
+                        this.map.url = context.nameToUrl(bundleId);
+                        this.load();
+                        return;
+                    }
+
+                    load = bind(this, function (value) {
+                        this.init([], function () { return value; }, null, {
+                            enabled: true
+                        });
+                    });
+
+                    load.error = bind(this, function (err) {
+                        this.inited = true;
+                        this.error = err;
+                        err.requireModules = [id];
+
+                        //Remove temp unnormalized modules for this module,
+                        //since they will never be resolved otherwise now.
+                        eachProp(registry, function (mod) {
+                            if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
+                                cleanRegistry(mod.map.id);
+                            }
+                        });
+
+                        onError(err);
+                    });
+
+                    //Allow plugins to load other code without having to know the
+                    //context or how to 'complete' the load.
+                    load.fromText = bind(this, function (text, textAlt) {
+                        /*jslint evil: true */
+                        var moduleName = map.name,
+                            moduleMap = makeModuleMap(moduleName),
+                            hasInteractive = useInteractive;
+
+                        //As of 2.1.0, support just passing the text, to reinforce
+                        //fromText only being called once per resource. Still
+                        //support old style of passing moduleName but discard
+                        //that moduleName in favor of the internal ref.
+                        if (textAlt) {
+                            text = textAlt;
+                        }
+
+                        //Turn off interactive script matching for IE for any define
+                        //calls in the text, then turn it back on at the end.
+                        if (hasInteractive) {
+                            useInteractive = false;
+                        }
+
+                        //Prime the system by creating a module instance for
+                        //it.
+                        getModule(moduleMap);
+
+                        //Transfer any config to this other module.
+                        if (hasProp(config.config, id)) {
+                            config.config[moduleName] = config.config[id];
+                        }
+
+                        try {
+                            req.exec(text);
+                        } catch (e) {
+                            return onError(makeError('fromtexteval',
+                                             'fromText eval for ' + id +
+                                            ' failed: ' + e,
+                                             e,
+                                             [id]));
+                        }
+
+                        if (hasInteractive) {
+                            useInteractive = true;
+                        }
+
+                        //Mark this as a dependency for the plugin
+                        //resource
+                        this.depMaps.push(moduleMap);
+
+                        //Support anonymous modules.
+                        context.completeLoad(moduleName);
+
+                        //Bind the value of that module to the value for this
+                        //resource ID.
+                        localRequire([moduleName], load);
+                    });
+
+                    //Use parentName here since the plugin's name is not reliable,
+                    //could be some weird string with no path that actually wants to
+                    //reference the parentName's path.
+                    plugin.load(map.name, localRequire, load, config);
+                }));
+
+                context.enable(pluginMap, this);
+                this.pluginMaps[pluginMap.id] = pluginMap;
+            },
+
+            enable: function () {
+                enabledRegistry[this.map.id] = this;
+                this.enabled = true;
+
+                //Set flag mentioning that the module is enabling,
+                //so that immediate calls to the defined callbacks
+                //for dependencies do not trigger inadvertent load
+                //with the depCount still being zero.
+                this.enabling = true;
+
+                //Enable each dependency
+                each(this.depMaps, bind(this, function (depMap, i) {
+                    var id, mod, handler;
+
+                    if (typeof depMap === 'string') {
+                        //Dependency needs to be converted to a depMap
+                        //and wired up to this module.
+                        depMap = makeModuleMap(depMap,
+                                               (this.map.isDefine ? this.map : this.map.parentMap),
+                                               false,
+                                               !this.skipMap);
+                        this.depMaps[i] = depMap;
+
+                        handler = getOwn(handlers, depMap.id);
+
+                        if (handler) {
+                            this.depExports[i] = handler(this);
+                            return;
+                        }
+
+                        this.depCount += 1;
+
+                        on(depMap, 'defined', bind(this, function (depExports) {
+                            this.defineDep(i, depExports);
+                            this.check();
+                        }));
+
+                        if (this.errback) {
+                            on(depMap, 'error', bind(this, this.errback));
+                        } else if (this.events.error) {
+                            // No direct errback on this module, but something
+                            // else is listening for errors, so be sure to
+                            // propagate the error correctly.
+                            on(depMap, 'error', bind(this, function(err) {
+                                this.emit('error', err);
+                            }));
+                        }
+                    }
+
+                    id = depMap.id;
+                    mod = registry[id];
+
+                    //Skip special modules like 'require', 'exports', 'module'
+                    //Also, don't call enable if it is already enabled,
+                    //important in circular dependency cases.
+                    if (!hasProp(handlers, id) && mod && !mod.enabled) {
+                        context.enable(depMap, this);
+                    }
+                }));
+
+                //Enable each plugin that is used in
+                //a dependency
+                eachProp(this.pluginMaps, bind(this, function (pluginMap) {
+                    var mod = getOwn(registry, pluginMap.id);
+                    if (mod && !mod.enabled) {
+                        context.enable(pluginMap, this);
+                    }
+                }));
+
+                this.enabling = false;
+
+                this.check();
+            },
+
+            on: function (name, cb) {
+                var cbs = this.events[name];
+                if (!cbs) {
+                    cbs = this.events[name] = [];
+                }
+                cbs.push(cb);
+            },
+
+            emit: function (name, evt) {
+                each(this.events[name], function (cb) {
+                    cb(evt);
+                });
+                if (name === 'error') {
+                    //Now that the error handler was triggered, remove
+                    //the listeners, since this broken Module instance
+                    //can stay around for a while in the registry.
+                    delete this.events[name];
+                }
+            }
+        };
+
+        function callGetModule(args) {
+            //Skip modules already defined.
+            if (!hasProp(defined, args[0])) {
+                getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
+            }
+        }
+
+        function removeListener(node, func, name, ieName) {
+            //Favor detachEvent because of IE9
+            //issue, see attachEvent/addEventListener comment elsewhere
+            //in this file.
+            if (node.detachEvent && !isOpera) {
+                //Probably IE. If not it will throw an error, which will be
+                //useful to know.
+                if (ieName) {
+                    node.detachEvent(ieName, func);
+                }
+            } else {
+                node.removeEventListener(name, func, false);
+            }
+        }
+
+        /**
+         * Given an event from a script node, get the requirejs info from it,
+         * and then removes the event listeners on the node.
+         * @param {Event} evt
+         * @returns {Object}
+         */
+        function getScriptData(evt) {
+            //Using currentTarget instead of target for Firefox 2.0's sake. Not
+            //all old browsers will be supported, but this one was easy enough
+            //to support and still makes sense.
+            var node = evt.currentTarget || evt.srcElement;
+
+            //Remove the listeners once here.
+            removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
+            removeListener(node, context.onScriptError, 'error');
+
+            return {
+                node: node,
+                id: node && node.getAttribute('data-requiremodule')
+            };
+        }
+
+        function intakeDefines() {
+            var args;
+
+            //Any defined modules in the global queue, intake them now.
+            takeGlobalQueue();
+
+            //Make sure any remaining defQueue items get properly processed.
+            while (defQueue.length) {
+                args = defQueue.shift();
+                if (args[0] === null) {
+                    return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
+                } else {
+                    //args are id, deps, factory. Should be normalized by the
+                    //define() function.
+                    callGetModule(args);
+                }
+            }
+        }
+
+        context = {
+            config: config,
+            contextName: contextName,
+            registry: registry,
+            defined: defined,
+            urlFetched: urlFetched,
+            defQueue: defQueue,
+            Module: Module,
+            makeModuleMap: makeModuleMap,
+            nextTick: req.nextTick,
+            onError: onError,
+
+            /**
+             * Set a configuration for the context.
+             * @param {Object} cfg config object to integrate.
+             */
+            configure: function (cfg) {
+                //Make sure the baseUrl ends in a slash.
+                if (cfg.baseUrl) {
+                    if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
+                        cfg.baseUrl += '/';
+                    }
+                }
+
+                //Save off the paths since they require special processing,
+                //they are additive.
+                var shim = config.shim,
+                    objs = {
+                        paths: true,
+                        bundles: true,
+                        config: true,
+                        map: true
+                    };
+
+                eachProp(cfg, function (value, prop) {
+                    if (objs[prop]) {
+                        if (!config[prop]) {
+                            config[prop] = {};
+                        }
+                        mixin(config[prop], value, true, true);
+                    } else {
+                        config[prop] = value;
+                    }
+                });
+
+                //Reverse map the bundles
+                if (cfg.bundles) {
+                    eachProp(cfg.bundles, function (value, prop) {
+                        each(value, function (v) {
+                            if (v !== prop) {
+                                bundlesMap[v] = prop;
+                            }
+                        });
+                    });
+                }
+
+                //Merge shim
+                if (cfg.shim) {
+                    eachProp(cfg.shim, function (value, id) {
+                        //Normalize the structure
+                        if (isArray(value)) {
+                            value = {
+                                deps: value
+                            };
+                        }
+                        if ((value.exports || value.init) && !value.exportsFn) {
+                            value.exportsFn = context.makeShimExports(value);
+                        }
+                        shim[id] = value;
+                    });
+                    config.shim = shim;
+                }
+
+                //Adjust packages if necessary.
+                if (cfg.packages) {
+                    each(cfg.packages, function (pkgObj) {
+                        var location, name;
+
+                        pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
+
+                        name = pkgObj.name;
+                        location = pkgObj.location;
+                        if (location) {
+                            config.paths[name] = pkgObj.location;
+                        }
+
+                        //Save pointer to main module ID for pkg name.
+                        //Remove leading dot in main, so main paths are normalized,
+                        //and remove any trailing .js, since different package
+                        //envs have different conventions: some use a module name,
+                        //some use a file name.
+                        config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
+                                     .replace(currDirRegExp, '')
+                                     .replace(jsSuffixRegExp, '');
+                    });
+                }
+
+                //If there are any "waiting to execute" modules in the registry,
+                //update the maps for them, since their info, like URLs to load,
+                //may have changed.
+                eachProp(registry, function (mod, id) {
+                    //If module already has init called, since it is too
+                    //late to modify them, and ignore unnormalized ones
+                    //since they are transient.
+                    if (!mod.inited && !mod.map.unnormalized) {
+                        mod.map = makeModuleMap(id);
+                    }
+                });
+
+                //If a deps array or a config callback is specified, then call
+                //require with those args. This is useful when require is defined as a
+                //config object before require.js is loaded.
+                if (cfg.deps || cfg.callback) {
+                    context.require(cfg.deps || [], cfg.callback);
+                }
+            },
+
+            makeShimExports: function (value) {
+                function fn() {
+                    var ret;
+                    if (value.init) {
+                        ret = value.init.apply(global, arguments);
+                    }
+                    return ret || (value.exports && getGlobal(value.exports));
+                }
+                return fn;
+            },
+
+            makeRequire: function (relMap, options) {
+                options = options || {};
+
+                function localRequire(deps, callback, errback) {
+                    var id, map, requireMod;
+
+                    if (options.enableBuildCallback && callback && isFunction(callback)) {
+                        callback.__requireJsBuild = true;
+                    }
+
+                    if (typeof deps === 'string') {
+                        if (isFunction(callback)) {
+                            //Invalid call
+                            return onError(makeError('requireargs', 'Invalid require call'), errback);
+                        }
+
+                        //If require|exports|module are requested, get the
+                        //value for them from the special handlers. Caveat:
+                        //this only works while module is being defined.
+                        if (relMap && hasProp(handlers, deps)) {
+                            return handlers[deps](registry[relMap.id]);
+                        }
+
+                        //Synchronous access to one module. If require.get is
+                        //available (as in the Node adapter), prefer that.
+                        if (req.get) {
+                            return req.get(context, deps, relMap, localRequire);
+                        }
+
+                        //Normalize module name, if it contains . or ..
+                        map = makeModuleMap(deps, relMap, false, true);
+                        id = map.id;
+
+                        if (!hasProp(defined, id)) {
+                            return onError(makeError('notloaded', 'Module name "' +
+                                        id +
+                                        '" has not been loaded yet for context: ' +
+                                        contextName +
+                                        (relMap ? '' : '. Use require([])')));
+                        }
+                        return defined[id];
+                    }
+
+                    //Grab defines waiting in the global queue.
+                    intakeDefines();
+
+                    //Mark all the dependencies as needing to be loaded.
+                    context.nextTick(function () {
+                        //Some defines could have been added since the
+                        //require call, collect them.
+                        intakeDefines();
+
+                        requireMod = getModule(makeModuleMap(null, relMap));
+
+                        //Store if map config should be applied to this require
+                        //call for dependencies.
+                        requireMod.skipMap = options.skipMap;
+
+                        requireMod.init(deps, callback, errback, {
+                            enabled: true
+                        });
+
+                        checkLoaded();
+                    });
+
+                    return localRequire;
+                }
+
+                mixin(localRequire, {
+                    isBrowser: isBrowser,
+
+                    /**
+                     * Converts a module name + .extension into an URL path.
+                     * *Requires* the use of a module name. It does not support using
+                     * plain URLs like nameToUrl.
+                     */
+                    toUrl: function (moduleNamePlusExt) {
+                        var ext,
+                            index = moduleNamePlusExt.lastIndexOf('.'),
+                            segment = moduleNamePlusExt.split('/')[0],
+                            isRelative = segment === '.' || segment === '..';
+
+                        //Have a file extension alias, and it is not the
+                        //dots from a relative path.
+                        if (index !== -1 && (!isRelative || index > 1)) {
+                            ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
+                            moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
+                        }
+
+                        return context.nameToUrl(normalize(moduleNamePlusExt,
+                                                relMap && relMap.id, true), ext,  true);
+                    },
+
+                    defined: function (id) {
+                        return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
+                    },
+
+                    specified: function (id) {
+                        id = makeModuleMap(id, relMap, false, true).id;
+                        return hasProp(defined, id) || hasProp(registry, id);
+                    }
+                });
+
+                //Only allow undef on top level require calls
+                if (!relMap) {
+                    localRequire.undef = function (id) {
+                        //Bind any waiting define() calls to this context,
+                        //fix for #408
+                        takeGlobalQueue();
+
+                        var map = makeModuleMap(id, relMap, true),
+                            mod = getOwn(registry, id);
+
+                        removeScript(id);
+
+                        delete defined[id];
+                        delete urlFetched[map.url];
+                        delete undefEvents[id];
+
+                        //Clean queued defines too. Go backwards
+                        //in array so that the splices do not
+                        //mess up the iteration.
+                        eachReverse(defQueue, function(args, i) {
+                            if(args[0] === id) {
+                                defQueue.splice(i, 1);
+                            }
+                        });
+
+                        if (mod) {
+                            //Hold on to listeners in case the
+                            //module will be attempted to be reloaded
+                            //using a different config.
+                            if (mod.events.defined) {
+                                undefEvents[id] = mod.events;
+                            }
+
+                            cleanRegistry(id);
+                        }
+                    };
+                }
+
+                return localRequire;
+            },
+
+            /**
+             * Called to enable a module if it is still in the registry
+             * awaiting enablement. A second arg, parent, the parent module,
+             * is passed in for context, when this method is overridden by
+             * the optimizer. Not shown here to keep code compact.
+             */
+            enable: function (depMap) {
+                var mod = getOwn(registry, depMap.id);
+                if (mod) {
+                    getModule(depMap).enable();
+                }
+            },
+
+            /**
+             * Internal method used by environment adapters to complete a load event.
+             * A load event could be a script load or just a load pass from a synchronous
+             * load call.
+             * @param {String} moduleName the name of the module to potentially complete.
+             */
+            completeLoad: function (moduleName) {
+                var found, args, mod,
+                    shim = getOwn(config.shim, moduleName) || {},
+                    shExports = shim.exports;
+
+                takeGlobalQueue();
+
+                while (defQueue.length) {
+                    args = defQueue.shift();
+                    if (args[0] === null) {
+                        args[0] = moduleName;
+                        //If already found an anonymous module and bound it
+                        //to this name, then this is some other anon module
+                        //waiting for its completeLoad to fire.
+                        if (found) {
+                            break;
+                        }
+                        found = true;
+                    } else if (args[0] === moduleName) {
+                        //Found matching define call for this script!
+                        found = true;
+                    }
+
+                    callGetModule(args);
+                }
+
+                //Do this after the cycle of callGetModule in case the result
+                //of those calls/init calls changes the registry.
+                mod = getOwn(registry, moduleName);
+
+                if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
+                    if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
+                        if (hasPathFallback(moduleName)) {
+                            return;
+                        } else {
+                            return onError(makeError('nodefine',
+                                             'No define call for ' + moduleName,
+                                             null,
+                                             [moduleName]));
+                        }
+                    } else {
+                        //A script that does not call define(), so just simulate
+                        //the call for it.
+                        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
+                    }
+                }
+
+                checkLoaded();
+            },
+
+            /**
+             * Converts a module name to a file path. Supports cases where
+             * moduleName may actually be just an URL.
+             * Note that it **does not** call normalize on the moduleName,
+             * it is assumed to have already been normalized. This is an
+             * internal API, not a public one. Use toUrl for the public API.
+             */
+            nameToUrl: function (moduleName, ext, skipExt) {
+                var paths, syms, i, parentModule, url,
+                    parentPath, bundleId,
+                    pkgMain = getOwn(config.pkgs, moduleName);
+
+                if (pkgMain) {
+                    moduleName = pkgMain;
+                }
+
+                bundleId = getOwn(bundlesMap, moduleName);
+
+                if (bundleId) {
+                    return context.nameToUrl(bundleId, ext, skipExt);
+                }
+
+                //If a colon is in the URL, it indicates a protocol is used and it is just
+                //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
+                //or ends with .js, then assume the user meant to use an url and not a module id.
+                //The slash is important for protocol-less URLs as well as full paths.
+                if (req.jsExtRegExp.test(moduleName)) {
+                    //Just a plain path, not module name lookup, so just return it.
+                    //Add extension if it is included. This is a bit wonky, only non-.js things pass
+                    //an extension, this method probably needs to be reworked.
+                    url = moduleName + (ext || '');
+                } else {
+                    //A module that needs to be converted to a path.
+                    paths = config.paths;
+
+                    syms = moduleName.split('/');
+                    //For each module name segment, see if there is a path
+                    //registered for it. Start with most specific name
+                    //and work up from it.
+                    for (i = syms.length; i > 0; i -= 1) {
+                        parentModule = syms.slice(0, i).join('/');
+
+                        parentPath = getOwn(paths, parentModule);
+                        if (parentPath) {
+                            //If an array, it means there are a few choices,
+                            //Choose the one that is desired
+                            if (isArray(parentPath)) {
+                                parentPath = parentPath[0];
+                            }
+                            syms.splice(0, i, parentPath);
+                            break;
+                        }
+                    }
+
+                    //Join the path parts together, then figure out if baseUrl is needed.
+                    url = syms.join('/');
+                    url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js'));
+                    url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
+                }
+
+                return config.urlArgs ? url +
+                                        ((url.indexOf('?') === -1 ? '?' : '&') +
+                                         config.urlArgs) : url;
+            },
+
+            //Delegates to req.load. Broken out as a separate function to
+            //allow overriding in the optimizer.
+            load: function (id, url) {
+                req.load(context, id, url);
+            },
+
+            /**
+             * Executes a module callback function. Broken out as a separate function
+             * solely to allow the build system to sequence the files in the built
+             * layer in the right sequence.
+             *
+             * @private
+             */
+            execCb: function (name, callback, args, exports) {
+                return callback.apply(exports, args);
+            },
+
+            /**
+             * callback for script loads, used to check status of loading.
+             *
+             * @param {Event} evt the event from the browser for the script
+             * that was loaded.
+             */
+            onScriptLoad: function (evt) {
+                //Using currentTarget instead of target for Firefox 2.0's sake. Not
+                //all old browsers will be supported, but this one was easy enough
+                //to support and still makes sense.
+                if (evt.type === 'load' ||
+                        (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
+                    //Reset interactive script so a script node is not held onto for
+                    //to long.
+                    interactiveScript = null;
+
+                    //Pull out the name of the module and the context.
+                    var data = getScriptData(evt);
+                    context.completeLoad(data.id);
+                }
+            },
+
+            /**
+             * Callback for script errors.
+             */
+            onScriptError: function (evt) {
+                var data = getScriptData(evt);
+                if (!hasPathFallback(data.id)) {
+                    return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
+                }
+            }
+        };
+
+        context.require = context.makeRequire();
+        return context;
+    }
+
+    /**
+     * Main entry point.
+     *
+     * If the only argument to require is a string, then the module that
+     * is represented by that string is fetched for the appropriate context.
+     *
+     * If the first argument is an array, then it will be treated as an array
+     * of dependency string names to fetch. An optional function callback can
+     * be specified to execute when all of those dependencies are available.
+     *
+     * Make a local req variable to help Caja compliance (it assumes things
+     * on a require that are not standardized), and to give a short
+     * name for minification/local scope use.
+     */
+    req = requirejs = function (deps, callback, errback, optional) {
+
+        //Find the right context, use default
+        var context, config,
+            contextName = defContextName;
+
+        // Determine if have config object in the call.
+        if (!isArray(deps) && typeof deps !== 'string') {
+            // deps is a config object
+            config = deps;
+            if (isArray(callback)) {
+                // Adjust args if there are dependencies
+                deps = callback;
+                callback = errback;
+                errback = optional;
+            } else {
+                deps = [];
+            }
+        }
+
+        if (config && config.context) {
+            contextName = config.context;
+        }
+
+        context = getOwn(contexts, contextName);
+        if (!context) {
+            context = contexts[contextName] = req.s.newContext(contextName);
+        }
+
+        if (config) {
+            context.configure(config);
+        }
+
+        return context.require(deps, callback, errback);
+    };
+
+    /**
+     * Support require.config() to make it easier to cooperate with other
+     * AMD loaders on globally agreed names.
+     */
+    req.config = function (config) {
+        return req(config);
+    };
+
+    /**
+     * Execute something after the current tick
+     * of the event loop. Override for other envs
+     * that have a better solution than setTimeout.
+     * @param  {Function} fn function to execute later.
+     */
+    req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
+        setTimeout(fn, 4);
+    } : function (fn) { fn(); };
+
+    /**
+     * Export require as a global, but only if it does not already exist.
+     */
+    if (!require) {
+        require = req;
+    }
+
+    req.version = version;
+
+    //Used to filter out dependencies that are already paths.
+    req.jsExtRegExp = /^\/|:|\?|\.js$/;
+    req.isBrowser = isBrowser;
+    s = req.s = {
+        contexts: contexts,
+        newContext: newContext
+    };
+
+    //Create default context.
+    req({});
+
+    //Exports some context-sensitive methods on global require.
+    each([
+        'toUrl',
+        'undef',
+        'defined',
+        'specified'
+    ], function (prop) {
+        //Reference from contexts instead of early binding to default context,
+        //so that during builds, the latest instance of the default context
+        //with its config gets used.
+        req[prop] = function () {
+            var ctx = contexts[defContextName];
+            return ctx.require[prop].apply(ctx, arguments);
+        };
+    });
+
+    if (isBrowser) {
+        head = s.head = document.getElementsByTagName('head')[0];
+        //If BASE tag is in play, using appendChild is a problem for IE6.
+        //When that browser dies, this can be removed. Details in this jQuery bug:
+        //http://dev.jquery.com/ticket/2709
+        baseElement = document.getElementsByTagName('base')[0];
+        if (baseElement) {
+            head = s.head = baseElement.parentNode;
+        }
+    }
+
+    /**
+     * Any errors that require explicitly generates will be passed to this
+     * function. Intercept/override it if you want custom error handling.
+     * @param {Error} err the error object.
+     */
+    req.onError = defaultOnError;
+
+    /**
+     * Creates the node for the load command. Only used in browser envs.
+     */
+    req.createNode = function (config, moduleName, url) {
+        var node = config.xhtml ?
+                document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
+                document.createElement('script');
+        node.type = config.scriptType || 'text/javascript';
+        node.charset = 'utf-8';
+        node.async = true;
+        return node;
+    };
+
+    /**
+     * Does the request to load a module for the browser case.
+     * Make this a separate function to allow other environments
+     * to override it.
+     *
+     * @param {Object} context the require context to find state.
+     * @param {String} moduleName the name of the module.
+     * @param {Object} url the URL to the module.
+     */
+    req.load = function (context, moduleName, url) {
+        var config = (context && context.config) || {},
+            node;
+        if (isBrowser) {
+            //In the browser so use a script tag
+            node = req.createNode(config, moduleName, url);
+
+            node.setAttribute('data-requirecontext', context.contextName);
+            node.setAttribute('data-requiremodule', moduleName);
+
+            //Set up load listener. Test attachEvent first because IE9 has
+            //a subtle issue in its addEventListener and script onload firings
+            //that do not match the behavior of all other browsers with
+            //addEventListener support, which fire the onload event for a
+            //script right after the script execution. See:
+            //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
+            //UNFORTUNATELY Opera implements attachEvent but does not follow the script
+            //script execution mode.
+            if (node.attachEvent &&
+                    //Check if node.attachEvent is artificially added by custom script or
+                    //natively supported by browser
+                    //read https://github.com/jrburke/requirejs/issues/187
+                    //if we can NOT find [native code] then it must NOT natively supported.
+                    //in IE8, node.attachEvent does not have toString()
+                    //Note the test for "[native code" with no closing brace, see:
+                    //https://github.com/jrburke/requirejs/issues/273
+                    !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
+                    !isOpera) {
+                //Probably IE. IE (at least 6-8) do not fire
+                //script onload right after executing the script, so
+                //we cannot tie the anonymous define call to a name.
+                //However, IE reports the script as being in 'interactive'
+                //readyState at the time of the define call.
+                useInteractive = true;
+
+                node.attachEvent('onreadystatechange', context.onScriptLoad);
+                //It would be great to add an error handler here to catch
+                //404s in IE9+. However, onreadystatechange will fire before
+                //the error handler, so that does not help. If addEventListener
+                //is used, then IE will fire error before load, but we cannot
+                //use that pathway given the connect.microsoft.com issue
+                //mentioned above about not doing the 'script execute,
+                //then fire the script load event listener before execute
+                //next script' that other browsers do.
+                //Best hope: IE10 fixes the issues,
+                //and then destroys all installs of IE 6-9.
+                //node.attachEvent('onerror', context.onScriptError);
+            } else {
+                node.addEventListener('load', context.onScriptLoad, false);
+                node.addEventListener('error', context.onScriptError, false);
+            }
+            node.src = url;
+
+            //For some cache cases in IE 6-8, the script executes before the end
+            //of the appendChild execution, so to tie an anonymous define
+            //call to the module name (which is stored on the node), hold on
+            //to a reference to this node, but clear after the DOM insertion.
+            currentlyAddingScript = node;
+            if (baseElement) {
+                head.insertBefore(node, baseElement);
+            } else {
+                head.appendChild(node);
+            }
+            currentlyAddingScript = null;
+
+            return node;
+        } else if (isWebWorker) {
+            try {
+                //In a web worker, use importScripts. This is not a very
+                //efficient use of importScripts, importScripts will block until
+                //its script is downloaded and evaluated. However, if web workers
+                //are in play, the expectation that a build has been done so that
+                //only one script needs to be loaded anyway. This may need to be
+                //reevaluated if other use cases become common.
+                importScripts(url);
+
+                //Account for anonymous modules
+                context.completeLoad(moduleName);
+            } catch (e) {
+                context.onError(makeError('importscripts',
+                                'importScripts failed for ' +
+                                    moduleName + ' at ' + url,
+                                e,
+                                [moduleName]));
+            }
+        }
+    };
+
+    function getInteractiveScript() {
+        if (interactiveScript && interactiveScript.readyState === 'interactive') {
+            return interactiveScript;
+        }
+
+        eachReverse(scripts(), function (script) {
+            if (script.readyState === 'interactive') {
+                return (interactiveScript = script);
+            }
+        });
+        return interactiveScript;
+    }
+
+    //Look for a data-main script attribute, which could also adjust the baseUrl.
+    if (isBrowser && !cfg.skipDataMain) {
+        //Figure out baseUrl. Get it from the script tag with require.js in it.
+        eachReverse(scripts(), function (script) {
+            //Set the 'head' where we can append children by
+            //using the script's parent.
+            if (!head) {
+                head = script.parentNode;
+            }
+
+            //Look for a data-main attribute to set main script for the page
+            //to load. If it is there, the path to data main becomes the
+            //baseUrl, if it is not already set.
+            dataMain = script.getAttribute('data-main');
+            if (dataMain) {
+                //Preserve dataMain in case it is a path (i.e. contains '?')
+                mainScript = dataMain;
+
+                //Set final baseUrl if there is not already an explicit one.
+                if (!cfg.baseUrl) {
+                    //Pull off the directory of data-main for use as the
+                    //baseUrl.
+                    src = mainScript.split('/');
+                    mainScript = src.pop();
+                    subPath = src.length ? src.join('/')  + '/' : './';
+
+                    cfg.baseUrl = subPath;
+                }
+
+                //Strip off any trailing .js since mainScript is now
+                //like a module name.
+                mainScript = mainScript.replace(jsSuffixRegExp, '');
+
+                 //If mainScript is still a path, fall back to dataMain
+                if (req.jsExtRegExp.test(mainScript)) {
+                    mainScript = dataMain;
+                }
+
+                //Put the data-main script in the files to load.
+                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
+
+                return true;
+            }
+        });
+    }
+
+    /**
+     * The function that handles definitions of modules. Differs from
+     * require() in that a string for the module should be the first argument,
+     * and the function to execute after dependencies are loaded should
+     * return a value to define the module corresponding to the first argument's
+     * name.
+     */
+    define = function (name, deps, callback) {
+        var node, context;
+
+        //Allow for anonymous modules
+        if (typeof name !== 'string') {
+            //Adjust args appropriately
+            callback = deps;
+            deps = name;
+            name = null;
+        }
+
+        //This module may not have dependencies
+        if (!isArray(deps)) {
+            callback = deps;
+            deps = null;
+        }
+
+        //If no name, and callback is a function, then figure out if it a
+        //CommonJS thing with dependencies.
+        if (!deps && isFunction(callback)) {
+            deps = [];
+            //Remove comments from the callback string,
+            //look for require calls, and pull them into the dependencies,
+            //but only if there are function args.
+            if (callback.length) {
+                callback
+                    .toString()
+                    .replace(commentRegExp, '')
+                    .replace(cjsRequireRegExp, function (match, dep) {
+                        deps.push(dep);
+                    });
+
+                //May be a CommonJS thing even without require calls, but still
+                //could use exports, and module. Avoid doing exports and module
+                //work though if it just needs require.
+                //REQUIRES the function to expect the CommonJS variables in the
+                //order listed below.
+                deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
+            }
+        }
+
+        //If in IE 6-8 and hit an anonymous define() call, do the interactive
+        //work.
+        if (useInteractive) {
+            node = currentlyAddingScript || getInteractiveScript();
+            if (node) {
+                if (!name) {
+                    name = node.getAttribute('data-requiremodule');
+                }
+                context = contexts[node.getAttribute('data-requirecontext')];
+            }
+        }
+
+        //Always save off evaluating the def call until the script onload handler.
+        //This allows multiple modules to be in a file without prematurely
+        //tracing dependencies, and allows for anonymous module support,
+        //where the module name is not known until the script onload event
+        //occurs. If no context, use the global queue, and get it processed
+        //in the onscript load callback.
+        (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
+    };
+
+    define.amd = {
+        jQuery: true
+    };
+
+
+    /**
+     * Executes the text. Normally just uses eval, but can be modified
+     * to use a better, environment-specific call. Only used for transpiling
+     * loader plugins, not for plain JS modules.
+     * @param {String} text the text to execute/evaluate.
+     */
+    req.exec = function (text) {
+        /*jslint evil: true */
+        return eval(text);
+    };
+
+    //Set up with config info.
+    req(cfg);
+}(this));
diff --git a/dev/js/src/api.js b/dev/js/src/api.js
index ed33cc2..f9058bc 100644
--- a/dev/js/src/api.js
+++ b/dev/js/src/api.js
@@ -1,15 +1,4 @@
-var KorAP = KorAP || {};
-
-(function (KorAP) {
-  "use strict";
-
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
-  KorAP.URL = KorAP.URL || 'http://korap.ids-mannheim.de/kalamar';
-
+define(['util'], function () {
   // TODO: https://github.com/honza/140medley/blob/master/140medley.js
   // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
   // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
@@ -17,6 +6,8 @@
   // http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
   // http://stackoverflow.com/questions/6112744/load-javascript-on-demand
 
+  KorAP.URL = KorAP.URL || 'http://korap.ids-mannheim.de/kalamar';
+
   KorAP.API = {
     getMatchInfo : function (match, param, cb) {
       // match is a KorAP.Match object
@@ -44,14 +35,11 @@
 
       this.getJSON(url, cb);
     },
+
     getJSON : function (url, onload) {
       var req = new XMLHttpRequest();
 
-      console.log('Request url: ' + url);
-
       req.open("GET", url, true);
-
-
       req.setRequestHeader("Accept", "application/json");
       req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       req.onreadystatechange = function () {
@@ -62,7 +50,7 @@
 	  2 - headers received
 	  3 - loading (responseText has partial data)
 	  4 - done
-	 */
+	*/
 	if (this.readyState == 4) {
 	  if (this.status === 200)
 	    onload(JSON.parse(this.responseText));
@@ -76,5 +64,4 @@
       req.send();
     }
   };
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/hint.js b/dev/js/src/hint.js
index 11c3e1e..6aed544 100644
--- a/dev/js/src/hint.js
+++ b/dev/js/src/hint.js
@@ -3,23 +3,20 @@
  *
  * @author Nils Diewald
  */
-
-// requires menu.js
-
-var KorAP = KorAP || {};
-
-(function (KorAP) {
+define([
+  'hint/input',
+  'hint/menu',
+  'hint/contextanalyzer',
+  'util'
+], function (inputClass, 
+	     menuClass, 
+	     analyzerClass) {
   "use strict";
 
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
   /**
    * @define {regex} Regular expression for context
    */
-  KorAP.context =
+  KorAP.context = KorAP.context ||
     "(?:^|[^-_a-zA-Z0-9])" +   // Anchor
     "((?:[-_a-zA-Z0-9]+?)\/" + // Foundry
     "(?:" +
@@ -27,10 +24,18 @@
     "(?:(?:[^:=\/ ]+?):)?" +   // Key
     ")?" +
     ")$";
-
-  // Initialize hint array
   KorAP.hintArray = KorAP.hintArray || {};
 
+  /**
+   * Return keycode based on event
+   */
+  function _codeFromEvent (e) {
+    if ((e.charCode) && (e.keyCode==0))
+      return e.charCode
+    return e.keyCode;
+  };
+
+  // Initialize hint array
 
   /**
    * KorAP.Hint.create({
@@ -38,16 +43,20 @@
    *   context : context regex
    * });
    */
-  KorAP.Hint = {
+  return {
 
     // Some variables
     // _firstTry : true,
     active : false,
 
+    /**
+     * Create new hint helper.
+     */
     create : function (param) {
-      return Object.create(KorAP.Hint)._init(param);
+      return Object.create(this)._init(param);
     },
 
+    // Initialize hint helper
     _init : function (param) {
       param = param || {};
 
@@ -55,9 +64,11 @@
       this._menu = {};
 
       // Get input field
-      this._inputField = KorAP.InputField.create(
-	param["inputField"] || document.getElementById("q-field")
-      );
+      var qfield = param["inputField"] || document.getElementById("q-field");
+      if (!qfield)
+	return null;
+
+      this._inputField = inputClass.create(qfield);
 
       var inputFieldElement = this._inputField.element();
 
@@ -83,7 +94,7 @@
       );
 
       // Set Analyzer for context
-      this._analyzer = KorAP.ContextAnalyzer.create(
+      this._analyzer = analyzerClass.create(
 	param["context"] || KorAP.context
       );
       return this;
@@ -124,10 +135,9 @@
 	  return;
 
 	// Create matching hint menu
-	this._menu[action] = KorAP.HintMenu.create(
+	this._menu[action] = menuClass.create(
 	  this, action, KorAP.hintArray[action]
 	);
-
       };
 
       // Return matching hint menu
@@ -189,278 +199,4 @@
       };
     }
   };
-
-
-  // Input field for queries
-  KorAP.InputField = {
-    create : function (element) {
-      return Object.create(KorAP.InputField)._init(element);
-    },
-
-    _init : function (element) {
-      this._element = element;
-
-      // Create mirror for searchField
-      if ((this._mirror = document.getElementById("searchMirror")) === null) {
-	this._mirror = document.createElement("div");
-	this._mirror.setAttribute("id", "searchMirror");
-	this._mirror.appendChild(document.createElement("span"));
-	this._container = this._mirror.appendChild(document.createElement("div"));
-	this._mirror.style.height = "0px";
-	document.getElementsByTagName("body")[0].appendChild(this._mirror);
-      };
-
-      // Update position of the mirror
-      var that = this;
-      var repos = function () {
-	that.reposition();
-      };
-      window.addEventListener('resize', repos);
-      this._element.addEventListener('onfocus', repos);
-      that.reposition();
-
-      return this;
-    },
-
-    rightPos : function () {
-      var box = this._mirror.firstChild.getBoundingClientRect();
-      return box.right - box.left;
-    },
-
-    mirror : function () {
-      return this._mirror;
-    },
-
-    container : function () {
-      return this._container;
-    },
-
-    element : function () {
-      return this._element;
-    },
-
-    value : function () {
-      return this._element.value;
-    },
-
-    update : function () {
-      this._mirror.firstChild.textContent = this.split()[0];
-      this._container.style.left = this.rightPos() + 'px';
-    },
-
-    insert : function (text) {
-      var splittedText = this.split();
-      var s = this._element;
-      s.value = splittedText[0] + text + splittedText[1];
-      s.selectionStart = (splittedText[0] + text).length;
-      s.selectionEnd = s.selectionStart;
-      this._mirror.firstChild.textContent = splittedText[0] + text;
-    },
-
-    // Return two substrings, splitted at current cursor position
-    split : function () {
-      var s = this._element;
-      var value = s.value;
-      var start = s.selectionStart;
-      return new Array(
-	value.substring(0, start),
-	value.substring(start, value.length)
-      );
-    },
-
-    // Position the input mirror directly below the input box
-    reposition : function () {
-      var inputClientRect = this._element.getBoundingClientRect();
-      var inputStyle = window.getComputedStyle(this._element, null);
-
-      var bodyClientRect = 
-	document.getElementsByTagName('body')[0].getBoundingClientRect();
-
-      // Reset position
-      var mirrorStyle = this._mirror.style;
-      mirrorStyle.left = inputClientRect.left + "px";
-      mirrorStyle.top  = (inputClientRect.bottom - bodyClientRect.top) + "px";
-      mirrorStyle.width = inputStyle.getPropertyValue("width");
-
-      // These may be relevant in case of media depending css
-      mirrorStyle.paddingLeft     = inputStyle.getPropertyValue("padding-left");
-      mirrorStyle.marginLeft      = inputStyle.getPropertyValue("margin-left");
-      mirrorStyle.borderLeftWidth = inputStyle.getPropertyValue("border-left-width");
-      mirrorStyle.borderLeftStyle = inputStyle.getPropertyValue("border-left-style");
-      mirrorStyle.fontSize        = inputStyle.getPropertyValue("font-size");
-      mirrorStyle.fontFamily      = inputStyle.getPropertyValue("font-family");
-    },
-    context : function () {
-      return this.split()[0];
-    }
-  };
-
-
-  /**
-   * Regex object for checking the context of the hint
-   */
-  KorAP.ContextAnalyzer = {
-    create : function (regex) {
-      return Object.create(KorAP.ContextAnalyzer)._init(regex);
-    },
-    _init : function (regex) {
-      try {
-	this._regex = new RegExp(regex);
-      }
-      catch (e) {
-	KorAP.log(0, e);
-	return;
-      };
-      return this;
-    },
-    test : function (text) {
-      if (!this._regex.exec(text))
-	return;
-      return RegExp.$1;
-    }
-  };
-
-
-  /**
-   * Hint menu
-   */
-  KorAP.HintMenu = {
-    create : function (hint, context, params) {
-      var obj = Object.create(KorAP.Menu)
-	.upgradeTo(KorAP.HintMenu)
-	._init(KorAP.HintMenuItem, KorAP.HintMenuPrefix, params);
-      obj._context = context;
-      obj._element.classList.add('hint');
-      obj._hint = hint;
-
-      // This is only domspecific
-      obj.element().addEventListener('blur', function (e) {
-	this.menu.hide();
-      });
-
-      // Focus on input field on hide
-      obj.onHide = function () {
-	var input = this._hint.inputField();
-	input.container().classList.remove('active');
-	input.element().focus();
-      };
-
-      return obj;
-    },
-    // Todo: Is this necessary?
-    context : function () {
-      return this._context;
-    },
-    hint : function () {
-      return this._hint;
-    }
-  };
-
-
-  /**
-   * Hint menu item based on MenuItem
-   */
-  KorAP.HintMenuItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.HintMenuItem)
-	._init(params);
-    },
-    _init : function (params) {
-      if (params[0] === undefined ||
-	  params[1] === undefined)
-	throw new Error("Missing parameters");
-      
-      this._name   = params[0];
-      this._action = params[1];
-      this._lcField = ' ' + this._name.toLowerCase();
-      
-      if (params.length > 2) {
-	this._desc = params[2];
-	this._lcField += " " + this._desc.toLowerCase();
-      };
-
-      return this;
-    },
-    content : function (content) {
-      if (arguments.length === 1) {
-	this._content = content;
-      };
-      return this._content;
-    },
-    onclick : function () {
-      var m = this.menu();
-      var h = m.hint();
-      m.hide();
-
-      // Update input field
-      var input = h.inputField();
-      input.insert(this._action);
-      input.update();
-
-      h.active = false;
-      h.show(true);
-    },
-    name : function () {
-      return this._name;
-    },
-    action : function () {
-      return this._action;
-    },
-    desc : function () {
-      return this._desc;
-    },
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-
-      if (this.onclick !== undefined) {
-	li["onclick"] = this.onclick.bind(this);
-      };
-
-      // Create title
-      var name =  document.createElement("span");
-      name.appendChild(document.createTextNode(this._name));
-      
-      li.appendChild(name);
-
-      // Create description
-      if (this._desc !== undefined) {
-	var desc = document.createElement("span");
-	desc.classList.add('desc');
-	desc.appendChild(document.createTextNode(this._desc));
-	li.appendChild(desc);
-      };
-      return this._element = li;
-    }
-  };
-
-  KorAP.HintMenuPrefix = {
-    create : function (params) {
-      return Object.create(KorAP.MenuPrefix).upgradeTo(KorAP.HintMenuPrefix)._init(params);
-    },
-    onclick : function () {
-      var m = this.menu();
-      var h = m.hint();
-      m.hide();
-
-      h.inputField().insert(this.value());
-      h.active = false;
-    }
-  };
-
-
-  /**
-   * Return keycode based on event
-   */
-  function _codeFromEvent (e) {
-    if ((e.charCode) && (e.keyCode==0))
-      return e.charCode
-    return e.keyCode;
-  };
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/hint/contextanalyzer.js b/dev/js/src/hint/contextanalyzer.js
new file mode 100644
index 0000000..bdbf885
--- /dev/null
+++ b/dev/js/src/hint/contextanalyzer.js
@@ -0,0 +1,23 @@
+/**
+ * Regex object for checking the context of the hint
+ */
+define({
+  create : function (regex) {
+    return Object.create(this)._init(regex);
+  },
+  _init : function (regex) {
+    try {
+      this._regex = new RegExp(regex);
+    }
+    catch (e) {
+      KorAP.log(0, e);
+      return;
+    };
+    return this;
+  },
+  test : function (text) {
+    if (!this._regex.exec(text))
+      return;
+    return RegExp.$1;
+  }
+});
diff --git a/dev/js/src/hint/input.js b/dev/js/src/hint/input.js
new file mode 100644
index 0000000..b1c6632
--- /dev/null
+++ b/dev/js/src/hint/input.js
@@ -0,0 +1,103 @@
+// Input field for queries
+define({
+  create : function (element) {
+    return Object.create(this)._init(element);
+  },
+    
+  _init : function (element) {
+    this._element = element;
+
+    // Create mirror for searchField
+    if ((this._mirror = document.getElementById("searchMirror")) === null) {
+      this._mirror = document.createElement("div");
+      this._mirror.setAttribute("id", "searchMirror");
+      this._mirror.appendChild(document.createElement("span"));
+      this._container = this._mirror.appendChild(document.createElement("div"));
+      this._mirror.style.height = "0px";
+      document.getElementsByTagName("body")[0].appendChild(this._mirror);
+    };
+
+    // Update position of the mirror
+    var that = this;
+    var repos = function () {
+      that.reposition();
+    };
+    window.addEventListener('resize', repos);
+    this._element.addEventListener('onfocus', repos);
+    that.reposition();
+
+    return this;
+  },
+
+  rightPos : function () {
+    var box = this._mirror.firstChild.getBoundingClientRect();
+    return box.right - box.left;
+  },
+
+  mirror : function () {
+    return this._mirror;
+  },
+
+  container : function () {
+    return this._container;
+  },
+
+  element : function () {
+    return this._element;
+  },
+
+  value : function () {
+    return this._element.value;
+  },
+
+  update : function () {
+    this._mirror.firstChild.textContent = this.split()[0];
+    this._container.style.left = this.rightPos() + 'px';
+  },
+
+  insert : function (text) {
+    var splittedText = this.split();
+    var s = this._element;
+    s.value = splittedText[0] + text + splittedText[1];
+    s.selectionStart = (splittedText[0] + text).length;
+    s.selectionEnd = s.selectionStart;
+    this._mirror.firstChild.textContent = splittedText[0] + text;
+  },
+  
+  // Return two substrings, splitted at current cursor position
+  split : function () {
+    var s = this._element;
+    var value = s.value;
+    var start = s.selectionStart;
+    return new Array(
+      value.substring(0, start),
+      value.substring(start, value.length)
+    );
+  },
+
+  // Position the input mirror directly below the input box
+  reposition : function () {
+    var inputClientRect = this._element.getBoundingClientRect();
+    var inputStyle = window.getComputedStyle(this._element, null);
+
+    var bodyClientRect = 
+      document.getElementsByTagName('body')[0].getBoundingClientRect();
+
+    // Reset position
+    var mirrorStyle = this._mirror.style;
+    mirrorStyle.left = inputClientRect.left + "px";
+    mirrorStyle.top  = (inputClientRect.bottom - bodyClientRect.top) + "px";
+    mirrorStyle.width = inputStyle.getPropertyValue("width");
+    
+    // These may be relevant in case of media depending css
+    mirrorStyle.paddingLeft     = inputStyle.getPropertyValue("padding-left");
+    mirrorStyle.marginLeft      = inputStyle.getPropertyValue("margin-left");
+    mirrorStyle.borderLeftWidth = inputStyle.getPropertyValue("border-left-width");
+    mirrorStyle.borderLeftStyle = inputStyle.getPropertyValue("border-left-style");
+    mirrorStyle.fontSize        = inputStyle.getPropertyValue("font-size");
+    mirrorStyle.fontFamily      = inputStyle.getPropertyValue("font-family");
+  },
+  context : function () {
+    return this.split()[0];
+  }
+});
diff --git a/dev/js/src/hint/item.js b/dev/js/src/hint/item.js
new file mode 100644
index 0000000..f23cabc
--- /dev/null
+++ b/dev/js/src/hint/item.js
@@ -0,0 +1,85 @@
+/**
+ * Hint menu item based on MenuItem
+ */
+define(['menu/item'], function (itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)
+	._init(params);
+    },
+    _init : function (params) {
+      if (params[0] === undefined ||
+	  params[1] === undefined)
+	throw new Error("Missing parameters");
+      
+      this._name   = params[0];
+      this._action = params[1];
+      this._lcField = ' ' + this._name.toLowerCase();
+      
+      if (params.length > 2) {
+	this._desc = params[2];
+	this._lcField += " " + this._desc.toLowerCase();
+      };
+
+      return this;
+    },
+
+    content : function (content) {
+      if (arguments.length === 1) {
+	this._content = content;
+      };
+      return this._content;
+    },
+    
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
+
+      // Update input field
+      var input = h.inputField();
+      input.insert(this._action);
+      input.update();
+
+      h.active = false;
+      h.show(true);
+    },
+    name : function () {
+      return this._name;
+    },
+    action : function () {
+      return this._action;
+    },
+    desc : function () {
+      return this._desc;
+    },
+    element : function () {
+      // already defined
+      if (this._element !== undefined)
+	return this._element;
+
+      // Create list item
+      var li = document.createElement("li");
+
+      if (this.onclick !== undefined) {
+	li["onclick"] = this.onclick.bind(this);
+      };
+
+      // Create title
+      var name =  document.createElement("span");
+      name.appendChild(document.createTextNode(this._name));
+      
+      li.appendChild(name);
+
+      // Create description
+      if (this._desc !== undefined) {
+	var desc = document.createElement("span");
+	desc.classList.add('desc');
+	desc.appendChild(document.createTextNode(this._desc));
+	li.appendChild(desc);
+      };
+      return this._element = li;
+    }
+  };
+});
diff --git a/dev/js/src/hint/menu.js b/dev/js/src/hint/menu.js
new file mode 100644
index 0000000..c579945
--- /dev/null
+++ b/dev/js/src/hint/menu.js
@@ -0,0 +1,36 @@
+/**
+ * Hint menu
+ */
+define(['menu', 'hint/item', 'hint/prefix'], function (menuClass, itemClass, prefixClass) {
+  return {
+    create : function (hint, context, params) {
+      var obj = Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, prefixClass, params);
+      obj._context = context;
+      obj._element.classList.add('hint');
+      obj._hint = hint;
+
+      // This is only domspecific
+      obj.element().addEventListener('blur', function (e) {
+	this.menu.hide();
+      });
+
+      // Focus on input field on hide
+      obj.onHide = function () {
+	var input = this._hint.inputField();
+	input.container().classList.remove('active');
+	input.element().focus();
+      };
+
+      return obj;
+    },
+    // Todo: Is this necessary?
+    context : function () {
+      return this._context;
+    },
+    hint : function () {
+      return this._hint;
+    }
+  };
+});
diff --git a/dev/js/src/hint/prefix.js b/dev/js/src/hint/prefix.js
new file mode 100644
index 0000000..84f785a
--- /dev/null
+++ b/dev/js/src/hint/prefix.js
@@ -0,0 +1,15 @@
+define(['menu/prefix'], function (prefixClass) {
+  return {
+    create : function (params) {
+      return Object.create(prefixClass).upgradeTo(this)._init(params);
+    },
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
+
+      h.inputField().insert(this.value());
+      h.active = false;
+    }
+  };
+});
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index ecaad6f..66bc081 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -1,42 +1,17 @@
-/**
- * These are utility functions for the frontend
- */
-
-// Add toggleClass method similar to jquery
-HTMLElement.prototype.toggleClass = function (c1, c2) {
-  var cl = this.classList;
-  if (cl.contains(c1)) {
-    cl.add(c2);
-    cl.remove(c1);
-  }
-  else {
-    cl.remove(c2);
-    cl.add(c1);
-  };
-};
-
-
-// Don't let events bubble up
-if (Event.halt === undefined) {
-  // Don't let events bubble up
-  Event.prototype.halt = function () {
-    this.stopPropagation();
-    this.preventDefault();
-  };
-};
-
-var KorAP = KorAP || {};
-
-
-(function (KorAP) {
-  "use strict";
-
-
-  /**
-   * Initialize user interface elements
-   */
-  KorAP.init = function () {
-    var obj = Object.create(KorAP.init);
+define([
+  'match',
+  'hint',
+  'vc',
+  'tutorial',
+  'lib/domReady',
+  'util'
+], function (matchClass,
+	     hintClass,
+	     vcClass,
+	     tutClass,
+	     domReady) {
+  domReady(function (event) {
+    var obj = {};
 
     /**
      * Add actions to match entries
@@ -49,13 +24,13 @@
       inactiveLi[i].addEventListener('click', function (e) {
 	if (this._match !== undefined)
 	  this._match.open();
-	else
-	  KorAP.Match.create(this).open();
+	else {
+	  matchClass.create(this).open();
+	};
 	e.halt();
       });
     };
 
-
     /**
      * Toggle the alignment (left <=> right)
      */
@@ -97,28 +72,29 @@
       input.parentNode.insertBefore(vcname, input);
       
       vcname.onclick = function () {
-	var vc = KorAP.VirtualCollection.render(vcExample);
+	var vc = vcClass.render(vcExample);
 	var view = document.getElementById('vc-view');
 	view.appendChild(vc.element());
       };
     };
 
+  
     /**
      * Init Tutorial view
      */
-    obj.tutorial = KorAP.Tutorial.create(
+    obj.tutorial = tutClass.create(
       document.getElementById('view-tutorial')
     );
 
+  
     /**
      * Init hint helper
      * has to be final because of
      * reposition
      */
-// Todo: Pass an element, so this works with
-// tutorial pages as well!
-    obj.hint = KorAP.Hint.create();
+    // Todo: Pass an element, so this works with
+    // tutorial pages as well!
+    obj.hint = hintClass.create();
     return obj;
-  };
-
-}(this.KorAP));
+  });
+});
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index 4e3786b..beb4bca 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -4,46 +4,31 @@
  *
  * @author Nils Diewald
  */
-// require menu.js, dagre
 /*
  * - Highlight (at least mark as bold) the match
  * - Scroll to match vertically per default
  */
-var KorAP = KorAP || {};
-
-(function (KorAP) {
-  "use strict";
-
-  var svgXmlns = "http://www.w3.org/2000/svg";
-
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
+define([
+  'match/infolayer',
+  'match/info',
+  'util'
+], function (infoLayerClass,
+	     infoClass) {
 
   // Localization values
-  var loc   = (KorAP.Locale = KorAP.Locale || {} );
+  var loc   = KorAP.Locale;
   loc.ADDTREE  = loc.ADDTREE  || 'Add tree view';
   loc.SHOWINFO = loc.SHOWINFO || 'Show information';
   loc.CLOSE    = loc.CLOSE    || 'Close';
-
-  KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
-  KorAP._TermRE      = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
-  KorAP._matchTerms  = ['corpusID', 'docID', 'textID', 'matchID', 'available'];
-
-  // API requests
-  KorAP.API = KorAP.API || {};
-
-  // TODO: Make this async
-  KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
-    KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
-    return {};
-  };
+  
+  // KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
+  // KorAP._TermRE      = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+  var _matchTerms  = ['corpusID', 'docID', 'textID', 'matchID', 'available'];
 
   /**
    * Match object
    */
-  KorAP.Match = {
+  return {
 
     /**
      * Create a new annotation object.
@@ -51,7 +36,7 @@
      * Supported types are 'spans', 'tokens' and 'rels'.
      */
     create : function (match) {
-      return Object.create(KorAP.Match)._init(match);
+      return Object.create(this)._init(match);
     },
 
     /**
@@ -87,8 +72,8 @@
       else {
 
 	// Iterate over allowed match terms
-	for (var i in KorAP._matchTerms) {
-	  var term = KorAP._matchTerms[i];
+	for (var i in _matchTerms) {
+	  var term = _matchTerms[i];
 	  if (match[term] !== undefined) {
 	    this[term] = match[term];
 	  }
@@ -97,7 +82,7 @@
 	  }
 	};
       };
-
+      
       this._available = {
 	tokens : [],
 	spans  : [],
@@ -110,7 +95,7 @@
 
 	// Create info layer objects
 	try {
-	  var layer = KorAP.InfoLayer.create(term);
+	  var layer = infoLayerClass.create(term);
 	  this._available[layer.type].push(layer);
 	}
 	catch (e) {
@@ -178,7 +163,7 @@
 	.appendChild(document.createTextNode(loc.CLOSE));
       close.classList.add('close');
       close.setAttribute('title', loc.CLOSE);
-
+      
       // Add info button
       var info = document.createElement('li');
       info.appendChild(document.createElement('span'))
@@ -227,7 +212,7 @@
 
       // Create match info
       if (this._info === undefined)
-	this._info = KorAP.MatchInfo.create(this);
+	this._info = infoClass.create(this);
 
       // There is an element to append
       if (this._element === undefined ||
@@ -251,812 +236,4 @@
       return this._element;
     }
   };
-
-
-
-  /**
-   * Information about a match.
-   */
-  KorAP.MatchInfo = {
-
-    /**
-     * Create new object
-     */
-    create : function (match) {
-      return Object.create(KorAP.MatchInfo)._init(match);
-    },
-
-    /**
-     * Initialize object
-     */
-    _init : function (match) {
-      this._match = match;
-      this.opened = false;
-      return this;
-    },
-
-    /**
-     * Get match object
-     */
-    match : function () {
-      return this._match;
-    },
-
-    toggle : function () {
-      if (this.opened == true) {
-	this._match.element().children[0].removeChild(
-	  this.element()
-	);
-	this.opened = false;
-      }
-      else {
-	// Append element to match
-	this._match.element().children[0].appendChild(
-	  this.element()
-	);
-	this.opened = true;
-      };
-
-      return this.opened;
-    },
-
-
-    /**
-     * Retrieve and parse snippet for table representation
-     */
-    getTable : function (tokens, cb) {
-      var focus = [];
-
-      // Get all tokens
-      if (tokens === undefined) {
-	focus = this._match.getTokens();
-      } 
-
-      // Get only some tokens
-      else {
-
-	// Push newly to focus array
-	for (var i = 0; i < tokens.length; i++) {
-	  var term = tokens[i];
-	  try {
-	    // Create info layer objects
-	    var layer = KorAP.InfoLayer.create(term);
-	    layer.type = "tokens";
-	    focus.push(layer);
-	  }
-	  catch (e) {
-	    continue;
-	  };
-	};
-      };
-
-      // No tokens chosen
-      if (focus.length == 0)
-	cb(null);
-
-      // Get info (may be cached)
-      // TODO: Async
-      KorAP.API.getMatchInfo(
-	this._match,
-	{ 'spans' : false, 'layer' : focus },
-
-	// Callback for retrieval
-	function (matchResponse) {
-	  // Get snippet from match info
-	  if (matchResponse["snippet"] !== undefined) {
-	    this._table = KorAP.MatchTable.create(matchResponse["snippet"]);
-	    cb(this._table);
-	  };
-	}.bind(this)
-      );
-
-/*
-      // Todo: Store the table as a hash of the focus
-      return null;
-*/
-    },
-
-
-    /**
-     * Retrieve and parse snippet for tree representation
-     */
-    getTree : function (foundry, layer, cb) {
-      var focus = [];
-
-      // TODO: Support and cache multiple trees
-
-      KorAP.API.getMatchInfo(
-	this._match, {
-	  'spans' : true,
-	  'foundry' : foundry,
-	  'layer' : layer
-	},
-	function (matchResponse) {
-	  // Get snippet from match info
-	  if (matchResponse["snippet"] !== undefined) {
-	    // Todo: This should be cached somehow
-	    cb(KorAP.MatchTree.create(matchResponse["snippet"]));
-	  }
-	  else {
-	    cb(null);
-	  };
-	}.bind(this)
-      );
-    },
-
-    /**
-     * Destroy this match information view.
-     */
-    destroy : function () {
-
-      // Remove circular reference
-      if (this._treeMenu !== undefined)
-	delete this._treeMenu["info"];
-
-      this._treeMenu.destroy();
-      this._treeMenu = undefined;
-      this._match = undefined;
-
-      // Element destroy
-    },
-
-
-    /**
-     * Add a new tree view to the list
-     */
-    addTree : function (foundry, layer, cb) {
-      var matchtree = document.createElement('div');
-      matchtree.classList.add('matchtree');
-
-      var h6 = matchtree.appendChild(document.createElement('h6'));
-      h6.appendChild(document.createElement('span'))
-	.appendChild(document.createTextNode(foundry));
-      h6.appendChild(document.createElement('span'))
-	.appendChild(document.createTextNode(layer));
-
-      var tree = matchtree.appendChild(
-	document.createElement('div')
-      );
-
-      this._element.insertBefore(matchtree, this._element.lastChild);
-
-      var close = tree.appendChild(document.createElement('em'));
-      close.addEventListener(
-	'click', function (e) {
-	  matchtree.parentNode.removeChild(matchtree);
-	  e.halt();
-	}
-      );
-
-      // Get tree data async
-      this.getTree(foundry, layer, function (treeObj) {
-	// Something went wrong - probably log!!!
-	if (treeObj === null) {
-	  tree.appendChild(document.createTextNode('No data available.'));
-	}
-	else {
-	  tree.appendChild(treeObj.element());
-	  // Reposition the view to the center
-	  // (This may in a future release be a reposition
-	  // to move the root into the center or the actual
-	  // match)
-	  treeObj.center();
-	}
-
-	if (cb !== undefined)
-	  cb(treeObj);
-      });
-    },
-
-    /**
-     * Create match information view.
-     */
-    element : function () {
-
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create info table
-      var info = document.createElement('div');
-      info.classList.add('matchinfo');
-
-      // Append default table
-      var matchtable = document.createElement('div');
-      matchtable.classList.add('matchtable');
-      info.appendChild(matchtable);
-
-      // Create the table asynchronous
-      this.getTable(undefined, function (table) {
-	if (table !== null) {
-	  matchtable.appendChild(table.element());
-	};
-      });
-
-      // Get spans
-      var spanLayers = this._match.getSpans().sort(
-	function (a, b) {
-	  if (a.foundry < b.foundry) {
-	    return -1;
-	  }
-	  else if (a.foundry > b.foundry) {
-	    return 1;
-	  }
-	  else if (a.layer < b.layer) {
-	    return -1;
-	  }
-	  else if (a.layer > b.layer) {
-	    return 1;
-	  };
-	  return 0;
-	});
-
-      var menuList = [];
-
-      // Show tree views
-      for (var i = 0; i < spanLayers.length; i++) {
-	var span = spanLayers[i];
-	
-	// Add foundry/layer to menu list
-	menuList.push([
-	  span.foundry + '/' + span.layer,
-	  span.foundry,
-	  span.layer
-	]);
-      };
-
-      // Create tree menu
-      var treemenu = this.treeMenu(menuList);
-      var span = info.appendChild(document.createElement('p'));
-      span.classList.add('addtree');
-      span.appendChild(document.createTextNode(loc.ADDTREE));
-
-      var treeElement = treemenu.element();
-      span.appendChild(treeElement);
-
-      span.addEventListener('click', function (e) {
-	treemenu.show('');
-	treemenu.focus();
-      });
-      
-      this._element = info;
-
-      return info;
-
-    },
-
-
-    /**
-     * Get tree menu.
-     * There is only one menu rendered
-     * - no matter how many trees exist
-     */
-    treeMenu : function (list) {
-      if (this._treeMenu !== undefined)
-	return this._treeMenu;
-
-      return this._treeMenu = KorAP.MatchTreeMenu.create(this, list);
-    }
-  };
-
-
-
-  /**
-   *
-   * Alternatively pass a string as <tt>base/s=span</tt>
-   *
-   * @param foundry
-   */
-  KorAP.InfoLayer = {
-    create : function (foundry, layer, type) {
-      return Object.create(KorAP.InfoLayer)._init(foundry, layer, type);
-    },
-    _init : function (foundry, layer, type) {
-      if (foundry === undefined)
-	throw new Error("Missing parameters");
-
-      if (layer === undefined) {
-	if (KorAP._AvailableRE.exec(foundry)) {
-	  this.foundry = RegExp.$1;
-	  this.layer = RegExp.$2;
-	  this.type = RegExp.$3;
-	}
-	else {
-	  throw new Error("Missing parameters");
-	};
-      }
-      else {
-	this.foundry = foundry;
-	this.layer = layer;
-	this.type = type;
-      };
-
-      if (this.type === undefined)
-	this.type = 'tokens';
-
-      return this;
-    }
-  };
-
-
-  KorAP.MatchTable = {
-    create : function (snippet) {
-      return Object.create(KorAP.MatchTable)._init(snippet);
-    },
-    _init : function (snippet) {
-      // Create html for traversal
-      var html = document.createElement("div");
-      html.innerHTML = snippet;
-
-      this._pos = 0;
-      this._token = [];
-      this._info = [];
-      this._foundry = {};
-      this._layer = {};
-
-      // Parse the snippet
-      this._parse(html.childNodes);      
-
-      html.innerHTML = '';
-      return this;
-    },
-
-    length : function () {
-      return this._pos;
-    },
-
-    getToken : function (pos) {
-      if (pos === undefined)
-	return this._token;
-      return this._token[pos];
-    },
-
-    getValue : function (pos, foundry, layer) {
-      return this._info[pos][foundry + '/' + layer]
-    },
-
-    getLayerPerFoundry : function (foundry) {
-      return this._foundry[foundry]
-    },
-
-    getFoundryPerLayer : function (layer) {
-      return this._layer[layer];
-    },
-
-    // Parse the snippet
-    _parse : function (children) {
-
-      // Get all children
-      for (var i in children) {
-	var c = children[i];
-
-	// Create object on position unless it exists
-	if (this._info[this._pos] === undefined)
-	  this._info[this._pos] = {};
-
-	// Store at position in foundry/layer as array
-	var found = this._info[this._pos];
-
-	// Element with title
-	if (c.nodeType === 1) {
-	  if (c.getAttribute("title") &&
-	      KorAP._TermRE.exec(c.getAttribute("title"))) {
-
-	    // Fill position with info
-	    var foundry, layer, value;
-	    if (RegExp.$2) {
-	      foundry = RegExp.$1;
-	      layer   = RegExp.$2;
-	    }
-	    else {
-	      foundry = "base";
-	      layer   = RegExp.$1
-	    };
-
-	    value = RegExp.$3;
-
-	    if (found[foundry + "/" + layer] === undefined)
-	      found[foundry + "/" + layer] = [];
-
-	    // Push value to foundry/layer at correct position
-	    found[foundry + "/" + layer].push(RegExp.$3);
-
-	    // Set foundry
-	    if (this._foundry[foundry] === undefined)
-	      this._foundry[foundry] = {};
-	    this._foundry[foundry][layer] = 1;
-
-	    // Set layer
-	    if (this._layer[layer] === undefined)
-	      this._layer[layer] = {};
-	    this._layer[layer][foundry] = 1;
-	  };
-
-	  // depth search
-	  if (c.hasChildNodes())
-	    this._parse(c.childNodes);
-	}
-
-	// Leaf node
-	// store string on position and go to next string
-	else if (c.nodeType === 3) {
-	  if (c.nodeValue.match(/[a-z0-9]/i))
-	    this._token[this._pos++] = c.nodeValue;
-	};
-      };
-
-      delete this._info[this._pos];
-    },
-
-
-    /**
-     * Get HTML table view of annotations.
-     */
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      // First the legend table
-      var d = document;
-      var table = d.createElement('table');
-
-      // Single row in head
-      var tr = table.appendChild(d.createElement('thead'))
-	.appendChild(d.createElement('tr'));
-
-      // Add cell to row
-      var addCell = function (type, name) {
-	var c = this.appendChild(d.createElement(type))
-	if (name === undefined)
-	  return c;
-
-	if (name instanceof Array) {
-	  for (var n = 0; n < name.length; n++) {
-	    c.appendChild(d.createTextNode(name[n]));
-	    if (n !== name.length - 1) {
-	      c.appendChild(d.createElement('br'));
-	    };
-	  };
-	}
-	else {
-	  c.appendChild(d.createTextNode(name));
-	};
-      };
-
-      tr.addCell = addCell;
-
-      // Add header information
-      tr.addCell('th', 'Foundry');
-      tr.addCell('th', 'Layer');
-
-      // Add tokens
-      for (var i in this._token) {
-	tr.addCell('th', this.getToken(i));
-      };
-
-      var tbody = table.appendChild(
-	d.createElement('tbody')
-      );
-
-      var foundryList = Object.keys(this._foundry).sort();
-
-      for (var f = 0; f < foundryList.length; f++) {
-	var foundry = foundryList[f];
-	var layerList =
-	  Object.keys(this._foundry[foundry]).sort();
-
-	for (var l = 0; l < layerList.length; l++) {
-	  var layer = layerList[l];
-	  tr = tbody.appendChild(
-	    d.createElement('tr')
-	  );
-	  tr.setAttribute('tabindex', 0);
-	  tr.addCell = addCell;
-
-	  tr.addCell('th', foundry);
-	  tr.addCell('th', layer);
-
-	  for (var v = 0; v < this.length(); v++) {
-	    tr.addCell(
-	      'td',
-	      this.getValue(v, foundry, layer) 
-	    );
-	  };
-	};
-      };
-
-      return this._element = table;
-    }
-  };
-
-
-  /**
-   * Visualize span annotations as a tree using Dagre.
-   */
-  KorAP.MatchTree = {
-
-    create : function (snippet) {
-      return Object.create(KorAP.MatchTree)._init(snippet);
-    },
-
-    nodes : function () {
-      return this._next;
-    },
-
-    _addNode : function (id, obj) {
-      obj["width"] = 55;
-      obj["height"] = 20;
-      this._graph.setNode(id, obj)
-    },
-
-    _addEdge : function (src, target) {
-      this._graph.setEdge(src, target);
-    },
-
-    _init : function (snippet) {
-      this._next = new Number(0);
-
-      // Create html for traversal
-      var html = document.createElement("div");
-      html.innerHTML = snippet;
-      var g = new dagre.graphlib.Graph({
-	"directed" : true	
-      });
-      g.setGraph({
-	"nodesep" : 35,
-	"ranksep" : 15,
-	"marginx" : 40,
-	"marginy" : 10
-      });
-      g.setDefaultEdgeLabel({});
-
-      this._graph = g;
-
-      // This is a new root
-      this._addNode(
-	this._next++,
-	{ "class" : "root" }
-      );
-
-      // Parse nodes from root
-      this._parse(0, html.childNodes);
-
-      // Root node has only one child - remove
-      if (g.outEdges(0).length === 1)
-	g.removeNode(0);
-
-      html = undefined;
-      return this;
-    },
-
-    // Remove foundry and layer for labels
-    _clean : function (title) {
-      return title.replace(KorAP._TermRE, "$3");
-    },
-
-    // Parse the snippet
-    _parse : function (parent, children) {
-      for (var i in children) {
-	var c = children[i];
-
-	// Element node
-	if (c.nodeType == 1) {
-
-	  // Get title from html
-	  if (c.getAttribute("title")) {
-	    var title = this._clean(c.getAttribute("title"));
-
-	    // Add child node
-	    var id = this._next++;
-
-	    this._addNode(id, {
-	      "class" : "middle",
-	      "label" : title
-	    });
-	    this._addEdge(parent, id);
-
-	    // Check for next level
-	    if (c.hasChildNodes())
-	      this._parse(id, c.childNodes);
-	  }
-
-	  // Step further
-	  else if (c.hasChildNodes())
-	    this._parse(parent, c.childNodes);
-	}
-
-	// Text node
-	else if (c.nodeType == 3)
-
-	  if (c.nodeValue.match(/[-a-z0-9]/i)) {
-
-	    // Add child node
-	    var id = this._next++;
-	    this._addNode(id, {
-	      "class" : "leaf",
-	      "label" : c.nodeValue
-	    });
-
-	    this._addEdge(parent, id);
-	  };
-      };
-      return this;
-    },
-
-    /**
-     * Center the viewport of the canvas
-     */
-    center : function () {
-      if (this._element === undefined)
-	return;
-
-      var treeDiv = this._element.parentNode;
-
-      var cWidth = parseFloat(window.getComputedStyle(this._element).width);
-      var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
-      // Reposition:
-      if (cWidth > treeWidth) {
-	var scrollValue = (cWidth - treeWidth) / 2;
-	treeDiv.scrollLeft = scrollValue;
-      };
-    },
-
-    // Get element
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      var g = this._graph;
-
-      dagre.layout(g);
-
-      var canvas = document.createElementNS(svgXmlns, 'svg');
-      this._element = canvas;
-
-      canvas.setAttribute('height', g.graph().height);
-      canvas.setAttribute('width', g.graph().width);
-
-      // Create edges
-      g.edges().forEach(
-	function (e) {
-	  var src = g.node(e.v);
-	  var target = g.node(e.w);
-	  var p = document.createElementNS(svgXmlns, 'path');
-	  p.setAttributeNS(null, "d", _line(src, target));
-	  p.classList.add('edge');
-	  canvas.appendChild(p);
-	});
-
-      // Create nodes
-      g.nodes().forEach(
-	function (v) {
-	  v = g.node(v);
-	  var group = document.createElementNS(svgXmlns, 'g');
-	  group.classList.add(v.class);
-
-	  // Add node box
-	  var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
-	  rect.setAttributeNS(null, 'x', v.x - v.width / 2);
-	  rect.setAttributeNS(null, 'y', v.y - v.height / 2);
-	  rect.setAttributeNS(null, 'rx', 5);
-	  rect.setAttributeNS(null, 'ry', 5);
-	  rect.setAttributeNS(null, 'width', v.width);
-	  rect.setAttributeNS(null, 'height', v.height);
-
-	  if (v.class === 'root' && v.label === undefined) {
-	    rect.setAttributeNS(null, 'width', v.height);
-	    rect.setAttributeNS(null, 'x', v.x - v.height / 2);
-	    rect.setAttributeNS(null, 'class', 'empty');
-	  };
-
-	  // Add label
-	  if (v.label !== undefined) {
-	    var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
-	    text.setAttributeNS(null, 'x', v.x - v.width / 2);
-	    text.setAttributeNS(null, 'y', v.y - v.height / 2);
-	    text.setAttributeNS(
-	      null,
-	      'transform',
-	      'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
-	    );
-
-	    var tspan = document.createElementNS(svgXmlns, 'tspan');
-	    tspan.appendChild(document.createTextNode(v.label));
-	    text.appendChild(tspan);
-	  };
-
-	  canvas.appendChild(group);
-	}
-      );
-
-      return this._element;
-    }
-  };
-
-  /**
-   * Menu item for tree view choice.
-   */
-  KorAP.MatchTreeItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.MatchTreeItem)._init(params);
-    },
-    content : function (content) {
-      if (arguments.length === 1) {
-	this._content = content;
-      };
-      return this._content;
-    },
-
-    // The foundry attribute
-    foundry : function () {
-      return this._foundry;
-    },
-
-    // The layer attribute
-    layer : function () {
-      return this._layer;
-    },
-
-    // enter or click
-    onclick : function (e) {
-      var menu = this.menu();
-      menu.hide();
-      e.halt();
-      if (menu.info() !== undefined)
-	menu.info().addTree(this._foundry, this._layer);
-    },
-    
-    _init : function (params) {
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this._name    = params[0];
-      this._foundry = params[1];
-      this._layer   = params[2];
-      this._content = document.createTextNode(this._name);
-      this._lcField = ' ' + this.content().textContent.toLowerCase();
-      return this;
-    }
-  };
-
-
-  /**
-   * Menu to choose from for tree views.
-   */
-  KorAP.MatchTreeMenu = {
-    create : function (info, params) {
-      var obj = Object.create(KorAP.Menu)
-	.upgradeTo(KorAP.MatchTreeMenu)
-	._init(KorAP.MatchTreeItem, undefined, params);
-      obj.limit(6);
-
-      obj._info = info;
-
-      // This is only domspecific
-      obj.element().addEventListener('blur', function (e) {
-	this.menu.hide();
-      });
-
-      return obj;
-    },
-    info :function () {
-      return this._info;
-    }
-  };
-
-
-  // Create path for node connections 
-  function _line (src, target) {
-    var x1 = src.x,
-        y1 = src.y,
-        x2 = target.x,
-        y2 = target.y - target.height / 2;
-
-    // c 0,0 -10,0
-    return 'M ' + x1 + ',' + y1 + ' ' + 
-      'C ' + x1 + ',' + y1 + ' ' + 
-      x2 + ',' + (y2 - (y2 - y1) / 2)  + ' ' + 
-      x2 + ',' + y2;
-  };
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
new file mode 100644
index 0000000..b24bed5
--- /dev/null
+++ b/dev/js/src/match/info.js
@@ -0,0 +1,290 @@
+  /**
+   * Information about a match.
+   */
+define(['match/infolayer','match/table','match/tree', 'match/treemenu', 'util'], function (infoLayerClass, matchTableClass, matchTreeClass, matchTreeMenuClass) {
+
+  // TODO: Make this async
+  KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
+    KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
+    return {};
+  };
+
+  var loc = KorAP.Locale;
+
+  /**
+   * Create new object
+   */
+  return {
+    create : function (match) {
+      return Object.create(this)._init(match);
+    },
+
+    /**
+     * Initialize object
+     */
+    _init : function (match) {
+      this._match = match;
+      this.opened = false;
+      return this;
+    },
+
+    /**
+     * Get match object
+     */
+    match : function () {
+      return this._match;
+    },
+
+    toggle : function () {
+      if (this.opened == true) {
+	this._match.element().children[0].removeChild(
+	  this.element()
+	);
+	this.opened = false;
+      }
+      else {
+	// Append element to match
+	this._match.element().children[0].appendChild(
+	  this.element()
+	);
+	this.opened = true;
+      };
+      
+      return this.opened;
+    },
+
+
+    /**
+     * Retrieve and parse snippet for table representation
+     */
+    getTable : function (tokens, cb) {
+      var focus = [];
+
+      // Get all tokens
+      if (tokens === undefined) {
+	focus = this._match.getTokens();
+      } 
+
+      // Get only some tokens
+      else {
+
+	// Push newly to focus array
+	for (var i = 0; i < tokens.length; i++) {
+	  var term = tokens[i];
+	  try {
+	    // Create info layer objects
+	    var layer = infoLayerClass.create(term);
+	    layer.type = "tokens";
+	    focus.push(layer);
+	  }
+	  catch (e) {
+	    continue;
+	  };
+	};
+      };
+      
+      // No tokens chosen
+      if (focus.length == 0)
+	cb(null);
+
+      // Get info (may be cached)
+      // TODO: Async
+      KorAP.API.getMatchInfo(
+	this._match,
+	{ 'spans' : false, 'layer' : focus },
+
+	// Callback for retrieval
+	function (matchResponse) {
+	  // Get snippet from match info
+	  if (matchResponse["snippet"] !== undefined) {
+	    this._table = matchTableClass.create(matchResponse["snippet"]);
+	    cb(this._table);
+	  };
+	}.bind(this)
+      );
+
+      /*
+      // Todo: Store the table as a hash of the focus
+      return null;
+      */
+    },
+    
+
+    /**
+     * Retrieve and parse snippet for tree representation
+     */
+    getTree : function (foundry, layer, cb) {
+      var focus = [];
+      
+      // TODO: Support and cache multiple trees
+      KorAP.API.getMatchInfo(
+	this._match, {
+	  'spans' : true,
+	  'foundry' : foundry,
+	  'layer' : layer
+	},
+	function (matchResponse) {
+	  // Get snippet from match info
+	  if (matchResponse["snippet"] !== undefined) {
+	    // Todo: This should be cached somehow
+	    cb(matchTreeClass.create(matchResponse["snippet"]));
+	  }
+	  else {
+	    cb(null);
+	  };
+	}.bind(this)
+      );
+    },
+
+    /**
+     * Destroy this match information view.
+     */
+    destroy : function () {
+
+      // Remove circular reference
+      if (this._treeMenu !== undefined)
+	delete this._treeMenu["info"];
+      
+      this._treeMenu.destroy();
+      this._treeMenu = undefined;
+      this._match = undefined;
+      
+      // Element destroy
+    },
+
+    /**
+     * Add a new tree view to the list
+     */
+    addTree : function (foundry, layer, cb) {
+      var matchtree = document.createElement('div');
+      matchtree.classList.add('matchtree');
+      
+      var h6 = matchtree.appendChild(document.createElement('h6'));
+      h6.appendChild(document.createElement('span'))
+	.appendChild(document.createTextNode(foundry));
+      h6.appendChild(document.createElement('span'))
+	.appendChild(document.createTextNode(layer));
+      
+      var tree = matchtree.appendChild(
+	document.createElement('div')
+      );
+      
+      this._element.insertBefore(matchtree, this._element.lastChild);
+
+      var close = tree.appendChild(document.createElement('em'));
+      close.addEventListener(
+	'click', function (e) {
+	  matchtree.parentNode.removeChild(matchtree);
+	  e.halt();
+	}
+      );
+
+      // Get tree data async
+      this.getTree(foundry, layer, function (treeObj) {
+	// Something went wrong - probably log!!!
+	if (treeObj === null) {
+	  tree.appendChild(document.createTextNode('No data available.'));
+	}
+	else {
+	  tree.appendChild(treeObj.element());
+	  // Reposition the view to the center
+	  // (This may in a future release be a reposition
+	  // to move the root into the center or the actual
+	  // match)
+	  treeObj.center();
+	}
+	
+	if (cb !== undefined)
+	  cb(treeObj);
+      });
+    },
+    
+    /**
+     * Create match information view.
+     */
+    element : function () {
+      
+      if (this._element !== undefined)
+	return this._element;
+      
+      // Create info table
+      var info = document.createElement('div');
+      info.classList.add('matchinfo');
+
+      // Append default table
+      var matchtable = document.createElement('div');
+      matchtable.classList.add('matchtable');
+      info.appendChild(matchtable);
+
+      // Create the table asynchronous
+      this.getTable(undefined, function (table) {
+	if (table !== null) {
+	  matchtable.appendChild(table.element());
+	};
+      });
+
+      // Get spans
+      var spanLayers = this._match.getSpans().sort(
+	function (a, b) {
+	  if (a.foundry < b.foundry) {
+	    return -1;
+	  }
+	  else if (a.foundry > b.foundry) {
+	    return 1;
+	  }
+	  else if (a.layer < b.layer) {
+	    return -1;
+	  }
+	  else if (a.layer > b.layer) {
+	    return 1;
+	  };
+	  return 0;
+	});
+      
+      var menuList = [];
+      
+      // Show tree views
+      for (var i = 0; i < spanLayers.length; i++) {
+	var span = spanLayers[i];
+	
+	// Add foundry/layer to menu list
+	menuList.push([
+	  span.foundry + '/' + span.layer,
+	  span.foundry,
+	  span.layer
+	]);
+      };
+
+      // Create tree menu
+      var treemenu = this.treeMenu(menuList);
+      var span = info.appendChild(document.createElement('p'));
+      span.classList.add('addtree');
+      span.appendChild(document.createTextNode(loc.ADDTREE));
+
+      var treeElement = treemenu.element();
+      span.appendChild(treeElement);
+
+      span.addEventListener('click', function (e) {
+	treemenu.show('');
+	treemenu.focus();
+      });
+      
+      this._element = info;
+
+      return info;
+    },
+
+    
+    /**
+     * Get tree menu.
+     * There is only one menu rendered
+     * - no matter how many trees exist
+     */
+    treeMenu : function (list) {
+      if (this._treeMenu !== undefined)
+	return this._treeMenu;
+      
+      return this._treeMenu = matchTreeMenuClass.create(this, list);
+    }
+  };
+});
diff --git a/dev/js/src/match/infolayer.js b/dev/js/src/match/infolayer.js
new file mode 100644
index 0000000..dbd93f9
--- /dev/null
+++ b/dev/js/src/match/infolayer.js
@@ -0,0 +1,41 @@
+/**
+ *
+ * Alternatively pass a string as <tt>base/s=span</tt>
+ *
+ * @param foundry
+ */
+define(function () {
+  var _AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
+
+  return {
+    create : function (foundry, layer, type) {
+      return Object.create(this)._init(foundry, layer, type);
+    },
+    _init : function (foundry, layer, type) {
+      if (foundry === undefined)
+	throw new Error("Missing parameters");
+      
+      if (layer === undefined) {
+	if (_AvailableRE.exec(foundry)) {
+	  this.foundry = RegExp.$1;
+	  this.layer = RegExp.$2;
+	  this.type = RegExp.$3;
+	}
+	else {
+	  throw new Error("Missing parameters");
+	};
+      }
+      else {
+	this.foundry = foundry;
+	this.layer = layer;
+	this.type = type;
+      };
+      
+      if (this.type === undefined)
+	this.type = 'tokens';
+
+      return this;
+    }
+  };
+});
+
diff --git a/dev/js/src/match/table.js b/dev/js/src/match/table.js
new file mode 100644
index 0000000..7eba8a0
--- /dev/null
+++ b/dev/js/src/match/table.js
@@ -0,0 +1,193 @@
+define(function () {
+  var _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+  
+  return {
+    create : function (snippet) {
+      return Object.create(this)._init(snippet);
+    },
+    _init : function (snippet) {
+      // Create html for traversal
+      var html = document.createElement("div");
+      html.innerHTML = snippet;
+      
+      this._pos = 0;
+      this._token = [];
+      this._info = [];
+      this._foundry = {};
+      this._layer = {};
+    
+      // Parse the snippet
+      this._parse(html.childNodes);      
+    
+      html.innerHTML = '';
+      return this;
+    },
+    
+    length : function () {
+      return this._pos;
+    },
+
+    getToken : function (pos) {
+      if (pos === undefined)
+	return this._token;
+      return this._token[pos];
+    },
+    
+    getValue : function (pos, foundry, layer) {
+      return this._info[pos][foundry + '/' + layer]
+    },
+    
+    getLayerPerFoundry : function (foundry) {
+      return this._foundry[foundry]
+    },
+    
+    getFoundryPerLayer : function (layer) {
+      return this._layer[layer];
+    },
+
+    // Parse the snippet
+    _parse : function (children) {
+
+      // Get all children
+      for (var i in children) {
+	var c = children[i];
+
+	// Create object on position unless it exists
+	if (this._info[this._pos] === undefined)
+	  this._info[this._pos] = {};
+
+	// Store at position in foundry/layer as array
+	var found = this._info[this._pos];
+
+	// Element with title
+	if (c.nodeType === 1) {
+	  if (c.getAttribute("title") &&
+	      _TermRE.exec(c.getAttribute("title"))) {
+
+	    // Fill position with info
+	    var foundry, layer, value;
+	    if (RegExp.$2) {
+	      foundry = RegExp.$1;
+	      layer   = RegExp.$2;
+	    }
+	    else {
+	      foundry = "base";
+	      layer   = RegExp.$1
+	    };
+
+	    value = RegExp.$3;
+	    
+	    if (found[foundry + "/" + layer] === undefined)
+	      found[foundry + "/" + layer] = [];
+
+	    // Push value to foundry/layer at correct position
+	    found[foundry + "/" + layer].push(RegExp.$3);
+
+	    // Set foundry
+	    if (this._foundry[foundry] === undefined)
+	      this._foundry[foundry] = {};
+	    this._foundry[foundry][layer] = 1;
+
+	    // Set layer
+	    if (this._layer[layer] === undefined)
+	      this._layer[layer] = {};
+	    this._layer[layer][foundry] = 1;
+	  };
+
+	  // depth search
+	  if (c.hasChildNodes())
+	    this._parse(c.childNodes);
+	}
+
+	// Leaf node
+	// store string on position and go to next string
+	else if (c.nodeType === 3) {
+	  if (c.nodeValue.match(/[a-z0-9]/i))
+	    this._token[this._pos++] = c.nodeValue;
+	};
+      };
+
+      delete this._info[this._pos];
+    },
+
+
+    /**
+     * Get HTML table view of annotations.
+     */
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      // First the legend table
+      var d = document;
+      var table = d.createElement('table');
+
+      // Single row in head
+      var tr = table.appendChild(d.createElement('thead'))
+	.appendChild(d.createElement('tr'));
+
+      // Add cell to row
+      var addCell = function (type, name) {
+	var c = this.appendChild(d.createElement(type))
+	if (name === undefined)
+	  return c;
+
+	if (name instanceof Array) {
+	  for (var n = 0; n < name.length; n++) {
+	    c.appendChild(d.createTextNode(name[n]));
+	    if (n !== name.length - 1) {
+	      c.appendChild(d.createElement('br'));
+	    };
+	  };
+	}
+	else {
+	  c.appendChild(d.createTextNode(name));
+	};
+      };
+
+      tr.addCell = addCell;
+
+      // Add header information
+      tr.addCell('th', 'Foundry');
+      tr.addCell('th', 'Layer');
+
+      // Add tokens
+      for (var i in this._token) {
+	tr.addCell('th', this.getToken(i));
+      };
+
+      var tbody = table.appendChild(
+	d.createElement('tbody')
+      );
+
+      var foundryList = Object.keys(this._foundry).sort();
+
+      for (var f = 0; f < foundryList.length; f++) {
+	var foundry = foundryList[f];
+	var layerList =
+	  Object.keys(this._foundry[foundry]).sort();
+
+	for (var l = 0; l < layerList.length; l++) {
+	  var layer = layerList[l];
+	  tr = tbody.appendChild(
+	    d.createElement('tr')
+	  );
+	  tr.setAttribute('tabindex', 0);
+	  tr.addCell = addCell;
+
+	  tr.addCell('th', foundry);
+	  tr.addCell('th', layer);
+
+	  for (var v = 0; v < this.length(); v++) {
+	    tr.addCell(
+	      'td',
+	      this.getValue(v, foundry, layer) 
+	    );
+	  };
+	};
+      };
+
+      return this._element = table;
+    }
+  };
+});
diff --git a/dev/js/src/match/tree.js b/dev/js/src/match/tree.js
new file mode 100644
index 0000000..b379b37
--- /dev/null
+++ b/dev/js/src/match/tree.js
@@ -0,0 +1,222 @@
+/**
+ * Visualize span annotations as a tree using Dagre.
+ */
+define(['lib/dagre'], function (dagre) {
+  "use strict";
+
+  var svgXmlns = "http://www.w3.org/2000/svg";
+  var _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+
+  // Create path for node connections 
+  function _line (src, target) {
+    var x1 = src.x,
+        y1 = src.y,
+        x2 = target.x,
+        y2 = target.y - target.height / 2;
+
+    // c 0,0 -10,0
+    return 'M ' + x1 + ',' + y1 + ' ' + 
+      'C ' + x1 + ',' + y1 + ' ' + 
+      x2 + ',' + (y2 - (y2 - y1) / 2)  + ' ' + 
+      x2 + ',' + y2;
+  };
+
+  return {
+    create : function (snippet) {
+      return Object.create(this)._init(snippet);
+    },
+
+    nodes : function () {
+      return this._next;
+    },
+
+    _addNode : function (id, obj) {
+      obj["width"] = 55;
+      obj["height"] = 20;
+      this._graph.setNode(id, obj)
+    },
+    
+    _addEdge : function (src, target) {
+      this._graph.setEdge(src, target);
+    },
+    
+    _init : function (snippet) {
+      this._next = new Number(0);
+
+      // Create html for traversal
+      var html = document.createElement("div");
+      html.innerHTML = snippet;
+      var g = new dagre.graphlib.Graph({
+	"directed" : true	
+      });
+      g.setGraph({
+	"nodesep" : 35,
+	"ranksep" : 15,
+	"marginx" : 40,
+	"marginy" : 10
+      });
+      g.setDefaultEdgeLabel({});
+
+      this._graph = g;
+      
+      // This is a new root
+      this._addNode(
+	this._next++,
+	{ "class" : "root" }
+      );
+      
+      // Parse nodes from root
+      this._parse(0, html.childNodes);
+
+      // Root node has only one child - remove
+      if (g.outEdges(0).length === 1)
+	g.removeNode(0);
+
+      html = undefined;
+      return this;
+    },
+
+    // Remove foundry and layer for labels
+    _clean : function (title) {
+      return title.replace(_TermRE, "$3");
+    },
+
+    // Parse the snippet
+    _parse : function (parent, children) {
+      for (var i in children) {
+	var c = children[i];
+
+	// Element node
+	if (c.nodeType == 1) {
+
+	  // Get title from html
+	  if (c.getAttribute("title")) {
+	    var title = this._clean(c.getAttribute("title"));
+
+	    // Add child node
+	    var id = this._next++;
+
+	    this._addNode(id, {
+	      "class" : "middle",
+	      "label" : title
+	    });
+	    this._addEdge(parent, id);
+
+	    // Check for next level
+	    if (c.hasChildNodes())
+	      this._parse(id, c.childNodes);
+	  }
+
+	  // Step further
+	  else if (c.hasChildNodes())
+	    this._parse(parent, c.childNodes);
+	}
+
+	// Text node
+	else if (c.nodeType == 3)
+
+	  if (c.nodeValue.match(/[-a-z0-9]/i)) {
+
+	    // Add child node
+	    var id = this._next++;
+	    this._addNode(id, {
+	      "class" : "leaf",
+	      "label" : c.nodeValue
+	    });
+
+	    this._addEdge(parent, id);
+	  };
+      };
+      return this;
+    },
+
+    /**
+     * Center the viewport of the canvas
+     */
+    center : function () {
+      if (this._element === undefined)
+	return;
+
+      var treeDiv = this._element.parentNode;
+
+      var cWidth = parseFloat(window.getComputedStyle(this._element).width);
+      var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
+      // Reposition:
+      if (cWidth > treeWidth) {
+	var scrollValue = (cWidth - treeWidth) / 2;
+	treeDiv.scrollLeft = scrollValue;
+      };
+    },
+
+    // Get element
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      var g = this._graph;
+
+      dagre.layout(g);
+
+      var canvas = document.createElementNS(svgXmlns, 'svg');
+      this._element = canvas;
+
+      canvas.setAttribute('height', g.graph().height);
+      canvas.setAttribute('width', g.graph().width);
+
+      // Create edges
+      g.edges().forEach(
+	function (e) {
+	  var src = g.node(e.v);
+	  var target = g.node(e.w);
+	  var p = document.createElementNS(svgXmlns, 'path');
+	  p.setAttributeNS(null, "d", _line(src, target));
+	  p.classList.add('edge');
+	  canvas.appendChild(p);
+	});
+
+      // Create nodes
+      g.nodes().forEach(
+	function (v) {
+	  v = g.node(v);
+	  var group = document.createElementNS(svgXmlns, 'g');
+	  group.classList.add(v.class);
+
+	  // Add node box
+	  var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
+	  rect.setAttributeNS(null, 'x', v.x - v.width / 2);
+	  rect.setAttributeNS(null, 'y', v.y - v.height / 2);
+	  rect.setAttributeNS(null, 'rx', 5);
+	  rect.setAttributeNS(null, 'ry', 5);
+	  rect.setAttributeNS(null, 'width', v.width);
+	  rect.setAttributeNS(null, 'height', v.height);
+
+	  if (v.class === 'root' && v.label === undefined) {
+	    rect.setAttributeNS(null, 'width', v.height);
+	    rect.setAttributeNS(null, 'x', v.x - v.height / 2);
+	    rect.setAttributeNS(null, 'class', 'empty');
+	  };
+
+	  // Add label
+	  if (v.label !== undefined) {
+	    var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
+	    text.setAttributeNS(null, 'x', v.x - v.width / 2);
+	    text.setAttributeNS(null, 'y', v.y - v.height / 2);
+	    text.setAttributeNS(
+	      null,
+	      'transform',
+	      'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
+	    );
+
+	    var tspan = document.createElementNS(svgXmlns, 'tspan');
+	    tspan.appendChild(document.createTextNode(v.label));
+	    text.appendChild(tspan);
+	  };
+
+	  canvas.appendChild(group);
+	}
+      );
+
+      return this._element;
+    }
+  };
+});
diff --git a/dev/js/src/match/treeitem.js b/dev/js/src/match/treeitem.js
new file mode 100644
index 0000000..f096861
--- /dev/null
+++ b/dev/js/src/match/treeitem.js
@@ -0,0 +1,49 @@
+define(['menu/item'], function (itemClass) {
+  /**
+   * Menu item for tree view choice.
+   */
+
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)._init(params);
+    },
+    content : function (content) {
+      if (arguments.length === 1) {
+	this._content = content;
+      };
+      return this._content;
+    },
+    
+    // The foundry attribute
+    foundry : function () {
+      return this._foundry;
+    },
+
+    // The layer attribute
+    layer : function () {
+      return this._layer;
+    },
+
+    // enter or click
+    onclick : function (e) {
+      var menu = this.menu();
+      menu.hide();
+      e.halt();
+      if (menu.info() !== undefined)
+	menu.info().addTree(this._foundry, this._layer);
+    },
+    
+    _init : function (params) {
+      if (params[0] === undefined)
+	throw new Error("Missing parameters");
+
+      this._name    = params[0];
+      this._foundry = params[1];
+      this._layer   = params[2];
+      this._content = document.createTextNode(this._name);
+      this._lcField = ' ' + this.content().textContent.toLowerCase();
+      return this;
+    }
+  };
+});
diff --git a/dev/js/src/match/treemenu.js b/dev/js/src/match/treemenu.js
new file mode 100644
index 0000000..23341a4
--- /dev/null
+++ b/dev/js/src/match/treemenu.js
@@ -0,0 +1,26 @@
+  /**
+   * Menu to choose from for tree views.
+   */
+define(['menu', 'match/treeitem'], function (menuClass, itemClass) {
+  "use strict";
+
+  return {
+    create : function (info, params) {
+      var obj = Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, undefined, params);
+      obj.limit(6);
+      obj._info = info;
+
+      // This is only domspecific
+      obj.element().addEventListener('blur', function (e) {
+	this.menu.hide();
+      });
+      
+      return obj;
+    },
+    info :function () {
+      return this._info;
+    }
+  };
+});
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index 78f9ea7..0d5e6ac 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -1,35 +1,35 @@
-var KorAP = KorAP || {};
-
 /**
  * Create scrollable drop-down menus.
  *
  * @author Nils Diewald
  */
-
 /*
-  * TODO: space is not a valid prefix!
+ * TODO: space is not a valid prefix!
  */
-(function (KorAP) {
-  "use strict";
+define([
+  'menu/item',
+  'menu/prefix',
+  'util'
+], function (defaultItemClass,
+	     defaultPrefixClass) {
 
-  // Don't let events bubble up
-  if (Event.halt === undefined) {
-    // Don't let events bubble up
-    Event.prototype.halt = function () {
-      this.stopPropagation();
-      this.preventDefault();
-    };
+  // Todo: This may not be necessary
+  // Default maximum number of menu items
+  var menuLimit = 8;
+
+  function _codeFromEvent (e) {
+    if (e.charCode && (e.keyCode == 0))
+      return e.charCode
+    return e.keyCode;
   };
 
-  // Default maximum number of menu items
-  KorAP.menuLimit = 8;
 
   /**
    * List of items for drop down menu (complete).
    * Only a sublist of the menu is filtered (live).
    * Only a sublist of the filtered menu is visible (shown).
    */
-  KorAP.Menu = {
+  return {
     /**
      * Create new Menu based on the action prefix
      * and a list of menu items.
@@ -40,7 +40,7 @@
      * @param {Array.<Array.<string>>} List of menu items
      */
     create : function (params) {
-      return Object.create(KorAP.Menu)._init(params);
+      return Object.create(this)._init(params);
     },
 
     /**
@@ -143,12 +143,12 @@
     // Initialize list
     _init : function (itemClass, prefixClass, params) {
       var that = this;
-      this._itemClass = itemClass;
+      this._itemClass = itemClass || defaultItemClass;
 
       if (prefixClass !== undefined)
 	this._prefix = prefixClass.create();
       else
-	this._prefix = KorAP.MenuPrefix.create();
+	this._prefix = defaultPrefixClass.create();
 
       this._prefix._menu = this;
 
@@ -188,14 +188,14 @@
 
       // Initialize item list based on parameters
       for (i in params) {
-	var obj = itemClass.create(params[i]);
+	var obj = this._itemClass.create(params[i]);
 
 	// This may become circular
 	obj["_menu"] = this;
 
 	this._items.push(obj);
       };
-      this._limit    = KorAP.menuLimit;
+      this._limit    = menuLimit;
       this._position = 0;  // position in the active list
       this._active   = -1; // active item in the item list
       this._reset();
@@ -654,318 +654,4 @@
       this._element.removeChild(this._element.lastChild);
     }
   };
-
-
-  /**
-   * Item in the Dropdown menu
-   */
-  KorAP.MenuItem = {
-
-    /**
-     * Create a new MenuItem object.
-     *
-     * @constructor
-     * @this {MenuItem}
-     * @param {Array.<string>} An array object of name, action and
-     *   optionally a description
-     */
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)._init(params);
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object] An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    content : function (content) {
-      if (arguments.length === 1)
-	this._content = document.createTextNode(content);
-      return this._content;
-    },
-
-    lcField : function () {
-      return this._lcField;
-    },
-
-    action : function (action) {
-      if (arguments.length === 1)
-	this._action = action;
-      return this._action;
-    },
-
-    /**
-     * Check or set if the item is active
-     *
-     * @param {boolean|null} State of activity
-     */
-    active : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("active");
-      else if (bool)
-	cl.add("active");
-      else
-	cl.remove("active");
-    },
-
-    /**
-     * Check or set if the item is
-     * at the boundary of the menu
-     * list
-     *
-     * @param {boolean|null} State of activity
-     */
-    noMore : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("no-more");
-      else if (bool)
-	cl.add("no-more");
-      else
-	cl.remove("no-more");
-    },
-
-    /**
-     * Get the document element of the menu item
-     */
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-
-      // Connect action
-      if (this["onclick"] !== undefined) {
-	li["onclick"] = this.onclick.bind(this);
-      };
-
-      // Append template
-      li.appendChild(this.content());
-
-      return this._element = li;
-    },
-
-    /**
-     * Highlight parts of the item
-     *
-     * @param {string} Prefix string for highlights
-     */
-    highlight : function (prefix) {
-      var children = this.element().childNodes;
-      for (var i = children.length -1; i >= 0; i--) {
-	this._highlight(children[i], prefix);
-      };
-    },
-
-    // Highlight a certain substring of the menu item
-    _highlight : function (elem, prefix) {
-
-      if (elem.nodeType === 3) {
-
-	var text   = elem.nodeValue;
-	var textlc = text.toLowerCase();
-	var pos    = textlc.indexOf(prefix);
-	if (pos >= 0) {
-
-	  // First element
-	  if (pos > 0) {
-	    elem.parentNode.insertBefore(
-	      document.createTextNode(text.substr(0, pos)),
-	      elem
-	    );
-	  };
-
-	  // Second element
-	  var hl = document.createElement("mark");
-	  hl.appendChild(
-	    document.createTextNode(text.substr(pos, prefix.length))
-	  );
-	  elem.parentNode.insertBefore(hl, elem);
-
-	  // Third element
-	  var third = text.substr(pos + prefix.length);
-	  if (third.length > 0) {
-	    var thirdE = document.createTextNode(third);
-	    elem.parentNode.insertBefore(
-	      thirdE,
-	      elem
-	    );
-	    this._highlight(thirdE, prefix);
-	  };
-
-	  var p = elem.parentNode;
-	  p.removeChild(elem);
-	};
-      }
-      else {
-	var children = elem.childNodes;
-	for (var i = children.length -1; i >= 0; i--) {
-	  this._highlight(children[i], prefix);
-	};
-      };
-    },
-
-
-    /**
-     * Remove highlight of the menu item
-     */
-    lowlight : function () {
-      var e = this.element();
-
-      var marks = e.getElementsByTagName("mark");
-      for (var i = marks.length - 1; i >= 0; i--) {
-	// Create text node clone
-	var x = document.createTextNode(
-	  marks[i].firstChild.nodeValue
-	);
-
-	// Replace with content
-	marks[i].parentNode.replaceChild(
-	  x,
-	  marks[i]
-	);
-      };
-
-      // Remove consecutive textnodes
-      e.normalize();
-    },
-
-    // Initialize menu item
-    _init : function (params) {
-
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this.content(params[0]);
-
-      if (params.length === 2)
-	this._action = params[1];
-
-      this._lcField = ' ' + this.content().textContent.toLowerCase();
-
-      return this;
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  KorAP.MenuPrefix = {
-    create : function (params) {
-      return Object.create(KorAP.MenuPrefix)._init();
-    },
-    _init : function () {
-      this._string = '';
-
-      // Add prefix span
-      this._element = document.createElement('span');
-      this._element.classList.add('pref');
-      // Connect action
-
-      if (this["onclick"] !== undefined)
-	this._element["onclick"] = this.onclick.bind(this);
-
-      return this;
-    },
-    _update : function () {
-      this._element.innerHTML
-      = this._string;
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object} An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    active : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("active");
-      else if (bool)
-	cl.add("active");
-      else
-	cl.remove("active");
-    },
-
-    element : function () {
-      return this._element;
-    },
-
-    isSet : function () {
-      return this._string.length > 0 ?
-	true : false;
-    },
-
-    value : function (string) {
-      if (arguments.length === 1) {
-	this._string = string;
-	this._update();
-      };
-      return this._string;
-    },
-
-    add : function (string) {
-      this._string += string;
-      this._update();
-    },
-
-    onclick : function () {},
-
-    backspace : function () {
-      if (this._string.length > 1) {
-	this._string = this._string.substring(
-	  0, this._string.length - 1
-	);
-      }
-      else {
-	this._string = '';
-      };
-
-      this._update();
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  function _codeFromEvent (e) {
-    if (e.charCode && (e.keyCode == 0))
-      return e.charCode
-    return e.keyCode;
-  };
-
-}(this.KorAP));
-
-/**
- * MenuItems may define:
- *
- * onclick: action happen on click and enter.
- * further: action happen on right arrow
- */
+});
diff --git a/dev/js/src/menu/item.js b/dev/js/src/menu/item.js
new file mode 100644
index 0000000..b80aa2a
--- /dev/null
+++ b/dev/js/src/menu/item.js
@@ -0,0 +1,213 @@
+/*
+ * MenuItems may define:
+ *
+ * onclick: action happen on click and enter.
+ * further: action happen on right arrow
+ */
+
+/**
+ * Item in the Dropdown menu
+ */
+define({
+  /**
+   * Create a new MenuItem object.
+   *
+   * @constructor
+   * @this {MenuItem}
+   * @param {Array.<string>} An array object of name, action and
+   *   optionally a description
+   */
+  create : function (params) {
+    return Object.create(this)._init(params);
+  },
+
+  /**
+   * Upgrade this object to another object,
+   * while private data stays intact.
+   *
+   * @param {Object] An object with properties.
+   */
+  upgradeTo : function (props) {
+    for (var prop in props) {
+      this[prop] = props[prop];
+    };
+    return this;
+  },
+
+  content : function (content) {
+    if (arguments.length === 1)
+      this._content = document.createTextNode(content);
+    return this._content;
+  },
+
+  lcField : function () {
+    return this._lcField;
+  },
+
+  action : function (action) {
+    if (arguments.length === 1)
+      this._action = action;
+    return this._action;
+  },
+
+  /**
+   * Check or set if the item is active
+   *
+   * @param {boolean|null} State of activity
+   */
+  active : function (bool) {
+    var cl = this.element().classList;
+    if (bool === undefined)
+      return cl.contains("active");
+    else if (bool)
+      cl.add("active");
+    else
+      cl.remove("active");
+  },
+
+  /**
+   * Check or set if the item is
+   * at the boundary of the menu
+   * list
+   *
+   * @param {boolean|null} State of activity
+   */
+  noMore : function (bool) {
+    var cl = this.element().classList;
+    if (bool === undefined)
+      return cl.contains("no-more");
+    else if (bool)
+      cl.add("no-more");
+    else
+      cl.remove("no-more");
+  },
+  
+  /**
+   * Get the document element of the menu item
+   */
+  element : function () {
+    // already defined
+    if (this._element !== undefined)
+      return this._element;
+    
+    // Create list item
+    var li = document.createElement("li");
+
+    // Connect action
+    if (this["onclick"] !== undefined) {
+      li["onclick"] = this.onclick.bind(this);
+    };
+
+    // Append template
+    li.appendChild(this.content());
+    
+    return this._element = li;
+  },
+
+  /**
+   * Highlight parts of the item
+   *
+   * @param {string} Prefix string for highlights
+   */
+  highlight : function (prefix) {
+    var children = this.element().childNodes;
+    for (var i = children.length -1; i >= 0; i--) {
+      this._highlight(children[i], prefix);
+    };
+  },
+
+  // Highlight a certain substring of the menu item
+  _highlight : function (elem, prefix) {
+    
+    if (elem.nodeType === 3) {
+      
+      var text   = elem.nodeValue;
+      var textlc = text.toLowerCase();
+      var pos    = textlc.indexOf(prefix);
+      if (pos >= 0) {
+	
+	// First element
+	if (pos > 0) {
+	  elem.parentNode.insertBefore(
+	    document.createTextNode(text.substr(0, pos)),
+	    elem
+	  );
+	};
+	
+	// Second element
+	var hl = document.createElement("mark");
+	hl.appendChild(
+	  document.createTextNode(text.substr(pos, prefix.length))
+	);
+	elem.parentNode.insertBefore(hl, elem);
+	
+	// Third element
+	var third = text.substr(pos + prefix.length);
+	if (third.length > 0) {
+	  var thirdE = document.createTextNode(third);
+	  elem.parentNode.insertBefore(
+	    thirdE,
+	    elem
+	  );
+	  this._highlight(thirdE, prefix);
+	};
+	
+	var p = elem.parentNode;
+	p.removeChild(elem);
+      };
+    }
+    else {
+      var children = elem.childNodes;
+      for (var i = children.length -1; i >= 0; i--) {
+	this._highlight(children[i], prefix);
+      };
+    };
+  },
+
+  /**
+   * Remove highlight of the menu item
+   */
+  lowlight : function () {
+    var e = this.element();
+    
+    var marks = e.getElementsByTagName("mark");
+    for (var i = marks.length - 1; i >= 0; i--) {
+      // Create text node clone
+      var x = document.createTextNode(
+	marks[i].firstChild.nodeValue
+      );
+      
+      // Replace with content
+      marks[i].parentNode.replaceChild(
+	x,
+	marks[i]
+      );
+    };
+
+    // Remove consecutive textnodes
+    e.normalize();
+  },
+
+  // Initialize menu item
+  _init : function (params) {
+    
+    if (params[0] === undefined)
+      throw new Error("Missing parameters");
+
+    this.content(params[0]);
+    
+    if (params.length === 2)
+      this._action = params[1];
+
+    this._lcField = ' ' + this.content().textContent.toLowerCase();
+
+    return this;
+  },
+
+  /**
+   * Return menu list.
+   */
+  menu : function () {
+    return this._menu;
+  }
+});
diff --git a/dev/js/src/menu/prefix.js b/dev/js/src/menu/prefix.js
new file mode 100644
index 0000000..a4e428f
--- /dev/null
+++ b/dev/js/src/menu/prefix.js
@@ -0,0 +1,89 @@
+define({
+  create : function (params) {
+    return Object.create(this)._init();
+  },
+  _init : function () {
+    this._string = '';
+
+    // Add prefix span
+    this._element = document.createElement('span');
+    this._element.classList.add('pref');
+    // Connect action
+
+    if (this["onclick"] !== undefined)
+      this._element["onclick"] = this.onclick.bind(this);
+    
+    return this;
+  },
+  _update : function () {
+    this._element.innerHTML
+      = this._string;
+  },
+
+  /**
+   * Upgrade this object to another object,
+   * while private data stays intact.
+   *
+   * @param {Object} An object with properties.
+   */
+  upgradeTo : function (props) {
+    for (var prop in props) {
+      this[prop] = props[prop];
+    };
+    return this;
+  },
+
+  active : function (bool) {
+    var cl = this.element().classList;
+    if (bool === undefined)
+      return cl.contains("active");
+    else if (bool)
+      cl.add("active");
+    else
+      cl.remove("active");
+  },
+
+  element : function () {
+    return this._element;
+  },
+
+  isSet : function () {
+    return this._string.length > 0 ?
+      true : false;
+  },
+
+  value : function (string) {
+    if (arguments.length === 1) {
+      this._string = string;
+      this._update();
+    };
+    return this._string;
+  },
+  
+  add : function (string) {
+    this._string += string;
+    this._update();
+  },
+
+  onclick : function () {},
+
+  backspace : function () {
+    if (this._string.length > 1) {
+      this._string = this._string.substring(
+	0, this._string.length - 1
+      );
+    }
+    else {
+      this._string = '';
+    };
+    
+    this._update();
+  },
+
+  /**
+   * Return menu list.
+   */
+  menu : function () {
+    return this._menu;
+  }
+});
diff --git a/dev/js/src/session.js b/dev/js/src/session.js
index a10ce81..f81eb8f 100644
--- a/dev/js/src/session.js
+++ b/dev/js/src/session.js
@@ -4,77 +4,68 @@
  *
  * @author Nils Diewald
  */
-var KorAP = KorAP || {};
+define({
+  /**
+   * Create a new session.
+   * Expects a name or defaults to 'korap'
+   */
+  create : function (name) {
+    var obj = Object.create(this);
+    if (name === undefined)
+      name = 'korap';
+    obj._name = name.toLowerCase();
+    obj._hash = {};
+    obj._parse();
+    return obj;
+  },
 
-(function (KorAP) {
-  "use strict";
+  /**
+   * Get a value based on a key.
+   * The value can be complex, as the value is stored as JSON.
+   */
+  get : function (key) {
+    return this._hash[key.toLowerCase()];
+  },
 
-  
-  KorAP.Session = {
+  /**
+   * Set a value based on a key.
+   * The value can be complex, as the value is stored as JSON.
+   */
+  set : function (key, value) {
+    this._hash[key] = value;
+    this._store();
+  },
 
-    /**
-     * Create a new session.
-     * Expects a name or defaults to 'korap'
-     */
-    create : function (name) {
-      var obj = Object.create(KorAP.Session);
-      if (name === undefined)
-	name = 'korap';
-      obj._name = name.toLowerCase();
-      obj._hash = {};
-      obj._parse();
-      return obj;
-    },
+  /**
+   * Clears the session by removing the cookie
+   */
+  clear : function () {
+    document.cookie = this._name + '=; expires=-1';
+  },
 
-    /**
-     * Get a value based on a key.
-     * The value can be complex, as the value is stored as JSON.
-     */
-    get : function (key) {
-      return this._hash[key.toLowerCase()];
-    },
+  /* Store cookie */
+  _store : function () {
+    /*
+      var date = new Date();
+      date.setYear(date.getFullYear() + 1);
+    */
+    document.cookie =
+      this._name + '=' + encodeURIComponent(JSON.stringify(this._hash)) + ';';
+  },
 
-    /**
-     * Set a value based on a key.
-     * The value can be complex, as the value is stored as JSON.
-     */
-    set : function (key, value) {
-      this._hash[key] = value;
-      this._store();
-    },
-
-    /**
-     * Clears the session by removing the cookie
-     */
-    clear : function () {
-      document.cookie = this._name + '=; expires=-1';
-    },
-
-    /* Store cookie */
-    _store : function () {
-      /*
-	var date = new Date();
-	date.setYear(date.getFullYear() + 1);
-      */
-      document.cookie =
-	this._name + '=' + encodeURIComponent(JSON.stringify(this._hash)) + ';';
-    },
-
-    /* Parse cookie */
-    _parse : function () {
-      var c = document.cookie;
-      var part = document.cookie.split(';');
-      for(var i = 0; i < part.length; i++) {
-        var pair = part[i].split('=');
-        var name = pair[0].trim().toLowerCase();
-	if (name === this._name) {
-	  if (pair.length === 1 || pair[1].length === 0)
-	    return;
-          this._hash = JSON.parse(decodeURIComponent(pair[1]));
+  /* Parse cookie */
+  _parse : function () {
+    var c = document.cookie;
+    var part = document.cookie.split(';');
+    for(var i = 0; i < part.length; i++) {
+      var pair = part[i].split('=');
+      var name = pair[0].trim().toLowerCase();
+      if (name === this._name) {
+	if (pair.length === 1 || pair[1].length === 0)
 	  return;
-	};
+        this._hash = JSON.parse(decodeURIComponent(pair[1]));
+	return;
       };
-    }
+    };
   }
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/tutorial.js b/dev/js/src/tutorial.js
index 03cf903..dae5fbf 100644
--- a/dev/js/src/tutorial.js
+++ b/dev/js/src/tutorial.js
@@ -2,31 +2,30 @@
  * Open and close a tutorial page.
  * The current page is stored and retrieved in a session cookie.
  */
-// Requires session.js
-var KorAP = KorAP || {};
-
 // Todo: add query mechanism!
 
-(function (KorAP) {
+define(['session', 'util'], function (sessionClass) {
   "use strict";
 
   // Localization values
-  var loc   = (KorAP.Locale = KorAP.Locale || {} );
+  var loc   = KorAP.Locale;
   loc.CLOSE = loc.CLOSE || 'Close';
 
-  KorAP.Tutorial = {
-
+  return {
     /**
      * Create new tutorial object.
      * Accepts an element to bind the tutorial window to.
      */
     create : function (obj) {
-      return Object.create(KorAP.Tutorial)._init(obj);
+      if (!obj)
+	return null;
+      return Object.create(this)._init(obj);
     },
 
     // Initialize Tutorial object
     _init : function (obj) {
-      this._session = KorAP.Session.create();
+
+      this._session = sessionClass.create();
       this._show = obj;
       this.start = obj.getAttribute('href');
       obj.removeAttribute('href');
@@ -58,9 +57,6 @@
 	var ul = document.createElement('ul');
 	ul.classList.add('action', 'right');
 
-	// Use localization
-	var loc = KorAP.Locale;
-
 	// Add close button
 	var close = document.createElement('li');
 	close.appendChild(document.createElement('span'))
@@ -80,7 +76,7 @@
 	  info.classList.add('info');
 	  info.setAttribute('title', loc.SHOWINFO);
 	*/
-
+	
 	ul.appendChild(close);
 
 	element.appendChild(ul);
@@ -129,5 +125,5 @@
     getPage : function () {
       this._session.get('tutpage');
     },
-  }
-}(this.KorAP));
+  };
+});
diff --git a/dev/js/src/util.js b/dev/js/src/util.js
new file mode 100644
index 0000000..d183c36
--- /dev/null
+++ b/dev/js/src/util.js
@@ -0,0 +1,45 @@
+var KorAP = KorAP || {};
+
+// TODO: Make this part of util!
+// Don't let events bubble up
+if (Event.halt === undefined) {
+  // Don't let events bubble up
+  Event.prototype.halt = function () {
+    this.stopPropagation();
+    this.preventDefault();
+  };
+};
+
+// Add toggleClass method similar to jquery
+HTMLElement.prototype.toggleClass = function (c1, c2) {
+  var cl = this.classList;
+  if (cl.contains(c1)) {
+    cl.add(c2);
+    cl.remove(c1);
+  }
+  else {
+    cl.remove(c2);
+    cl.add(c1);
+  };
+};
+
+
+// Utility for removing all children of a node
+function _removeChildren (node) {
+  // Remove everything underneath
+  while (node.firstChild)
+    node.removeChild(node.firstChild);
+};
+
+
+define(function () {
+  KorAP.API = KorAP.API || {};
+  KorAP.Locale = KorAP.Locale || {};
+
+  // Default log message
+  KorAP.log = KorAP.log || function (type, msg) {
+    console.log(type + ": " + msg);
+  };
+
+  return KorAP;
+});
diff --git a/dev/js/src/vc.js b/dev/js/src/vc.js
index 2c8ad01..48c5694 100644
--- a/dev/js/src/vc.js
+++ b/dev/js/src/vc.js
@@ -6,9 +6,6 @@
 /*
  * Replaces a previous version written by Mengfei Zhou
  */
-var KorAP = KorAP || {};
-
-// Requires menu.js
 
 /*
   TODO: Implement a working localization solution!
@@ -33,131 +30,60 @@
   815: "Rewrite expects source"
 */
 
-(function (KorAP) {
+define([
+  'vc/unspecified',
+  'vc/doc',
+  'vc/docgroup',
+  'util'
+], function (unspecDocClass, docClass, docGroupClass) {
   "use strict";
 
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
   KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains|excludes)$");
-  KorAP._validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
+  // KorAP._validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
   KorAP._validDateMatchRE   = new RegExp("^[lg]?eq$");
   KorAP._validDateRE        = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
-  KorAP._validGroupOpRE     = new RegExp("^(?:and|or)$");
-  KorAP._validRewriteOpRE   = new RegExp("^(?:injec|modifica)tion$");
-  KorAP._quote              = new RegExp("([\"\\\\])", 'g');
+  // KorAP._validGroupOpRE     = new RegExp("^(?:and|or)$");
+  // KorAP._quote              = new RegExp("([\"\\\\])", 'g');
 
   // Localization values
   var loc   = (KorAP.Locale = KorAP.Locale || {} );
-  loc.AND   = loc.AND   || 'and';
-  loc.OR    = loc.OR    || 'or';
-  loc.DEL   = loc.DEL   || '×';
-  loc.EMPTY = loc.EMPTY || '⋯'
-
-  // Utility for analysing boolean values
-  function _bool (bool) {
-    return (bool === undefined || bool === null || bool === false) ? false : true;
-  };
-
-
-  // Utility for removing all children of a node
-  function _removeChildren (node) {
-    // Remove everything underneath
-    while (node.firstChild)
-      node.removeChild(node.firstChild);
-  };
-
-
-  // Add new unspecified document
-  KorAP._add = function (obj, type) {
-    var ref = obj.parentNode.refTo;
-    var parent = ref.parent();
-
-    if (ref.ldType() === 'docGroup') {
-
-      // Check that the action differs from the type
-      if (ref.operation() === type)
-	return;
-
-      if (parent.ldType() !== null) {
-	return parent.newAfter(ref);
-      }
-      else {
-	// The group is on root - wrap
-	return ref.wrapOnRoot();
-      };
-    }
-    else if (ref.ldType() === 'doc') {
-
-      if (parent.ldType() === null) {
-	return ref.wrapOnRoot(type);
-      }
-      else if (parent.operation() === type) {
-	return parent.newAfter(ref);
-      }
-      else {
-	return ref.wrap(type);
-      };
-    };
-  };
-
-
-  // Add doc with 'and' relation
-  KorAP._and = function () {
-    return KorAP._add(this, 'and');
-  };
-
-
-  // Add doc with 'or' relation
-  KorAP._or = function () {
-    return KorAP._add(this, 'or');
-  };
-
-
-  // Remove doc or docGroup
-  KorAP._delete = function () {
-    var ref = this.parentNode.refTo;
-    if (ref.parent().ldType() !== null) {
-      return ref.parent().delOperand(ref).update();
-    }
-    else {
-      ref.parent().clean();
-    };
-  };
-
+  /*
+    loc.AND   = loc.AND   || 'and';
+    loc.OR    = loc.OR    || 'or';
+    loc.DEL   = loc.DEL   || '×';
+    loc.EMPTY = loc.EMPTY || '⋯'
+  */
 
   /**
    * Virtual Collection
    */
-  KorAP.VirtualCollection = {
+  return {
     ldType : function () {
       return null;
     },
 
     create : function () {
-      return Object.create(KorAP.VirtualCollection);
+      return Object.create(this);
     },
 
     clean : function () {
       if (this._root.ldType() !== "non") {
 	this._root.destroy();
-	this.root(KorAP.UnspecifiedDoc.create(this));
+	this.root(unspecDocClass.create(this));
       };
       return this;
     },
 
     render : function (json) {
-      var obj = Object.create(KorAP.VirtualCollection);
+      var obj = Object.create(this);
 
       if (json !== undefined) {
 	// Root object
 	if (json['@type'] == 'koral:doc') {
-	  obj._root = KorAP.Doc.create(obj, json);
+	  obj._root = docClass.create(obj, json);
 	}
 	else if (json['@type'] == 'koral:docGroup') {
-	  obj._root = KorAP.DocGroup.create(obj, json);
+	  obj._root = docGroupClass.create(obj, json);
 	}
 	else {
 	  KorAP.log(813, "Collection type is not supported");
@@ -225,1174 +151,4 @@
       return this._root.toQuery();
     }
   };
-
-
-  /**
-   * Operators for criteria
-   */
-  KorAP.Operators = {
-    create : function (and, or, del) {
-      var op = Object.create(KorAP.Operators);
-      op.and(and);
-      op.or(or);
-      op.del(del);
-      return op;
-    },
-
-    update : function () {
-      // Init the element
-      if (this._element === undefined)
-	return this.element();
-
-      var op = this._element;
-
-      op.refTo = this.parent();
-
-      // Remove everything underneath
-      _removeChildren(op);
-
-      // Add and button
-      if (this._and === true) {
-	var andE = document.createElement('span');
-	andE.setAttribute('class', 'and');
-	andE.addEventListener('click', KorAP._and, false);
-	andE.appendChild(
-	  document.createTextNode(KorAP.Locale.AND)
-	);
-	op.appendChild(andE);
-      };
-
-      // Add or button
-      if (this._or === true) {
-	var orE = document.createElement('span');
-	orE.setAttribute('class', 'or');
-	orE.addEventListener('click', KorAP._or, false);
-	orE.appendChild(document.createTextNode(KorAP.Locale.OR));
-	op.appendChild(orE);
-      };
-
-      // Add delete button
-      if (this._del === true) {
-	var delE = document.createElement('span');
-	delE.setAttribute('class', 'delete');
-	delE.appendChild(document.createTextNode(KorAP.Locale.DEL));
-	delE.addEventListener('click', KorAP._delete, false);
-	op.appendChild(delE);
-      };
-
-      return op;
-    },
-
-    // Be aware! This may be cyclic
-    parent : function (obj) {
-      if (arguments.length === 1)
-	this._parent = obj;
-      return this._parent;
-    },
-
-    element : function () {
-
-      // Return existing element
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'operators');
-
-      // Init elements
-      this.update();
-      return this._element;
-    },
-
-    and : function (bool) {
-      if (arguments.length === 1)
-	this._and = _bool(bool);
-      return this._and;
-    },
-
-    or : function (bool) {
-      if (arguments.length === 1)
-	this._or = _bool(bool);
-      return this._or;
-    },
-
-    del : function (bool) {
-      if (arguments.length === 1)
-	this._del = _bool(bool);
-      return this._del;
-    }
-  };
-
-
-  /**
-   * Unspecified criterion
-   */
-  KorAP.UnspecifiedDoc = {
-    _ldType : "non",
-    create : function (parent) {
-      var obj = Object.create(KorAP.JsonLD).
-	upgradeTo(KorAP.UnspecifiedDoc);
-
-      if (parent !== undefined)
-	obj._parent = parent;
-
-      return obj;
-    },
-
-    // Set key - replace
-    key : function (v) {
-
-      // Not replaceable
-      if (this._parent === undefined)
-	return null;
-
-      // Set JSON-LD type
-      var newDoc = KorAP.Doc.create(this._parent, {
-	"@type" : "koral:doc",
-	"value" : "",
-	"key"   : v
-      });
-
-      // Unspecified document on root
-      if (this._parent.ldType() === null) {
-	this._parent.root(newDoc);
-	this.destroy();
-      }
-
-      // Unspecified document in group
-      else {
-	this._parent.replaceOperand(this, newDoc);
-      };
-      this._parent.update();
-      return newDoc;
-    },
-
-    update : function () {
-
-      if (this._element === undefined)
-	return this.element();
-
-      // Remove element content
-      _removeChildren(this._element);
-
-      var ellipsis = document.createElement('span');
-      ellipsis.appendChild(document.createTextNode(loc.EMPTY));
-      this._element.appendChild(ellipsis);
-
-      // Set ref - TODO: Cleanup!
-      this._element.refTo = this;
-
-      // Set operators
-      if (this._parent !== undefined && this.parent().ldType() !== null) {
-	var op = this.operators(
-	  false,
-	  false,
-	  true
-	);
-
-	this._element.appendChild(
-	  op.element()
-	);
-      };
-
-      return this.element();
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'doc unspecified');
-      this.update();
-      return this._element;
-    },
-
-    
-  };
-
-
-  /**
-   * Document criterion
-   */
-  KorAP.Doc = {
-    _ldType : "doc",
-    _obj : function () { return KorAP.Doc },
-
-    create : function (parent, json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.Doc).
-	fromJson(json);
-
-      if (parent !== undefined)
-	obj._parent = parent;
-
-      obj.__changed = true;
-      return obj;
-    },
-
-    update : function () {
-      if (this._element === undefined)
-	return this.element();
-
-      // Get element
-      var e = this._element;
-
-      // Set ref - TODO: Cleanup!
-      e.refTo = this;
-
-      // Check if there is a change
-      if (this.__changed) {
-
-	// Was rewritten
-	if (this.rewrites() !== undefined) {
-	  e.classList.add("rewritten");
-	};
-
-	// Added key
-	var key = document.createElement('span');
-	key.setAttribute('class', 'key');
-
-	// Change key
-	key.addEventListener('click', KorAP._changeKey, false);
-
-	if (this.key())
-	  key.appendChild(document.createTextNode(this.key()));
-
-	// Added match operator
-	var matchop = document.createElement('span');
-	matchop.setAttribute('data-type', this.type());
-	matchop.setAttribute('class', 'match');
-	matchop.appendChild(
-	  document.createTextNode(this.matchop())
-	);
-
-	// Added match operator
-	var value = document.createElement('span');
-	value.setAttribute('data-type', this.type());
-	value.setAttribute('class', 'value');
-	if (this.value())
-	  value.appendChild(
-	    document.createTextNode(this.value())
-	  );
-
-	// Remove all element children
-	_removeChildren(e);
-
-	// Add spans
-	e.appendChild(key);
-	e.appendChild(matchop);
-	e.appendChild(value);
-
-	this.__changed = false;
-      };
-
-      if (this._rewrites !== undefined) {
-	e.appendChild(this._rewrites.element());
-      };
-
-      if (this._parent !== undefined) {
-	// Set operators
-	var op = this.operators(
-	  true,
-	  true,
-	  true
-	);
-
-	// Append new operators
-	e.appendChild(op.element());
-      };
-
-      return e;
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'doc');
-
-      this.update();
-      return this._element;
-    },
-
-    // Wrap a new operation around the doc element
-    wrap : function (op) {
-      var parent = this.parent();
-      var group = KorAP.DocGroup.create(parent);
-      group.operation(op);
-      group.append(this);
-      group.append();
-      return parent.replaceOperand(this, group).update();
-    },
-
-    // Deserialize from json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      if (json["value"] === undefined ||
-	  typeof json["value"] != 'string') {
-	KorAP.log(805, "Value is invalid");
-	return;
-      };
-
-      // There is a defined key
-      if (json["key"] !== undefined &&
-	  typeof json["key"] === 'string') {
-
-	// Set key
-	this.key(json["key"]);
-
-	// Set match operation
-	if (json["match"] !== undefined) {
-	  if (typeof json["match"] === 'string') {
-	    this.matchop(json["match"]);
-	  }
-	  else {
-	    KorAP.log(802, "Match type is not supported by value type");
-	    return;
-	  };
-	};
-
-	// Key is a string
-	if (json["type"] === undefined ||
-	    json["type"] == "type:string") {
-	  this.type("string");
-
-	  // Check match type
-	  if (!KorAP._validStringMatchRE.test(this.matchop())) {
-	    KorAP.log(802, "Match type is not supported by value type");
-	    return;
-	  };
-
-	  // Set string value
-	  this.value(json["value"]);
-	}
-
-	// Key is a date
-	else if (json["type"] === "type:date") {
-	  this.type("date");
-
-	  if (json["value"] !== undefined &&
-	      KorAP._validDateRE.test(json["value"])) {
-
-	    if (!KorAP._validDateMatchRE.test(this.matchop())) {
-	      KorAP.log(802, "Match type is not supported by value type");
-	      return;
-	    };
-
-	    // Set value
-	    this.value(json["value"]);
-	  }
-	  else {
-	    KorAP.log(806, "Value is not a valid date string");
-	    return;
-	  };
-	}
-
-	// Key is a regular expression
-	else if (json["type"] === "type:regex") {
-	  this.type("regex");
-
-	  try {
-
-	    // Try to create a regular expression
-	    var check = new RegExp(json["value"]);
-
-	    if (!KorAP._validRegexMatchRE.test(this.matchop())) {
-	      KorAP.log(802, "Match type is not supported by value type");
-	      return;
-	    };
-
-	    this.value(json["value"]);
-	  }
-
-	  catch (e) {
-	    KorAP.log(807, "Value is not a valid regular expression");
-	    return;
-	  };
-	  this.type("regex");
-	}
-
-	else {
-	  KorAP.log(804, "Unknown value type");
-	  return;
-	};
-
-      };
-
-      if (json["rewrites"] !== undefined) {
-	this._rewrites = KorAP.RewriteList.create(json["rewrites"]);
-      };
-	
-      return this;
-    },
-
-    key : function (value) {
-      if (arguments.length === 1) {
-	this._key = value;
-	this._changed();
-	return this;
-      };
-      return this._key;
-    },
-
-    matchop : function (match) {
-      if (arguments.length === 1) {
-	this._matchop = match.replace(/^match:/, '');
-	this._changed();
-	return this;
-      };
-      return this._matchop || "eq";
-    },
-
-    type : function (type) {
-      if (arguments.length === 1) {
-	this._type = type;
-	this._changed();
-	return this;
-      };
-      return this._type || "string";
-    },
-
-    value : function (value) {
-      if (arguments.length === 1) {
-	this._value = value;
-	this._changed();
-	return this;
-      };
-      return this._value;
-    },
-
-    rewrites : function () {
-      return this._rewrites;
-    },
-
-    _changed : function () {
-      this.__changed = true;
-
-      if (this._rewrites === undefined)
-	return;
-      delete this["_rewrites"];
-      if (this._element === undefined)
-	return;
-      this._element.classList.remove("rewritten");
-    },
-
-    toJson : function () {
-      if (!this.matchop() || !this.key())
-	return {};
-      
-      return {
-	"@type" : "koral:" + this.ldType(),
-	"key"   : this.key(),
-	"match" : "match:" + this.matchop(),
-	"value" : this.value() || '',
-	"type"  : "type:" + this.type()
-      };
-    },
-
-    toQuery : function () {
-      if (!this.matchop() || !this.key())
-	return "";
-
-      // Build doc string based on key
-      var string = this.key() + ' ';
-
-      // Add match operator
-      switch (this.matchop()) {
-      case "ne":
-	string += '!=';
-	break;
-      case "contains":
-	string += '~';
-	break;
-      case "excludes":
-	string += '!~';
-	break;
-      case "geq":
-	string += 'since';
-	break;
-      case "leq":
-	string += 'until';
-	break;
-      default:
-	string += (this.type() == 'date') ? 'in' : '=';
-	break;
-      };
-
-      string += ' ';
-
-      // Add value
-      switch (this.type()) {
-      case "date":
-	return string + this.value();
-	break;
-      case "regex":
-	return string + '/' + this.value() + '/';
-	break;
-      case "string":
-	return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
-	break;
-      };
-
-      return "";
-    }
-  };
-
-
-  /**
-   * Document group criterion
-   */
-  KorAP.DocGroup = {
-    _ldType : "docGroup",
-
-    create : function (parent, json) {
-      var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.DocGroup);
-      obj._operands = [];
-      obj.fromJson(json);
-      if (parent !== undefined)
-	obj._parent = parent;
-      return obj;
-    },
-
-    newAfter : function (obj) {
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === obj) {
-	  var operand = KorAP.UnspecifiedDoc.create(this);
-	  this._operands.splice(i + 1, 0, operand);
-	  return this.update();
-	};
-      };
-    },
-
-    // The doc is already set in the group
-    _duplicate : function (operand) {
-      if (operand.ldType() !== 'doc')
-	return null;
-
-      for (var i = 0; i < this._operands.length; i++) {
-	var op = this.getOperand(i);
-	if (op.ldType() === 'doc'
-	    && operand.key() === op.key()
-	    && operand.matchop() === op.matchop()
-	    && operand.value() === op.value()) {
-	  return op;
-	};
-      };
-      return null;
-    },
-
-    append : function (operand) {
-
-      // Append unspecified object
-      if (operand === undefined) {
-
-	// Be aware of cyclic structures!
-	operand = KorAP.UnspecifiedDoc.create(this);
-	this._operands.push(operand);
-	return operand;
-      };
-
-      switch (operand["@type"]) {
-
-      case undefined:
-	// No @type defined
-	if (operand["ldType"] !== undefined) {
-	  if (operand.ldType() !== 'doc' &&
-	      operand.ldType() !== 'docGroup') {
-	    KorAP.log(812, "Operand not supported in document group");
-	    return;
-	  };
-	  // Be aware of cyclic structures!
-	  operand.parent(this);
-
-	  var dupl = this._duplicate(operand);
-	  if (dupl === null) {
-	    this._operands.push(operand);
-	    return operand;
-	  };
-	  return dupl;
-	};
-
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-
-      case "koral:doc":
-	// Be aware of cyclic structures!
-	var doc = KorAP.Doc.create(this, operand);
-	if (doc === undefined)
-	  return;
-	var dupl = this._duplicate(doc);
-	if (dupl === null) {
-	  this._operands.push(doc);
-	  return doc;
-	};
-	return dupl;
-
-      case "koral:docGroup":
-	// Be aware of cyclic structures!
-	var docGroup = KorAP.DocGroup.create(this, operand);
-	if (docGroup === undefined)
-	  return;
-
-	// Flatten group
-	if (docGroup.operation() === this.operation()) {
-	  for (var op in docGroup.operands()) {
-	    op = docGroup.getOperand(op);
-	    var dupl = this._duplicate(op);
-	    if (dupl === null) {
-	      this._operands.push(op);
-	      op.parent(this);
-	    };
-	  };
-	  docGroup._operands = [];
-	  docGroup.destroy();
-	  return this;
-	};
-	this._operands.push(docGroup);
-	return docGroup;
-
-      default:
-	KorAP.log(812, "Operand not supported in document group");
-	return;
-      };
-    },
-
-    update : function () {
-      // There is only one operand in group
-
-      if (this._operands.length === 1) {
-
-	var parent = this.parent();
-	var op = this.getOperand(0);
-
-	// This will prevent destruction of
-	// the operand
-	this._operands = [];
-
-	// Parent is a group
-	if (parent.ldType() !== null)
-	  return parent.replaceOperand(this, op).update();
-
-	// Parent is vc
-	else {
-	  this.destroy();
-	  // Cyclic madness
-	  parent.root(op);
-	  op.parent(parent);
-	  return parent.root();
-	};
-      };
-
-      if (this._element === undefined)
-	return this;
-
-      var group = this._element;
-      group.setAttribute('data-operation', this.operation());
-
-      _removeChildren(group);
-
-      // Append operands
-      for (var i = 0; i < this._operands.length; i++) {
-	group.appendChild(
-	  this.getOperand(i).element()
-	);
-      };
-
-      // Set operators
-      var op = this.operators(
-	this.operation() == 'and' ? false : true,
-	this.operation() == 'or'  ? false : true,
-	true
-      );
-
-      group.appendChild(
-	op.element()
-      );
-
-      return this;
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'docGroup');
-
-      // Update the object - including optimization
-      this.update();
-
-      return this._element;
-    },
-
-    operation : function (op) {
-      if (arguments.length === 1) {
-	if (KorAP._validGroupOpRE.test(op)) {
-	  this._op = op;
-	}
-	else {
-	  KorAP.log(810, "Unknown operation type");
-	  return;
-	};
-      };
-      return this._op || 'and';
-    },
-
-    operands : function () {
-      return this._operands;
-    },
-
-    getOperand : function (index) {
-      return this._operands[index];
-    },
-
-    // Replace operand
-    replaceOperand : function (oldOp, newOp) {
-
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === oldOp) {
-
-	  // Just insert a doc or ...
-	  if (newOp.ldType() === "doc" ||
-	      newOp.ldType() === "non" ||
-	      // ... insert a group of a different operation
-	      // (i.e. "and" in "or"/"or" in "and")
-	      newOp.operation() != this.operation()) {
-	    this._operands[i] = newOp;
-	    newOp.parent(this);
-	  }
-
-	  // Flatten group
-	  else {
-	    // Remove old group
-	    this._operands.splice(i, 1);
-
-	    // Inject new operands
-	    for (var op in newOp.operands().reverse()) {
-	      op = newOp.getOperand(op);
-	      this._operands.splice(i, 0, op);
-	      op.parent(this);
-	    };
-	    // Prevent destruction of operands
-	    newOp._operands = [];
-	    newOp.destroy();
-	  };
-	  oldOp.destroy();
-	  return this;
-	}
-      };
-      return false;
-    },
-
-    // Delete operand from group
-    delOperand : function (obj) {
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === obj) {
-
-	  // Delete identified operand
-	  this._operands.splice(i,1);
-
-	  // Destroy object for cyclic references
-	  obj.destroy();
-
-	  return this;
-	};
-      };
-
-      // Operand not found
-      return undefined;
-    },
-
-    // Deserialize from json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      if (json["operation"] === undefined ||
-	  typeof json["operation"] !== 'string') {
-	KorAP.log(811, "Document group expects operation");
-	return;
-      };
-
-      var operation = json["operation"];
-
-      this.operation(operation.replace(/^operation:/,''));
-
-      if (json["operands"] === undefined ||
-	  !(json["operands"] instanceof Array)) {
-	KorAP.log(704, "Operation needs operand list")
-	return;
-      };
-
-      // Add all documents
-      for (var i in json["operands"]) {
-	var operand = json["operands"][i];
-	this.append(operand);
-      };
-    
-      return this;
-    },
-
-    toJson : function () {
-      var opArray = new Array();
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i].ldType() !== 'non')
-	  opArray.push(this._operands[i].toJson());
-      };
-      return {
-	"@type"     : "koral:" + this.ldType(),
-	"operation" : "operation:" + this.operation(),
-	"operands"  : opArray
-      };
-    },
-
-    toQuery : function (brackets) {
-      var list = this._operands
-	.filter(function (op) {
-	  return op.ldType() !== 'non';
-	})
-	.map(function (op) {
-	  return (op.ldType() === 'docGroup') ?
-	    op.toQuery(true) :
-	    op.toQuery();
-	});
-
-      if (list.length === 1)
-	return list.join('');
-      else {
-	var str = list.join(this.operation() === 'or' ? ' | ' : ' & ');
-	return brackets ? '(' + str + ')' : str;
-      };
-    }
-  };
-
-
-  KorAP.RewriteList = {
-    // Construction method
-    create : function (json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.RewriteList).
-	fromJson(json);
-      return obj;
-    },
-    fromJson : function (json) {
-      this._list = new Array();
-      for (var i = 0; i < json.length; i++) {
-	this._list.push(
-	  KorAP.Rewrite.create(json[i])
-	);
-      };
-      return this;
-    },
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'rewrite');
-      for (var x in this._list) {
-	var rewrite = this._list[x];
-	var span = document.createElement('span');
-
-	// Set class attribute
-	span.setAttribute('class', rewrite.operation());
-
-	// Append source information
-	span.appendChild(document.createTextNode(rewrite.src()));
-
-	// Append scope information
-	if (rewrite.scope() !== undefined) {
-	  span.appendChild(
-	    document.createTextNode(
-	      ': ' + rewrite.scope()
-	    )
-	  );
-	};
-	this._element.appendChild(span);
-      };
-      return this._element;
-    }
-  };
-
-
-  /**
-   * Implementation of rewrite objects.
-   */
-  KorAP.Rewrite = {
-
-    // Construction method
-    create : function (json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.Rewrite).
-	fromJson(json);
-      return obj;
-    },
-
-    // Get or set source
-    src : function (string) {
-      if (arguments.length === 1)
-	this._src = string;
-      return this._src;
-    },
-    
-    // Get or set operation
-    operation : function (op) {
-      if (arguments.length === 1) {
-	if (KorAP._validRewriteOpRE.test(op)) {
-	  this._op = op;
-	}
-	else {
-	  KorAP.log(814, "Unknown rewrite operation");
-	  return;
-	};
-      };
-      return this._op || 'injection';
-    },
-
-    // Get or set scope
-    scope : function (attr) {
-      if (arguments.length === 1)
-	this._scope = attr;
-      return this._scope;
-    },
-
-    // Serialize from Json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      // Missing @type
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      // Missing source
-      if (json["src"] === undefined ||
-	 typeof json["src"] !== 'string') {
-	KorAP.log(815, "Rewrite expects source");
-	return;
-      };
-
-      // Set source
-      this.src(json["src"]);
-
-      // Set operation
-      if (json["operation"] !== undefined) {
-	var operation = json["operation"];
-	this.operation(operation.replace(/^operation:/,''));
-      };
-
-      // Set scope
-      if (json["scope"] !== undefined &&
-	  typeof json["scope"] === 'string')
-	this.scope(json["scope"]);
-
-      return this;
-    },
-
-    toString : function () {
-      var str = '';
-      var op = this.operation();
-      str += op.charAt(0).toUpperCase() + op.slice(1);
-      str += ' of ' + (
-	this._scope === null ?
-	  'object' :
-	  '"' +
-	  this.scope().replace(KorAP._quote, '\\$1') +
-	  '"'
-      );
-      str += ' by ' +
-	'"' +
-	this.src().replace(KorAP._quote, '\\$1') +
-	'"';
-      return str;
-    }
-  };
-
-
-  /**
-   * Abstract JsonLD criterion object
-   */
-  KorAP.JsonLD = {
-    __changed : false,
-
-    create : function () {
-      return Object.create(KorAP.JsonLD);
-    },
-
-    /**
-     * Upgrade this object to another object
-     * while private data stays intact
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    ldType : function (type) {
-      if (arguments.length === 1)
-	this._ldType = type;
-      return this._ldType;
-    },
-
-    parent : function (obj) {
-      if (arguments.length === 1) {
-	this._parent = obj;
-	this.__changed = true;
-      };
-      return this._parent;
-    },
-
-    // Destroy object - especially for
-    // acyclic structures!
-    // I'm paranoid!
-    destroy : function () {
-      if (this._ops != undefined) {
-	this._ops._parent = undefined;
-	if (this._ops._element !== undefined)
-	  this._ops._element.refTo = undefined;
-	this._ops = undefined;
-      };
-      if (this._element !== undefined)
-	this._element = undefined;
-
-      // In case of a group, destroy all operands
-      if (this._operands !== undefined) {
-      for (var i = 0; i < this._operands.length; i++)
-	  this.getOperand(i).destroy();
-	this._operands = [];
-      };
-    },
-
-    // Wrap a new operation around the root group element 
-    wrapOnRoot : function (op) {
-      var parent = this.parent();
-
-      var group = KorAP.DocGroup.create(parent);
-      if (arguments.length === 1)
-	group.operation(op);
-      else
-	group.operation(
-	  this.operation() === 'and' ? 'or' : 'and'
-	);
-      group.append(this);
-      this.parent(group);
-      group.append();
-      group.element(); // Init (seems to be necessary)
-      parent.root(group);
-      return this.parent();
-    },
-
-    // Be aware! This may be cyclic
-    operators : function (and, or, del) {
-      if (arguments === 0)
-	return this._ops;
-      this._ops = KorAP.Operators.create(
-	and, or, del
-      );
-      this._ops.parent(this);
-      return this._ops;
-    },
-
-    toJson : function () {
-      return {
-	// Unspecified object
-	"@type" : "koral:" + this.ldType()
-      };
-    },
-
-    toQuery : function () {
-      return '';
-    }
-  };
-
-
-  /**
-   * Criterion in a KorAP.Doc
-   */
-  KorAP._changeKey = function () {
-    var doc = this.parentNode.refTo;
-    var key = doc.element().firstChild;
-    key.appendChild(KorAP.FieldChooser.element());
-    KorAP.FieldChooser.show();
-    KorAP.FieldChooser.focus();
-    // key, matchop, type, value
-  };
-  
-  // Field menu
-  KorAP.FieldMenu = {
-    create : function (params) {
-      return Object.create(KorAP.Menu)
-	.upgradeTo(KorAP.FieldMenu)
-	._init(KorAP.FieldMenuItem, undefined, params)
-    }
-  };
-
-
-  // Field menu item
-  KorAP.FieldMenuItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.FieldMenuItem)
-	._init(params);
-    },
-    _init : function (params) {
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this._name  = params[0];
-      this._value = params[1];
-      this._type  = params[2];
-
-      this._lcField = ' ' + this._name.toLowerCase();
-
-      return this;
-    },
-    name : function () {
-      return this._name;
-    },
-    type : function () {
-      return this._type;
-    },
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-      li.setAttribute("data-type", this._type);
-      li.setAttribute("data-value", this._value);
-      li.appendChild(document.createTextNode(this._name));
-      return this._element = li;
-    }
-  };
-
-  KorAP.FieldChooser = KorAP.FieldMenu.create([
-    ['Titel', 'title', 'string'],
-    ['Untertitel', 'subTitle', 'string'],
-    ['Veröffentlichungsdatum', 'pubDate', 'date'],
-    ['Autor', 'author', 'string']
-  ]);
-  KorAP.FieldChooser.limit(5);
- 
-}(this.KorAP));
+});
diff --git a/dev/js/src/vc/doc.js b/dev/js/src/vc/doc.js
new file mode 100644
index 0000000..61c6439
--- /dev/null
+++ b/dev/js/src/vc/doc.js
@@ -0,0 +1,363 @@
+/**
+ * Document criterion
+ */
+
+/**
+ * Criterion in a KorAP.Doc
+ */
+function _changeKey () {
+  var doc = this.parentNode.refTo;
+  var key = doc.element().firstChild;
+  key.appendChild(fieldMenu.element());
+  fieldMenu.show();
+  fieldMenu.focus();
+  // key, matchop, type, value
+};
+
+define([
+  'vc/jsonld', 'vc/menu', 'vc/rewritelist'], function (jsonldClass, menuClass, rewriteListClass) {
+  var fieldMenu = menuClass.create([
+    ['Titel', 'title', 'string'],
+    ['Untertitel', 'subTitle', 'string'],
+    ['Veröffentlichungsdatum', 'pubDate', 'date'],
+    ['Autor', 'author', 'string']
+  ]);
+
+  fieldMenu.limit(5);
+
+  _validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
+
+  return {
+    _ldType : "doc",
+    _obj : function () { return '???'; /*KorAP.Doc*/ },
+    
+    create : function (parent, json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      
+      if (parent !== undefined)
+	obj._parent = parent;
+      
+      obj.__changed = true;
+      return obj;
+    },
+
+    update : function () {
+      if (this._element === undefined)
+	return this.element();
+      
+      // Get element
+      var e = this._element;
+
+      // Set ref - TODO: Cleanup!
+      e.refTo = this;
+
+      // Check if there is a change
+      if (this.__changed) {
+
+	// Was rewritten
+	if (this.rewrites() !== undefined) {
+	  e.classList.add("rewritten");
+	};
+
+	// Added key
+	var key = document.createElement('span');
+	key.setAttribute('class', 'key');
+
+	// Change key
+	key.addEventListener('click', _changeKey, false);
+
+	if (this.key())
+	  key.appendChild(document.createTextNode(this.key()));
+	
+	// Added match operator
+	var matchop = document.createElement('span');
+	matchop.setAttribute('data-type', this.type());
+	matchop.setAttribute('class', 'match');
+	matchop.appendChild(
+	  document.createTextNode(this.matchop())
+	);
+
+	// Added match operator
+	var value = document.createElement('span');
+	value.setAttribute('data-type', this.type());
+	value.setAttribute('class', 'value');
+	if (this.value())
+	  value.appendChild(
+	    document.createTextNode(this.value())
+	  );
+
+	// Remove all element children
+	_removeChildren(e);
+
+	// Add spans
+	e.appendChild(key);
+	e.appendChild(matchop);
+	e.appendChild(value);
+
+	this.__changed = false;
+      };
+
+      if (this._rewrites !== undefined) {
+	e.appendChild(this._rewrites.element());
+      };
+
+      if (this._parent !== undefined) {
+	// Set operators
+	var op = this.operators(
+	  true,
+	  true,
+	  true
+	);
+
+	// Append new operators
+	e.appendChild(op.element());
+      };
+      
+      return e;
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'doc');
+
+      this.update();
+      return this._element;
+    },
+
+    // Wrap a new operation around the doc element
+    wrap : function (op) {
+      var parent = this.parent();
+      var group = KorAP.DocGroup.create(parent);
+      group.operation(op);
+      group.append(this);
+      group.append();
+      return parent.replaceOperand(this, group).update();
+    },
+
+    // Deserialize from json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+
+      if (json["value"] === undefined ||
+	  typeof json["value"] != 'string') {
+	KorAP.log(805, "Value is invalid");
+	return;
+      };
+
+      // There is a defined key
+      if (json["key"] !== undefined &&
+	  typeof json["key"] === 'string') {
+
+	// Set key
+	this.key(json["key"]);
+
+	// Set match operation
+	if (json["match"] !== undefined) {
+	  if (typeof json["match"] === 'string') {
+	    this.matchop(json["match"]);
+	  }
+	  else {
+	    KorAP.log(802, "Match type is not supported by value type");
+	    return;
+	  };
+	};
+
+	// Key is a string
+	if (json["type"] === undefined ||
+	    json["type"] == "type:string") {
+	  this.type("string");
+
+	  // Check match type
+	  if (!KorAP._validStringMatchRE.test(this.matchop())) {
+	    KorAP.log(802, "Match type is not supported by value type");
+	    return;
+	  };
+
+	  // Set string value
+	  this.value(json["value"]);
+	}
+
+	// Key is a date
+	else if (json["type"] === "type:date") {
+	  this.type("date");
+
+	  if (json["value"] !== undefined &&
+	      KorAP._validDateRE.test(json["value"])) {
+
+	    if (!KorAP._validDateMatchRE.test(this.matchop())) {
+	      KorAP.log(802, "Match type is not supported by value type");
+	      return;
+	    };
+
+	    // Set value
+	    this.value(json["value"]);
+	  }
+	  else {
+	    KorAP.log(806, "Value is not a valid date string");
+	    return;
+	  };
+	}
+
+	// Key is a regular expression
+	else if (json["type"] === "type:regex") {
+	  this.type("regex");
+
+	  try {
+
+	    // Try to create a regular expression
+	    var check = new RegExp(json["value"]);
+
+	    if (!_validRegexMatchRE.test(this.matchop())) {
+	      KorAP.log(802, "Match type is not supported by value type");
+	      return;
+	    };
+
+	    this.value(json["value"]);
+	  }
+
+	  catch (e) {
+	    KorAP.log(807, "Value is not a valid regular expression");
+	    return;
+	  };
+	  this.type("regex");
+	}
+
+	else {
+	  KorAP.log(804, "Unknown value type");
+	  return;
+	};
+      };
+
+      if (json["rewrites"] !== undefined) {
+	this._rewrites = rewriteListClass.create(json["rewrites"]);
+      };
+      
+      return this;
+    },
+
+    key : function (value) {
+      if (arguments.length === 1) {
+	this._key = value;
+	this._changed();
+	return this;
+      };
+      return this._key;
+    },
+
+    matchop : function (match) {
+      if (arguments.length === 1) {
+	this._matchop = match.replace(/^match:/, '');
+	this._changed();
+	return this;
+      };
+      return this._matchop || "eq";
+    },
+
+    type : function (type) {
+      if (arguments.length === 1) {
+	this._type = type;
+	this._changed();
+	return this;
+      };
+      return this._type || "string";
+    },
+
+    value : function (value) {
+      if (arguments.length === 1) {
+	this._value = value;
+	this._changed();
+	return this;
+      };
+      return this._value;
+    },
+
+    rewrites : function () {
+      return this._rewrites;
+    },
+
+    _changed : function () {
+      this.__changed = true;
+      
+      if (this._rewrites === undefined)
+	return;
+
+      delete this["_rewrites"];
+
+      if (this._element === undefined)
+	return;
+      this._element.classList.remove("rewritten");
+    },
+
+    toJson : function () {
+      if (!this.matchop() || !this.key())
+	return {};
+      
+      return {
+	"@type" : "koral:" + this.ldType(),
+	"key"   : this.key(),
+	"match" : "match:" + this.matchop(),
+	"value" : this.value() || '',
+	"type"  : "type:" + this.type()
+      };
+    },
+
+    toQuery : function () {
+      if (!this.matchop() || !this.key())
+	return "";
+
+      // Build doc string based on key
+      var string = this.key() + ' ';
+
+      // Add match operator
+      switch (this.matchop()) {
+      case "ne":
+	string += '!=';
+	break;
+      case "contains":
+	string += '~';
+	break;
+      case "excludes":
+	string += '!~';
+	break;
+      case "geq":
+	string += 'since';
+	break;
+      case "leq":
+	string += 'until';
+	break;
+      default:
+	string += (this.type() == 'date') ? 'in' : '=';
+	break;
+      };
+
+      string += ' ';
+
+      // Add value
+      switch (this.type()) {
+      case "date":
+	return string + this.value();
+	break;
+      case "regex":
+	return string + '/' + this.value() + '/';
+	break;
+      case "string":
+	return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
+	break;
+      };
+
+      return "";
+    }
+  };
+});
diff --git a/dev/js/src/vc/docgroup.js b/dev/js/src/vc/docgroup.js
new file mode 100644
index 0000000..5e5f010
--- /dev/null
+++ b/dev/js/src/vc/docgroup.js
@@ -0,0 +1,343 @@
+/**
+ * Document group criterion
+ */
+define([
+  'vc/jsonld',
+  'vc/unspecified',
+  'vc/doc',
+  'util'
+], function (jsonldClass,
+	     unspecClass,
+	     docClass) {
+
+  var _validGroupOpRE = new RegExp("^(?:and|or)$");
+
+  var docGroupClass = {
+    _ldType : "docGroup",
+
+    create : function (parent, json) {
+      var obj = Object.create(jsonldClass).upgradeTo(this);
+      obj._operands = [];
+      obj.fromJson(json);
+      if (parent !== undefined)
+	obj._parent = parent;
+      return obj;
+    },
+    
+    newAfter : function (obj) {
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === obj) {
+	  var operand = unspecClass.create(this);
+	  this._operands.splice(i + 1, 0, operand);
+	  return this.update();
+	};
+      };
+    },
+
+    // The doc is already set in the group
+    _duplicate : function (operand) {
+      if (operand.ldType() !== 'doc')
+	return null;
+
+      for (var i = 0; i < this._operands.length; i++) {
+	var op = this.getOperand(i);
+	if (op.ldType() === 'doc'
+	    && operand.key() === op.key()
+	    && operand.matchop() === op.matchop()
+	    && operand.value() === op.value()) {
+	  return op;
+	};
+      };
+      return null;
+    },
+    
+    append : function (operand) {
+      
+      // Append unspecified object
+      if (operand === undefined) {
+
+	// Be aware of cyclic structures!
+	operand = unspecClass.create(this);
+	this._operands.push(operand);
+	return operand;
+      };
+      
+      switch (operand["@type"]) {
+	
+      case undefined:
+	// No @type defined
+	if (operand["ldType"] !== undefined) {
+	  if (operand.ldType() !== 'doc' &&
+	      operand.ldType() !== 'docGroup') {
+	    KorAP.log(812, "Operand not supported in document group");
+	    return;
+	  };
+
+	  // Be aware of cyclic structures!
+	  operand.parent(this);
+
+	  var dupl = this._duplicate(operand);
+	  if (dupl === null) {
+	    this._operands.push(operand);
+	    return operand;
+	  };
+	  return dupl;
+	};
+
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+
+      case "koral:doc":
+	// Be aware of cyclic structures!
+	var doc = docClass.create(this, operand);
+	if (doc === undefined)
+	  return;
+	var dupl = this._duplicate(doc);
+	if (dupl === null) {
+	  this._operands.push(doc);
+	  return doc;
+	};
+	return dupl;
+
+      case "koral:docGroup":
+	// Be aware of cyclic structures!
+	var docGroup = docGroupClass.create(this, operand);
+	if (docGroup === undefined)
+	  return;
+
+	// Flatten group
+	if (docGroup.operation() === this.operation()) {
+	  for (var op in docGroup.operands()) {
+	    op = docGroup.getOperand(op);
+	    var dupl = this._duplicate(op);
+	    if (dupl === null) {
+	      this._operands.push(op);
+	      op.parent(this);
+	    };
+	  };
+	  docGroup._operands = [];
+	  docGroup.destroy();
+	  return this;
+	};
+	this._operands.push(docGroup);
+	return docGroup;
+
+      default:
+	KorAP.log(812, "Operand not supported in document group");
+	return;
+      };
+    },
+
+    update : function () {
+      // There is only one operand in group
+      
+      if (this._operands.length === 1) {
+	
+	var parent = this.parent();
+	var op = this.getOperand(0);
+	
+	// This will prevent destruction of
+	// the operand
+	this._operands = [];
+
+	// Parent is a group
+	if (parent.ldType() !== null)
+	  return parent.replaceOperand(this, op).update();
+
+	// Parent is vc
+	else {
+	  this.destroy();
+	  // Cyclic madness
+	  parent.root(op);
+	  op.parent(parent);
+	  return parent.root();
+	};
+      };
+
+      if (this._element === undefined)
+	return this;
+
+      var group = this._element;
+      group.setAttribute('data-operation', this.operation());
+
+      _removeChildren(group);
+
+      // Append operands
+      for (var i = 0; i < this._operands.length; i++) {
+	group.appendChild(
+	  this.getOperand(i).element()
+	);
+      };
+
+      // Set operators
+      var op = this.operators(
+	this.operation() == 'and' ? false : true,
+	this.operation() == 'or'  ? false : true,
+	true
+      );
+
+      group.appendChild(op.element());
+
+      return this;
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'docGroup');
+
+      // Update the object - including optimization
+      this.update();
+
+      return this._element;
+    },
+
+    operation : function (op) {
+      if (arguments.length === 1) {
+	if (_validGroupOpRE.test(op)) {
+	  this._op = op;
+	}
+	else {
+	  KorAP.log(810, "Unknown operation type");
+	  return;
+	};
+      };
+      return this._op || 'and';
+    },
+
+    operands : function () {
+      return this._operands;
+    },
+
+    getOperand : function (index) {
+      return this._operands[index];
+    },
+
+    // Replace operand
+    replaceOperand : function (oldOp, newOp) {
+      
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === oldOp) {
+	  
+	  // Just insert a doc or ...
+	  if (newOp.ldType() === "doc" ||
+	      newOp.ldType() === "non" ||
+	      // ... insert a group of a different operation
+	      // (i.e. "and" in "or"/"or" in "and")
+	      newOp.operation() != this.operation()) {
+	    this._operands[i] = newOp;
+	    newOp.parent(this);
+	  }
+
+	  // Flatten group
+	  else {
+	    // Remove old group
+	    this._operands.splice(i, 1);
+
+	    // Inject new operands
+	    for (var op in newOp.operands().reverse()) {
+	      op = newOp.getOperand(op);
+	      this._operands.splice(i, 0, op);
+	      op.parent(this);
+	    };
+	    // Prevent destruction of operands
+	    newOp._operands = [];
+	    newOp.destroy();
+	  };
+	  oldOp.destroy();
+	  return this;
+	}
+      };
+      return false;
+    },
+
+    // Delete operand from group
+    delOperand : function (obj) {
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === obj) {
+	  
+	  // Delete identified operand
+	  this._operands.splice(i,1);
+
+	  // Destroy object for cyclic references
+	  obj.destroy();
+
+	  return this;
+	};
+      };
+
+      // Operand not found
+      return undefined;
+    },
+    
+    // Deserialize from json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+
+      if (json["operation"] === undefined ||
+	  typeof json["operation"] !== 'string') {
+	KorAP.log(811, "Document group expects operation");
+	return;
+      };
+
+      var operation = json["operation"];
+
+      this.operation(operation.replace(/^operation:/,''));
+
+      if (json["operands"] === undefined ||
+	  !(json["operands"] instanceof Array)) {
+	KorAP.log(704, "Operation needs operand list")
+	return;
+      };
+
+      // Add all documents
+      for (var i in json["operands"]) {
+	var operand = json["operands"][i];
+	this.append(operand);
+      };
+      
+      return this;
+    },
+
+    toJson : function () {
+      var opArray = new Array();
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i].ldType() !== 'non')
+	  opArray.push(this._operands[i].toJson());
+      };
+      return {
+	"@type"     : "koral:" + this.ldType(),
+	"operation" : "operation:" + this.operation(),
+	"operands"  : opArray
+      };
+    },
+
+    toQuery : function (brackets) {
+      var list = this._operands
+	.filter(function (op) {
+	  return op.ldType() !== 'non';
+	})
+	.map(function (op) {
+	  return (op.ldType() === 'docGroup') ?
+	    op.toQuery(true) :
+	    op.toQuery();
+	});
+      
+      if (list.length === 1)
+	return list.join('');
+      else {
+	var str = list.join(this.operation() === 'or' ? ' | ' : ' & ');
+	return brackets ? '(' + str + ')' : str;
+      };
+    }
+  };
+  return docGroupClass;
+});
diff --git a/dev/js/src/vc/item.js b/dev/js/src/vc/item.js
new file mode 100644
index 0000000..bfefe38
--- /dev/null
+++ b/dev/js/src/vc/item.js
@@ -0,0 +1,44 @@
+// Field menu item
+define(['menu/item'], function (itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)
+	._init(params);
+    },
+
+    _init : function (params) {
+      if (params[0] === undefined)
+	throw new Error("Missing parameters");
+
+      this._name  = params[0];
+      this._value = params[1];
+      this._type  = params[2];
+
+      this._lcField = ' ' + this._name.toLowerCase();
+
+      return this;
+    },
+
+    name : function () {
+      return this._name;
+    },
+
+    type : function () {
+      return this._type;
+    },
+
+    element : function () {
+      // already defined
+      if (this._element !== undefined)
+	return this._element;
+
+      // Create list item
+      var li = document.createElement("li");
+      li.setAttribute("data-type", this._type);
+      li.setAttribute("data-value", this._value);
+      li.appendChild(document.createTextNode(this._name));
+      return this._element = li;
+    }
+  };
+});
diff --git a/dev/js/src/vc/jsonld.js b/dev/js/src/vc/jsonld.js
new file mode 100644
index 0000000..324e7db
--- /dev/null
+++ b/dev/js/src/vc/jsonld.js
@@ -0,0 +1,99 @@
+/**
+ * Abstract JsonLD criterion object
+ */
+define(['vc/operators'], function (operatorsClass) {
+  return {
+    __changed : false,
+    
+    create : function () {
+      return Object.create(this);
+    },
+
+    /**
+     * Upgrade this object to another object
+     * while private data stays intact
+     */
+    upgradeTo : function (props) {
+      for (var prop in props) {
+	this[prop] = props[prop];
+      };
+      return this;
+    },
+    
+    ldType : function (type) {
+      if (arguments.length === 1)
+	this._ldType = type;
+      return this._ldType;
+    },
+    
+    parent : function (obj) {
+      if (arguments.length === 1) {
+	this._parent = obj;
+	this.__changed = true;
+      };
+      return this._parent;
+    },
+
+    // Destroy object - especially for
+    // acyclic structures!
+    // I'm paranoid!
+    destroy : function () {
+      if (this._ops != undefined) {
+	this._ops._parent = undefined;
+	if (this._ops._element !== undefined)
+	  this._ops._element.refTo = undefined;
+	this._ops = undefined;
+      };
+      if (this._element !== undefined)
+	this._element = undefined;
+      
+      // In case of a group, destroy all operands
+      if (this._operands !== undefined) {
+	for (var i = 0; i < this._operands.length; i++)
+	  this.getOperand(i).destroy();
+	this._operands = [];
+      };
+    },
+    
+    // Wrap a new operation around the root group element 
+    wrapOnRoot : function (op) {
+      var parent = this.parent();
+      
+      var group = require('vc/docgroup').create(parent);
+      if (arguments.length === 1)
+	group.operation(op);
+      else
+	group.operation(
+	  this.operation() === 'and' ? 'or' : 'and'
+	);
+      group.append(this);
+      this.parent(group);
+      group.append();
+      group.element(); // Init (seems to be necessary)
+      parent.root(group);
+      return this.parent();
+    },
+
+    // Be aware! This may be cyclic
+    operators : function (and, or, del) {
+      if (arguments === 0)
+	return this._ops;
+      this._ops = operatorsClass.create(
+	and, or, del
+      );
+      this._ops.parent(this);
+      return this._ops;
+    },
+
+    toJson : function () {
+      return {
+	// Unspecified object
+	"@type" : "koral:" + this.ldType()
+      };
+    },
+
+    toQuery : function () {
+      return '';
+    }
+  };
+});
diff --git a/dev/js/src/vc/menu.js b/dev/js/src/vc/menu.js
new file mode 100644
index 0000000..6f6d2bd
--- /dev/null
+++ b/dev/js/src/vc/menu.js
@@ -0,0 +1,10 @@
+// Field menu
+define(['menu', 'menu/item'], function (menuClass, itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, undefined, params)
+    }
+  };
+});
diff --git a/dev/js/src/vc/operators.js b/dev/js/src/vc/operators.js
new file mode 100644
index 0000000..312f75d
--- /dev/null
+++ b/dev/js/src/vc/operators.js
@@ -0,0 +1,168 @@
+/**
+ * Operators for criteria
+ */
+define(['util'], function () {
+
+  var loc = KorAP.Locale;
+  loc.AND   = loc.AND   || 'and';
+  loc.OR    = loc.OR    || 'or';
+  loc.DEL   = loc.DEL   || '×';
+
+
+  // Utility for analysing boolean values
+  function _bool (bool) {
+    return (bool === undefined || bool === null || bool === false) ? false : true;
+  };
+
+
+  // Add new unspecified document
+  function _add (obj, type) {
+    var ref = obj.parentNode.refTo;
+    var parent = ref.parent();
+
+    if (ref.ldType() === 'docGroup') {
+
+      // Check that the action differs from the type
+      if (ref.operation() === type)
+	return;
+
+      if (parent.ldType() !== null) {
+	return parent.newAfter(ref);
+      }
+      else {
+	// The group is on root - wrap
+	return ref.wrapOnRoot();
+      };
+    }
+    else if (ref.ldType() === 'doc') {
+
+      if (parent.ldType() === null) {
+	return ref.wrapOnRoot(type);
+      }
+      else if (parent.operation() === type) {
+	return parent.newAfter(ref);
+      }
+      else {
+	return ref.wrap(type);
+      };
+    };
+  };
+
+
+  // Add doc with 'and' relation
+  var _and = function () {
+    return _add(this, 'and');
+  };
+
+
+  // Add doc with 'or' relation
+  var _or = function () {
+    return _add(this, 'or');
+  };
+
+
+  // Remove doc or docGroup
+  var _delete = function () {
+    var ref = this.parentNode.refTo;
+    if (ref.parent().ldType() !== null) {
+      return ref.parent().delOperand(ref).update();
+    }
+    else {
+      ref.parent().clean();
+    };
+  };
+
+
+  return {
+    create : function (and, or, del) {
+      var op = Object.create(this);
+      op.and(and);
+      op.or(or);
+      op.del(del);
+      return op;
+    },
+
+    update : function () {
+      // Init the element
+      if (this._element === undefined)
+	return this.element();
+
+      var op = this._element;
+
+      op.refTo = this.parent();
+
+      // Remove everything underneath
+      _removeChildren(op);
+      
+      // Add and button
+      if (this._and === true) {
+	var andE = document.createElement('span');
+	andE.setAttribute('class', 'and');
+	andE.addEventListener('click', _and, false);
+	andE.appendChild(
+	  document.createTextNode(loc.AND)
+	);
+	op.appendChild(andE);
+      };
+
+      // Add or button
+      if (this._or === true) {
+	var orE = document.createElement('span');
+	orE.setAttribute('class', 'or');
+	orE.addEventListener('click', _or, false);
+	orE.appendChild(document.createTextNode(loc.OR));
+	op.appendChild(orE);
+      };
+
+      // Add delete button
+      if (this._del === true) {
+	var delE = document.createElement('span');
+	delE.setAttribute('class', 'delete');
+	delE.appendChild(document.createTextNode(loc.DEL));
+	delE.addEventListener('click', _delete, false);
+	op.appendChild(delE);
+      };
+
+      return op;
+    },
+
+    // Be aware! This may be cyclic
+    parent : function (obj) {
+      if (arguments.length === 1)
+	this._parent = obj;
+      return this._parent;
+    },
+
+    element : function () {
+
+      // Return existing element
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'operators');
+
+      // Init elements
+      this.update();
+      return this._element;
+    },
+
+    and : function (bool) {
+      if (arguments.length === 1)
+	this._and = _bool(bool);
+      return this._and;
+    },
+
+    or : function (bool) {
+      if (arguments.length === 1)
+	this._or = _bool(bool);
+      return this._or;
+    },
+
+    del : function (bool) {
+      if (arguments.length === 1)
+	this._del = _bool(bool);
+      return this._del;
+    }
+  };
+});
diff --git a/dev/js/src/vc/rewrite.js b/dev/js/src/vc/rewrite.js
new file mode 100644
index 0000000..79ba4b3
--- /dev/null
+++ b/dev/js/src/vc/rewrite.js
@@ -0,0 +1,100 @@
+/**
+ * Implementation of rewrite objects.
+ */
+define(['vc/jsonld', 'util'], function (jsonldClass) {
+
+  var _validRewriteOpRE   = new RegExp("^(?:injec|modifica)tion$");
+  var _quote              = new RegExp("([\"\\\\])", 'g');
+
+  return {
+    // Construction method
+    create : function (json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      return obj;
+    },
+
+    // Get or set source
+    src : function (string) {
+      if (arguments.length === 1)
+	this._src = string;
+      return this._src;
+    },
+    
+    // Get or set operation
+    operation : function (op) {
+      if (arguments.length === 1) {
+	if (_validRewriteOpRE.test(op)) {
+	  this._op = op;
+	}
+	else {
+	  KorAP.log(814, "Unknown rewrite operation");
+	  return;
+	};
+      };
+      return this._op || 'injection';
+    },
+
+    // Get or set scope
+    scope : function (attr) {
+      if (arguments.length === 1)
+	this._scope = attr;
+      return this._scope;
+    },
+
+    // Serialize from Json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      // Missing @type
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+      
+      // Missing source
+      if (json["src"] === undefined ||
+	  typeof json["src"] !== 'string') {
+	KorAP.log(815, "Rewrite expects source");
+	return;
+      };
+
+      // Set source
+      this.src(json["src"]);
+
+      // Set operation
+      if (json["operation"] !== undefined) {
+	var operation = json["operation"];
+	this.operation(operation.replace(/^operation:/,''));
+      };
+
+      // Set scope
+      if (json["scope"] !== undefined &&
+	  typeof json["scope"] === 'string')
+	this.scope(json["scope"]);
+
+      return this;
+    },
+    
+    toString : function () {
+      var str = '';
+      var op = this.operation();
+      str += op.charAt(0).toUpperCase() + op.slice(1);
+      str += ' of ' + (
+	this._scope === null ?
+	  'object' :
+	  '"' +
+	  this.scope().replace(_quote, '\\$1') +
+	  '"'
+      );
+      str += ' by ' +
+	'"' +
+	this.src().replace(_quote, '\\$1') +
+	'"';
+      return str;
+    }
+  };
+});
diff --git a/dev/js/src/vc/rewritelist.js b/dev/js/src/vc/rewritelist.js
new file mode 100644
index 0000000..af3c05a
--- /dev/null
+++ b/dev/js/src/vc/rewritelist.js
@@ -0,0 +1,49 @@
+define(['vc/jsonld', 'vc/rewrite'], function (jsonldClass, rewriteClass) {
+  return {
+    // Construction method
+    create : function (json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      return obj;
+    },
+    fromJson : function (json) {
+      this._list = new Array();
+      for (var i = 0; i < json.length; i++) {
+	this._list.push(
+	  rewriteClass.create(json[i])
+	);
+      };
+      return this;
+    },
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'rewrite');
+      for (var x in this._list) {
+	var rewrite = this._list[x];
+	var span = document.createElement('span');
+
+	// Set class attribute
+	span.setAttribute('class', rewrite.operation());
+
+	// Append source information
+	span.appendChild(document.createTextNode(rewrite.src()));
+
+	// Append scope information
+	if (rewrite.scope() !== undefined) {
+	  span.appendChild(
+	    document.createTextNode(
+	      ': ' + rewrite.scope()
+	    )
+	  );
+	};
+	this._element.appendChild(span);
+      };
+      return this._element;
+    }
+  };
+});
diff --git a/dev/js/src/vc/unspecified.js b/dev/js/src/vc/unspecified.js
new file mode 100644
index 0000000..9efd007
--- /dev/null
+++ b/dev/js/src/vc/unspecified.js
@@ -0,0 +1,89 @@
+/**
+ * Unspecified criterion
+ */
+define(['vc/jsonld', 'vc/doc', 'util'], function (jsonldClass, docClass) {
+
+  var loc = KorAP.Locale;
+  loc.EMPTY = loc.EMPTY || '⋯';
+
+  return {
+    _ldType : "non",
+    create : function (parent) {
+      var obj = Object.create(jsonldClass).
+	upgradeTo(this);
+
+      if (parent !== undefined)
+	obj._parent = parent;
+
+      return obj;
+    },
+
+    // Set key - replace
+    key : function (v) {
+
+      // Not replaceable
+      if (this._parent === undefined)
+	return null;
+
+      // Set JSON-LD type
+      var newDoc = docClass.create(this._parent, {
+	"@type" : "koral:doc",
+	"value" : "",
+	"key"   : v
+      });
+
+      // Unspecified document on root
+      if (this._parent.ldType() === null) {
+	this._parent.root(newDoc);
+	this.destroy();
+      }
+
+      // Unspecified document in group
+      else {
+	this._parent.replaceOperand(this, newDoc);
+      };
+      this._parent.update();
+      return newDoc;
+    },
+
+    update : function () {
+
+      if (this._element === undefined)
+	return this.element();
+
+      // Remove element content
+      _removeChildren(this._element);
+
+      var ellipsis = document.createElement('span');
+      ellipsis.appendChild(document.createTextNode(loc.EMPTY));
+      this._element.appendChild(ellipsis);
+
+      // Set ref - TODO: Cleanup!
+      this._element.refTo = this;
+
+      // Set operators
+      if (this._parent !== undefined && this.parent().ldType() !== null) {
+	var op = this.operators(
+	  false,
+	  false,
+	  true
+	);
+	
+	this._element.appendChild(
+	  op.element()
+	);
+      };
+
+      return this.element();
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'doc unspecified');
+      this.update();
+      return this._element;
+    },
+  };
+});
diff --git a/dev/scss/header.scss b/dev/scss/header.scss
index f2d1279..9876f80 100644
--- a/dev/scss/header.scss
+++ b/dev/scss/header.scss
@@ -4,8 +4,7 @@
 header {
   position: relative;
   background-color: $light-green;
-  @include light-noise;
-//  background-color: $ids-grey-1;
+//  @include light-noise;
   @include box-sizing-box();
   padding: 8px;
   padding-bottom: 0;
diff --git a/dev/scss/kwic.scss b/dev/scss/kwic.scss
index a58c23e..0c91c7b 100644
--- a/dev/scss/kwic.scss
+++ b/dev/scss/kwic.scss
@@ -81,7 +81,7 @@
       height: auto;
       border-width: 2px;
       background-color: $dark-orange;
-      @include light-noise;
+//      @include light-noise;
       position: relative;
       > div {
 	min-height: 42pt;
diff --git a/dev/scss/logos.scss b/dev/scss/logos.scss
index e9058ae..eb91e5e 100644
--- a/dev/scss/logos.scss
+++ b/dev/scss/logos.scss
@@ -99,6 +99,11 @@
   }
 }
 
+#overview {
+  text-align: center;
+  width: 100%;
+}
+
 /*
 #leibniz-logo, #ids-logo {
   height: (130 / 20) + em;
diff --git a/dev/scss/util.scss b/dev/scss/util.scss
index 86bfb34..3321de1 100644
--- a/dev/scss/util.scss
+++ b/dev/scss/util.scss
@@ -19,7 +19,7 @@
 $middle-orange:  #ffd080;
 $dark-orange:    $ids-orange-1; // #ffa500;
 $darker-orange:  #ff8000;
-$darkest-orange: darken($dark-orange, 20%);
+$darkest-orange: #e55d00;
 // $light-orange-2: #f4eebb;, #ffd080;
 // Yellow: #fff48d
 
