You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by de...@apache.org on 2014/03/31 21:45:55 UTC

[01/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Repository: couchdb
Updated Branches:
  refs/heads/Update-Sidebar-Ui f364947e0 -> c1e142377 (forced update)


Fix error message in database permissions

Show the message from the server instead of the whole JSON as text


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7dba4223
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7dba4223
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7dba4223

Branch: refs/heads/Update-Sidebar-Ui
Commit: 7dba422367222b2f75e20e55ab2b4b09df7167b2
Parents: bef40dc
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Wed Mar 19 20:31:25 2014 +0100

----------------------------------------------------------------------
 src/fauxton/app/addons/permissions/views.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7dba4223/src/fauxton/app/addons/permissions/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/views.js b/src/fauxton/app/addons/permissions/views.js
index eb5a378..43f5aab 100644
--- a/src/fauxton/app/addons/permissions/views.js
+++ b/src/fauxton/app/addons/permissions/views.js
@@ -148,7 +148,7 @@ function (app, FauxtonAPI, Permissions ) {
         });
       }, function (xhr) {
         FauxtonAPI.addNotification({
-          msg: 'Could not update permissions - reason: ' + xhr.responseText,
+          msg: 'Could not update permissions - reason: ' + xhr.responseJSON.reason,
           type: 'error'
         });
       });


[02/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Keys validation, textarea and cleanup


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/3be8c85b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/3be8c85b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/3be8c85b

Branch: refs/heads/Update-Sidebar-Ui
Commit: 3be8c85bde6d4ee513a736cdaf7d7aaf171d825d
Parents: 65c814a
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Mar 20 18:35:43 2014 +0200
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400

----------------------------------------------------------------------
 .../addons/documents/assets/less/documents.less | 16 +++++
 src/fauxton/app/addons/documents/resources.js   | 23 ++++---
 .../documents/templates/advanced_options.html   | 10 +--
 src/fauxton/app/addons/documents/views.js       | 69 +++++++++++++++-----
 4 files changed, 90 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 61d864b..36429ff 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -39,6 +39,10 @@ button.beautify {
 }
 
 
+#query div.controls-group.well{
+    height: 150px;
+}
+
 /** used in all_docs_list.html **/
 .view {
     table td div {
@@ -97,3 +101,15 @@ button.beautify {
     height: 688px;
     font-size: 16px;
 }
+
+#keys-input {
+  display: inline-block;
+  width: 35%;
+}
+
+#keys-error {
+  display: inline-block;
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index 6f4323a..efd7f69 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -468,14 +468,21 @@ function(app, FauxtonAPI) {
       if (this.skipFirstItem) {
         rows = rows.splice(1);
       }
-      return _.map(rows, function(row) {
-        return {
-          _id: row.id,
-          _rev: row.value.rev,
-          value: row.value,
-          key: row.key,
-          doc: row.doc || undefined
-        };
+      
+      // remove any query errors that may return without doc info
+      // important for when querying keys on all docs
+      var noQueryErrors = _.filter(rows, function(row){
+        return row.value;
+      });
+
+      return _.map(noQueryErrors, function(row) {
+          return {
+            _id: row.id,
+            _rev: row.value.rev,
+            value: row.value,
+            key: row.key,
+            doc: row.doc || undefined
+          };
       });
     }
   }));

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index 8acf30a..d8d57cd 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -28,7 +28,8 @@ the License.
   <div class="controls-group well">
     <div class="row-fluid" id="js-showKeys">
       <div class="controls controls-row">
-        <input name="keys" class="input-xxlarge" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON.">
+        <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON."></textarea>
+        <div id="keys-error" class="inline-block js-keys-error"></div>
       </div>
     </div>
     <div class="row-fluid hide" id="js-showStartEnd">
@@ -48,7 +49,7 @@ the License.
   <div class="controls-group">
       <label class="drop-down inline">
         Limit:
-        <select name="limit" class="input-small" disabled>
+        <select name="limit" class="input-small">
           <option>5</option>
           <option>10</option>
           <option selected="selected">20</option>
@@ -59,10 +60,9 @@ the License.
         </select>
       </label>
       <label for="skipRows" class="inline drop-down">
-        Skip
-        <input name="skip" class="input-large" type="text" id="skipRows" disabled placeholder="Number of rows to skip">
+        Skip: 
+        <input name="skip" class="input-large" type="text" id="skipRows" placeholder="Number of rows to skip">
       </label>
-      <span class="js-disabled-message"> Limit &amp; and Skip are disabled when using Keys.</span>
 
       <div class="checkbox inline"> 
         <input id="check1" type="checkbox" name="include_docs" value="true">  

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 1e7addf..cc23e19 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -1107,13 +1107,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     showKeys: function(){
       this.$("#js-showKeys, .js-disabled-message").show();
-      this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
+      this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
       this.$('[name="keys"]').removeAttr("disabled");
     },
 
     showStartEnd: function(){
       this.$("#js-showStartEnd").show();
-      this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
+      this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
       this.$('.js-disabled-message').hide();
       this.$('[name="keys"]').attr("disabled","true");
     },
@@ -1132,33 +1132,62 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.hasReduce = hasReduce;
       this.render();
     },
-    validateKeys:  function(val){
-      return JSON.parse(val);
+
+    parseJSON: function (value) {
+      try {
+        return JSON.parse(value);
+      } catch(e) {
+        return undefined;
+      }
+    },
+
+    validateKeys:  function(param){
+      var errorMsg = false,
+          parsedValue = this.parseJSON(param.value);
+
+      if (_.isUndefined(parsedValue)) {
+        errorMsg = "Keys must be valid json.";
+      } else if (!_.isArray(parsedValue)) {
+        errorMsg =  "Keys values must be in an array. E.g [1,2,3]"; 
+      }
+
+      if (errorMsg) {
+        this.$('.js-keys-error').empty();
+        FauxtonAPI.addNotification({
+          type: "error",
+          msg: errorMsg,
+          clear:  false,
+          selector: '.js-keys-error'
+        });
+        return false;
+      }
+
+      return true; 
     },
     queryParams: function () {
-      var $form = this.$(".js-view-query-update");
+      var $form = this.$(".js-view-query-update"),
+          keysParam = false;
 
       var params = _.reduce($form.serializeArray(), function(params, param) {
         if (!param.value) { return params; }
         if (param.name === "limit" && param.value === 'None') { return params; }
+        if (param.name === "keys") { keysParam = param; }
         params.push(param);
         return params;
       }, []);
 
+
+      if (keysParam && !this.validateKeys(keysParam)) { return false; }
+
       // Validate *key* params to ensure they're valid JSON
       var keyParams = ["keys","startkey","endkey"];
       var errorParams = _.filter(params, function(param) {
-        if (_.contains(keyParams, param.name)) {
-          try {
-            JSON.parse(param.value);
-            return false;
-          } catch(e) {
+        if (_.contains(keyParams, param.name) && _.isUndefined(this.parseJSON(param.value))) {
             return true;
           }
-        } else {
+
           return false;
-        }
-      });
+      }, this);
 
       return {params: params, errorParams: errorParams};
     },
@@ -1222,6 +1251,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           }
           this.updateFiltersFor(key, $ele);
           break;
+          case "key": 
+          case "keys": 
+            $form.find("textarea[name='"+key+"']").val(val);
+          break;
           default:
             $form.find("input[name='"+key+"']").val(val);
           break;
@@ -1231,11 +1264,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     updateView: function (event) {
       event.preventDefault();
-      this.updateViewFn(event, this.queryParams());
+      var params = this.queryParams();
+      if (!params) { return;}
+      this.updateViewFn(event, params);
     },
 
     previewView: function (event) {
-      this.previewFn(event, this.queryParams());
+      var params = this.queryParams();
+      if (!params) { return;}
+      this.previewFn(event, params);
     },
 
     serialize: function () {
@@ -1615,6 +1652,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     toggleIndexNav: function (event) {
+      $('#dashboard-content').scrollTop(0); //scroll up
+      
       var $targetId = this.$(event.target).attr('id'),
           $previousTab = this.$(this.$('li.active a').attr('href')),
           $targetTab = this.$(this.$(event.target).attr('href'));


[32/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
docs: clarify that .d and multiple .ini files only apply to unix

- closes COUCHDB-2104

Thanks Ole Johan for reporting this


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/282cddf1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/282cddf1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/282cddf1

Branch: refs/heads/Update-Sidebar-Ui
Commit: 282cddf1f6ac6cb37f6b14e2aa8beeb585b3b91e
Parents: e3d5d12
Author: Dave Cottlehuber <dc...@apache.org>
Authored: Wed Mar 26 21:12:19 2014 +0100
Committer: Dave Cottlehuber <dc...@apache.org>
Committed: Wed Mar 26 21:12:19 2014 +0100

----------------------------------------------------------------------
 share/doc/src/config/intro.rst | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/282cddf1/share/doc/src/config/intro.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/config/intro.rst b/share/doc/src/config/intro.rst
index c528f74..835643a 100644
--- a/share/doc/src/config/intro.rst
+++ b/share/doc/src/config/intro.rst
@@ -23,6 +23,14 @@ Introduction Into Configuring
 Configuration files
 -------------------
 
+.. warning::
+   The following section covering load order of config files
+   applies only to UNIX-ish systems.
+   For Windows, only the provided ``default.ini`` and ``local.ini``
+   files are relevant. These can of course have content
+   appended, which achieves the same type of functionality
+   as outlined for UNIX-ish systems below.
+
 By default, CouchDB reads configuration files from the following locations,
 in the following order:
 
@@ -148,7 +156,7 @@ Setting parameters via the HTTP API
 
 Alternatively, configuration parameters could be set via the
 :ref:`HTTP API <api/config>`. This API allows to change CouchDB configuration
-on-fly without need for server restart::
+on-the-fly without requiring a server restart::
 
   curl -X PUT http://localhost:5984/_config/uuids/algorithm -d '"random"'
 
@@ -157,16 +165,17 @@ In the response the old parameter's value returns::
   "sequential"
 
 You should be careful with changing configuration via the HTTP API since it's
-easy to make CouchDB unavailable. For instance, you'd like to change the
-:option:`httpd/bind_address` for new one::
+easy to make CouchDB unavailable. For instance, if you'd like to change the
+:option:`httpd/bind_address` for a new one::
 
   curl -X PUT http://localhost:5984/_config/httpd/bind_address -d '"10.10.0.128"'
 
-However, if you would made a typo or the specified IP address is not available
-from your network, you'll make CouchDB unavailable for you in both cases and
-you will have the only way to fix the problem by edit the configuration file
-and restart the server. To protect yourself against such accidents you may
-setup the :option:`httpd/config_whitelist` of configuration parameters that
-are allowed to edit via the HTTP API. For others you'll need to directly edit
-the configuration file so you may quick fix any problems that had occurred due
-to misconfiguring.
+However, if you make a typo, or the specified IP address is not available
+from your network, CouchDB will be unavailable for you in both cases and
+the only way to resolve this will be by remoting into the server, correcting
+the errant file, and restarting CouchDB. To protect yourself against such
+accidents you may set the :option:`httpd/config_whitelist` of permitted
+configuration parameters for updates via the HTTP API. Once this option is set,
+further changes to non-whitelisted parameters must take place via the
+configuration file, and in most cases, also requires a server restart before
+hand-edited options take effect.


[36/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
s/401/403


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/8b429c83
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/8b429c83
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/8b429c83

Branch: refs/heads/Update-Sidebar-Ui
Commit: 8b429c8362505a59e5332bd4c9d93142d495f01a
Parents: 83cc813
Author: Robert Newson <rn...@apache.org>
Authored: Thu Mar 27 13:19:46 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Mar 27 13:19:46 2014 +0000

----------------------------------------------------------------------
 share/www/script/test/uuids.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/8b429c83/share/www/script/test/uuids.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/uuids.js b/share/www/script/test/uuids.js
index 0f141a9..d304c4e 100644
--- a/share/www/script/test/uuids.js
+++ b/share/www/script/test/uuids.js
@@ -82,7 +82,7 @@ couchTests.uuids = function(debug) {
 
   // test max_uuid_count
   var xhr = CouchDB.request("GET", "/_uuids?count=1001");
-  TEquals(401, xhr.status, "should error when count > max_count");
+  TEquals(403, xhr.status, "should error when count > max_count");
 
   run_on_modified_server([{
       "section": "uuids",


[26/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
moving myself from THANKS to AUTHORS


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/35a03037
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/35a03037
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/35a03037

Branch: refs/heads/Update-Sidebar-Ui
Commit: 35a030378f032ec1839b8f0c35a8191c261a2005
Parents: 7296e53
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 15:55:16 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 15:55:16 2014 -0400

----------------------------------------------------------------------
 AUTHORS   | 1 +
 THANKS.in | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/35a03037/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index dd0260a..ab48b58 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -28,5 +28,6 @@ documentation or developing software. Some of these people are:
  * Sue Lockwood <de...@apache.org>
  * Andy Wenk <an...@apache.org>
  * Klaus Trainer <kl...@apache.org>
+ * Benjamin Young <bi...@apache.org>
 
 For a list of other credits see the `THANKS` file.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/35a03037/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index bdfb3cd..b3e5cc8 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -66,7 +66,6 @@ suggesting improvements or submitting changes. Some of these people are:
  * David Davis <xa...@xantus.org>
  * Juuso Väänänen <ju...@vaananen.org>
  * Jeff Zellner <je...@gmail.com>
- * Benjamin Young <by...@bigbluehat.com>
  * Gabriel Farrell <gs...@gmail.com>
  * Mike Leddy <mi...@loop.com.br>
  * Wayne Conrad <wa...@databill.com>


[20/41] Updating d3 to v3.4.3 and nv.d3 to v1.1.15

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/js/libs/nv.d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/nv.d3.js b/src/fauxton/assets/js/libs/nv.d3.js
index 936b406..4ddf400 100755
--- a/src/fauxton/assets/js/libs/nv.d3.js
+++ b/src/fauxton/assets/js/libs/nv.d3.js
@@ -2,14 +2,15 @@
 
 var nv = window.nv || {};
 
-nv.version = '0.0.1a';
+
+nv.version = '1.1.15b';
 nv.dev = true //set false when in production
 
 window.nv = nv;
 
-nv.tooltip = {}; // For the tooltip system
-nv.utils = {}; // Utility subsystem
-nv.models = {}; //stores all the possible models/components
+nv.tooltip = nv.tooltip || {}; // For the tooltip system
+nv.utils = nv.utils || {}; // Utility subsystem
+nv.models = nv.models || {}; //stores all the possible models/components
 nv.charts = {}; //stores all the ready to use charts
 nv.graphs = []; //stores all the graphs currently on the page
 nv.logs = {}; //stores some statistics and potential error messages
@@ -35,10 +36,13 @@ if (nv.dev) {
 //  Public Core NV functions
 
 // Logs all arguments, and returns the last so you can test things in place
+// Note: in IE8 console.log is an object not a function, and if modernizr is used
+// then calling Function.prototype.bind with with anything other than a function
+// causes a TypeError to be thrown.
 nv.log = function() {
   if (nv.dev && console.log && console.log.apply)
     console.log.apply(console, arguments)
-  else if (nv.dev && console.log && Function.prototype.bind) {
+  else if (nv.dev && typeof console.log == "function" && Function.prototype.bind) {
     var log = Function.prototype.bind.call(console.log, console);
     log.apply(console, arguments);
   }
@@ -64,7 +68,10 @@ nv.render = function render(step) {
     nv.render.queue.splice(0, i);
 
     if (nv.render.queue.length) setTimeout(arguments.callee, 0);
-    else { nv.render.active = false; nv.dispatch.render_end(); }
+    else {
+      nv.dispatch.render_end();
+      nv.render.active = false;
+    }
   }, 0);
 };
 
@@ -117,137 +124,744 @@ d3.time.monthEnds = d3_time_range(d3.time.monthEnd, function(date) {
   }
 );
 
+/* Utility class to handle creation of an interactive layer.
+This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch
+containing the X-coordinate. It can also render a vertical line where the mouse is located.
+
+dispatch.elementMousemove is the important event to latch onto.  It is fired whenever the mouse moves over
+the rectangle. The dispatch is given one object which contains the mouseX/Y location.
+It also has 'pointXValue', which is the conversion of mouseX to the x-axis scale.
+*/
+nv.interactiveGuideline = function() {
+	"use strict";
+	var tooltip = nv.models.tooltip();
+	//Public settings
+	var width = null
+	, height = null
+    //Please pass in the bounding chart's top and left margins
+    //This is important for calculating the correct mouseX/Y positions.
+	, margin = {left: 0, top: 0}
+	, xScale = d3.scale.linear()
+	, yScale = d3.scale.linear()
+	, dispatch = d3.dispatch('elementMousemove', 'elementMouseout','elementDblclick')
+	, showGuideLine = true
+	, svgContainer = null  
+    //Must pass in the bounding chart's <svg> container.
+    //The mousemove event is attached to this container.
+	;
+
+	//Private variables
+	var isMSIE = navigator.userAgent.indexOf("MSIE") !== -1  //Check user-agent for Microsoft Internet Explorer.
+	;
+
+
+	function layer(selection) {
+		selection.each(function(data) {
+				var container = d3.select(this);
+				
+				var availableWidth = (width || 960), availableHeight = (height || 400);
+
+				var wrap = container.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([data]);
+				var wrapEnter = wrap.enter()
+								.append("g").attr("class", " nv-wrap nv-interactiveLineLayer");
+								
+				
+				wrapEnter.append("g").attr("class","nv-interactiveGuideLine");
+				
+				if (!svgContainer) {
+					return;
+				}
+
+                function mouseHandler() {
+                      var d3mouse = d3.mouse(this);
+                      var mouseX = d3mouse[0];
+                      var mouseY = d3mouse[1];
+                      var subtractMargin = true;
+                      var mouseOutAnyReason = false;
+                      if (isMSIE) {
+                         /*
+                            D3.js (or maybe SVG.getScreenCTM) has a nasty bug in Internet Explorer 10.
+                            d3.mouse() returns incorrect X,Y mouse coordinates when mouse moving
+                            over a rect in IE 10.
+                            However, d3.event.offsetX/Y also returns the mouse coordinates
+                            relative to the triggering <rect>. So we use offsetX/Y on IE.  
+                         */
+                         mouseX = d3.event.offsetX;
+                         mouseY = d3.event.offsetY;
+
+                         /*
+                            On IE, if you attach a mouse event listener to the <svg> container,
+                            it will actually trigger it for all the child elements (like <path>, <circle>, etc).
+                            When this happens on IE, the offsetX/Y is set to where ever the child element
+                            is located.
+                            As a result, we do NOT need to subtract margins to figure out the mouse X/Y
+                            position under this scenario. Removing the line below *will* cause 
+                            the interactive layer to not work right on IE.
+                         */
+                         if(d3.event.target.tagName !== "svg")
+                            subtractMargin = false;
+
+                         if (d3.event.target.className.baseVal.match("nv-legend"))
+                         	mouseOutAnyReason = true;
+                          
+                      }
+
+                      if(subtractMargin) {
+                         mouseX -= margin.left;
+                         mouseY -= margin.top;
+                      }
+
+                      /* If mouseX/Y is outside of the chart's bounds,
+                      trigger a mouseOut event.
+                      */
+                      if (mouseX < 0 || mouseY < 0 
+                        || mouseX > availableWidth || mouseY > availableHeight
+                        || (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined)
+                        || mouseOutAnyReason
+                        ) 
+                      {
+                      		if (isMSIE) {
+                      			if (d3.event.relatedTarget 
+                      				&& d3.event.relatedTarget.ownerSVGElement === undefined
+                      				&& d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass)) {
+                      				return;
+                      			}
+                      		}
+                            dispatch.elementMouseout({
+                               mouseX: mouseX,
+                               mouseY: mouseY
+                            });
+                            layer.renderGuideLine(null); //hide the guideline
+                            return;
+                      }
+                      
+                      var pointXValue = xScale.invert(mouseX);
+                      dispatch.elementMousemove({
+                            mouseX: mouseX,
+                            mouseY: mouseY,
+                            pointXValue: pointXValue
+                      });
+
+                      //If user double clicks the layer, fire a elementDblclick dispatch.
+                      if (d3.event.type === "dblclick") {
+                        dispatch.elementDblclick({
+                            mouseX: mouseX,
+                            mouseY: mouseY,
+                            pointXValue: pointXValue
+                        });
+                      }
+                }
+
+				svgContainer
+				      .on("mousemove",mouseHandler, true)
+				      .on("mouseout" ,mouseHandler,true)
+                      .on("dblclick" ,mouseHandler)
+				      ;
+
+				 //Draws a vertical guideline at the given X postion.
+				layer.renderGuideLine = function(x) {
+				 	if (!showGuideLine) return;
+				 	var line = wrap.select(".nv-interactiveGuideLine")
+				 	      .selectAll("line")
+				 	      .data((x != null) ? [nv.utils.NaNtoZero(x)] : [], String);
+
+				 	line.enter()
+				 		.append("line")
+				 		.attr("class", "nv-guideline")
+				 		.attr("x1", function(d) { return d;})
+				 		.attr("x2", function(d) { return d;})
+				 		.attr("y1", availableHeight)
+				 		.attr("y2",0)
+				 		;
+				 	line.exit().remove();
+
+				}
+		});
+	}
+
+	layer.dispatch = dispatch;
+	layer.tooltip = tooltip;
+
+	layer.margin = function(_) {
+	    if (!arguments.length) return margin;
+	    margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
+	    margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
+	    return layer;
+    };
+
+	layer.width = function(_) {
+		if (!arguments.length) return width;
+		width = _;
+		return layer;
+	};
+
+	layer.height = function(_) {
+		if (!arguments.length) return height;
+		height = _;
+		return layer;
+	};
+
+	layer.xScale = function(_) {
+		if (!arguments.length) return xScale;
+		xScale = _;
+		return layer;
+	};
+
+	layer.showGuideLine = function(_) {
+		if (!arguments.length) return showGuideLine;
+		showGuideLine = _;
+		return layer;
+	};
+
+	layer.svgContainer = function(_) {
+		if (!arguments.length) return svgContainer;
+		svgContainer = _;
+		return layer;
+	};
+
+
+	return layer;
+};
+
+/* Utility class that uses d3.bisect to find the index in a given array, where a search value can be inserted.
+This is different from normal bisectLeft; this function finds the nearest index to insert the search value.
+
+For instance, lets say your array is [1,2,3,5,10,30], and you search for 28. 
+Normal d3.bisectLeft will return 4, because 28 is inserted after the number 10.  But interactiveBisect will return 5
+because 28 is closer to 30 than 10.
+
+Unit tests can be found in: interactiveBisectTest.html
+
+Has the following known issues:
+   * Will not work if the data points move backwards (ie, 10,9,8,7, etc) or if the data points are in random order.
+   * Won't work if there are duplicate x coordinate values.
+*/
+nv.interactiveBisect = function (values, searchVal, xAccessor) {
+	  "use strict";
+      if (! values instanceof Array) return null;
+      if (typeof xAccessor !== 'function') xAccessor = function(d,i) { return d.x;}
+
+      var bisect = d3.bisector(xAccessor).left;
+      var index = d3.max([0, bisect(values,searchVal) - 1]);
+      var currentValue = xAccessor(values[index], index);
+      if (typeof currentValue === 'undefined') currentValue = index;
+
+      if (currentValue === searchVal) return index;  //found exact match
 
-/*****
- * A no-frills tooltip implementation.
- *****/
+      var nextIndex = d3.min([index+1, values.length - 1]);
+      var nextValue = xAccessor(values[nextIndex], nextIndex);
+      if (typeof nextValue === 'undefined') nextValue = nextIndex;
 
+      if (Math.abs(nextValue - searchVal) >= Math.abs(currentValue - searchVal))
+          return index;
+      else
+          return nextIndex
+};
+
+/*
+Returns the index in the array "values" that is closest to searchVal.
+Only returns an index if searchVal is within some "threshold".
+Otherwise, returns null.
+*/
+nv.nearestValueIndex = function (values, searchVal, threshold) {
+      "use strict";
+      var yDistMax = Infinity, indexToHighlight = null;
+      values.forEach(function(d,i) {
+         var delta = Math.abs(searchVal - d);
+         if ( delta <= yDistMax && delta < threshold) {
+            yDistMax = delta;
+            indexToHighlight = i;
+         }
+      });
+      return indexToHighlight;
+};/* Tooltip rendering model for nvd3 charts.
+window.nv.models.tooltip is the updated,new way to render tooltips.
 
+window.nv.tooltip.show is the old tooltip code.
+window.nv.tooltip.* also has various helper methods.
+*/
 (function() {
+  "use strict";
+  window.nv.tooltip = {};
+
+  /* Model which can be instantiated to handle tooltip rendering.
+    Example usage: 
+    var tip = nv.models.tooltip().gravity('w').distance(23)
+                .data(myDataObject);
+
+        tip();    //just invoke the returned function to render tooltip.
+  */
+  window.nv.models.tooltip = function() {
+        var content = null    //HTML contents of the tooltip.  If null, the content is generated via the data variable.
+        ,   data = null     /* Tooltip data. If data is given in the proper format, a consistent tooltip is generated.
+        Format of data:
+        {
+            key: "Date",
+            value: "August 2009", 
+            series: [
+                    {
+                        key: "Series 1",
+                        value: "Value 1",
+                        color: "#000"
+                    },
+                    {
+                        key: "Series 2",
+                        value: "Value 2",
+                        color: "#00f"
+                    }
+            ]
 
-  var nvtooltip = window.nv.tooltip = {};
+        }
 
-  nvtooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
+        */
+        ,   gravity = 'w'   //Can be 'n','s','e','w'. Determines how tooltip is positioned.
+        ,   distance = 50   //Distance to offset tooltip from the mouse location.
+        ,   snapDistance = 25   //Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)
+        ,   fixedTop = null //If not null, this fixes the top position of the tooltip.
+        ,   classes = null  //Attaches additional CSS classes to the tooltip DIV that is created.
+        ,   chartContainer = null   //Parent DIV, of the SVG Container that holds the chart.
+        ,   tooltipElem = null  //actual DOM element representing the tooltip.
+        ,   position = {left: null, top: null}      //Relative position of the tooltip inside chartContainer.
+        ,   enabled = true  //True -> tooltips are rendered. False -> don't render tooltips.
+        //Generates a unique id when you create a new tooltip() object
+        ,   id = "nvtooltip-" + Math.floor(Math.random() * 100000)
+        ;
+
+        //CSS class to specify whether element should not have mouse events.
+        var  nvPointerEventsClass = "nv-pointer-events-none";
+
+        //Format function for the tooltip values column
+        var valueFormatter = function(d,i) {
+            return d;
+        };
 
-    var container = document.createElement('div');
-        container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip');
+        //Format function for the tooltip header value.
+        var headerFormatter = function(d) {
+            return d;
+        };
 
-    gravity = gravity || 's';
-    dist = dist || 20;
+        //By default, the tooltip model renders a beautiful table inside a DIV.
+        //You can override this function if a custom tooltip is desired.
+        var contentGenerator = function(d) {
+            if (content != null) return content;
+
+            if (d == null) return '';
+
+            var table = d3.select(document.createElement("table"));
+            var theadEnter = table.selectAll("thead")
+                .data([d])
+                .enter().append("thead");
+            theadEnter.append("tr")
+                .append("td")
+                .attr("colspan",3)
+                .append("strong")
+                    .classed("x-value",true)
+                    .html(headerFormatter(d.value));
+
+            var tbodyEnter = table.selectAll("tbody")
+                .data([d])
+                .enter().append("tbody");
+            var trowEnter = tbodyEnter.selectAll("tr")
+                .data(function(p) { return p.series})
+                .enter()
+                .append("tr")
+                .classed("highlight", function(p) { return p.highlight})
+                ;
+
+            trowEnter.append("td")
+                .classed("legend-color-guide",true)
+                .append("div")
+                    .style("background-color", function(p) { return p.color});
+            trowEnter.append("td")
+                .classed("key",true)
+                .html(function(p) {return p.key});
+            trowEnter.append("td")
+                .classed("value",true)
+                .html(function(p,i) { return valueFormatter(p.value,i) });
+
+
+            trowEnter.selectAll("td").each(function(p) {
+                if (p.highlight) {
+                    var opacityScale = d3.scale.linear().domain([0,1]).range(["#fff",p.color]);
+                    var opacity = 0.6;
+                    d3.select(this)
+                        .style("border-bottom-color", opacityScale(opacity))
+                        .style("border-top-color", opacityScale(opacity))
+                        ;
+                }
+            });
 
-    var body = parentContainer;
-    if ( !parentContainer || parentContainer.tagName.match(/g|svg/i)) {
-        //If the parent element is an SVG element, place tooltip in the <body> element.
-        body = document.getElementsByTagName('body')[0];
-    }
+            var html = table.node().outerHTML;
+            if (d.footer !== undefined)
+                html += "<div class='footer'>" + d.footer + "</div>";
+            return html;
 
-    container.innerHTML = content;
-    container.style.left = 0;
-    container.style.top = 0;
-    container.style.opacity = 0;
-
-    body.appendChild(container);
-
-    var height = parseInt(container.offsetHeight),
-        width = parseInt(container.offsetWidth),
-        windowWidth = nv.utils.windowSize().width,
-        windowHeight = nv.utils.windowSize().height,
-        scrollTop = window.scrollY,
-        scrollLeft = window.scrollX,
-        left, top;
-
-    windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16;
-    windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16;
-
-    var tooltipTop = function ( Elem ) {
-        var offsetTop = top;
-        do {
-            if( !isNaN( Elem.offsetTop ) ) {
-                offsetTop += (Elem.offsetTop);
+        };
+
+        var dataSeriesExists = function(d) {
+            if (d && d.series && d.series.length > 0) return true;
+
+            return false;
+        };
+
+        //In situations where the chart is in a 'viewBox', re-position the tooltip based on how far chart is zoomed.
+        function convertViewBoxRatio() {
+            if (chartContainer) {
+              var svg = d3.select(chartContainer);
+              if (svg.node().tagName !== "svg") {
+                 svg = svg.select("svg");
+              }
+              var viewBox = (svg.node()) ? svg.attr('viewBox') : null;
+              if (viewBox) {
+                viewBox = viewBox.split(' ');
+                var ratio = parseInt(svg.style('width')) / viewBox[2];
+                
+                position.left = position.left * ratio;
+                position.top  = position.top * ratio;
+              }
             }
-        } while( Elem = Elem.offsetParent );
-        return offsetTop;
-    }
+        }
 
-    var tooltipLeft = function ( Elem ) {
-        var offsetLeft = left;
-        do {
-            if( !isNaN( Elem.offsetLeft ) ) {
-                offsetLeft += (Elem.offsetLeft);
+        //Creates new tooltip container, or uses existing one on DOM.
+        function getTooltipContainer(newContent) {
+            var body;
+            if (chartContainer)
+                body = d3.select(chartContainer);
+            else
+                body = d3.select("body");
+
+            var container = body.select(".nvtooltip");
+            if (container.node() === null) {
+                //Create new tooltip div if it doesn't exist on DOM.
+                container = body.append("div")
+                    .attr("class", "nvtooltip " + (classes? classes: "xy-tooltip"))
+                    .attr("id",id)
+                    ;
             }
-        } while( Elem = Elem.offsetParent );
-        return offsetLeft;
-    }
+        
 
-    switch (gravity) {
-      case 'e':
-        left = pos[0] - width - dist;
-        top = pos[1] - (height / 2);
-        var tLeft = tooltipLeft(container);
-        var tTop = tooltipTop(container);
-        if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left;
-        if (tTop < scrollTop) top = scrollTop - tTop + top;
-        if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
-        break;
-      case 'w':
-        left = pos[0] + dist;
-        top = pos[1] - (height / 2);
-        if (tLeft + width > windowWidth) left = pos[0] - width - dist;
-        if (tTop < scrollTop) top = scrollTop + 5;
-        if (tTop + height > scrollTop + windowHeight) top = scrollTop - height - 5;
-        break;
-      case 'n':
-        left = pos[0] - (width / 2) - 5;
-        top = pos[1] + dist;
-        var tLeft = tooltipLeft(container);
-        var tTop = tooltipTop(container);
-        if (tLeft < scrollLeft) left = scrollLeft + 5;
-        if (tLeft + width > windowWidth) left = left - width/2 + 5;
-        if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
-        break;
-      case 's':
-        left = pos[0] - (width / 2);
-        top = pos[1] - height - dist;
-        var tLeft = tooltipLeft(container);
-        var tTop = tooltipTop(container);
-        if (tLeft < scrollLeft) left = scrollLeft + 5;
-        if (tLeft + width > windowWidth) left = left - width/2 + 5;
-        if (scrollTop > tTop) top = scrollTop;
-        break;
-    }
+            container.node().innerHTML = newContent;
+            container.style("top",0).style("left",0).style("opacity",0);
+            container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true)
+            container.classed(nvPointerEventsClass,true);
+            return container.node();
+        }
 
+        
 
-    container.style.left = left+'px';
-    container.style.top = top+'px';
-    container.style.opacity = 1;
-    container.style.position = 'absolute'; //fix scroll bar issue
-    container.style.pointerEvents = 'none'; //fix scroll bar issue
+        //Draw the tooltip onto the DOM.
+        function nvtooltip() {
+            if (!enabled) return;
+            if (!dataSeriesExists(data)) return;
+
+            convertViewBoxRatio();
+
+            var left = position.left;
+            var top = (fixedTop != null) ? fixedTop : position.top;
+            var container = getTooltipContainer(contentGenerator(data));
+            tooltipElem = container;
+            if (chartContainer) {
+                var svgComp = chartContainer.getElementsByTagName("svg")[0];
+                var boundRect = (svgComp) ? svgComp.getBoundingClientRect() : chartContainer.getBoundingClientRect();
+                var svgOffset = {left:0,top:0};
+                if (svgComp) {
+                    var svgBound = svgComp.getBoundingClientRect();
+                    var chartBound = chartContainer.getBoundingClientRect();
+                    var svgBoundTop = svgBound.top;
+                    
+                    //Defensive code. Sometimes, svgBoundTop can be a really negative
+                    //  number, like -134254. That's a bug. 
+                    //  If such a number is found, use zero instead. FireFox bug only
+                    if (svgBoundTop < 0) {
+                        var containerBound = chartContainer.getBoundingClientRect();
+                        svgBoundTop = (Math.abs(svgBoundTop) > containerBound.height) ? 0 : svgBoundTop;
+                    } 
+                    svgOffset.top = Math.abs(svgBoundTop - chartBound.top);
+                    svgOffset.left = Math.abs(svgBound.left - chartBound.left);
+                }
+                //If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
+                //You need to also add any offset between the <svg> element and its containing <div>
+                //Finally, add any offset of the containing <div> on the whole page.
+                left += chartContainer.offsetLeft + svgOffset.left - 2*chartContainer.scrollLeft;
+                top += chartContainer.offsetTop + svgOffset.top - 2*chartContainer.scrollTop;
+            }
 
-    return container;
-  };
+            if (snapDistance && snapDistance > 0) {
+                top = Math.floor(top/snapDistance) * snapDistance;
+            }
 
-  nvtooltip.cleanup = function() {
+            nv.tooltip.calcTooltipPosition([left,top], gravity, distance, container);
+            return nvtooltip;
+        };
 
-      // Find the tooltips, mark them for removal by this class (so others cleanups won't find it)
-      var tooltips = document.getElementsByClassName('nvtooltip');
-      var purging = [];
-      while(tooltips.length) {
-        purging.push(tooltips[0]);
-        tooltips[0].style.transitionDelay = '0 !important';
-        tooltips[0].style.opacity = 0;
-        tooltips[0].className = 'nvtooltip-pending-removal';
-      }
+        nvtooltip.nvPointerEventsClass = nvPointerEventsClass;
+        
+        nvtooltip.content = function(_) {
+            if (!arguments.length) return content;
+            content = _;
+            return nvtooltip;
+        };
 
+        //Returns tooltipElem...not able to set it.
+        nvtooltip.tooltipElem = function() {
+            return tooltipElem;
+        };
 
-      setTimeout(function() {
+        nvtooltip.contentGenerator = function(_) {
+            if (!arguments.length) return contentGenerator;
+            if (typeof _ === 'function') {
+                contentGenerator = _;
+            }
+            return nvtooltip;
+        };
 
-          while (purging.length) {
-             var removeMe = purging.pop();
-              removeMe.parentNode.removeChild(removeMe);
-          }
-    }, 500);
+        nvtooltip.data = function(_) {
+            if (!arguments.length) return data;
+            data = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.gravity = function(_) {
+            if (!arguments.length) return gravity;
+            gravity = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.distance = function(_) {
+            if (!arguments.length) return distance;
+            distance = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.snapDistance = function(_) {
+            if (!arguments.length) return snapDistance;
+            snapDistance = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.classes = function(_) {
+            if (!arguments.length) return classes;
+            classes = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.chartContainer = function(_) {
+            if (!arguments.length) return chartContainer;
+            chartContainer = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.position = function(_) {
+            if (!arguments.length) return position;
+            position.left = (typeof _.left !== 'undefined') ? _.left : position.left;
+            position.top = (typeof _.top !== 'undefined') ? _.top : position.top;
+            return nvtooltip;
+        };
+
+        nvtooltip.fixedTop = function(_) {
+            if (!arguments.length) return fixedTop;
+            fixedTop = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.enabled = function(_) {
+            if (!arguments.length) return enabled;
+            enabled = _;
+            return nvtooltip;
+        };
+
+        nvtooltip.valueFormatter = function(_) {
+            if (!arguments.length) return valueFormatter;
+            if (typeof _ === 'function') {
+                valueFormatter = _;
+            }
+            return nvtooltip;
+        };
+
+        nvtooltip.headerFormatter = function(_) {
+            if (!arguments.length) return headerFormatter;
+            if (typeof _ === 'function') {
+                headerFormatter = _;
+            }
+            return nvtooltip;
+        };
+
+        //id() is a read-only function. You can't use it to set the id.
+        nvtooltip.id = function() {
+            return id;
+        };
+
+
+        return nvtooltip;
+  };
+
+
+  //Original tooltip.show function. Kept for backward compatibility.
+  // pos = [left,top]
+  nv.tooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
+      
+        //Create new tooltip div if it doesn't exist on DOM.
+        var   container = document.createElement('div');
+        container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip');
+
+        var body = parentContainer;
+        if ( !parentContainer || parentContainer.tagName.match(/g|svg/i)) {
+            //If the parent element is an SVG element, place tooltip in the <body> element.
+            body = document.getElementsByTagName('body')[0];
+        }
+   
+        container.style.left = 0;
+        container.style.top = 0;
+        container.style.opacity = 0;
+        container.innerHTML = content;
+        body.appendChild(container);
+        
+        //If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
+        if (parentContainer) {
+           pos[0] = pos[0] - parentContainer.scrollLeft;
+           pos[1] = pos[1] - parentContainer.scrollTop;
+        }
+        nv.tooltip.calcTooltipPosition(pos, gravity, dist, container);
+  };
+
+  //Looks up the ancestry of a DOM element, and returns the first NON-svg node.
+  nv.tooltip.findFirstNonSVGParent = function(Elem) {
+            while(Elem.tagName.match(/^g|svg$/i) !== null) {
+                Elem = Elem.parentNode;
+            }
+            return Elem;
   };
 
+  //Finds the total offsetTop of a given DOM element.
+  //Looks up the entire ancestry of an element, up to the first relatively positioned element.
+  nv.tooltip.findTotalOffsetTop = function ( Elem, initialTop ) {
+                var offsetTop = initialTop;
+                
+                do {
+                    if( !isNaN( Elem.offsetTop ) ) {
+                        offsetTop += (Elem.offsetTop);
+                    }
+                } while( Elem = Elem.offsetParent );
+                return offsetTop;
+  };
+
+  //Finds the total offsetLeft of a given DOM element.
+  //Looks up the entire ancestry of an element, up to the first relatively positioned element.
+  nv.tooltip.findTotalOffsetLeft = function ( Elem, initialLeft) {
+                var offsetLeft = initialLeft;
+                
+                do {
+                    if( !isNaN( Elem.offsetLeft ) ) {
+                        offsetLeft += (Elem.offsetLeft);
+                    }
+                } while( Elem = Elem.offsetParent );
+                return offsetLeft;
+  };
+
+  //Global utility function to render a tooltip on the DOM.
+  //pos = [left,top] coordinates of where to place the tooltip, relative to the SVG chart container.
+  //gravity = how to orient the tooltip
+  //dist = how far away from the mouse to place tooltip
+  //container = tooltip DIV
+  nv.tooltip.calcTooltipPosition = function(pos, gravity, dist, container) {
+
+            var height = parseInt(container.offsetHeight),
+                width = parseInt(container.offsetWidth),
+                windowWidth = nv.utils.windowSize().width,
+                windowHeight = nv.utils.windowSize().height,
+                scrollTop = window.pageYOffset,
+                scrollLeft = window.pageXOffset,
+                left, top;
+
+            windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16;
+            windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16;
+
+            gravity = gravity || 's';
+            dist = dist || 20;
+
+            var tooltipTop = function ( Elem ) {
+                return nv.tooltip.findTotalOffsetTop(Elem, top);
+            };
+
+            var tooltipLeft = function ( Elem ) {
+                return nv.tooltip.findTotalOffsetLeft(Elem,left);
+            };
+
+            switch (gravity) {
+              case 'e':
+                left = pos[0] - width - dist;
+                top = pos[1] - (height / 2);
+                var tLeft = tooltipLeft(container);
+                var tTop = tooltipTop(container);
+                if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left;
+                if (tTop < scrollTop) top = scrollTop - tTop + top;
+                if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+                break;
+              case 'w':
+                left = pos[0] + dist;
+                top = pos[1] - (height / 2);
+                var tLeft = tooltipLeft(container);
+                var tTop = tooltipTop(container);
+                if (tLeft + width > windowWidth) left = pos[0] - width - dist;
+                if (tTop < scrollTop) top = scrollTop + 5;
+                if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+                break;
+              case 'n':
+                left = pos[0] - (width / 2) - 5;
+                top = pos[1] + dist;
+                var tLeft = tooltipLeft(container);
+                var tTop = tooltipTop(container);
+                if (tLeft < scrollLeft) left = scrollLeft + 5;
+                if (tLeft + width > windowWidth) left = left - width/2 + 5;
+                if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+                break;
+              case 's':
+                left = pos[0] - (width / 2);
+                top = pos[1] - height - dist;
+                var tLeft = tooltipLeft(container);
+                var tTop = tooltipTop(container);
+                if (tLeft < scrollLeft) left = scrollLeft + 5;
+                if (tLeft + width > windowWidth) left = left - width/2 + 5;
+                if (scrollTop > tTop) top = scrollTop;
+                break;
+              case 'none':
+                left = pos[0];
+                top = pos[1] - dist;
+                var tLeft = tooltipLeft(container);
+                var tTop = tooltipTop(container);
+                break;
+            }
+
+
+            container.style.left = left+'px';
+            container.style.top = top+'px';
+            container.style.opacity = 1;
+            container.style.position = 'absolute'; 
+
+            return container;
+    };
+
+    //Global utility function to remove tooltips from the DOM.
+    nv.tooltip.cleanup = function() {
+
+              // Find the tooltips, mark them for removal by this class (so others cleanups won't find it)
+              var tooltips = document.getElementsByClassName('nvtooltip');
+              var purging = [];
+              while(tooltips.length) {
+                purging.push(tooltips[0]);
+                tooltips[0].style.transitionDelay = '0 !important';
+                tooltips[0].style.opacity = 0;
+                tooltips[0].className = 'nvtooltip-pending-removal';
+              }
+
+              setTimeout(function() {
+
+                  while (purging.length) {
+                     var removeMe = purging.pop();
+                      removeMe.parentNode.removeChild(removeMe);
+                  }
+            }, 500);
+    };
 
 })();
 
@@ -282,6 +896,7 @@ nv.utils.windowSize = function() {
 // Easy way to bind multiple functions to window.onresize
 // TODO: give a way to remove a function after its bound, other than removing all of them
 nv.utils.windowResize = function(fun){
+  if (fun === undefined) return;
   var oldresize = window.onresize;
 
   window.onresize = function(e) {
@@ -356,20 +971,53 @@ nv.utils.pjax = function(links, content) {
 }
 
 /* For situations where we want to approximate the width in pixels for an SVG:text element.
-Most common instance is when the element is in a display:none; container. 
+Most common instance is when the element is in a display:none; container.
 Forumla is : text.length * font-size * constant_factor
 */
 nv.utils.calcApproxTextWidth = function (svgTextElem) {
-    if (svgTextElem instanceof d3.selection) {
+    if (typeof svgTextElem.style === 'function'
+        && typeof svgTextElem.text === 'function') {
         var fontSize = parseInt(svgTextElem.style("font-size").replace("px",""));
         var textLength = svgTextElem.text().length;
 
-        return textLength * fontSize * 0.5; 
+        return textLength * fontSize * 0.5;
     }
     return 0;
 };
-nv.models.axis = function() {
 
+/* Numbers that are undefined, null or NaN, convert them to zeros.
+*/
+nv.utils.NaNtoZero = function(n) {
+    if (typeof n !== 'number'
+        || isNaN(n)
+        || n === null
+        || n === Infinity) return 0;
+
+    return n;
+};
+
+/*
+Snippet of code you can insert into each nv.models.* to give you the ability to
+do things like:
+chart.options({
+  showXAxis: true,
+  tooltips: true
+});
+
+To enable in the chart:
+chart.options = nv.utils.optionsFunc.bind(chart);
+*/
+nv.utils.optionsFunc = function(args) {
+    if (args) {
+      d3.map(args).forEach((function(key,value) {
+        if (typeof this[key] === "function") {
+           this[key](value);
+        }
+      }).bind(this));
+    }
+    return this;
+};nv.models.axis = function() {
+  "use strict";
   //============================================================
   // Public Variables with Default Settings
   //------------------------------------------------------------
@@ -389,6 +1037,7 @@ nv.models.axis = function() {
     , staggerLabels = false
     , isOrdinal = false
     , ticks = null
+    , axisLabelDistance = 12 //The larger this number is, the closer the axis label is to the axis.
     ;
 
   axis
@@ -434,8 +1083,7 @@ nv.models.axis = function() {
       //TODO: consider calculating width/height based on whether or not label is added, for reference in charts using this component
 
 
-      d3.transition(g)
-          .call(axis);
+      g.transition().call(axis);
 
       scale0 = scale0 || axis.scale();
 
@@ -465,14 +1113,14 @@ nv.models.axis = function() {
                   return 'translate(' + scale(d) + ',0)'
                 })
               .select('text')
-                .attr('dy', '0em')
+                .attr('dy', '-0.5em')
                 .attr('y', -axis.tickPadding())
                 .attr('text-anchor', 'middle')
                 .text(function(d,i) {
                   var v = fmt(d);
                   return ('' + v).match('NaN') ? '' : v;
                 });
-            d3.transition(axisMaxMin)
+            axisMaxMin.transition()
                 .attr('transform', function(d,i) {
                   return 'translate(' + scale.range()[i] + ',0)'
                 });
@@ -494,7 +1142,7 @@ nv.models.axis = function() {
             //Rotate all xTicks
             xTicks
               .attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' })
-              .attr('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');
+              .style('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');
           }
           axisLabel.enter().append('text').attr('class', 'nv-axislabel');
           var w = (scale.range().length==2) ? scale.range()[1] : (scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]));
@@ -517,12 +1165,12 @@ nv.models.axis = function() {
                 .attr('dy', '.71em')
                 .attr('y', axis.tickPadding())
                 .attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' })
-                .attr('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')
+                .style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')
                 .text(function(d,i) {
                   var v = fmt(d);
                   return ('' + v).match('NaN') ? '' : v;
                 });
-            d3.transition(axisMaxMin)
+            axisMaxMin.transition()
                 .attr('transform', function(d,i) {
                   //return 'translate(' + scale.range()[i] + ',0)'
                   //return 'translate(' + scale(d) + ',0)'
@@ -537,7 +1185,7 @@ nv.models.axis = function() {
         case 'right':
           axisLabel.enter().append('text').attr('class', 'nv-axislabel');
           axisLabel
-              .attr('text-anchor', rotateYLabel ? 'middle' : 'begin')
+              .style('text-anchor', rotateYLabel ? 'middle' : 'begin')
               .attr('transform', rotateYLabel ? 'rotate(90)' : '')
               .attr('y', rotateYLabel ? (-Math.max(margin.right,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
               .attr('x', rotateYLabel ? (scale.range()[0] / 2) : axis.tickPadding());
@@ -555,12 +1203,12 @@ nv.models.axis = function() {
                 .attr('dy', '.32em')
                 .attr('y', 0)
                 .attr('x', axis.tickPadding())
-                .attr('text-anchor', 'start')
+                .style('text-anchor', 'start')
                 .text(function(d,i) {
                   var v = fmt(d);
                   return ('' + v).match('NaN') ? '' : v;
                 });
-            d3.transition(axisMaxMin)
+            axisMaxMin.transition()
                 .attr('transform', function(d,i) {
                   return 'translate(0,' + scale.range()[i] + ')'
                 })
@@ -579,9 +1227,9 @@ nv.models.axis = function() {
           */
           axisLabel.enter().append('text').attr('class', 'nv-axislabel');
           axisLabel
-              .attr('text-anchor', rotateYLabel ? 'middle' : 'end')
+              .style('text-anchor', rotateYLabel ? 'middle' : 'end')
               .attr('transform', rotateYLabel ? 'rotate(-90)' : '')
-              .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
+              .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + axisLabelDistance) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
               .attr('x', rotateYLabel ? (-scale.range()[0] / 2) : -axis.tickPadding());
           if (showMaxMin) {
             var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
@@ -602,7 +1250,7 @@ nv.models.axis = function() {
                   var v = fmt(d);
                   return ('' + v).match('NaN') ? '' : v;
                 });
-            d3.transition(axisMaxMin)
+            axisMaxMin.transition()
                 .attr('transform', function(d,i) {
                   return 'translate(0,' + scale.range()[i] + ')'
                 })
@@ -623,7 +1271,7 @@ nv.models.axis = function() {
               if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it!
                 if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL
                   d3.select(this).attr('opacity', 0);
-                
+
                 d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!!
               }
             });
@@ -688,6 +1336,8 @@ nv.models.axis = function() {
   d3.rebind(chart, axis, 'orient', 'tickValues', 'tickSubdivide', 'tickSize', 'tickPadding', 'tickFormat');
   d3.rebind(chart, scale, 'domain', 'range', 'rangeBand', 'rangeBands'); //these are also accessible by chart.scale(), but added common ones directly for ease of use
 
+  chart.options = nv.utils.optionsFunc.bind(chart);
+
   chart.margin = function(_) {
     if(!arguments.length) return margin;
     margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
@@ -760,71 +1410,79 @@ nv.models.axis = function() {
     return chart;
   };
 
+  chart.axisLabelDistance = function(_) {
+    if (!arguments.length) return axisLabelDistance;
+    axisLabelDistance = _;
+    return chart;
+  };
 
   //============================================================
 
 
   return chart;
 }
-
-// Chart design based on the recommendations of Stephen Few. Implementation
-// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
-// http://projects.instantcognition.com/protovis/bulletchart/
-
-nv.models.bullet = function() {
-
+//TODO: consider deprecating and using multibar with single series for this
+nv.models.historicalBar = function() {
+  "use strict";
   //============================================================
   // Public Variables with Default Settings
   //------------------------------------------------------------
 
   var margin = {top: 0, right: 0, bottom: 0, left: 0}
-    , orient = 'left' // TODO top & bottom
-    , reverse = false
-    , ranges = function(d) { return d.ranges }
-    , markers = function(d) { return d.markers }
-    , measures = function(d) { return d.measures }
-    , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
-    , width = 380
-    , height = 30
-    , tickFormat = null
-    , color = nv.utils.getColor(['#1f77b4'])
-    , dispatch = d3.dispatch('elementMouseover', 'elementMouseout')
+    , width = 960
+    , height = 500
+    , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
+    , x = d3.scale.linear()
+    , y = d3.scale.linear()
+    , getX = function(d) { return d.x }
+    , getY = function(d) { return d.y }
+    , forceX = []
+    , forceY = [0]
+    , padData = false
+    , clipEdge = true
+    , color = nv.utils.defaultColor()
+    , xDomain
+    , yDomain
+    , xRange
+    , yRange
+    , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
+    , interactive = true
     ;
 
   //============================================================
 
 
   function chart(selection) {
-    selection.each(function(d, i) {
+    selection.each(function(data) {
       var availableWidth = width - margin.left - margin.right,
           availableHeight = height - margin.top - margin.bottom,
           container = d3.select(this);
 
-      var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
-          markerz = markers.call(this, d, i).slice().sort(d3.descending),
-          measurez = measures.call(this, d, i).slice().sort(d3.descending);
-
 
       //------------------------------------------------------------
       // Setup Scales
 
-      // Compute the new x-scale.
-      var x1 = d3.scale.linear()
-          .domain( d3.extent(d3.merge([forceX, rangez])) )
-          .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
+      x   .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ))
 
-      // Retrieve the old x-scale, if this is an update.
-      var x0 = this.__chart__ || d3.scale.linear()
-          .domain([0, Infinity])
-          .range(x1.range());
+      if (padData)
+        x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);
+      else
+        x.range(xRange || [0, availableWidth]);
 
-      // Stash the new scale.
-      this.__chart__ = x1;
+      y   .domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) ))
+          .range(yRange || [availableHeight, 0]);
 
+      // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point
 
-      var rangeMin = d3.min(rangez), //rangez[2]
-          rangeMax = d3.max(rangez), //rangez[0]
-          rangeAvg = rangez[1];
+      if (x.domain()[0] === x.domain()[1])
+        x.domain()[0] ?
+            x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])
+          : x.domain([-1,1]);
+
+      if (y.domain()[0] === y.domain()[1])
+        y.domain()[0] ?
+            y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])
+          : y.domain([-1,1]);
 
       //------------------------------------------------------------
 
@@ -832,63 +1490,397 @@ nv.models.bullet = function() {
       //------------------------------------------------------------
       // Setup containers and skeleton of chart
 
-      var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);
-      var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');
+      var wrap = container.selectAll('g.nv-wrap.nv-historicalBar-' + id).data([data[0].values]);
+      var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBar-' + id);
+      var defsEnter = wrapEnter.append('defs');
       var gEnter = wrapEnter.append('g');
       var g = wrap.select('g');
 
-      gEnter.append('rect').attr('class', 'nv-range nv-rangeMax');
-      gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg');
-      gEnter.append('rect').attr('class', 'nv-range nv-rangeMin');
-      gEnter.append('rect').attr('class', 'nv-measure');
-      gEnter.append('path').attr('class', 'nv-markerTriangle');
+      gEnter.append('g').attr('class', 'nv-bars');
 
       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
 
       //------------------------------------------------------------
 
 
+      container
+          .on('click', function(d,i) {
+            dispatch.chartClick({
+                data: d,
+                index: i,
+                pos: d3.event,
+                id: id
+            });
+          });
 
-      var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)
-          w1 = function(d) { return Math.abs(x1(d) - x1(0)) };
-      var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },
-          xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };
 
+      defsEnter.append('clipPath')
+          .attr('id', 'nv-chart-clip-path-' + id)
+        .append('rect');
 
-      g.select('rect.nv-rangeMax')
-          .attr('height', availableHeight)
-          .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin))
-          .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin))
-          .datum(rangeMax > 0 ? rangeMax : rangeMin)
-          /*
-          .attr('x', rangeMin < 0 ?
-                         rangeMax > 0 ?
-                             x1(rangeMin)
-                           : x1(rangeMax)
-                       : x1(0))
-                      */
+      wrap.select('#nv-chart-clip-path-' + id + ' rect')
+          .attr('width', availableWidth)
+          .attr('height', availableHeight);
 
-      g.select('rect.nv-rangeAvg')
-          .attr('height', availableHeight)
-          .attr('width', w1(rangeAvg))
-          .attr('x', xp1(rangeAvg))
-          .datum(rangeAvg)
-          /*
-          .attr('width', rangeMax <= 0 ?
-                             x1(rangeMax) - x1(rangeAvg)
-                           : x1(rangeAvg) - x1(rangeMin))
-          .attr('x', rangeMax <= 0 ?
-                         x1(rangeAvg)
-                       : x1(rangeMin))
-                      */
+      g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');
 
-      g.select('rect.nv-rangeMin')
-          .attr('height', availableHeight)
-          .attr('width', w1(rangeMax))
-          .attr('x', xp1(rangeMax))
-          .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax))
-          .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax))
-          .datum(rangeMax > 0 ? rangeMin : rangeMax)
+
+
+      var bars = wrap.select('.nv-bars').selectAll('.nv-bar')
+          .data(function(d) { return d }, function(d,i) {return getX(d,i)});
+
+      bars.exit().remove();
+
+
+      var barsEnter = bars.enter().append('rect')
+          //.attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })
+          .attr('x', 0 )
+          .attr('y', function(d,i) {  return nv.utils.NaNtoZero(y(Math.max(0, getY(d,i)))) })
+          .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.abs(y(getY(d,i)) - y(0))) })
+          .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; }) 
+          .on('mouseover', function(d,i) {
+            if (!interactive) return;
+            d3.select(this).classed('hover', true);
+            dispatch.elementMouseover({
+                point: d,
+                series: data[0],
+                pos: [x(getX(d,i)), y(getY(d,i))],  // TODO: Figure out why the value appears to be shifted
+                pointIndex: i,
+                seriesIndex: 0,
+                e: d3.event
+            });
+
+          })
+          .on('mouseout', function(d,i) {
+                if (!interactive) return;
+                d3.select(this).classed('hover', false);
+                dispatch.elementMouseout({
+                    point: d,
+                    series: data[0],
+                    pointIndex: i,
+                    seriesIndex: 0,
+                    e: d3.event
+                });
+          })
+          .on('click', function(d,i) {
+                if (!interactive) return;
+                dispatch.elementClick({
+                    //label: d[label],
+                    value: getY(d,i),
+                    data: d,
+                    index: i,
+                    pos: [x(getX(d,i)), y(getY(d,i))],
+                    e: d3.event,
+                    id: id
+                });
+              d3.event.stopPropagation();
+          })
+          .on('dblclick', function(d,i) {
+              if (!interactive) return;
+              dispatch.elementDblClick({
+                  //label: d[label],
+                  value: getY(d,i),
+                  data: d,
+                  index: i,
+                  pos: [x(getX(d,i)), y(getY(d,i))],
+                  e: d3.event,
+                  id: id
+              });
+              d3.event.stopPropagation();
+          });
+
+      bars
+          .attr('fill', function(d,i) { return color(d, i); })
+          .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })
+          .transition()
+          .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; }) 
+           //TODO: better width calculations that don't assume always uniform data spacing;w
+          .attr('width', (availableWidth / data[0].values.length) * .9 );
+
+
+      bars.transition()
+          .attr('y', function(d,i) {
+            var rval = getY(d,i) < 0 ?
+                    y(0) :
+                    y(0) - y(getY(d,i)) < 1 ?
+                      y(0) - 1 :
+                      y(getY(d,i));
+            return nv.utils.NaNtoZero(rval);
+          })
+          .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) });
+
+    });
+
+    return chart;
+  }
+
+  //Create methods to allow outside functions to highlight a specific bar.
+  chart.highlightPoint = function(pointIndex, isHoverOver) {
+      d3.select(".nv-historicalBar-" + id)
+        .select(".nv-bars .nv-bar-0-" + pointIndex)
+              .classed("hover", isHoverOver)
+               ;
+  };
+
+  chart.clearHighlights = function() {
+      d3.select(".nv-historicalBar-" + id)
+        .select(".nv-bars .nv-bar.hover")
+              .classed("hover", false)
+               ;
+  };
+  //============================================================
+  // Expose Public Variables
+  //------------------------------------------------------------
+
+  chart.dispatch = dispatch;
+
+  chart.options = nv.utils.optionsFunc.bind(chart);
+  
+  chart.x = function(_) {
+    if (!arguments.length) return getX;
+    getX = _;
+    return chart;
+  };
+
+  chart.y = function(_) {
+    if (!arguments.length) return getY;
+    getY = _;
+    return chart;
+  };
+
+  chart.margin = function(_) {
+    if (!arguments.length) return margin;
+    margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
+    margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;
+    margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
+    margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
+    return chart;
+  };
+
+  chart.width = function(_) {
+    if (!arguments.length) return width;
+    width = _;
+    return chart;
+  };
+
+  chart.height = function(_) {
+    if (!arguments.length) return height;
+    height = _;
+    return chart;
+  };
+
+  chart.xScale = function(_) {
+    if (!arguments.length) return x;
+    x = _;
+    return chart;
+  };
+
+  chart.yScale = function(_) {
+    if (!arguments.length) return y;
+    y = _;
+    return chart;
+  };
+
+  chart.xDomain = function(_) {
+    if (!arguments.length) return xDomain;
+    xDomain = _;
+    return chart;
+  };
+
+  chart.yDomain = function(_) {
+    if (!arguments.length) return yDomain;
+    yDomain = _;
+    return chart;
+  };
+
+  chart.xRange = function(_) {
+    if (!arguments.length) return xRange;
+    xRange = _;
+    return chart;
+  };
+
+  chart.yRange = function(_) {
+    if (!arguments.length) return yRange;
+    yRange = _;
+    return chart;
+  };
+
+  chart.forceX = function(_) {
+    if (!arguments.length) return forceX;
+    forceX = _;
+    return chart;
+  };
+
+  chart.forceY = function(_) {
+    if (!arguments.length) return forceY;
+    forceY = _;
+    return chart;
+  };
+
+  chart.padData = function(_) {
+    if (!arguments.length) return padData;
+    padData = _;
+    return chart;
+  };
+
+  chart.clipEdge = function(_) {
+    if (!arguments.length) return clipEdge;
+    clipEdge = _;
+    return chart;
+  };
+
+  chart.color = function(_) {
+    if (!arguments.length) return color;
+    color = nv.utils.getColor(_);
+    return chart;
+  };
+
+  chart.id = function(_) {
+    if (!arguments.length) return id;
+    id = _;
+    return chart;
+  };
+
+  chart.interactive = function(_) {
+    if(!arguments.length) return interactive;
+    interactive = false;
+    return chart;
+  };
+
+  //============================================================
+
+
+  return chart;
+}
+
+// Chart design based on the recommendations of Stephen Few. Implementation
+// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
+// http://projects.instantcognition.com/protovis/bulletchart/
+
+nv.models.bullet = function() {
+  "use strict";
+  //============================================================
+  // Public Variables with Default Settings
+  //------------------------------------------------------------
+
+  var margin = {top: 0, right: 0, bottom: 0, left: 0}
+    , orient = 'left' // TODO top & bottom
+    , reverse = false
+    , ranges = function(d) { return d.ranges }
+    , markers = function(d) { return d.markers }
+    , measures = function(d) { return d.measures }
+    , rangeLabels = function(d) { return d.rangeLabels ? d.rangeLabels : [] }
+    , markerLabels = function(d) { return d.markerLabels ? d.markerLabels : []  }
+    , measureLabels = function(d) { return d.measureLabels ? d.measureLabels : []  }
+    , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
+    , width = 380
+    , height = 30
+    , tickFormat = null
+    , color = nv.utils.getColor(['#1f77b4'])
+    , dispatch = d3.dispatch('elementMouseover', 'elementMouseout')
+    ;
+
+  //============================================================
+
+
+  function chart(selection) {
+    selection.each(function(d, i) {
+      var availableWidth = width - margin.left - margin.right,
+          availableHeight = height - margin.top - margin.bottom,
+          container = d3.select(this);
+
+      var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
+          markerz = markers.call(this, d, i).slice().sort(d3.descending),
+          measurez = measures.call(this, d, i).slice().sort(d3.descending),
+          rangeLabelz = rangeLabels.call(this, d, i).slice(),
+          markerLabelz = markerLabels.call(this, d, i).slice(),
+          measureLabelz = measureLabels.call(this, d, i).slice();
+
+
+      //------------------------------------------------------------
+      // Setup Scales
+
+      // Compute the new x-scale.
+      var x1 = d3.scale.linear()
+          .domain( d3.extent(d3.merge([forceX, rangez])) )
+          .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
+
+      // Retrieve the old x-scale, if this is an update.
+      var x0 = this.__chart__ || d3.scale.linear()
+          .domain([0, Infinity])
+          .range(x1.range());
+
+      // Stash the new scale.
+      this.__chart__ = x1;
+
+
+      var rangeMin = d3.min(rangez), //rangez[2]
+          rangeMax = d3.max(rangez), //rangez[0]
+          rangeAvg = rangez[1];
+
+      //------------------------------------------------------------
+
+
+      //------------------------------------------------------------
+      // Setup containers and skeleton of chart
+
+      var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);
+      var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');
+      var gEnter = wrapEnter.append('g');
+      var g = wrap.select('g');
+
+      gEnter.append('rect').attr('class', 'nv-range nv-rangeMax');
+      gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg');
+      gEnter.append('rect').attr('class', 'nv-range nv-rangeMin');
+      gEnter.append('rect').attr('class', 'nv-measure');
+      gEnter.append('path').attr('class', 'nv-markerTriangle');
+
+      wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
+
+      //------------------------------------------------------------
+
+
+
+      var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)
+          w1 = function(d) { return Math.abs(x1(d) - x1(0)) };
+      var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },
+          xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };
+
+
+      g.select('rect.nv-rangeMax')
+          .attr('height', availableHeight)
+          .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin))
+          .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin))
+          .datum(rangeMax > 0 ? rangeMax : rangeMin)
+          /*
+          .attr('x', rangeMin < 0 ?
+                         rangeMax > 0 ?
+                             x1(rangeMin)
+                           : x1(rangeMax)
+                       : x1(0))
+                      */
+
+      g.select('rect.nv-rangeAvg')
+          .attr('height', availableHeight)
+          .attr('width', w1(rangeAvg))
+          .attr('x', xp1(rangeAvg))
+          .datum(rangeAvg)
+          /*
+          .attr('width', rangeMax <= 0 ?
+                             x1(rangeMax) - x1(rangeAvg)
+                           : x1(rangeAvg) - x1(rangeMin))
+          .attr('x', rangeMax <= 0 ?
+                         x1(rangeAvg)
+                       : x1(rangeMin))
+                      */
+
+      g.select('rect.nv-rangeMin')
+          .attr('height', availableHeight)
+          .attr('width', w1(rangeMax))
+          .attr('x', xp1(rangeMax))
+          .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax))
+          .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax))
+          .datum(rangeMax > 0 ? rangeMin : rangeMax)
           /*
           .attr('width', rangeMax <= 0 ?
                              x1(rangeAvg) - x1(rangeMin)
@@ -909,14 +1901,14 @@ nv.models.bullet = function() {
           .on('mouseover', function() {
               dispatch.elementMouseover({
                 value: measurez[0],
-                label: 'Current',
+                label: measureLabelz[0] || 'Current',
                 pos: [x1(measurez[0]), availableHeight/2]
               })
           })
           .on('mouseout', function() {
               dispatch.elementMouseout({
                 value: measurez[0],
-                label: 'Current'
+                label: measureLabelz[0] || 'Current'
               })
           })
 
@@ -928,14 +1920,14 @@ nv.models.bullet = function() {
             .on('mouseover', function() {
               dispatch.elementMouseover({
                 value: markerz[0],
-                label: 'Previous',
+                label: markerLabelz[0] || 'Previous',
                 pos: [x1(markerz[0]), availableHeight/2]
               })
             })
             .on('mouseout', function() {
               dispatch.elementMouseout({
                 value: markerz[0],
-                label: 'Previous'
+                label: markerLabelz[0] || 'Previous'
               })
             });
       } else {
@@ -945,7 +1937,7 @@ nv.models.bullet = function() {
 
       wrap.selectAll('.nv-range')
           .on('mouseover', function(d,i) {
-            var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum";
+            var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum");
 
             dispatch.elementMouseover({
               value: d,
@@ -954,7 +1946,7 @@ nv.models.bullet = function() {
             })
           })
           .on('mouseout', function(d,i) {
-            var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum";
+            var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum");
 
             dispatch.elementMouseout({
               value: d,
@@ -1068,6 +2060,8 @@ nv.models.bullet = function() {
 
   chart.dispatch = dispatch;
 
+  chart.options = nv.utils.optionsFunc.bind(chart);
+  
   // left, right, top, bottom
   chart.orient = function(_) {
     if (!arguments.length) return orient;
@@ -1148,7 +2142,7 @@ nv.models.bullet = function() {
 // based on the work of Clint Ivy, Jamie Love, and Jason Davies.
 // http://projects.instantcognition.com/protovis/bulletchart/
 nv.models.bulletChart = function() {
-
+  "use strict";
   //============================================================
   // Public Variables with Default Settings
   //------------------------------------------------------------
@@ -1403,6 +2397,8 @@ nv.models.bulletChart = function() {
 
   d3.rebind(chart, bullet, 'color');
 
+  chart.options = nv.utils.optionsFunc.bind(chart);
+  
   // left, right, top, bottom
   chart.orient = function(x) {
     if (!arguments.length) return orient;
@@ -1486,7 +2482,7 @@ nv.models.bulletChart = function() {
 
 
 nv.models.cumulativeLineChart = function() {
-
+  "use strict";
   //============================================================
   // Public Variables with Default Settings
   //------------------------------------------------------------
@@ -1496,6 +2492,7 @@ nv.models.cumulativeLineChart = function() {
     , yAxis = nv.models.axis()
     , legend = nv.models.legend()
     , controls = nv.models.legend()
+    , interactiveLayer = nv.interactiveGuideline()
     ;
 
   var margin = {top: 30, right: 30, bottom: 50, left: 60}
@@ -1503,8 +2500,12 @@ nv.models.cumulativeLineChart = function() {
     , width = null
     , height = null
     , showLegend = true
+    , showXAxis = true
+    , showYAxis = true
+    , rightAlignYAxis = false
     , tooltips = true
     , showControls = true
+    , useInteractiveGuideline = false
     , rescaleY = true
     , tooltip = function(key, x, y, e, graph) {
         return '<h3>' + key + '</h3>' +
@@ -1518,6 +2519,8 @@ nv.models.cumulativeLineChart = function() {
     , noData = 'No Data Available.'
     , average = function(d) { return d.average }
     , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
+    , transitionDuration = 250
+    , noErrorCheck = false  //if set to TRUE, will bypass an error check in the indexify function.
     ;
 
   xAxis
@@ -1525,11 +2528,11 @@ nv.models.cumulativeLineChart = function() {
     .tickPadding(7)
     ;
   yAxis
-    .orient('left')
+    .orient((rightAlignYAxis) ? 'right' : 'left')
     ;
 
   //============================================================
-
+  controls.updateState(false);
 
   //============================================================
   // Private Variables
@@ -1549,36 +2552,8 @@ nv.models.cumulativeLineChart = function() {
     nv.tooltip.show([left, top], content, null, null, offsetElement);
   };
 
-/*
-  //Moved to see if we can get better behavior to fix issue #315
-  var indexDrag = d3.behavior.drag()
-                    .on('dragstart', dragStart)
-                    .on('drag', dragMove)
-                    .on('dragend', dragEnd);
-
-  function dragStart(d,i) {
-    d3.select(chart.container)
-        .style('cursor', 'ew-resize');
-  }
-
-  function dragMove(d,i) {
-    d.x += d3.event.dx;
-    d.i = Math.round(dx.invert(d.x));
-
-    d3.select(this).attr('transform', 'translate(' + dx(d.i) + ',0)');
-    chart.update();
-  }
-
-  function dragEnd(d,i) {
-    d3.select(chart.container)
-        .style('cursor', 'auto');
-    chart.update();
-  }
-*/
-
   //============================================================
 
-
   function chart(selection) {
     selection.each(function(data) {
       var container = d3.select(this).classed('nv-chart-' + id, true),
@@ -1590,7 +2565,7 @@ nv.models.cumulativeLineChart = function() {
                              - margin.top - margin.bottom;
 
 
-      chart.update = function() { container.transition().call(chart) };
+      chart.update = function() { container.transition().duration(transitionDuration).call(chart) };
       chart.container = this;
 
       //set state.disabled
@@ -1633,9 +2608,6 @@ nv.models.cumulativeLineChart = function() {
         dispatch.stateChange(state);
       }
 
-
-
-
       //------------------------------------------------------------
       // Display No Data message if there's nothing to show.
 
@@ -1705,21 +2677,20 @@ nv.models.cumulativeLineChart = function() {
 
       //------------------------------------------------------------
       // Setup containers and skeleton of chart
-
+      var interactivePointerEvents = (useInteractiveGuideline) ? "none" : "all";
       var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]);
       var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-cumulativeLine').append('g');
       var g = wrap.select('g');
 
-      gEnter.append('g').attr('class', 'nv-x nv-axis');
+      gEnter.append('g').attr('class', 'nv-interactive');
+      gEnter.append('g').attr('class', 'nv-x nv-axis').style("pointer-events","none");
       gEnter.append('g').attr('class', 'nv-y nv-axis');
       gEnter.append('g').attr('class', 'nv-background');
-      gEnter.append('g').attr('class', 'nv-linesWrap');
-      gEnter.append('g').attr('class', 'nv-avgLinesWrap');
+      gEnter.append('g').attr('class', 'nv-linesWrap').style("pointer-events",interactivePointerEvents);
+      gEnter.append('g').attr('class', 'nv-avgLinesWrap').style("pointer-events","none");
       gEnter.append('g').attr('class', 'nv-legendWrap');
       gEnter.append('g').attr('class', 'nv-controlsWrap');
 
-      //------------------------------------------------------------
-
 
       //------------------------------------------------------------
       // Legend
@@ -1732,7 +2703,7 @@ nv.models.cumulativeLineChart = function() {
             .call(legend);
 
         if ( margin.top != legend.height()) {
-          margin.top = legend.height() + legend.legendBelowPadding();// added legend.legendBelowPadding to allow for more spacing
+          margin.top = legend.height();
           availableHeight = (height || parseInt(container.style('height')) || 400)
                              - margin.top - margin.bottom;
         }
@@ -1752,7 +2723,13 @@ nv.models.cumulativeLineChart = function() {
           { key: 'Re-scale y-axis', disabled: !rescaleY }
         ];
 
-        controls.width(140).color(['#444', '#444', '#444']);
+        controls
+            .width(140)
+            .color(['#444', '#444', '#444'])
+            .rightAlign(false)
+            .margin({top: 5, right: 0, bottom: 5, left: 20})
+            ;
+
         g.select('.nv-controlsWrap')
             .datum(controlsData)
             .attr('transform', 'translate(0,' + (-margin.top) +')')
@@ -1764,6 +2741,10 @@ nv.models.cumulativeLineChart = function() {
 
       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
 
+      if (rightAlignYAxis) {
+          g.select(".nv-y.nv-axis")
+              .attr("transform", "translate(" + availableWidth + ",0)");
+      }
 
       // Show error if series goes below 100%
       var tempDisabled = data.filter(function(d) { return d.tempDisabled });
@@ -1780,6 +2761,18 @@ nv.models.cumulativeLineChart = function() {
       //------------------------------------------------------------
       // Main Chart Component(s)
 
+      //------------------------------------------------------------
+      //Set up interactive layer
+      if (useInteractiveGuideline) {
+        interactiveLayer
+          .width(availableWidth)
+          .height(availableHeight)
+          .margin({left:margin.left,top:margin.top})
+          .svgContainer(container)
+          .xScale(x);
+        wrap.select(".nv-interactive").call(interactiveLayer);
+      }
+
       gEnter.select('.nv-background')
         .append('rect');
 
@@ -1818,6 +2811,14 @@ nv.models.cumulativeLineChart = function() {
       var avgLines = g.select(".nv-avgLinesWrap").selectAll("line")
               .data(avgLineData, function(d) { return d.key; });
 
+      var getAvgLineY = function(d) {
+          //If average lines go off the svg element, clamp them to the svg bounds.
+          var yVal = y(average(d));
+          if (yVal < 0) return 0;
+          if (yVal > availableHeight) return availableHeight;
+          return yVal;
+      };
+
       avgLines.enter()
               .append('line')
               .style('stroke-width',2)
@@ -1827,14 +2828,20 @@ nv.models.cumulativeLineChart = function() {
               })
               .attr('x1',0)
               .attr('x2',availableWidth)
-              .attr('y1', function(d) { return y(average(d)); })
-              .attr('y2', function(d) { return y(average(d)); });
+              .attr('y1', getAvgLineY)
+              .attr('y2', getAvgLineY);
 
       avgLines
+              .style('stroke-opacity',function(d){
+                  //If average lines go offscreen, make them transparent
+                  var yVal = y(average(d));
+                  if (yVal < 0 || yVal > availableHeight) return 0;
+                  return 1;
+              })
               .attr('x1',0)
               .attr('x2',availableWidth)
-              .attr('y1', function(d) { return y(average(d)); })
-              .attr('y2', function(d) { return y(average(d)); });
+              .attr('y1', getAvgLineY)
+              .attr('y2', getAvgLineY);
 
       avgLines.exit().remove();
 
@@ -1847,6 +2854,7 @@ nv.models.cumulativeLineChart = function() {
           .attr('x', -2)
           .attr('fill', 'red')
           .attr('fill-opacity', .5)
+          .style("pointer-events","all")
           .call(indexDrag)
 
       indexLine
@@ -1859,26 +2867,29 @@ nv.models.cumulativeLineChart = function() {
       //------------------------------------------------------------
       // Setup Axes
 
-      xAxis
-        .scale(x)
-        //Suggest how many ticks based on the chart width and D3 should listen (70 is the optimal number for MM/DD/YY dates)
-        .ticks( Math.min(data[0].values.length,availableWidth/70) )
-        .tickSize(-availableHeight, 0);
-
-      g.select('.nv-x.nv-axis')
-          .attr('transform', 'translate(0,' + y.range()[0] + ')');
-      d3.transition(g.select('.nv-x.nv-axis'))
-          .call(xAxis);
+      if (showXAxis) {
+        xAxis
+          .scale(x)
+          //Suggest how many ticks based on the chart width and D3 should listen (70 is the optimal number for MM/DD/YY dates)
+          .ticks( Math.min(data[0].values.length,availableWidth/70) )
+          .tickSize(-availableHeight, 0);
 
+        g.select('.nv-x.nv-axis')
+            .attr('transform', 'translate(0,' + y.range()[0] + ')');
+        d3.transition(g.select('.nv-x.nv-axis'))
+            .call(xAxis);
+      }
 
-      yAxis
-        .scale(y)
-        .ticks( availableHeight / 36 )
-        .tickSize( -availableWidth, 0);
 
-      d3.transition(g.select('.nv-y.nv-axis'))
-          .call(yAxis);
+      if (showYAxis) {
+        yAxis
+          .scale(y)
+          .ticks( availableHeight / 36 )
+          .tickSize( -availableWidth, 0);
 
+        d3.transition(g.select('.nv-y.nv-axis'))
+            .call(yAxis);
+      }
       //------------------------------------------------------------
 
 
@@ -1891,7 +2902,12 @@ nv.models.cumulativeLineChart = function() {
         indexLine
           .data([index]);
 
-        container.call(chart);
+        //When dragging the index line, turn off line transitions.
+        // Then turn them back on when done dragging.
+        var oldDuration = chart.transitionDuration();
+        chart.transitionDuration(0);
+        chart.update();
+        chart.transitionDuration(oldDuration);
       }
 
       g.select('.nv-background rect')
@@ -1917,61 +2933,79 @@ nv.models.cumulativeLineChart = function() {
         updateZero();
       });
 
-      controls.dispatch.on('legendClick', function(d,i) { 
+      controls.dispatch.on('legendClick', function(d,i) {
         d.disabled = !d.disabled;
         rescaleY = !d.disabled;
 
         state.rescaleY = rescaleY;
         dispatch.stateChange(state);
-
-        //selection.transition().call(chart);
         chart.update();
       });
 
 
-      legend.dispatch.on('legendClick', function(d,i) { 
-        d.disabled = !d.disabled;
-
-        if (!data.filter(function(d) { return !d.disabled }).length) {
-          data.map(function(d) {
-            d.disabled = false;
-            wrap.selectAll('.nv-series').classed('disabled', false);
-            return d;
-          });
-        }
-
-        state.disabled = data.map(function(d) { return !!d.disabled });
+      legend.dispatch.on('stateChange', function(newState) {
+        state.disabled = newState.disabled;
         dispatch.stateChange(state);
-
-        //selection.transition().call(chart);
         chart.update();
       });
 
-      legend.dispatch.on('legendDblclick', function(d) {
-          //Double clicking should always enable current series, and disabled all others.
-          data.forEach(function(d) {
-             d.disabled = true;
+      interactiveLayer.dispatch.on('elementMousemove', function(e) {
+          lines.clearHighlights();
+          var singlePoint, pointIndex, pointXLocation, allData = [];
+
+
+          data
+          .filter(function(series, i) {
+            series.seriesIndex = i;
+            return !series.disabled;
+          })
+          .forEach(function(series,i) {
+              pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());
+              lines.highlightPoint(i, pointIndex, true);
+              var point = series.values[pointIndex];
+              if (typeof point === 'undefined') return;
+              if (typeof singlePoint === 'undefined') singlePoint = point;
+              if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));
+              allData.push({
+                  key: series.key,
+                  value: chart.y()(point, pointIndex),
+                  color: color(series,series.seriesIndex)
+              });
           });
-          d.disabled = false;  
 
-          state.disabled = data.map(function(d) { return !!d.disabled });
-          dispatch.stateChange(state);
-          chart.update();
-      });
+          //Highlight the tooltip entry based on which point the mouse is closest to.
+          if (allData.length > 2) {
+            var yValue = chart.yScale().invert(e.mouseY);
+            var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);
+            var threshold = 0.03 * domainExtent;
+            var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold);
+            if (indexToHighlight !== null)
+              allData[indexToHighlight].highlight = true;
+          }
 
+          var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex), pointIndex);
+          interactiveLayer.tooltip
+                  .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top})
+                  .chartContainer(that.parentNode)
+                  .enabled(tooltips)
+                  .valueFormatter(function(d,i) {
+                     return yAxis.tickFormat()(d);
+                  })
+                  .data(
+                      {
+                        value: xValue,
+                        series: allData
+                      }
+                  )();
+
+          interactiveLayer.renderGuideLine(pointXLocation);
 
-/*
-      //
-      legend.dispatch.on('legendMouseover', function(d, i) {
-        d.hover = true;
-        selection.transition().call(chart)
       });
 
-      legend.dispatch.on('legendMouseout', function(d, i) {
-        d.hover = false;
-        selection.transition().call(chart)
+      interactiveLayer.dispatch.on("elementMouseout",function(e) {
+          dispatch.tooltipHide();
+          lines.clearHighlights();
       });
-*/
 
       dispatch.on('tooltipShow', function(e) {
         if (tooltips) showTooltip(e, that.parentNode);
@@ -2046,8 +3080,11 @@ nv.models.cumulativeLineChart = function() {
   chart.legend = legend;
   chart.xAxis = xAxis;
   chart.yAxis = yAxis;
+  chart.interactiveLayer = interactiveLayer;
+
+  d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y', 'xScale','yScale', 'size', 'xDomain', 'yDomain', 'xRange', 'yRange', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi','useVoronoi',  'id');
 
-  d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
+  chart.options = nv.utils.optionsFunc.bind(chart);
 
   chart.margin = function(_) {
     if (!arguments.length) return margin;
@@ -2079,8 +3116,8 @@ nv.models.cumulativeLineChart = function() {
 
   chart.rescaleY = function(_) {
     if (!arguments.length) return rescaleY;
-    rescaleY = _
-    return rescaleY;
+    rescaleY = _;
+    return chart;
   };
 
   chart.showControls = function(_) {
@@ -2089,12 +3126,41 @@ nv.models.cumulativeLineChart = function() {
     return chart;
   };
 
+  chart.useInteractiveGuideline = function(_) {
+    if(!arguments.length) return useInteractiveGuideline;
+    useInteractiveGuideline = _;
+    if (_ === true) {
+       chart.interactive(false);
+       chart.useVoronoi(false);
+    }
+    return chart;
+  };
+
   chart.showLegend = function(_) {
     if (!arguments.length) return showLegend;
     showLegend = _;
     return chart;
   };
 
+  chart.showXAxis = function(_) {
+    if (!arguments.length) return showXAxis;
+    showXAxis = _;
+    return chart;
+  };
+
+  chart.showYAxis = function(_) {
+    if (!arguments.length) return showYAxis;
+    showYAxis = _;
+    return chart;
+  };
+
+  chart.rightAlignYAxis = function(_) {
+    if(!arguments.length) return rightAlignYAxis;
+    rightAlignYAxis = _;
+    yAxis.orient( (_) ? 'right' : 'left');
+    return chart;
+  };
+
   chart.tooltips = function(_) {
     if (!arguments.length) return tooltips;
     tooltips = _;
@@ -2131,6 +3197,18 @@ nv.models.cumulativeLineChart = function() {
      return chart;
   };
 
+  chart.transitionDuration = function(_) {
+    if (!arguments.length) return transitionDuration;
+    transitionDuration = _;
+    return chart;
+  };
+
+  chart.noErrorCheck = function(_) {
+    if (!arguments.length) return noErrorCheck;
+    noErrorCheck = _;
+    return chart;
+  };
+
   //============================================================
 
 
@@ -2144,11 +3222,16 @@ nv.models.cumulativeLineChart = function() {
       if (!line.values) {
          return line;
       }
-      var v = lines.y()(line.values[idx], idx);
+      var indexValue = line.values[idx];
+      if (indexValue == null) {
+        return line;
+      }
+      var v = lines.y()(indexValue, idx);
 
       //TODO: implement check below, and disable series if series loses 100% or more cause divide by 0 issue
-      if (v < -.95) {
+      if (v < -.95 && !noErrorCheck) {
         //if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically correct till it hits 100)
+
         line.tempDisabled = true;
         return line;
       }
@@ -2171,7 +3254,7 @@ nv.models.cumulativeLineChart = function() {
 }
 //TODO: consider deprecating by adding necessary features to multiBar model
 nv.models.discreteBar = function() {
-
+  "use strict";
   //============================================================
   // Public Variables with Default Settings
   //------------------------------------------------------------
@@ -2190,6 +3273,8 @@ nv.models.discreteBar = function() {
     , valueFormat = d3.format(',.2f')
     , xDomain
     , yDomain
+    , xRange
+    , yRange
     , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
     , rectClass = 'discreteBar'
     ;
@@ -2214,12 +3299,10 @@ nv.models.discreteBar = function() {
 
 
       //add series index to each data point for reference
-      data = data.map(function(series, i) {
-        series.values = series.values.map(function(point) {
+      data.forEach(function(series, i) {
+        series.values.forEach(function(point) {
           point.series = i;
-          return point;
         });
-        return series;
       });
 
 
@@ -2235,14 +3318,14 @@ nv.models.discreteBar = function() {
             });
 
       x   .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
-          .rangeBands([0, availableWidth], .1);
+          .rangeBands(xRange || [0, availableWidth], .1);
 
       y   .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y }).concat(forceY)));
 
 
       // If showValues, pad the Y axis range to account for label height
-      if (showValues) y.range([availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
-      else y.range([availableHeight, 0]);
+      if (showValues) y.range(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
+      else y.range(yRange || [availableHeight, 0]);
 
       //store old scales if they exist
       x0 = x0 || x;
@@ -2273,14 +3356,16 @@ nv.models.discreteBar = function() {
       groups.enter().append('g')
           .style('stroke-opacity', 1e-6)
           .style('fill-opacity', 1e-6);
-      d3.transition(groups.exit())
+      groups.exit()
+          .transition()
           .style('stroke-opacity', 1e-6)
           .style('fill-opacity', 1e-6)
           .remove();
       groups
           .attr('class', function(d,i) { return 'nv-group nv-series-' + i })
           .classed('hover', function(d) { return d.hover });
-      d3.transition(groups)
+      groups
+          .transition()
           .style('stroke-opacity', 1)
           .style('fill-opacity', .75);
 
@@ -2293,7 +3378,7 @@ nv.models.discreteBar = function() {
 
       var barsEnter = bars.enter().append('g')
           .attr('transform', function(d,i,j) {
-              return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')' 
+              return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'
           })
           .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here
             d3.select(this).classed('hover', true);
@@ -2350,10 +3435,15 @@ nv.models.discreteBar = function() {
       if (showValues) {
         barsEnter.append('text')
           .attr('text-anchor', 'middle')
+          ;
+
         bars.select('text')
+          .text(function(d,i) { return valueFormat(getY(d,i)) })
+          .transition()
           .attr('x', x.rangeBand() * .9 / 2)
           .attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 })
-          .text(function(d,i) { return 

<TRUNCATED>

[31/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
s/teh/the in json-structure


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e3d5d12f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e3d5d12f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e3d5d12f

Branch: refs/heads/Update-Sidebar-Ui
Commit: e3d5d12fe9c5c55de549591bf72241c8228018d5
Parents: 597b8d1
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Wed Mar 26 09:46:00 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Wed Mar 26 09:46:00 2014 -0400

----------------------------------------------------------------------
 share/doc/src/json-structure.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e3d5d12f/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index 68137d2..addc5ac 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -357,7 +357,7 @@ Request object
 +--------------------------------+---------------------------------------------+
 | query                          | URL query parameters `object`.              |
 |                                | Note that multiple keys are not supported   |
-|                                | and teh last key value suppresses others.   |
+|                                | and the last key value suppresses others.   |
 +--------------------------------+---------------------------------------------+
 | requested_path                 | List of actual requested path section.      |
 +--------------------------------+---------------------------------------------+


[34/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fix Fauxton dependancie issues

I've modified nv.d3 to be an amd module. This isn't pretty but it's the
best fix, otherwise we cannot use this library.

I've also added a new config in settings.json.default for couchapp
deployment as the current release config doesn't work with a couchapp


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/27cc89cb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/27cc89cb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/27cc89cb

Branch: refs/heads/Update-Sidebar-Ui
Commit: 27cc89cb7c306f72c2746b5ea3736bd94f17cebf
Parents: c84a71c
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Mar 27 11:04:49 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Mar 27 11:12:15 2014 +0200

----------------------------------------------------------------------
 src/Makefile.am                         |  1 -
 src/fauxton/Gruntfile.js                |  8 ++------
 src/fauxton/app/config.js               |  5 +----
 src/fauxton/assets/js/libs/d3.global.js | 18 ------------------
 src/fauxton/assets/js/libs/nv.d3.js     |  7 ++++++-
 src/fauxton/settings.json.default       | 16 ++++++++++++++++
 6 files changed, 25 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index ccf6ccd..e1007f9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -251,7 +251,6 @@ FAUXTON_FILES = \
     fauxton/assets/js/libs/backbone.js \
     fauxton/assets/js/libs/bootstrap.js \
     fauxton/assets/js/libs/d3.js \
-    fauxton/assets/js/libs/d3.global.js \
     fauxton/assets/js/libs/jquery.js \
     fauxton/assets/js/libs/lodash.js \
     fauxton/assets/js/libs/nv.d3.js \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 49c082e..29111eb 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -349,11 +349,6 @@ module.exports = function(grunt) {
       }
     },
     gen_initialize: templateSettings,
-    /*gen_initialize: {
-      "default": {
-        src: "settings.json"
-      }
-    },*/
 
     mkcouchdb: couch_config,
     rmcouchdb: couch_config,
@@ -448,6 +443,7 @@ module.exports = function(grunt) {
   grunt.registerTask('watchRun', ['clean:watch', 'dependencies', 'jshint']);
   // build a release
   grunt.registerTask('release', ['clean' ,'dependencies', "gen_initialize:release", 'jshint', 'build', 'minify', 'copy:dist', 'copy:ace']);
+  grunt.registerTask('couchapp_release', ['clean' ,'dependencies', "gen_initialize:couchapp", 'jshint', 'build', 'minify', 'copy:dist', 'copy:ace']);
 
   /*
    * Install into CouchDB in either debug, release, or couchapp mode
@@ -457,7 +453,7 @@ module.exports = function(grunt) {
   // make a minimized install that is server by mochiweb under _utils
   grunt.registerTask('couchdb', ['release', 'copy:couchdb']);
   // make an install that can be deployed as a couchapp
-  grunt.registerTask('couchapp_setup', ['release']);
+  grunt.registerTask('couchapp_setup', ['couchapp_release']);
   // install fauxton as couchapp
   grunt.registerTask('couchapp_install', ['rmcouchdb:fauxton', 'mkcouchdb:fauxton', 'couchapp:fauxton']);
   // setup and install fauxton as couchapp

http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 3ed1c31..4a2f136 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -30,8 +30,7 @@ require.config({
     spin: "../assets/js/libs/spin.min",
     d3: "../assets/js/libs/d3",
     "nv.d3": "../assets/js/libs/nv.d3",
-    "ace":"../assets/js/libs/ace",
-    "d3.global": "../assets/js/libs/d3.global"
+    "ace":"../assets/js/libs/ace"
   },
 
   baseUrl: '/',
@@ -55,8 +54,6 @@ require.config({
       exports: "Bootstrap"
     },
     
-    "nv.d3": ["d3.global"],
-
     "plugins/prettify": [],
     "plugins/beautify": [],
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/assets/js/libs/d3.global.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.global.js b/src/fauxton/assets/js/libs/d3.global.js
deleted file mode 100644
index 9f38d04..0000000
--- a/src/fauxton/assets/js/libs/d3.global.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Set the require.js configuration for your application.
-
-define("d3.global", ["d3"], function(_) {
-	//get that global back
-  d3 = _;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/assets/js/libs/nv.d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/nv.d3.js b/src/fauxton/assets/js/libs/nv.d3.js
index 4ddf400..409dc65 100755
--- a/src/fauxton/assets/js/libs/nv.d3.js
+++ b/src/fauxton/assets/js/libs/nv.d3.js
@@ -1,3 +1,5 @@
+//this is a hacky fix because nv.d3 doesn't support requirejs
+define("nvd3", ["d3"], function (d3) {
 (function(){
 
 var nv = window.nv || {};
@@ -14366,4 +14368,7 @@ nv.models.stackedAreaChart = function() {
 
   return chart;
 }
-})();
\ No newline at end of file
+})();
+
+return window.nv;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 1bc88f6..eedf2f1 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -46,7 +46,23 @@
           "host": "../..",
           "version": "1.0"
         }
+      },
+      "couchapp": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "./js/require.js",
+          "css": "./css/index.css",
+          "base": null,
+          "cachebuster": "?v1.0"
+        },
+        "app": {
+          "root": "/",
+          "host": "../../..",
+          "version": "1.0"
+        }
       }
+
     },
 
     "couch_config": {


[41/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
remove filter by in active tasks
Fix Active Tasks sidebar
dom cleanup
sidebar ui
Make Sidebar show all design doc functions


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c1e14237
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c1e14237
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c1e14237

Branch: refs/heads/Update-Sidebar-Ui
Commit: c1e142377265d35db484fa342538322c7cd1bee6
Parents: ce352c8
Author: suelockwood <de...@apache.org>
Authored: Mon Mar 31 14:56:07 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Mon Mar 31 15:45:38 2014 -0400

----------------------------------------------------------------------
 .../app/addons/activetasks/templates/tabs.html  |  11 +-
 src/fauxton/app/addons/activetasks/views.js     |   2 +
 .../addons/documents/assets/less/documents.less |  47 +++++-
 src/fauxton/app/addons/documents/routes.js      |  56 +++++--
 .../templates/add_new_ddoc_fn_dropdown.html     |  28 ++++
 .../documents/templates/attachments_footer.html |  20 +++
 .../documents/templates/design_doc_menu.html    |  24 +++
 .../templates/design_doc_selector.html          |   3 +
 .../documents/templates/index_menu_item.html    |   4 +-
 .../app/addons/documents/templates/sidebar.html |  41 ++---
 src/fauxton/app/addons/documents/views.js       | 151 +++++++++++++-----
 src/fauxton/app/templates/layouts/two_pane.html |   1 -
 .../assets/less/bootstrap/dropdowns.less        |  33 +++-
 src/fauxton/assets/less/bootstrap/navs.less     |   3 -
 .../assets/less/bootstrap/variables.less        |   8 +-
 src/fauxton/assets/less/fauxton.less            | 157 ++++++++++---------
 src/fauxton/assets/less/variables.less          |   1 +
 17 files changed, 407 insertions(+), 183 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/activetasks/templates/tabs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/tabs.html b/src/fauxton/app/addons/activetasks/templates/tabs.html
index 5869748..624c386 100644
--- a/src/fauxton/app/addons/activetasks/templates/tabs.html
+++ b/src/fauxton/app/addons/activetasks/templates/tabs.html
@@ -14,14 +14,6 @@ the License.
 
 
 
-
-
-<div id="sidenav">
-  <header class="row-fluid">
-    <h3>Filter by: </h3>
-  </header>
-
-  <nav>
 		<ul class="task-tabs nav nav-list">
 		  <% for (var filter in filters) { %>
 		      <li data-type="<%=filter%>">
@@ -42,5 +34,4 @@ the License.
 				<label for="pollingRange"><span>5</span> second(s)</label>
 			</li>
 		</ul>
-  </nav>
-</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/activetasks/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js
index b0940bf..453069f 100644
--- a/src/fauxton/app/addons/activetasks/views.js
+++ b/src/fauxton/app/addons/activetasks/views.js
@@ -29,6 +29,8 @@ function (app, FauxtonAPI, activetasks) {
   Views.Events = _.extend(Events, Backbone.Events);
 
   Views.TabMenu = FauxtonAPI.View.extend({
+    tagName: "nav",
+    className: "sidenav",
     template: "addons/activetasks/templates/tabs",
     events: {
       "click .task-tabs li": "requestByType",

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 36429ff..f00b674 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -35,7 +35,7 @@ button.beautify {
   #select-per-page {
     margin-top: 10px;
   }
-  
+
 }
 
 
@@ -112,4 +112,49 @@ button.beautify {
 }
 
 
+.sidenav{
+  margin-bottom: 40px;
+  li.nav-header {
+    position: relative;
+    .accordion-body{
+      color: #eee;
+      margin-left: 0;
+      li a{
+        padding-left: 55px;
+      }
+    }
+    > span{
+      display: block;
+      padding: 10px 13px 10px 30px;
+      color: #333333;
+      border-bottom: 1px solid #989898;
+      &:before{
+        font-size: 12px;
+        padding-right: 10px;
+      }
+      &.down:before {
+        transform:rotate(90deg);
+        -ms-transform:rotate(90deg); /* IE 9 */
+        -webkit-transform:rotate(90deg); /* Opera, Chrome, and Safari */
+      }
+    }
+    div.new-button {
+      position: absolute;
+      top: 2px;
+      right: 15px;
+      .dropdown-menu{
+        left: -57px;
+        padding-bottom: 0;
+      }
+      .dropdown-toggle{
+        text-decoration: none;
+      }
+      > a {
+        border-bottom: none;
+        text-decoration: none;
+        font-size: 16px;
+      }
+    }
+  }
+}
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index 699a496..90cf8b2 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -90,7 +90,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       database = this.database;
 
       doc.copy(newId).then(function () {
-        doc.set({_id: newId}); 
+        doc.set({_id: newId});
         docView.forceRender();
         FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.utils.safeURLName(newId), {trigger: true});
         FauxtonAPI.addNotification({
@@ -143,12 +143,25 @@ function(app, FauxtonAPI, Documents, Databases) {
     layout: "with_tabs_sidebar",
     selectedHeader: "Databases",
     routes: {
-      "database/:database/_all_docs(:extra)": "allDocs", 
-      "database/:database/_design/:ddoc/_view/:view": {
+      "database/:database/_all_docs(:extra)": "allDocs",
+      "database/:database/_design/:ddoc/_views/:view": {
         route: "viewFn",
         roles: ['_admin']
       },
-      "database/:database/new_view": "newViewEditor"
+      "database/:database/_design/:ddoc/_lists/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/_filters/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/_show/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_view": "newViewEditor",
+      "database/:database/new_view/:designDoc": "newViewEditor"
     },
 
     events: {
@@ -181,6 +194,16 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
+    tempFn:  function(databaseName, ddoc, fn){
+      this.setView("#dashboard-upper-content", new Documents.Views.temp({}));
+      this.crumbs = function () {
+        return [
+          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+
+    },
+
     establish: function () {
       return this.data.designDocs.fetch();
     },
@@ -194,7 +217,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     /*
-    * docParams are the options collection uses to fetch from the server 
+    * docParams are the options collection uses to fetch from the server
     * urlParams are what are shown in the url and to the user
     * They are not the same when paginating
     */
@@ -259,7 +282,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         view: view,
         params: docParams
       });
-     
+
       this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
         model: this.data.database,
         ddocs: this.data.designDocs,
@@ -274,7 +297,7 @@ function(app, FauxtonAPI, Documents, Databases) {
 
       this.documentsView = this.createViewDocumentsView({
         designDoc: decodeDdoc,
-        docParams: docParams, 
+        docParams: docParams,
         urlParams: urlParams,
         database: this.data.database,
         indexedDocs: this.data.indexedDocs,
@@ -302,7 +325,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       };
     },
 
-    createViewDocumentsView: function (options) { 
+    createViewDocumentsView: function (options) {
 
       return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         database: options.database,
@@ -315,13 +338,14 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
-    newViewEditor: function () {
+    newViewEditor: function (database, designDoc) {
       var params = app.getParams();
 
       this.toolsView && this.toolsView.remove();
       this.documentsView && this.documentsView.remove();
 
       this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        currentddoc: "_design/"+designDoc || "",
         ddocs: this.data.designDocs,
         params: params,
         database: this.data.database,
@@ -365,7 +389,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         if (!this.documentsView) {
           this.documentsView = this.createViewDocumentsView({
             designDoc: ddoc,
-            docParams: docParams, 
+            docParams: docParams,
             urlParams: urlParams,
             database: this.data.database,
             indexedDocs: this.indexedDocs,
@@ -427,14 +451,14 @@ function(app, FauxtonAPI, Documents, Databases) {
       urlParams = Documents.QueryParams.parse(urlParams);
 
       if (options.direction === 'next') {
-          params = Documents.paginate.next(collection.toJSON(), 
+          params = Documents.paginate.next(collection.toJSON(),
                                            collection.params,
-                                           options.perPage, 
+                                           options.perPage,
                                            !!collection.isAllDocs);
       } else {
-          params = Documents.paginate.previous(collection.toJSON(), 
-                                               collection.params, 
-                                               options.perPage, 
+          params = Documents.paginate.previous(collection.toJSON(),
+                                               collection.params,
+                                               options.perPage,
                                                !!collection.isAllDocs);
       }
 
@@ -473,7 +497,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         } else {
           storedPerPage = parseInt(storedPerPage, 10);
         }
-      } 
+      }
 
       if (!urlParams.limit || urlParams.limit > storedPerPage) {
         return storedPerPage;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html b/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
new file mode 100644
index 0000000..daf3864
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
@@ -0,0 +1,28 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="dropdown">
+	<a class="dropdown-toggle icon fonticon-circle-plus" data-toggle="dropdown" href="#" data-bypass="true"></a>
+	<ul class="dropdown-menu arrow" role="menu" aria-labelledby="dLabel">
+		<% if (full){ %>
+			<li><a class="icon fonticon-replication" href="#replicate/<%=database.id%>">Replicate</a><li>
+			<li><a class="icon fonticon-trash" href="#" data-bypass="true">Delete</a><li>
+		<%}%>
+		<li class="header-label">Add new</li>
+		<li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_view/<%=ddocSafe%>">Secondary View</a><li>
+	  <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_filter/<%=ddocSafe%>">Filter Function</a><li>
+	  <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_show/<%=ddocSafe%>">Show Function</a><li>
+	  <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_list/<%=ddocSafe%>">List function</a><li>
+	</ul>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/attachments_footer.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/attachments_footer.html b/src/fauxton/app/addons/documents/templates/attachments_footer.html
new file mode 100644
index 0000000..31bd5a5
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/attachments_footer.html
@@ -0,0 +1,20 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<ul>
+	<li> attachment 1</li>
+	<li> attachment 2 </li>
+	<li> attachment 3</li>
+	<li> attachment 4</li>
+</ul>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/design_doc_menu.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/design_doc_menu.html b/src/fauxton/app/addons/documents/templates/design_doc_menu.html
new file mode 100644
index 0000000..ee45ed6
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/design_doc_menu.html
@@ -0,0 +1,24 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<li class="nav-header">
+	<span  class="fonticon-play js-collapse-toggle" data-toggle="collapse" data-target="#<%=designDoc%>">
+		<%= designDoc%>
+	</span>
+	<div class="new-button">
+
+	</div>
+
+	<ul class="accordion-body collapse" id="<%=designDoc%>">
+	</ul>
+</li>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/design_doc_selector.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/design_doc_selector.html b/src/fauxton/app/addons/documents/templates/design_doc_selector.html
index 7bbe310..0a5bee2 100644
--- a/src/fauxton/app/addons/documents/templates/design_doc_selector.html
+++ b/src/fauxton/app/addons/documents/templates/design_doc_selector.html
@@ -16,7 +16,10 @@ the License.
   <select id="ddoc">
     <optgroup label="Select a document">
       <option value="new-doc">New document</option>
+
       <% ddocs.each(function(ddoc) { %>
+      <%= ddoc.id %>
+      <%= ddocName %>
       <% if (ddoc.id === ddocName) { %>
       <option selected="selected" value="<%= ddoc.id %>"><%= ddoc.id %></option>
       <% } else { %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/index_menu_item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/index_menu_item.html b/src/fauxton/app/addons/documents/templates/index_menu_item.html
index 7ca9012..77b51d0 100644
--- a/src/fauxton/app/addons/documents/templates/index_menu_item.html
+++ b/src/fauxton/app/addons/documents/templates/index_menu_item.html
@@ -12,6 +12,6 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_view/<%= index_encoded %>" class="toggle-view">
-  <%= ddoc %><span class="divider">/</span><%= index %>
+<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_<%=type%>/<%= index_encoded %>" class="toggle-view">
+  <%= index %>
 </a>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/sidebar.html b/src/fauxton/app/addons/documents/templates/sidebar.html
index 750cd30..59d76e1 100644
--- a/src/fauxton/app/addons/documents/templates/sidebar.html
+++ b/src/fauxton/app/addons/documents/templates/sidebar.html
@@ -11,34 +11,17 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 License for the specific language governing permissions and limitations under
 the License.
 -->
-
-<div id="sidenav">
-  <header class="row-fluid">
+<!--   <header class="row-fluid">
     <div class="span12">
-      <div class="btn-group">
-        <button class="btn dropdown-toggle dropdown-toggle-btn" data-toggle="dropdown">
-          Docs
-          <span class="caret"></span>
-        </button>
-        <ul class="dropdown-menu">
-          <!-- dropdown menu links -->
-          <li><a href="<%= db_url %>"><i class="icon icon-file"></i> Docs</a></li>
-          <li><a href="<%= permissions_url %>"><i class="icon icon-lock"></i> Permissions</a></li>
-          <li><a href="<%= changes_url %>"><i class="icon icon-forward"></i> Changes</a></li>
-          <% _.each(docLinks, function (link) { %>
-          <li><a href="<%= database_url + '/' + link.url %>"><i class="icon <%= link.icon %>"></i> <%= link.title %></a></li>
-          <% }); %>
-        </ul>
-      </div>
 
       <div class="btn-group">
         <button class="btn dropdown-toggle dropdown-toggle-btn" data-toggle="dropdown">
-          New
+          Create New
           <span class="caret"></span>
         </button>
         <ul class="dropdown-menu">
           <!-- dropdown menu links -->
-          <li>
+<!--           <li>
           <a id="doc" href="#<%= database.url('app') %>/new">Document</a>
           </li>
           <li>
@@ -51,18 +34,18 @@ the License.
       </div>
         <button id="delete-database" class="btn pull-right"><i class="icon-trash"></i> Database</button>
     </div>
-  </header>
+  </header> --> 
+
 
-  <nav>
     <ul class="nav nav-list">
+      <li><a id="changes" href="<%= permissions_url %>">Permissions</a><li>
+      <li><a id="changes" href="<%= changes_url %>">Changes</a><li>
+      <% _.each(docLinks, function (link) { %>
+        <li><a href="<%= database_url + '/' + link.url %>"><%= link.title %></a></li>
+      <% }); %>
+
       <li class="active"><a id="all-docs" href="#<%= database.url('index') %>" class="toggle-view"> All documents</a></li>
       <li><a id="design-docs" href='#<%= database.url("index") %>?startkey="_design"&endkey="_e"'  class="toggle-view"> All design docs</a></li>
     </ul>
-    <ul class="nav nav-list views">
-      <li class="nav-header">Secondary Indexes</li>
-      <li><a id="new-view" href="#<%= database.url('app') %>/new_view" class="new"><i class="icon-plus"></i> New</a></li>
-    </ul>
-    <div id="extension-navs"></div>
-  </nav>
+
   <div id="delete-db-modal"> </div>
-</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index cc23e19..6153e40 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -387,10 +387,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.ddoc = options.ddoc;
       this.database = options.database;
       this.selected = !! options.selected;
+      this.selector = options.selector;
     },
 
     serialize: function() {
       return {
+        type:  this.selector,
         index: this.index,
         ddoc: this.ddoc,
         database: this.database,
@@ -405,7 +407,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     afterRender: function() {
       if (this.selected) {
-        $("#sidenav ul.nav-list li").removeClass("active");
+        $(".sidenav ul.nav-list li").removeClass("active");
         this.$el.addClass("active");
       }
     }
@@ -418,7 +420,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.newView = options.newView || false;
       this.pagination = options.pagination;
       _.bindAll(this);
-      
+
       this._perPage = options.perPageDefault || 20;
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
@@ -1098,7 +1100,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       //highlight current
       this.$(".toggle-btns > label").removeClass('active');
       this.$(e.currentTarget).addClass("active");
-      
+
       this.$("[id^='js-show']").hide();
 
       //show section & disable what needs to be disabled
@@ -1148,7 +1150,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       if (_.isUndefined(parsedValue)) {
         errorMsg = "Keys must be valid json.";
       } else if (!_.isArray(parsedValue)) {
-        errorMsg =  "Keys values must be in an array. E.g [1,2,3]"; 
+        errorMsg =  "Keys values must be in an array. E.g [1,2,3]";
       }
 
       if (errorMsg) {
@@ -1162,7 +1164,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         return false;
       }
 
-      return true; 
+      return true;
     },
     queryParams: function () {
       var $form = this.$(".js-view-query-update"),
@@ -1251,8 +1253,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           }
           this.updateFiltersFor(key, $ele);
           break;
-          case "key": 
-          case "keys": 
+          case "key":
+          case "keys":
             $form.find("textarea[name='"+key+"']").val(val);
           break;
           default:
@@ -1373,6 +1375,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.ddocs = options.ddocs;
       this.params = options.params;
       this.database = options.database;
+      this.currentDdoc = options.currentddoc;
       if (this.newView) {
         this.viewName = 'newView';
       } else {
@@ -1653,7 +1656,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     toggleIndexNav: function (event) {
       $('#dashboard-content').scrollTop(0); //scroll up
-      
+
       var $targetId = this.$(event.target).attr('id'),
           $previousTab = this.$(this.$('li.active a').attr('href')),
           $targetTab = this.$(this.$(event.target).attr('href'));
@@ -1662,7 +1665,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         $previousTab.removeAttr('style');
       }
       //stop polling
-      this.ddocInfoView.stopRefreshInterval(); 
+      this.ddocInfoView.stopRefreshInterval();
 
       if ($targetId === 'index-nav') {
         if (this.newView) { return; }
@@ -1674,8 +1677,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       } else if ($targetId === "meta-nav"){
         if (!$("#ddoc-info").is(":visible")){
           this.ddocInfoView.startRefreshInterval();
-        } 
-        $targetTab.toggle('slow'); 
+        }
+        $targetTab.toggle('slow');
       } else {
         $targetTab.toggle('slow');
       }
@@ -1722,7 +1725,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     renderDdocInfo: function(){
       if(this.ddocInfoView){
         this.ddocInfoView.remove();
-      } 
+      }
 
       if (this.newView) { return; }
       this.ddocInfoView = this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));
@@ -1743,12 +1746,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         var ddocDecode = decodeURIComponent(this.ddocID);
         this.model = this.ddocs.get(ddocDecode).dDocModel();
         this.reduceFunStr = this.model.viewHasReduce(this.viewName);
-        
+
       }
 
       this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
         collection: this.ddocs,
-        ddocName: this.model.id,
+        ddocName: this.currentDdoc || this.model.id,
         database: this.database
       }));
 
@@ -1852,6 +1855,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
   Views.Sidebar = FauxtonAPI.View.extend({
     template: "addons/documents/templates/sidebar",
+    className: "sidenav",
+    tagName: "nav",
     events: {
       "click button#delete-database": "showDeleteDatabaseModal"
     },
@@ -1885,17 +1890,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       };
     },
 
-    buildIndexList: function(collection, selector, design){
-      _.each(_.keys(collection), function(key){
-        var selected = this.ddocID == "_design/"+design;
-        this.insertView("ul.nav." + selector, new Views.IndexItem({
-          ddoc: design,
-          index: key,
-          database: this.collection.database.id,
-          selected: selected && key == this.currView
-        }));
-      }, this);
-    },
 
     beforeRender: function(manage) {
       this.deleteDBModal = this.setView(
@@ -1903,21 +1897,14 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         new Views.DeleteDBModal({database: this.database})
       );
 
-      var sidebarListViews = FauxtonAPI.getExtensions('sidebar:list');
-      _.each(sidebarListViews, function (view) {
-        var extension = this.insertView('#extension-navs', view);
-        extension.update(this.database, this.collection, this.viewName);
-        extension.render();
-      }, this);
-
       this.collection.each(function(design) {
         if (design.has('doc')){
-          var ddoc = design.id.replace(/^_design\//,"");
-          if (design.get('doc').views){
-            this.buildIndexList(design.get('doc').views, "views", ddoc);
-          }
+          this.insertView(new Views.DdocSidenav({
+            model: design,
+            collection: this.collection
+          }));
         }
-      }, this);
+      },this);
     },
 
 
@@ -1934,6 +1921,72 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
+
+  Views.DdocSidenav = FauxtonAPI.View.extend({
+    tagName: "ul",
+    className:  "nav nav-list",
+    template: "addons/documents/templates/design_doc_menu",
+    events: {
+      "click button": "no",
+      "click .js-collapse-toggle": "toggleArrow"
+    },
+    initialize: function(){
+
+    },
+    toggleArrow:  function(e){
+      this.$(e.currentTarget).toggleClass("down");
+    },
+    no: function(event){
+      event.preventDefault();
+      alert("no");
+    },
+    buildIndexList: function(collection, selector){
+      var design = this.model.id.replace(/^_design\//,"");
+      _.each(_.keys(collection[selector]), function(key){
+        this.insertView(".accordion-body", new Views.IndexItem({
+          selector: selector,
+          ddoc: design,
+          index: key,
+          database: this.model.collection.database.id
+        }));
+      }, this);
+    },
+
+    serialize: function(){
+      var ddocName = this.model.id.replace(/^_design\//,"");
+      return{
+        database: this.collection.database,
+        designDoc: ddocName
+      };
+    },
+    beforeRender: function(manage) {
+      var ddocDocs = this.model.get("doc");
+      var ddocName = this.model.id.replace(/^_design\//,"");
+
+      var sidebarListTypes = FauxtonAPI.getExtensions('sidebar:list');
+          if (ddocDocs){
+            //Views
+            this.buildIndexList(ddocDocs, "views");
+            //lists
+            this.buildIndexList(ddocDocs, "lists");
+            //show
+            this.buildIndexList(ddocDocs, "show");
+            //filters
+            this.buildIndexList(ddocDocs, "filters");
+            //extensions
+            _.each(sidebarListTypes, function (type) {
+              this.buildIndexList(ddocDocs, type);
+            },this);
+          }
+      this.insertView(".new-button", new Views.newMenuDropdown({
+        database: this.collection.database,
+        ddocSafeName: app.utils.safeURLName(ddocName),
+        fullMenu: false
+      }));
+
+    }
+  });
+
   Views.Indexed = FauxtonAPI.View.extend({});
 
   Views.Changes = FauxtonAPI.View.extend({
@@ -1960,6 +2013,30 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
+
+  Views.newMenuDropdown = FauxtonAPI.View.extend({
+    template: "addons/documents/templates/add_new_ddoc_fn_dropdown",
+    tagName: "div",
+    className: "dropdown",
+    initialize: function(options){
+      this.database = options.database;
+      this.fullMenu = options.fullMenu;
+      this.ddocSafeName = options.ddocSafeName || "";
+    },
+    serialize: function(){
+      return {
+        database: this.database,
+        ddocSafe: this.ddocSafeName,
+        full:  this.fullMenu
+      };
+    }
+  });
+
+
+
+  Views.temp = FauxtonAPI.View.extend({
+  });
+
   Views.DdocInfo = FauxtonAPI.View.extend({
     template: "addons/documents/templates/ddoc_info",
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/templates/layouts/two_pane.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/layouts/two_pane.html b/src/fauxton/app/templates/layouts/two_pane.html
index 0c3165e..031ad12 100644
--- a/src/fauxton/app/templates/layouts/two_pane.html
+++ b/src/fauxton/app/templates/layouts/two_pane.html
@@ -22,7 +22,6 @@ the License.
 
 
   <div class="row-fluid content-area">
-  	<div id="tabs" class="row"></div>
     <div id="left-content" class="span6"></div>
     <div id="right-content" class="span6"></div>
   </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/dropdowns.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/dropdowns.less b/src/fauxton/assets/less/bootstrap/dropdowns.less
index 9e47b47..0425077 100644
--- a/src/fauxton/assets/less/bootstrap/dropdowns.less
+++ b/src/fauxton/assets/less/bootstrap/dropdowns.less
@@ -39,6 +39,7 @@
 // The dropdown menu (ul)
 // ----------------------
 .dropdown-menu {
+
   position: absolute;
   top: 100%;
   left: 0;
@@ -46,7 +47,6 @@
   display: none; // none by default, but block on "open" of the menu
   float: left;
   min-width: 160px;
-  padding: 5px 0;
   margin: 2px 0 0; // override default ul
   list-style: none;
   background-color: @dropdownBackground;
@@ -54,8 +54,6 @@
   border: 1px solid @dropdownBorder;
   *border-right-width: 2px;
   *border-bottom-width: 2px;
-  .border-radius(6px);
-  .box-shadow(0 5px 10px rgba(0,0,0,.2));
   -webkit-background-clip: padding-box;
      -moz-background-clip: padding;
           background-clip: padding-box;
@@ -65,7 +63,29 @@
     right: 0;
     left: auto;
   }
-
+  li.header-label{
+    background-color: #1A1A1A;
+    color: #676767;
+    padding: 3px 20px;
+    font-size: 13px;
+  }
+  &.arrow {
+    &:before{
+      content: "";
+      display: block;
+      position: absolute;
+      border-style: solid;
+      top: -20px;
+      left: 50%;
+      width: 0;
+      height: 0;
+      margin-left: -10px;
+      border-left: 10px solid transparent;
+      border-right: 10px solid transparent;
+      border-bottom: 10px solid #2b2f33;
+      border-top: 10px solid transparent;
+    }
+  }
   // Dividers (basically an hr) within the dropdown
   .divider {
     .nav-divider(@dropdownDividerTop, @dropdownDividerBottom);
@@ -73,6 +93,10 @@
 
   // Links within the dropdown menu
   > li > a {
+    &.icon:before{
+      padding-right: 5px;
+    }
+    font-size: 12px;
     display: block;
     padding: 3px 20px;
     clear: both;
@@ -80,6 +104,7 @@
     line-height: @baseLineHeight;
     color: @dropdownLinkColor;
     white-space: nowrap;
+    border-bottom: 1px solid #1A1A1A;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/navs.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/navs.less b/src/fauxton/assets/less/bootstrap/navs.less
index 01cd805..0013179 100644
--- a/src/fauxton/assets/less/bootstrap/navs.less
+++ b/src/fauxton/assets/less/bootstrap/navs.less
@@ -37,12 +37,9 @@
 .nav-header {
   display: block;
   padding: 3px 15px;
-  font-size: 11px;
-  font-weight: bold;
   line-height: @baseLineHeight;
   color: @grayLight;
   text-shadow: 0 1px 0 rgba(255,255,255,.5);
-  text-transform: uppercase;
 }
 // Space them out when they follow another list item (link)
 .nav li + .nav-header {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/variables.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/variables.less b/src/fauxton/assets/less/bootstrap/variables.less
index 31c131b..f52b2cb 100644
--- a/src/fauxton/assets/less/bootstrap/variables.less
+++ b/src/fauxton/assets/less/bootstrap/variables.less
@@ -119,12 +119,12 @@
 
 // Dropdowns
 // -------------------------
-@dropdownBackground:            @white;
+@dropdownBackground:            #2B2F33;
 @dropdownBorder:                rgba(0,0,0,.2);
-@dropdownDividerTop:            #e5e5e5;
-@dropdownDividerBottom:         @white;
+@dropdownDividerTop:            #1A1A1A;
+@dropdownDividerBottom:         #1A1A1A;
 
-@dropdownLinkColor:             @grayDark;
+@dropdownLinkColor:             #D9D9D9;
 @dropdownLinkColorHover:        @white;
 @dropdownLinkColorActive:       @white;
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 229075b..2fba9df 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -357,7 +357,7 @@ table.databases {
         background: url(../img/couchdb-site.png) no-repeat 0 0;
         display: block;
         height: 100%;
-        width: 100%; 
+        width: 100%;
       }
       .burger{
         .transition(all @transitionSpeed @transitionEaseType);
@@ -468,7 +468,7 @@ table.databases {
           background-color: @bottomNav;
           &.active{
             background-color:@linkRed;
-          } 
+          }
           &:hover{
             background-color: @navBGHover;
           }
@@ -527,12 +527,15 @@ table.databases {
     padding: 0px;
     bottom: 0px;
     top: 60px;
-    position: absolute;
+    position: fixed;
     overflow-x: hidden;
     overflow-y: auto;
-    left: @sidebarWidth;
+    left: @sidebarWidth+@navWidth;
     right: 0;
     .box-sizing(border-box);
+    .closeMenu & {
+      left: @sidebarWidth+@collapsedNavWidth;
+    }
   }
   > div.inner {
     display: block;
@@ -636,7 +639,7 @@ table.databases {
   }
 }
 
-#sidenav{
+.sidenav{
   padding: 0;
   header {
     width: @sidebarWidth;
@@ -644,46 +647,48 @@ table.databases {
     background: transparent url('../img/linen.png') repeat 0 0;
     .topmenu-defaults;
   }
-  nav {
-    .nav-list{
-      .divider {
-        border: none;
-      }
-      li.active a {
-        background-color: @darkRed;
-        color: #fff;
-      }
-      a{
-        display: block;
-        padding: 10px 5px 10px 15px;
-        color: #333333;
-        border-bottom: 1px solid #989898;
-        .divider {
-          background: none;
-          color: #ccc;
-          padding: 0 2px;
-        }
-      }
-      .nav-header{
-        background-color: #B2B2B2;
-        padding: 5px;
-        text-shadow: none;
-        color: #333333;
-        border-bottom: 1px solid #989898;
+  .nav-list{
+    .divider {
+      border: none;
+    }
+    li.active a {
+      background-color: @darkRed;
+      color: #fff;
+    }
+    > li > a{
+      padding: 10px 13px 10px 30px;
+      border-bottom: 1px solid #989898;
+    }
+    .dropdown-menu {
+      a {
+        color: #d9d9d9;
       }
+    }
+    a{
+      display: block;
+      padding: 10px 5px 10px 15px;
+      color: #333333;
 
+      .divider {
+        background: none;
+        color: #ccc;
+        padding: 0 2px;
+      }
+    }
+    .nav-header{
+      padding: 0px;
+      text-shadow: none;
+      color: #333333;
+      margin-bottom: -4px;
     }
   }
 }
+
 #sidebar-content {
-.box-shadow(-7px 0 15px -6px #000);
   position: absolute;
-  bottom: 0px;
   top: 60px;
   width: @sidebarWidth;
   left: 0;
-  overflow-x: hidden;
-  overflow-y: auto;
   background-color: @secondarySidebar;
   > div.inner {
     display: block;
@@ -749,14 +754,14 @@ table.databases {
 
 .custom-inputs{
 
-  input[type=radio], 
-  input[type=checkbox] {  
-    display: none;  
-  } 
+  input[type=radio],
+  input[type=checkbox] {
+    display: none;
+  }
 
-  .checkbox label:before {  
-    border-radius: 3px;  
-  }  
+  .checkbox label:before {
+    border-radius: 3px;
+  }
 
   .controls > .radio:first-child, .controls > .checkbox:first-child {
     padding-top: 15px;
@@ -769,42 +774,42 @@ table.databases {
     vertical-align: middle;
   }
 
-  input[type=checkbox]:checked + label:before {  
+  input[type=checkbox]:checked + label:before {
     /*content: "\2713"; */
-    content: "\00d7"; 
-    text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);  
+    content: "\00d7";
+    text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
     font-size: 16px;
-    background-color: @red;  
-    color: white;  
-    text-align: center;  
-    line-height: 15px;  
-  }  
-
-  label:before {  
-    content: "";  
-    display: inline-block;  
-
-    width: 16px;  
-    height: 16px;  
-
-    margin-right: 10px;  
-    position: absolute;  
-    left: 0;  
-    bottom: 1px;  
-    background-color: #aaa;  
-    box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);  
-  }  
-
-  .radio label:before {  
-    border-radius: 8px;  
-  }  
-
-  input[type=radio]:checked + label:before {  
-    content: "\2022";  
-    color: #f3f3f3;  
-    font-size: 30px;  
-    text-align: center;  
-    line-height: 18px;  
+    background-color: @red;
+    color: white;
+    text-align: center;
+    line-height: 15px;
+  }
+
+  label:before {
+    content: "";
+    display: inline-block;
+
+    width: 16px;
+    height: 16px;
+
+    margin-right: 10px;
+    position: absolute;
+    left: 0;
+    bottom: 1px;
+    background-color: #aaa;
+    box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
+  }
+
+  .radio label:before {
+    border-radius: 8px;
+  }
+
+  input[type=radio]:checked + label:before {
+    content: "\2022";
+    color: #f3f3f3;
+    font-size: 30px;
+    text-align: center;
+    line-height: 18px;
   }
 
   label.drop-down{

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/variables.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/variables.less b/src/fauxton/assets/less/variables.less
index 34f8b90..ab479a8 100644
--- a/src/fauxton/assets/less/variables.less
+++ b/src/fauxton/assets/less/variables.less
@@ -54,6 +54,7 @@
 @sidebarBG: #F2F2F2;
 @sidebarWidth: 330px;
 
+
 @NavIconActive: #ffffff;
 @NavIcon: @brown;
 


[37/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
minor documentation fix


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/053b471a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/053b471a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/053b471a

Branch: refs/heads/Update-Sidebar-Ui
Commit: 053b471a4f89420d2863842cc38354a3906af496
Parents: 8b429c8
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 27 21:07:03 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 27 21:07:03 2014 +0100

----------------------------------------------------------------------
 share/doc/src/install/freebsd.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/053b471a/share/doc/src/install/freebsd.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/install/freebsd.rst b/share/doc/src/install/freebsd.rst
index b82edd1..85b74b5 100644
--- a/share/doc/src/install/freebsd.rst
+++ b/share/doc/src/install/freebsd.rst
@@ -37,7 +37,7 @@ supported by the start script (defaults shown)::
     couchdb_enablelogs="YES"
     couchdb_user="couchdb"
 
-After enabling couchdb rc service use the following to start CouchDB::
+After enabling the couchdb rc service use the following command to start CouchDB::
 
     /usr/local/etc/rc.d/couchdb start
 


[13/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Merge branch 'fix/build2' of https://github.com/robertkowalski/couchdb

This closes #190


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/a7a6d2ee
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/a7a6d2ee
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/a7a6d2ee

Branch: refs/heads/Update-Sidebar-Ui
Commit: a7a6d2eec4d79dc12afed7cffbc5e4dc4c45e42f
Parents: 89eb4a6 5bdfa6c
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 21:45:45 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 21:45:45 2014 +0100

----------------------------------------------------------------------

----------------------------------------------------------------------



[22/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Updating d3 to v3.4.3 and nv.d3 to v1.1.15


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/95d6d6b0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/95d6d6b0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/95d6d6b0

Branch: refs/heads/Update-Sidebar-Ui
Commit: 95d6d6b035242d9a203b2df3af342274b29f98b1
Parents: 0fb5aa9
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 13:42:04 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:17 2014 -0400

----------------------------------------------------------------------
 src/fauxton/assets/css/nv.d3.css    |   191 +-
 src/fauxton/assets/js/libs/d3.js    | 14721 +++++++++++++++++------------
 src/fauxton/assets/js/libs/nv.d3.js |  4536 +++++----
 3 files changed, 11530 insertions(+), 7918 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/css/nv.d3.css
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/css/nv.d3.css b/src/fauxton/assets/css/nv.d3.css
index 28ccd05..cae8348 100644
--- a/src/fauxton/assets/css/nv.d3.css
+++ b/src/fauxton/assets/css/nv.d3.css
@@ -10,6 +10,18 @@
   overflow: hidden;
 }
 
+/********************
+  Box shadow and border radius styling
+*/
+.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {
+  -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+  box-shadow: 0 5px 10px rgba(0,0,0,.2);
+
+  -webkit-border-radius: 6px;
+  -moz-border-radius: 6px;
+  border-radius: 6px;
+}
 
 /********************
  * TOOLTIP CSS
@@ -17,31 +29,18 @@
 
 .nvtooltip {
   position: absolute;
-  background-color: rgba(255,255,255,1);
-  padding: 10px;
-  border: 1px solid #ddd;
+  background-color: rgba(255,255,255,1.0);
+  padding: 1px;
+  border: 1px solid rgba(0,0,0,.2);
   z-index: 10000;
 
   font-family: Arial;
   font-size: 13px;
-
-  transition: opacity 500ms linear;
-  -moz-transition: opacity 500ms linear;
-  -webkit-transition: opacity 500ms linear;
-
-  transition-delay: 500ms;
-  -moz-transition-delay: 500ms;
-  -webkit-transition-delay: 500ms;
-
-  -moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
-  -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
-  box-shadow: 4px 4px 8px rgba(0,0,0,.5);
-
-  -moz-border-radius: 10px;
-  border-radius: 10px;
-
+  text-align: left;
   pointer-events: none;
 
+  white-space: nowrap;
+
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -khtml-user-select: none;
@@ -50,15 +49,42 @@
   user-select: none;
 }
 
+/*Give tooltips that old fade in transition by
+    putting a "with-transitions" class on the container div.
+*/
+.nvtooltip.with-transitions, .with-transitions .nvtooltip {
+  transition: opacity 250ms linear;
+  -moz-transition: opacity 250ms linear;
+  -webkit-transition: opacity 250ms linear;
+
+  transition-delay: 250ms;
+  -moz-transition-delay: 250ms;
+  -webkit-transition-delay: 250ms;
+}
+
+.nvtooltip.x-nvtooltip,
+.nvtooltip.y-nvtooltip {
+  padding: 8px;
+}
+
 .nvtooltip h3 {
   margin: 0;
-  padding: 0;
+  padding: 4px 14px;
+  line-height: 18px;
+  font-weight: normal;
+  background-color: rgba(247,247,247,0.75);
   text-align: center;
+
+  border-bottom: 1px solid #ebebeb;
+
+  -webkit-border-radius: 5px 5px 0 0;
+  -moz-border-radius: 5px 5px 0 0;
+  border-radius: 5px 5px 0 0;
 }
 
 .nvtooltip p {
   margin: 0;
-  padding: 0;
+  padding: 5px 14px;
   text-align: center;
 }
 
@@ -67,6 +93,45 @@
   margin: 2px 0;
 }
 
+.nvtooltip table {
+  margin: 6px;
+  border-spacing:0;
+}
+
+
+.nvtooltip table td {
+  padding: 2px 9px 2px 0;
+  vertical-align: middle;
+}
+
+.nvtooltip table td.key {
+  font-weight:normal;
+}
+.nvtooltip table td.value {
+  text-align: right;
+  font-weight: bold;
+}
+
+.nvtooltip table tr.highlight td {
+  padding: 1px 9px 1px 0;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  border-top-style: solid;
+  border-top-width: 1px;
+}
+
+.nvtooltip table td.legend-color-guide div {
+  width: 8px;
+  height: 8px;
+  vertical-align: middle;
+}
+
+.nvtooltip .footer {
+  padding: 3px;
+  text-align: center;
+}
+
+
 .nvtooltip-pending-removal {
   position: absolute;
   pointer-events: none;
@@ -110,7 +175,7 @@ svg .title {
 
 .nvd3.nv-noData {
   font-size: 18px;
-  font-weight: bolf;
+  font-weight: bold;
 }
 
 
@@ -142,6 +207,9 @@ svg .title {
 /**********
 *  Axes
 */
+.nvd3 .nv-axis {
+  pointer-events:none;
+}
 
 .nvd3 .nv-axis path {
   fill: none;
@@ -160,12 +228,12 @@ svg .title {
 
 .nvd3 .nv-axis line {
   fill: none;
-  stroke: #000;
-  stroke-opacity: .25;
+  stroke: #e5e5e5;
   shape-rendering: crispEdges;
 }
 
-.nvd3 .nv-axis line.zero {
+.nvd3 .nv-axis .zero line,
+/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {
   stroke-opacity: .75;
 }
 
@@ -209,7 +277,7 @@ svg .title {
   -webkit-transition: fill-opacity 250ms linear;
 }
 
-.nvd3 .nv-bars rect:hover {
+.nvd3 .nv-bars rect.hover {
   fill-opacity: 1;
 }
 
@@ -259,7 +327,6 @@ svg .title {
 
 .nvd3.nv-pie path {
   stroke-opacity: 0;
-
   transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
   -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
   -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
@@ -279,12 +346,10 @@ svg .title {
 
 .nvd3.nv-pie .hover path {
   fill-opacity: .7;
-/*
-  stroke-width: 6px;
-  stroke-opacity: 1;
-*/
 }
-
+.nvd3.nv-pie .nv-label {
+  pointer-events: none;
+}
 .nvd3.nv-pie .nv-label rect {
   fill-opacity: 0;
   stroke-opacity: 0;
@@ -296,7 +361,7 @@ svg .title {
 
 .nvd3 .nv-groups path.nv-line {
   fill: none;
-  stroke-width: 2.5px;
+  stroke-width: 1.5px;
   /*
   stroke-linecap: round;
   shape-rendering: geometricPrecision;
@@ -311,6 +376,11 @@ svg .title {
   */
 }
 
+.nvd3 .nv-groups path.nv-line.nv-thin-line {
+  stroke-width: 1px;
+}
+
+
 .nvd3 .nv-groups path.nv-area {
   stroke: none;
   /*
@@ -350,17 +420,18 @@ svg .title {
 }
 
 
-.nvd3 .nv-groups .nv-point {
+.with-transitions .nvd3 .nv-groups .nv-point {
   transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
   -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
   -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
+
 }
 
 .nvd3.nv-scatter .nv-groups .nv-point.hover,
 .nvd3 .nv-groups .nv-point.hover {
-  stroke-width: 20px;
-  fill-opacity: .5 !important;
-  stroke-opacity: .5 !important;
+  stroke-width: 7px;
+  fill-opacity: .95 !important;
+  stroke-opacity: .95 !important;
 }
 
 
@@ -457,11 +528,12 @@ svg .title {
   fill-opacity: 0;
 }
 
+/*
 .nvd3.nv-stackedarea .nv-groups .nv-point.hover {
   stroke-width: 20px;
   stroke-opacity: .75;
   fill-opacity: 1;
-}
+}*/
 
 
 
@@ -496,7 +568,7 @@ svg .title {
 
 
 .nvd3.nv-bullet .nv-range {
-  fill: #999;
+  fill: #bababa;
   fill-opacity: .4;
 }
 .nvd3.nv-bullet .nv-range:hover {
@@ -653,4 +725,45 @@ svg .title {
   */
 }
 
+/**********
+* Parallel Coordinates
+*/
+
+.nvd3 .background path {
+  fill: none;
+  stroke: #ccc;
+  stroke-opacity: .4;
+  shape-rendering: crispEdges;
+}
+
+.nvd3 .foreground path {
+  fill: none;
+  stroke: steelblue;
+  stroke-opacity: .7;
+}
+
+.nvd3 .brush .extent {
+  fill-opacity: .3;
+  stroke: #fff;
+  shape-rendering: crispEdges;
+}
 
+.nvd3 .axis line, .axis path {
+  fill: none;
+  stroke: #000;
+  shape-rendering: crispEdges;
+}
+
+.nvd3 .axis text {
+  text-shadow: 0 1px 0 #fff;
+}
+
+/****
+Interactive Layer
+*/
+.nvd3 .nv-interactiveGuideLine {
+  pointer-events:none;
+}
+.nvd3 line.nv-guideline {
+  stroke: #ccc;
+}
\ No newline at end of file


[38/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
change the documentation for unix

the testsuite in Futon is not linked anymore (/_utils/couch_tests.html)
but there is the verify installation page. Changed the docs accordingly.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/81266c0a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/81266c0a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/81266c0a

Branch: refs/heads/Update-Sidebar-Ui
Commit: 81266c0a26158955645ec121e5c76263830dabb0
Parents: 053b471
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 27 21:17:05 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 27 21:17:05 2014 +0100

----------------------------------------------------------------------
 share/doc/src/install/unix.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/81266c0a/share/doc/src/install/unix.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/install/unix.rst b/share/doc/src/install/unix.rst
index da4e5bd..05e0459 100644
--- a/share/doc/src/install/unix.rst
+++ b/share/doc/src/install/unix.rst
@@ -175,7 +175,9 @@ To check that everything has worked, point your web browser to::
 
     http://127.0.0.1:5984/_utils/index.html
 
-From here you should run the test suite in Firefox.
+From here you should verify your installation by pointing your web browser to::
+
+    http://localhost:5984/_utils/verify_install.html
 
 Security Considerations
 -----------------------


[12/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: fix global var


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/89eb4a6d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/89eb4a6d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/89eb4a6d

Branch: refs/heads/Update-Sidebar-Ui
Commit: 89eb4a6d627e1f4e15a998319ac92210e7a1faba
Parents: 35390c8
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 20:49:41 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 20:49:41 2014 +0100

----------------------------------------------------------------------
 src/fauxton/app/addons/activetasks/views.js | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/89eb4a6d/src/fauxton/app/addons/activetasks/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js
index 1da8f52..b0940bf 100644
--- a/src/fauxton/app/addons/activetasks/views.js
+++ b/src/fauxton/app/addons/activetasks/views.js
@@ -58,8 +58,8 @@ function (app, FauxtonAPI, activetasks) {
     },
 
     requestByType: function(e){
-      var currentTarget = e.currentTarget;
-      datatype = this.$(currentTarget).attr("data-type");
+      var currentTarget = e.currentTarget,
+          datatype = this.$(currentTarget).attr("data-type");
 
       this.$('.task-tabs').find('li').removeClass('active');
       this.$(currentTarget).addClass('active');
@@ -119,8 +119,9 @@ function (app, FauxtonAPI, activetasks) {
       currentView = this.options.currentView;
     },
     sortByType:  function(e){
-      var currentTarget = e.currentTarget;
-      datatype = $(currentTarget).attr("data-type");
+      var currentTarget = e.currentTarget,
+          datatype = $(currentTarget).attr("data-type");
+
       this.collection.sortByColumn(datatype);
       this.render();
     },


[05/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
update documentation

explain better what happens with the view index when documents
in a view are being processed


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/fb59ccae
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/fb59ccae
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/fb59ccae

Branch: refs/heads/Update-Sidebar-Ui
Commit: fb59ccae8d90f6407e5b9d08a302f909778db9b7
Parents: 3be8c85
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 20 23:52:26 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 20 23:52:26 2014 +0100

----------------------------------------------------------------------
 share/doc/src/intro/overview.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/fb59ccae/share/doc/src/intro/overview.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/overview.rst b/share/doc/src/intro/overview.rst
index f94d656..4e3b72c 100644
--- a/share/doc/src/intro/overview.rst
+++ b/share/doc/src/intro/overview.rst
@@ -198,9 +198,10 @@ simultaneous client readers, who can read and query the view while the index
 is concurrently being refreshed for other clients without causing problems
 for the readers.
 
-As documents are examined, their previous row values are removed from the
-view indexes, if they exist. If the document is selected by a view function,
-the function results are inserted into the view as a new row.
+As documents are processed by the view engine through your 'map' and 'reduce'
+functions, their previous row values are removed from the view indexes, if
+they exist. If the document is selected by a view function, the function results
+are inserted into the view as a new row.
 
 When view index changes are written to disk, the updates are always appended
 at the end of the file, serving to both reduce disk head seek times during


[10/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: Fix tests


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/5bdfa6c4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/5bdfa6c4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/5bdfa6c4

Branch: refs/heads/Update-Sidebar-Ui
Commit: 5bdfa6c41c1dfd9782907b513954cdbd0b6edaa2
Parents: ca5913e
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:49:15 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:49:15 2014 +0100

----------------------------------------------------------------------
 .../app/addons/config/tests/resourcesSpec.js    | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5bdfa6c4/src/fauxton/app/addons/config/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/tests/resourcesSpec.js b/src/fauxton/app/addons/config/tests/resourcesSpec.js
index c78bc85..1cc9e62 100644
--- a/src/fauxton/app/addons/config/tests/resourcesSpec.js
+++ b/src/fauxton/app/addons/config/tests/resourcesSpec.js
@@ -28,7 +28,10 @@ define([
       });
 
       tabMenu = new Views.TableRow({
-        model: optionModel
+        model: optionModel,
+        uniqueName: function () {
+          return false;
+        }
       });
     });
 
@@ -47,8 +50,12 @@ define([
         var renderSpy = sinon.stub(tabMenu, 'render');
         var saveSpy = sinon.stub(optionModel, 'save');
 
-        tabMenu.$('.js-edit-value').trigger('dblclick');
-        tabMenu.$('.js-save-value').trigger('click');
+        var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+          return $(this).find('[name="value"]').length;
+        });
+
+        $fields.find('.js-edit-value').trigger('dblclick');
+        $fields.find('.js-save-value').trigger('click');
 
         assert.ok(renderSpy.calledOnce);
         assert.ok(saveSpy.calledOnce);
@@ -60,7 +67,12 @@ define([
 
         var e = $.Event("keyup");
         e.keyCode = 13;
-        tabMenu.$('.js-value-input').trigger(e);
+
+        var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+          return $(this).find('[name="value"]').length;
+        });
+
+        $fields.find('.js-value-input').trigger(e);
 
         assert.ok(renderSpy.calledOnce);
         assert.ok(saveSpy.calledOnce);


[39/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
moving myself from THANKS to AUTHORS


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/238f78ed
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/238f78ed
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/238f78ed

Branch: refs/heads/Update-Sidebar-Ui
Commit: 238f78ed36f256de31b660b537c1d4c6008a0627
Parents: 81266c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Sat Mar 29 17:44:51 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Sat Mar 29 17:45:38 2014 +0100

----------------------------------------------------------------------
 AUTHORS   | 1 +
 THANKS.in | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/238f78ed/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index ab48b58..a3c9ee5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -29,5 +29,6 @@ documentation or developing software. Some of these people are:
  * Andy Wenk <an...@apache.org>
  * Klaus Trainer <kl...@apache.org>
  * Benjamin Young <bi...@apache.org>
+ * Robert Kowalski <ro...@kowalski.gd>
 
 For a list of other credits see the `THANKS` file.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/238f78ed/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index b3e5cc8..8b2a34f 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -91,7 +91,6 @@ suggesting improvements or submitting changes. Some of these people are:
  * Tim Blair
  * Tady Walsh <he...@tady.me>
  * Sam Rijs <re...@awesam.de>
- * Robert Kowalski <ro...@kowalski.gd>
 # Authors from commit 6c976bd and onwards are auto-inserted. If you are merging
 # a commit from a non-committer, you should not add an entry to this file. When
 # `bootstrap` is run, the actual THANKS file will be generated.


[17/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Improving misleading example. Do not emit(foo, doc)!


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0f7be287
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0f7be287
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0f7be287

Branch: refs/heads/Update-Sidebar-Ui
Commit: 0f7be287d6a9358d960beb17b16ad7b5e20bd360
Parents: 0e8c178
Author: Joan Touzet <wo...@apache.org>
Authored: Fri Mar 21 19:44:58 2014 -0400
Committer: Joan Touzet <wo...@apache.org>
Committed: Fri Mar 21 19:44:58 2014 -0400

----------------------------------------------------------------------
 share/doc/src/couchapp/views/collation.rst | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0f7be287/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 9fa8513..06c4c6d 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -28,7 +28,7 @@ property serves as the key, thus the result will be sorted by ``LastName``:
 
   function(doc) {
     if (doc.Type == "customer") {
-      emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
+      emit(doc.LastName, null);
     }
   }
 
@@ -49,12 +49,17 @@ associated orders. The values 0 and 1 for the sorting token are arbitrary.
 
   function(doc) {
     if (doc.Type == "customer") {
-      emit([doc._id, 0], doc);
+      emit([doc._id, 0], null);
     } else if (doc.Type == "order") {
-      emit([doc.customer_id, 1], doc);
+      emit([doc.customer_id, 1], null);
     }
   }
 
+To list a specific customer with ``_id`` XYZ, and all of that customer's orders, limit the startkey and endkey ranges to cover only documents for that customer's ``_id``::
+
+  startkey=["XYZ"]&endkey=["XYZ", {}]
+
+It is not recommended to emit the document itself in the view. Instead, to include the bodies of the documents when requesting the view, request the view with ``?include_docs=true``.
 
 Sorting by Dates
 ================
@@ -67,14 +72,14 @@ the following emit function would sort by date:
 
 .. code-block:: javascript
 
-  emit(Date.parse(doc.created_at).getTime(), doc);
+  emit(Date.parse(doc.created_at).getTime(), null);
 
 Alternatively, if you use a date format which sorts lexicographically,
 such as ``"2013/06/09 13:52:11 +0000"`` you can just
 
 .. code-block:: javascript
 
-  emit(doc.created_at, doc);
+  emit(doc.created_at, null);
 
 and avoid the conversion. As a bonus, this date format is compatible with the
 JavaScript date parser, so you can use ``new Date(doc.created_at)`` in your


[30/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
fixed _update function example

It was only checking for req.id existance (it should
always be included in the request) and not its truthiness.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/597b8d16
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/597b8d16
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/597b8d16

Branch: refs/heads/Update-Sidebar-Ui
Commit: 597b8d1611e951cbff0a8f9521bae2c0694baa5d
Parents: 827b848
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Wed Mar 26 09:38:57 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Wed Mar 26 09:38:57 2014 -0400

----------------------------------------------------------------------
 share/doc/src/couchapp/ddocs.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/597b8d16/share/doc/src/couchapp/ddocs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/ddocs.rst b/share/doc/src/couchapp/ddocs.rst
index 754b9b7..4f4664a 100644
--- a/share/doc/src/couchapp/ddocs.rst
+++ b/share/doc/src/couchapp/ddocs.rst
@@ -419,7 +419,7 @@ The basic example that demonstrates all use-cases of update handlers below:
 
     function(doc, req){
         if (!doc){
-            if ('id' in req){
+            if ('id' in req && req['id']){
                 // create new document
                 return [{'_id': req['id']}, 'New World']
             }


[40/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: fix tests for Auth


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ce352c8d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ce352c8d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ce352c8d

Branch: refs/heads/Update-Sidebar-Ui
Commit: ce352c8d9a537574408d4fac69590384211b1203
Parents: 238f78e
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Sun Mar 30 01:58:23 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Sun Mar 30 03:59:19 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/auth/test/baseSpec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ce352c8d/src/fauxton/app/addons/auth/test/baseSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/test/baseSpec.js b/src/fauxton/app/addons/auth/test/baseSpec.js
index 1525306..ad92ec8 100644
--- a/src/fauxton/app/addons/auth/test/baseSpec.js
+++ b/src/fauxton/app/addons/auth/test/baseSpec.js
@@ -27,7 +27,7 @@ define([
         FauxtonAPI.auth = new Auth();
         Base.initialize();
         FauxtonAPI.auth.authDeniedCb();
-        assert.ok(navigateSpy.withArgs('/noAccess', {replace: true}).calledOnce);
+        assert.ok(navigateSpy.withArgs('/noAccess?urlback=', {replace: true}).calledOnce);
       });
     });
   });


[07/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: Fire authenticated event when user is authenticated


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/f2153c0f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/f2153c0f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/f2153c0f

Branch: refs/heads/Update-Sidebar-Ui
Commit: f2153c0f99050775e3ee1ddb94d9e68848010361
Parents: f0cdb70
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Mar 21 11:31:15 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Fri Mar 21 11:31:15 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/auth/base.js | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/f2153c0f/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
index 3354f53..c7bbb04 100644
--- a/src/fauxton/app/addons/auth/base.js
+++ b/src/fauxton/app/addons/auth/base.js
@@ -39,8 +39,10 @@ function(app, FauxtonAPI, Auth) {
       var deferred = $.Deferred();
 
       if (session.isAdminParty()) {
+        session.trigger("authenticated");
         deferred.resolve();
       } else if(session.matchesRoles(roles)) {
+        session.trigger("authenticated");
         deferred.resolve();
       } else {
         deferred.reject();


[29/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Readd 'Could not create admin.' to the beginning of the error message

was removed in b63ff1b50b7bde0c8f1f95988d076dda63f41fed


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/827b8489
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/827b8489
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/827b8489

Branch: refs/heads/Update-Sidebar-Ui
Commit: 827b84891d5c16a4e5c2b692d3694fe2ba4a1210
Parents: 1fb7cea
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Tue Mar 25 22:05:19 2014 +0100
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Mar 26 10:17:51 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/auth/resources.js | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/827b8489/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index edfd708..ba3a438 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -20,7 +20,7 @@ function (app, FauxtonAPI, CouchdbSession) {
 
   var Auth = new FauxtonAPI.addon();
 
-  var promiseErrorHandler = function (xhr, type, msg) {
+  var errorHandler = function (xhr, type, msg) {
     msg = xhr;
     if (arguments.length === 3) {
       msg = xhr.responseJSON.reason;
@@ -72,7 +72,8 @@ function (app, FauxtonAPI, CouchdbSession) {
           passwordsNotMatch:  'Passwords do not match.',
           loggedIn: 'You have been logged in.',
           adminCreated: 'CouchDB admin created',
-          changePassword: 'Your password has been updated.'
+          changePassword: 'Your password has been updated.',
+          adminCreationFailedPrefix: 'Could not create admin.'
         }, options.messages);
     },
 
@@ -245,7 +246,14 @@ function (app, FauxtonAPI, CouchdbSession) {
         }
       });
 
-      promise.fail(promiseErrorHandler);
+      promise.fail(function (xhr, type, msg) {
+        msg = xhr;
+        if (arguments.length === 3) {
+          msg = xhr.responseJSON.reason;
+        }
+        msg = FauxtonAPI.session.messages.adminCreationFailedPrefix + ' ' + msg;
+        errorHandler(msg);
+      });
     }
 
   });
@@ -279,7 +287,7 @@ function (app, FauxtonAPI, CouchdbSession) {
         FauxtonAPI.navigate('/');
       });
 
-      promise.fail(promiseErrorHandler);
+      promise.fail(errorHandler);
     }
 
   });
@@ -306,7 +314,7 @@ function (app, FauxtonAPI, CouchdbSession) {
         that.$('#password-confirm').val('');
       });
 
-      promise.fail(promiseErrorHandler);
+      promise.fail(errorHandler);
     }
   });
 


[16/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fix error message

Small typo in the error message. Was ?=rev but should
read ?rev=


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0e8c1787
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0e8c1787
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0e8c1787

Branch: refs/heads/Update-Sidebar-Ui
Commit: 0e8c1787a043a01c6daba9fa574c418b49ca1916
Parents: 2925614
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 23:16:55 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 23:16:55 2014 +0100

----------------------------------------------------------------------
 src/couchdb/couch_httpd_db.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0e8c1787/src/couchdb/couch_httpd_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index 0a7c17c..6940e47 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -44,7 +44,7 @@ handle_request(#httpd{path_parts=[DbName|RestParts],method=Method,
         case couch_httpd:qs_value(Req, "rev", false) of
             false -> delete_db_req(Req, DbName);
             _Rev -> throw({bad_request,
-                "You tried to DELETE a database with a ?=rev parameter. "
+                "You tried to DELETE a database with a ?rev= parameter. "
                 ++ "Did you mean to DELETE a document instead?"})
         end;
     {_, []} ->


[24/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Updating d3 license year to match d3's official license.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b1255309
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b1255309
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b1255309

Branch: refs/heads/Update-Sidebar-Ui
Commit: b1255309eca961d188d40ef509e7541a3d4ad14e
Parents: 6301060
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 16:31:07 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400

----------------------------------------------------------------------
 LICENSE | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1255309/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 6ae7303..21cfb8c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -689,7 +689,7 @@ For src/fauxton/assets/less/bootstrap
 
 For src/fauxton/assets/js/libs/d3.js
 
-	Copyright (c) 2012, Michael Bostock
+	Copyright (c) 2010-2014, Michael Bostock
 	All rights reserved.
 
 	Redistribution and use in source and binary forms, with or without


[19/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Configurable upper bound to _uuids count parameter


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0fb5aa9e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0fb5aa9e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0fb5aa9e

Branch: refs/heads/Update-Sidebar-Ui
Commit: 0fb5aa9e67bd291ca2638dba961f4ddd3f6ccb3e
Parents: 198bea3
Author: Robert Newson <rn...@apache.org>
Authored: Tue Mar 25 15:02:50 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Tue Mar 25 16:16:18 2014 +0000

----------------------------------------------------------------------
 etc/couchdb/default.ini.tpl.in            | 2 ++
 share/www/script/test/uuids.js            | 4 ++++
 src/couchdb/couch_httpd_misc_handlers.erl | 5 +++++
 3 files changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index fd953c2..32537e0 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -217,6 +217,8 @@ algorithm = sequential
 ; The utc_id_suffix value will be appended to uuids generated by the utc_id algorithm.
 ; Replicating instances should have unique utc_id_suffix values to ensure uniqueness of utc_id ids.
 utc_id_suffix =
+# Maximum number of UUIDs retrievable from /_uuids in a single request
+max_count = 1000
 
 [stats]
 ; rate is in milliseconds

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/share/www/script/test/uuids.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/uuids.js b/share/www/script/test/uuids.js
index 6f5d223..0f141a9 100644
--- a/share/www/script/test/uuids.js
+++ b/share/www/script/test/uuids.js
@@ -80,6 +80,10 @@ couchTests.uuids = function(debug) {
     }
   };
 
+  // test max_uuid_count
+  var xhr = CouchDB.request("GET", "/_uuids?count=1001");
+  TEquals(401, xhr.status, "should error when count > max_count");
+
   run_on_modified_server([{
       "section": "uuids",
       "key": "algorithm",

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 96a05c6..67e3a12 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -105,7 +105,12 @@ handle_restart_req(Req) ->
 
 
 handle_uuids_req(#httpd{method='GET'}=Req) ->
+    Max = list_to_integer(couch_config:get("uuids","max","1000")),
     Count = list_to_integer(couch_httpd:qs_value(Req, "count", "1")),
+    case Count > Max of
+        true -> throw({forbidden, <<"count parameter too large">>});
+        false -> ok
+    end,
     UUIDs = [couch_uuids:new() || _ <- lists:seq(1, Count)],
     Etag = couch_httpd:make_etag(UUIDs),
     couch_httpd:etag_respond(Req, Etag, fun() ->


[06/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
some minor documentatiom fixes


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/f0cdb701
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/f0cdb701
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/f0cdb701

Branch: refs/heads/Update-Sidebar-Ui
Commit: f0cdb701d268870a4157d76286269ed6fe4f0ead
Parents: fb59cca
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 00:22:06 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 00:22:06 2014 +0100

----------------------------------------------------------------------
 share/doc/src/intro/overview.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/f0cdb701/share/doc/src/intro/overview.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/overview.rst b/share/doc/src/intro/overview.rst
index 4e3b72c..7804cf9 100644
--- a/share/doc/src/intro/overview.rst
+++ b/share/doc/src/intro/overview.rst
@@ -261,9 +261,9 @@ updates, ensuring security and data validation in a shared, distributed system.
 Distributed Updates and Replication
 ===================================
 
-CouchDB is a peer-based distributed database system, it allows for users and
-servers to access and update the same shared data while disconnected and then
-bi-directionally replicate those changes later.
+CouchDB is a peer-based distributed database system. It allows users and servers
+to access and update the same shared data while disconnected. Those changes can
+then be replicated bi-directionally later.
 
 The CouchDB document storage, view and security models are designed to work
 together to make true bi-directional replication efficient and reliable.


[27/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
put back JSON return value in collation example

Originally removed in 0f7be287d6a9358d960beb17b16ad7b5e20bd360


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/bea5c947
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/bea5c947
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/bea5c947

Branch: refs/heads/Update-Sidebar-Ui
Commit: bea5c947d1c832f0054ae5d22376ebfbf37a366c
Parents: 35a0303
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 16:45:28 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 16:45:28 2014 -0400

----------------------------------------------------------------------
 share/doc/src/couchapp/views/collation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/bea5c947/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 06c4c6d..9c2f5c7 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -28,7 +28,7 @@ property serves as the key, thus the result will be sorted by ``LastName``:
 
   function(doc) {
     if (doc.Type == "customer") {
-      emit(doc.LastName, null);
+      emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
     }
   }
 


[33/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fix the build for the d3 update


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c84a71cb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c84a71cb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c84a71cb

Branch: refs/heads/Update-Sidebar-Ui
Commit: c84a71cb9b3d8fd20fe7b8df0a320152e035d6e2
Parents: 282cddf
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 26 21:12:19 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Wed Mar 26 16:48:55 2014 -0400

----------------------------------------------------------------------
 src/Makefile.am                         |  1 +
 src/fauxton/app/config.js               |  8 ++------
 src/fauxton/assets/js/libs/d3.global.js | 18 ++++++++++++++++++
 3 files changed, 21 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index e1007f9..ccf6ccd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -251,6 +251,7 @@ FAUXTON_FILES = \
     fauxton/assets/js/libs/backbone.js \
     fauxton/assets/js/libs/bootstrap.js \
     fauxton/assets/js/libs/d3.js \
+    fauxton/assets/js/libs/d3.global.js \
     fauxton/assets/js/libs/jquery.js \
     fauxton/assets/js/libs/lodash.js \
     fauxton/assets/js/libs/nv.d3.js \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index d33f3b8..3ed1c31 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -30,7 +30,8 @@ require.config({
     spin: "../assets/js/libs/spin.min",
     d3: "../assets/js/libs/d3",
     "nv.d3": "../assets/js/libs/nv.d3",
-    "ace":"../assets/js/libs/ace"
+    "ace":"../assets/js/libs/ace",
+    "d3.global": "../assets/js/libs/d3.global"
   },
 
   baseUrl: '/',
@@ -63,8 +64,3 @@ require.config({
   }
 });
 
-define("d3.global", ["d3"], function(_) {
-  d3 = _;
-});
-
-require(["d3", "nv.d3"], function(d3, nvd3) {});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/fauxton/assets/js/libs/d3.global.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.global.js b/src/fauxton/assets/js/libs/d3.global.js
new file mode 100644
index 0000000..9f38d04
--- /dev/null
+++ b/src/fauxton/assets/js/libs/d3.global.js
@@ -0,0 +1,18 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// Set the require.js configuration for your application.
+
+define("d3.global", ["d3"], function(_) {
+	//get that global back
+  d3 = _;
+});


[03/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Remove Stale for all docs, but keep it for indexes


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/65c814a9
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/65c814a9
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/65c814a9

Branch: refs/heads/Update-Sidebar-Ui
Commit: 65c814a9deb12f3c0fcbfc6c742683c3fcc7e08c
Parents: eaaa8f0
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400

----------------------------------------------------------------------
 .../app/addons/documents/templates/advanced_options.html       | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/65c814a9/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index 4ca8f12..8acf30a 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -105,6 +105,12 @@ the License.
         <label for="check6">Update Sequence</label>  
       </div>
 
+      <% if (showPreview) { %>
+      <div class="checkbox inline">  
+        <input id="check7" name="stale" type="checkbox" value="true">  
+        <label for="check7">Stale</label>  
+      </div>
+      <% } %>
   </div>
 
 


[04/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Cleaning up query options UI
null object fix.
Improved key support
initial linking with paginate
Fix linting issue


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/eaaa8f06
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/eaaa8f06
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/eaaa8f06

Branch: refs/heads/Update-Sidebar-Ui
Commit: eaaa8f06304bba8b33785168a557ef0f50d3f3ce
Parents: 7dba422
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400

----------------------------------------------------------------------
 .../addons/documents/assets/less/documents.less |   7 +
 .../documents/templates/advanced_options.html   | 145 +++++++++++--------
 src/fauxton/app/addons/documents/views.js       |  91 +++++++++---
 3 files changed, 160 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index c30a9af..61d864b 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -23,6 +23,12 @@ button.beautify {
 	margin-top: 20px;
 }
 
+.toggle-btns {
+    label{
+        margin-right: 0;
+    }
+}
+
 #per-page {
   float: right;
 
@@ -32,6 +38,7 @@ button.beautify {
   
 }
 
+
 /** used in all_docs_list.html **/
 .view {
     table td div {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index e282c62..4ca8f12 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -13,78 +13,103 @@ the License.
 -->
 <div class="errors-container"></div>
 <form class="js-view-query-update custom-inputs">
-  <div class="controls-group">
-    <div class="row-fluid">
+
+<!-- tabs for choosing Keys or Start & end -->
+
+  <div class="btn-group toggle-btns">
+    <label for="showKeys" class="drop-down btn active">
+     Specific Keys 
+    </label>
+    <label for="showStartEnd" class="drop-down btn">
+      Bounded Queries
+    </label>
+  </div>
+
+  <div class="controls-group well">
+    <div class="row-fluid" id="js-showKeys">
       <div class="controls controls-row">
-        <input name="key" class="span6" type="text" placeholder="Key">
-        <input name="keys" class="span6" type="text" placeholder="Keys">
+        <input name="keys" class="input-xxlarge" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON.">
       </div>
     </div>
-    <div class="row-fluid">
+    <div class="row-fluid hide" id="js-showStartEnd">
       <div class="controls controls-row">
-        <input name="startkey" class="span6" type="text" placeholder="Start Key">
+        <input name="startkey" class="span6" type="text" placeholder="Start Key" disabled>
         <input name="endkey" class="span6" type="text" placeholder="End Key">
       </div>
+      <div class="controls controls-row checkbox inline">  
+        <input id="check5" name="inclusive_end" type="checkbox" value="false" disabled>
+        <label for="check5">Disable Inclusive End</label>
+      </div>
     </div>
   </div>
+
+<!-- Limit and Skip are conditional -->
+
   <div class="controls-group">
-    <div class="row-fluid">
-      <div class="controls controls-row">
-        <div class="checkbox inline">  
-          <input id="check1" type="checkbox" name="include_docs" value="true">  
-          <label name="include_docs" for="check1">Include Docs</label>  
-          <% if (hasReduce) { %>
-          <input id="check2" name="reduce" type="checkbox" value="true">
-          <label for="check2">Reduce</label>  
-        </div> 
-        <label id="select1" class="drop-down inline">
-          Group Level:
-          <select id="select1" disabled name="group_level" class="input-small">
-            <option value="0">None</option>
-            <option value="1">1</option>
-            <option value="2">2</option>
-            <option value="3">3</option>
-            <option value="4">4</option>
-            <option value="5">5</option>
-            <option value="6">6</option>
-            <option value="7">7</option>
-            <option value="8">8</option>
-            <option value="9">9</option>
-            <option value="999" selected="selected">exact</option>
-          </select>
-        </label>
-        <% } else{ %>
-        </div>
-        <% } %>
+      <label class="drop-down inline">
+        Limit:
+        <select name="limit" class="input-small" disabled>
+          <option>5</option>
+          <option>10</option>
+          <option selected="selected">20</option>
+          <option>30</option>
+          <option>50</option>
+          <option>100</option>
+		  <option>500</option>
+        </select>
+      </label>
+      <label for="skipRows" class="inline drop-down">
+        Skip
+        <input name="skip" class="input-large" type="text" id="skipRows" disabled placeholder="Number of rows to skip">
+      </label>
+      <span class="js-disabled-message"> Limit &amp; and Skip are disabled when using Keys.</span>
 
-        <div class="checkbox inline">  
-          <input id="check3" name="stale" type="checkbox" value="ok">
-          <label for="check3">Stale</label>
-          <input id="check4" name="descending" type="checkbox" value="true">  
-          <label for="check4">Descending</label>  
-        </div> 
-        <label class="drop-down inline">
-          Limit:
-          <select name="limit" class="input-small">
-            <option>5</option>
-            <option>10</option>
-            <option >20</option>
-            <option>30</option>
-            <option>50</option>
-            <option >100</option>
-            <option>500</option>
-            <option selected="selected">None</option>
-          </select>
-        </label>
-        <div class="checkbox inline">  
-          <input id="check5" name="inclusive_end" type="checkbox" value="false">
-          <label for="check5">Disable Inclusive End</label>
-          <input id="check6" name="update_seq" type="checkbox" value="true">  
-          <label for="check6">Update Sequence</label>  
-        </div>
+      <div class="checkbox inline"> 
+        <input id="check1" type="checkbox" name="include_docs" value="true">  
+        <label name="include_docs" for="check1">Include Docs (show the entire doc body)</label>  
       </div>
-    </div>
+
+      <% if (hasReduce) { %>
+      <div class="checkbox inline">  
+        <input id="check2" name="reduce" type="checkbox" value="true">
+        <label for="check2">Reduce</label>  
+      </div> 
+      <label id="select1" class="drop-down inline">
+        Group Level:
+        <select id="select1" disabled name="group_level" class="input-small">
+          <option value="0">None</option>
+          <option value="1">1</option>
+          <option value="2">2</option>
+          <option value="3">3</option>
+          <option value="4">4</option>
+          <option value="5">5</option>
+          <option value="6">6</option>
+          <option value="7">7</option>
+          <option value="8">8</option>
+          <option value="9">9</option>
+          <option value="999" selected="selected">exact</option>
+        </select>
+      </label>
+      <% } %>
+
+      <label id="select2" class="drop-down inline">
+        Order: 
+        <select id="select2" name="descending" class="input-large">
+          <option value="false">Accending</option>
+          <option value="true">Descending</option>
+        </select>
+      </label>
+
+      <div class="checkbox inline">  
+        <input id="check6" name="update_seq" type="checkbox" value="true">  
+        <label for="check6">Update Sequence</label>  
+      </div>
+
   </div>
+
+
+
+
   <div class="controls-group">
     <div class="row-fluid">
       <div id="button-options" class="controls controls-row">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index f29ebaa..1e7addf 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -335,7 +335,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.model.destroy().then(function(resp) {
         FauxtonAPI.addNotification({
-          msg: "Succesfully destroyed your doc"
+          msg: "Succesfully destroyed your doc",
+          clear:  true
         });
         that.$el.fadeOut(function () {
           that.remove();
@@ -348,7 +349,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       }, function(resp) {
         FauxtonAPI.addNotification({
           msg: "Failed to destroy your doc!",
-          type: "error"
+          type: "error",
+          clear:  true
         });
       });
     }
@@ -518,13 +520,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           return FauxtonAPI.addNotification({
             msg: "JSON Parse Error on field: "+param.name,
             type: "error",
-            selector: ".advanced-options .errors-container"
+            selector: ".advanced-options .errors-container",
+            clear:  true
           });
         });
         FauxtonAPI.addNotification({
           msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
           type: "warning",
-          selector: ".advanced-options .errors-container"
+          selector: ".advanced-options .errors-container",
+          clear:  true
         });
 
         return false;
@@ -580,7 +584,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.ddocID = options.ddocInfo.id;
       }
       this.newView = options.newView || false;
-      this.docParams = options.docParams;
+      this.docParams = options.docParams || {};
       this.params = options.params || {};
       this.expandDocs = true;
       this.perPageDefault = this.docParams.limit || 20;
@@ -597,7 +601,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           // This should just throw a notification, not break the page
           FauxtonAPI.addNotification({
             msg: "Bad Request",
-            type: "error"
+            type: "error",
+            clear:  true
           });
 
           //now redirect back to alldocs
@@ -668,7 +673,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         }, function(resp) {
           FauxtonAPI.addNotification({
             msg: "Failed to destroy your doc!",
-            type: "error"
+            type: "error",
+            clear:  true
           });
         });
       }, this);
@@ -771,7 +777,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       if (this.model.isNewDoc()) {
         FauxtonAPI.addNotification({
           msg: 'This document has not been saved yet.',
-          type: 'warning'
+          type: 'warning',
+          clear:  true
         });
         return;
       }
@@ -784,13 +791,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.model.destroy().then(function(resp) {
         FauxtonAPI.addNotification({
-          msg: "Succesfully destroyed your doc"
+          msg: "Succesfully destroyed your doc",
+          clear:  true
         });
         FauxtonAPI.navigate(database.url("index"));
       }, function(resp) {
         FauxtonAPI.addNotification({
           msg: "Failed to destroy your doc!",
-          type: "error"
+          type: "error",
+          clear:  true
         });
       });
     },
@@ -808,7 +817,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       if (this.model.isNewDoc()) {
         FauxtonAPI.addNotification({
           msg: 'Please save the document before uploading an attachment.',
-          type: 'warning'
+          type: 'warning',
+          clear:  true
         });
         return;
       }
@@ -819,7 +829,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       if (this.model.isNewDoc()) {
         FauxtonAPI.addNotification({
           msg: 'Please save the document before duplicating it.',
-          type: 'warning'
+          type: 'warning',
+          clear:  true
         });
         return;
       }
@@ -891,14 +902,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           notification = FauxtonAPI.addNotification({
             msg: "Cannot save: " + 'Cannot change a documents _id, try Duplicate doc instead!',
             type: "error",
-            selector: "#doc .errors-container"
+            selector: "#doc .errors-container",
+            clear:  true
           });
         delete this.model.validationError;
       } else {
         notification = FauxtonAPI.addNotification({
           msg: "Please fix the JSON errors and try again.",
           type: "error",
-          selector: "#doc .errors-container"
+          selector: "#doc .errors-container",
+          clear:  true
         });
       }
     },
@@ -988,7 +1001,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         editor.setValue(JSON.stringify(changedDoc, null, "  "));
         FauxtonAPI.addNotification({
           type: "error",
-          msg: "Cannot remove a documents Id or Revision."
+          msg: "Cannot remove a documents Id or Revision.",
+          clear:  true
         });
       });
     },
@@ -1008,7 +1022,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     saveDoc: function(event) {
       FauxtonAPI.addNotification({
         type: "warning",
-        msg: "Save functionality coming soon."
+        msg: "Save functionality coming soon.",
+        clear:  true
       });
     },
 
@@ -1073,7 +1088,34 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       "change form.js-view-query-update input": "updateFilters",
       "change form.js-view-query-update select": "updateFilters",
       "submit form.js-view-query-update": "updateView",
-      "click button.preview": "previewView"
+      "click button.preview": "previewView",
+      "click .toggle-btns > label":  "toggleQuery"
+    },
+
+    toggleQuery: function(e){
+      e.preventDefault();
+      var showFunctionName =this.$(e.currentTarget).attr("for");
+      //highlight current
+      this.$(".toggle-btns > label").removeClass('active');
+      this.$(e.currentTarget).addClass("active");
+      
+      this.$("[id^='js-show']").hide();
+
+      //show section & disable what needs to be disabled
+      this[showFunctionName]();
+    },
+
+    showKeys: function(){
+      this.$("#js-showKeys, .js-disabled-message").show();
+      this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
+      this.$('[name="keys"]').removeAttr("disabled");
+    },
+
+    showStartEnd: function(){
+      this.$("#js-showStartEnd").show();
+      this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
+      this.$('.js-disabled-message').hide();
+      this.$('[name="keys"]').attr("disabled","true");
     },
 
     beforeRender: function () {
@@ -1090,20 +1132,21 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.hasReduce = hasReduce;
       this.render();
     },
-
+    validateKeys:  function(val){
+      return JSON.parse(val);
+    },
     queryParams: function () {
       var $form = this.$(".js-view-query-update");
-      // Ignore params without a value
+
       var params = _.reduce($form.serializeArray(), function(params, param) {
         if (!param.value) { return params; }
         if (param.name === "limit" && param.value === 'None') { return params; }
-
         params.push(param);
         return params;
       }, []);
 
       // Validate *key* params to ensure they're valid JSON
-      var keyParams = ["key","keys","startkey","endkey"];
+      var keyParams = ["keys","startkey","endkey"];
       var errorParams = _.filter(params, function(param) {
         if (_.contains(keyParams, param.name)) {
           try {
@@ -1140,7 +1183,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
             var notification = FauxtonAPI.addNotification({
               msg: "include_docs has been disabled as you cannot include docs on a reduced view",
               type: "warn",
-              selector: ".view.show .all-docs-list.errors-container"
+              selector: ".view.show .all-docs-list.errors-container",
+              clear:  true
             });
           }
           $form.find("input[name=include_docs]").prop("disabled", true);
@@ -1161,13 +1205,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         var $ele;
         switch (key) {
           case "limit":
+          case "descending":
           case "group_level":
             if (!val) { return; }
             $form.find("select[name='"+key+"']").val(val);
           break;
           case "include_docs":
             case "stale":
-            case "descending":
             case "inclusive_end":
             $form.find("input[name='"+key+"']").prop('checked', true);
           break;
@@ -1186,6 +1230,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     updateView: function (event) {
+      event.preventDefault();
       this.updateViewFn(event, this.queryParams());
     },
 


[15/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
fix documentation

explain why the HTTP status code 400 will be returned when ?rev=
is included in the request URL


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/29256149
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/29256149
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/29256149

Branch: refs/heads/Update-Sidebar-Ui
Commit: 29256149029714af6379dadd62022ee6f46b58ec
Parents: ebbee3c
Author: Andy Wenk <an...@nms.de>
Authored: Fri Mar 21 22:57:04 2014 +0100
Committer: Andy Wenk <an...@nms.de>
Committed: Fri Mar 21 22:57:04 2014 +0100

----------------------------------------------------------------------
 share/doc/src/api/database/common.rst | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/29256149/share/doc/src/api/database/common.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/api/database/common.rst b/share/doc/src/api/database/common.rst
index f715c70..a1483d9 100644
--- a/share/doc/src/api/database/common.rst
+++ b/share/doc/src/api/database/common.rst
@@ -223,6 +223,12 @@
   Deletes the specified database, and all the documents and attachments
   contained within it.
 
+  .. note::
+
+    To avoid deleting a database, CouchDB will respond with the HTTP status code 400
+    when the request URL includes a ?rev= parameter. This suggests that one wants to delete
+    a document but forgot to add the document id to the URL.
+
   :param db: Database name
   :<header Accept: - :mimetype:`application/json`
                    - :mimetype:`text/plain`
@@ -230,7 +236,7 @@
                          - :mimetype:`text/plain; charset=utf-8`
   :>json boolean ok: Operation status
   :code 200: Database removed successfully
-  :code 400: Invalid database name
+  :code 400: Invalid database name or forgotten document id by accident
   :code 401: CouchDB Server Administrator privileges required
   :code 404: Database doesn't exist
 


[11/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: Config test fixes


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/35390c83
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/35390c83
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/35390c83

Branch: refs/heads/Update-Sidebar-Ui
Commit: 35390c833333a7b5935b34da47be9a1696c845f7
Parents: f2153c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:49:15 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Fri Mar 21 13:35:43 2014 -0400

----------------------------------------------------------------------
 .../app/addons/config/tests/resourcesSpec.js    | 20 ++++++++--
 src/fauxton/app/addons/config/views.js          | 39 ++++++++++----------
 2 files changed, 36 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/35390c83/src/fauxton/app/addons/config/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/tests/resourcesSpec.js b/src/fauxton/app/addons/config/tests/resourcesSpec.js
index c78bc85..1cc9e62 100644
--- a/src/fauxton/app/addons/config/tests/resourcesSpec.js
+++ b/src/fauxton/app/addons/config/tests/resourcesSpec.js
@@ -28,7 +28,10 @@ define([
       });
 
       tabMenu = new Views.TableRow({
-        model: optionModel
+        model: optionModel,
+        uniqueName: function () {
+          return false;
+        }
       });
     });
 
@@ -47,8 +50,12 @@ define([
         var renderSpy = sinon.stub(tabMenu, 'render');
         var saveSpy = sinon.stub(optionModel, 'save');
 
-        tabMenu.$('.js-edit-value').trigger('dblclick');
-        tabMenu.$('.js-save-value').trigger('click');
+        var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+          return $(this).find('[name="value"]').length;
+        });
+
+        $fields.find('.js-edit-value').trigger('dblclick');
+        $fields.find('.js-save-value').trigger('click');
 
         assert.ok(renderSpy.calledOnce);
         assert.ok(saveSpy.calledOnce);
@@ -60,7 +67,12 @@ define([
 
         var e = $.Event("keyup");
         e.keyCode = 13;
-        tabMenu.$('.js-value-input').trigger(e);
+
+        var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+          return $(this).find('[name="value"]').length;
+        });
+
+        $fields.find('.js-value-input').trigger(e);
 
         assert.ok(renderSpy.calledOnce);
         assert.ok(saveSpy.calledOnce);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/35390c83/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 8453d90..7952182 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -80,28 +80,29 @@ function(app, FauxtonAPI, Config, Components) {
       return {option: this.model.toJSON()};
     },
     saveAndRender: function (event) {
-      var options = {};
-        $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
-        options[$input.attr('name')] = $input.val();
-
-        if ($input.attr('name')==='name'){
-          if (this.uniqueName($input.val())){
-            this.error = FauxtonAPI.addNotification({
-                msg: "This config already exists, enter a unique name",
-                type: "error",
-                clear: true
-            });
-          } else {
-            var newModel = this.model.clone();
-              newModel.save(options);
-              this.model.destroy();
-              this.model = newModel;
-              this.render();
-          }
+      var options = {},
+          $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
+
+      options[$input.attr('name')] = $input.val();
+
+      if ($input.attr('name')==='name'){
+        if (this.uniqueName($input.val())){
+          this.error = FauxtonAPI.addNotification({
+            msg: "This config already exists, enter a unique name",
+            type: "error",
+            clear: true
+          });
         } else {
+          var newModel = this.model.clone();
+          newModel.save(options);
+          this.model.destroy();
+          this.model = newModel;
+          this.render();
+        }
+      } else {
         this.model.save(options);
         this.render();
-        }
+      }
     }
 
   });


[21/41] Updating d3 to v3.4.3 and nv.d3 to v1.1.15

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/js/libs/d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.js b/src/fauxton/assets/js/libs/d3.js
index 44fc0b0..b57c8d0 100644
--- a/src/fauxton/assets/js/libs/d3.js
+++ b/src/fauxton/assets/js/libs/d3.js
@@ -1,4 +1,223 @@
-(function() {
+!function() {
+  var d3 = {
+    version: "3.4.3"
+  };
+  if (!Date.now) Date.now = function() {
+    return +new Date();
+  };
+  var d3_arraySlice = [].slice, d3_array = function(list) {
+    return d3_arraySlice.call(list);
+  };
+  var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window;
+  try {
+    d3_array(d3_documentElement.childNodes)[0].nodeType;
+  } catch (e) {
+    d3_array = function(list) {
+      var i = list.length, array = new Array(i);
+      while (i--) array[i] = list[i];
+      return array;
+    };
+  }
+  try {
+    d3_document.createElement("div").style.setProperty("opacity", 0, "");
+  } catch (error) {
+    var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
+    d3_element_prototype.setAttribute = function(name, value) {
+      d3_element_setAttribute.call(this, name, value + "");
+    };
+    d3_element_prototype.setAttributeNS = function(space, local, value) {
+      d3_element_setAttributeNS.call(this, space, local, value + "");
+    };
+    d3_style_prototype.setProperty = function(name, value, priority) {
+      d3_style_setProperty.call(this, name, value + "", priority);
+    };
+  }
+  d3.ascending = function(a, b) {
+    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+  };
+  d3.descending = function(a, b) {
+    return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
+  };
+  d3.min = function(array, f) {
+    var i = -1, n = array.length, a, b;
+    if (arguments.length === 1) {
+      while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
+      while (++i < n) if ((b = array[i]) != null && a > b) a = b;
+    } else {
+      while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
+    }
+    return a;
+  };
+  d3.max = function(array, f) {
+    var i = -1, n = array.length, a, b;
+    if (arguments.length === 1) {
+      while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
+      while (++i < n) if ((b = array[i]) != null && b > a) a = b;
+    } else {
+      while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
+    }
+    return a;
+  };
+  d3.extent = function(array, f) {
+    var i = -1, n = array.length, a, b, c;
+    if (arguments.length === 1) {
+      while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined;
+      while (++i < n) if ((b = array[i]) != null) {
+        if (a > b) a = b;
+        if (c < b) c = b;
+      }
+    } else {
+      while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+      while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
+        if (a > b) a = b;
+        if (c < b) c = b;
+      }
+    }
+    return [ a, c ];
+  };
+  d3.sum = function(array, f) {
+    var s = 0, n = array.length, a, i = -1;
+    if (arguments.length === 1) {
+      while (++i < n) if (!isNaN(a = +array[i])) s += a;
+    } else {
+      while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
+    }
+    return s;
+  };
+  function d3_number(x) {
+    return x != null && !isNaN(x);
+  }
+  d3.mean = function(array, f) {
+    var n = array.length, a, m = 0, i = -1, j = 0;
+    if (arguments.length === 1) {
+      while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j;
+    } else {
+      while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
+    }
+    return j ? m : undefined;
+  };
+  d3.quantile = function(values, p) {
+    var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
+    return e ? v + e * (values[h] - v) : v;
+  };
+  d3.median = function(array, f) {
+    if (arguments.length > 1) array = array.map(f);
+    array = array.filter(d3_number);
+    return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined;
+  };
+  d3.bisector = function(f) {
+    return {
+      left: function(a, x, lo, hi) {
+        if (arguments.length < 3) lo = 0;
+        if (arguments.length < 4) hi = a.length;
+        while (lo < hi) {
+          var mid = lo + hi >>> 1;
+          if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid;
+        }
+        return lo;
+      },
+      right: function(a, x, lo, hi) {
+        if (arguments.length < 3) lo = 0;
+        if (arguments.length < 4) hi = a.length;
+        while (lo < hi) {
+          var mid = lo + hi >>> 1;
+          if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1;
+        }
+        return lo;
+      }
+    };
+  };
+  var d3_bisector = d3.bisector(function(d) {
+    return d;
+  });
+  d3.bisectLeft = d3_bisector.left;
+  d3.bisect = d3.bisectRight = d3_bisector.right;
+  d3.shuffle = function(array) {
+    var m = array.length, t, i;
+    while (m) {
+      i = Math.random() * m-- | 0;
+      t = array[m], array[m] = array[i], array[i] = t;
+    }
+    return array;
+  };
+  d3.permute = function(array, indexes) {
+    var i = indexes.length, permutes = new Array(i);
+    while (i--) permutes[i] = array[indexes[i]];
+    return permutes;
+  };
+  d3.pairs = function(array) {
+    var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
+    while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
+    return pairs;
+  };
+  d3.zip = function() {
+    if (!(n = arguments.length)) return [];
+    for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
+      for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
+        zip[j] = arguments[j][i];
+      }
+    }
+    return zips;
+  };
+  function d3_zipLength(d) {
+    return d.length;
+  }
+  d3.transpose = function(matrix) {
+    return d3.zip.apply(d3, matrix);
+  };
+  d3.keys = function(map) {
+    var keys = [];
+    for (var key in map) keys.push(key);
+    return keys;
+  };
+  d3.values = function(map) {
+    var values = [];
+    for (var key in map) values.push(map[key]);
+    return values;
+  };
+  d3.entries = function(map) {
+    var entries = [];
+    for (var key in map) entries.push({
+      key: key,
+      value: map[key]
+    });
+    return entries;
+  };
+  d3.merge = function(arrays) {
+    var n = arrays.length, m, i = -1, j = 0, merged, array;
+    while (++i < n) j += arrays[i].length;
+    merged = new Array(j);
+    while (--n >= 0) {
+      array = arrays[n];
+      m = array.length;
+      while (--m >= 0) {
+        merged[--j] = array[m];
+      }
+    }
+    return merged;
+  };
+  var abs = Math.abs;
+  d3.range = function(start, stop, step) {
+    if (arguments.length < 3) {
+      step = 1;
+      if (arguments.length < 2) {
+        stop = start;
+        start = 0;
+      }
+    }
+    if ((stop - start) / step === Infinity) throw new Error("infinite range");
+    var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
+    start *= k, stop *= k, step *= k;
+    if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
+    return range;
+  };
+  function d3_range_integerScale(x) {
+    var k = 1;
+    while (x * k % 1) k *= 10;
+    return k;
+  }
   function d3_class(ctor, properties) {
     try {
       for (var key in properties) {
@@ -11,60 +230,206 @@
       ctor.prototype = properties;
     }
   }
-  function d3_arrayCopy(pseudoarray) {
-    var i = -1, n = pseudoarray.length, array = [];
-    while (++i < n) array.push(pseudoarray[i]);
-    return array;
+  d3.map = function(object) {
+    var map = new d3_Map();
+    if (object instanceof d3_Map) object.forEach(function(key, value) {
+      map.set(key, value);
+    }); else for (var key in object) map.set(key, object[key]);
+    return map;
+  };
+  function d3_Map() {}
+  d3_class(d3_Map, {
+    has: d3_map_has,
+    get: function(key) {
+      return this[d3_map_prefix + key];
+    },
+    set: function(key, value) {
+      return this[d3_map_prefix + key] = value;
+    },
+    remove: d3_map_remove,
+    keys: d3_map_keys,
+    values: function() {
+      var values = [];
+      this.forEach(function(key, value) {
+        values.push(value);
+      });
+      return values;
+    },
+    entries: function() {
+      var entries = [];
+      this.forEach(function(key, value) {
+        entries.push({
+          key: key,
+          value: value
+        });
+      });
+      return entries;
+    },
+    size: d3_map_size,
+    empty: d3_map_empty,
+    forEach: function(f) {
+      for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]);
+    }
+  });
+  var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
+  function d3_map_has(key) {
+    return d3_map_prefix + key in this;
   }
-  function d3_arraySlice(pseudoarray) {
-    return Array.prototype.slice.call(pseudoarray);
+  function d3_map_remove(key) {
+    key = d3_map_prefix + key;
+    return key in this && delete this[key];
   }
-  function d3_Map() {}
-  function d3_identity(d) {
-    return d;
+  function d3_map_keys() {
+    var keys = [];
+    this.forEach(function(key) {
+      keys.push(key);
+    });
+    return keys;
   }
-  function d3_this() {
-    return this;
+  function d3_map_size() {
+    var size = 0;
+    for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size;
+    return size;
   }
-  function d3_true() {
+  function d3_map_empty() {
+    for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false;
     return true;
   }
-  function d3_functor(v) {
-    return typeof v === "function" ? v : function() {
-      return v;
+  d3.nest = function() {
+    var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
+    function map(mapType, array, depth) {
+      if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
+      var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
+      while (++i < n) {
+        if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
+          values.push(object);
+        } else {
+          valuesByKey.set(keyValue, [ object ]);
+        }
+      }
+      if (mapType) {
+        object = mapType();
+        setter = function(keyValue, values) {
+          object.set(keyValue, map(mapType, values, depth));
+        };
+      } else {
+        object = {};
+        setter = function(keyValue, values) {
+          object[keyValue] = map(mapType, values, depth);
+        };
+      }
+      valuesByKey.forEach(setter);
+      return object;
+    }
+    function entries(map, depth) {
+      if (depth >= keys.length) return map;
+      var array = [], sortKey = sortKeys[depth++];
+      map.forEach(function(key, keyMap) {
+        array.push({
+          key: key,
+          values: entries(keyMap, depth)
+        });
+      });
+      return sortKey ? array.sort(function(a, b) {
+        return sortKey(a.key, b.key);
+      }) : array;
+    }
+    nest.map = function(array, mapType) {
+      return map(mapType, array, 0);
     };
-  }
-  function d3_rebind(target, source, method) {
-    return function() {
-      var value = method.apply(source, arguments);
-      return arguments.length ? target : value;
+    nest.entries = function(array) {
+      return entries(map(d3.map, array, 0), 0);
     };
+    nest.key = function(d) {
+      keys.push(d);
+      return nest;
+    };
+    nest.sortKeys = function(order) {
+      sortKeys[keys.length - 1] = order;
+      return nest;
+    };
+    nest.sortValues = function(order) {
+      sortValues = order;
+      return nest;
+    };
+    nest.rollup = function(f) {
+      rollup = f;
+      return nest;
+    };
+    return nest;
+  };
+  d3.set = function(array) {
+    var set = new d3_Set();
+    if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
+    return set;
+  };
+  function d3_Set() {}
+  d3_class(d3_Set, {
+    has: d3_map_has,
+    add: function(value) {
+      this[d3_map_prefix + value] = true;
+      return value;
+    },
+    remove: function(value) {
+      value = d3_map_prefix + value;
+      return value in this && delete this[value];
+    },
+    values: d3_map_keys,
+    size: d3_map_size,
+    empty: d3_map_empty,
+    forEach: function(f) {
+      for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1));
+    }
+  });
+  d3.behavior = {};
+  d3.rebind = function(target, source) {
+    var i = 1, n = arguments.length, method;
+    while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
+    return target;
+  };
+  function d3_rebind(target, source, method) {
+    return function() {
+      var value = method.apply(source, arguments);
+      return value === source ? target : value;
+    };
+  }
+  function d3_vendorSymbol(object, name) {
+    if (name in object) return name;
+    name = name.charAt(0).toUpperCase() + name.substring(1);
+    for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
+      var prefixName = d3_vendorPrefixes[i] + name;
+      if (prefixName in object) return prefixName;
+    }
   }
-  function d3_number(x) {
-    return x != null && !isNaN(x);
-  }
-  function d3_zipLength(d) {
-    return d.length;
-  }
-  function d3_splitter(d) {
-    return d == null;
-  }
-  function d3_collapse(s) {
-    return s.trim().replace(/\s+/g, " ");
-  }
-  function d3_range_integerScale(x) {
-    var k = 1;
-    while (x * k % 1) k *= 10;
-    return k;
-  }
+  var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
+  function d3_noop() {}
+  d3.dispatch = function() {
+    var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
+    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
+    return dispatch;
+  };
   function d3_dispatch() {}
+  d3_dispatch.prototype.on = function(type, listener) {
+    var i = type.indexOf("."), name = "";
+    if (i >= 0) {
+      name = type.substring(i + 1);
+      type = type.substring(0, i);
+    }
+    if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
+    if (arguments.length === 2) {
+      if (listener == null) for (type in this) {
+        if (this.hasOwnProperty(type)) this[type].on(name, null);
+      }
+      return this;
+    }
+  };
   function d3_dispatch_event(dispatch) {
+    var listeners = [], listenerByName = new d3_Map();
     function event() {
       var z = listeners, i = -1, n = z.length, l;
       while (++i < n) if (l = z[i].on) l.apply(this, arguments);
       return dispatch;
     }
-    var listeners = [], listenerByName = new d3_Map;
     event.on = function(name, listener) {
       var l = listenerByName.get(name), i;
       if (arguments.length < 2) return l && l.on;
@@ -80,82 +445,8 @@
     };
     return event;
   }
-  function d3_format_precision(x, p) {
-    return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1);
-  }
-  function d3_format_typeDefault(x) {
-    return x + "";
-  }
-  function d3_format_group(value) {
-    var i = value.lastIndexOf("."), f = i >= 0 ? value.substring(i) : (i = value.length, ""), t = [];
-    while (i > 0) t.push(value.substring(i -= 3, i + 3));
-    return t.reverse().join(",") + f;
-  }
-  function d3_formatPrefix(d, i) {
-    var k = Math.pow(10, Math.abs(8 - i) * 3);
-    return {
-      scale: i > 8 ? function(d) {
-        return d / k;
-      } : function(d) {
-        return d * k;
-      },
-      symbol: d
-    };
-  }
-  function d3_ease_clamp(f) {
-    return function(t) {
-      return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
-    };
-  }
-  function d3_ease_reverse(f) {
-    return function(t) {
-      return 1 - f(1 - t);
-    };
-  }
-  function d3_ease_reflect(f) {
-    return function(t) {
-      return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
-    };
-  }
-  function d3_ease_identity(t) {
-    return t;
-  }
-  function d3_ease_poly(e) {
-    return function(t) {
-      return Math.pow(t, e);
-    };
-  }
-  function d3_ease_sin(t) {
-    return 1 - Math.cos(t * Math.PI / 2);
-  }
-  function d3_ease_exp(t) {
-    return Math.pow(2, 10 * (t - 1));
-  }
-  function d3_ease_circle(t) {
-    return 1 - Math.sqrt(1 - t * t);
-  }
-  function d3_ease_elastic(a, p) {
-    var s;
-    if (arguments.length < 2) p = .45;
-    if (arguments.length < 1) {
-      a = 1;
-      s = p / 4;
-    } else s = p / (2 * Math.PI) * Math.asin(1 / a);
-    return function(t) {
-      return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
-    };
-  }
-  function d3_ease_back(s) {
-    if (!s) s = 1.70158;
-    return function(t) {
-      return t * t * ((s + 1) * t - s);
-    };
-  }
-  function d3_ease_bounce(t) {
-    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
-  }
-  function d3_eventCancel() {
-    d3.event.stopPropagation();
+  d3.event = null;
+  function d3_eventPreventDefault() {
     d3.event.preventDefault();
   }
   function d3_eventSource() {
@@ -164,7 +455,7 @@
     return e;
   }
   function d3_eventDispatch(target) {
-    var dispatch = new d3_dispatch, i = 0, n = arguments.length;
+    var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
     while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
     dispatch.of = function(thiz, argumentz) {
       return function(e1) {
@@ -180,204 +471,114 @@
     };
     return dispatch;
   }
-  function d3_transform(m) {
-    var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
-    if (r0[0] * r1[1] < r1[0] * r0[1]) {
-      r0[0] *= -1;
-      r0[1] *= -1;
-      kx *= -1;
-      kz *= -1;
-    }
-    this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
-    this.translate = [ m.e, m.f ];
-    this.scale = [ kx, ky ];
-    this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
-  }
-  function d3_transformDot(a, b) {
-    return a[0] * b[0] + a[1] * b[1];
-  }
-  function d3_transformNormalize(a) {
-    var k = Math.sqrt(d3_transformDot(a, a));
-    if (k) {
-      a[0] /= k;
-      a[1] /= k;
-    }
-    return k;
-  }
-  function d3_transformCombine(a, b, k) {
-    a[0] += k * b[0];
-    a[1] += k * b[1];
-    return a;
-  }
-  function d3_interpolateByName(name) {
-    return name == "transform" ? d3.interpolateTransform : d3.interpolate;
+  d3.requote = function(s) {
+    return s.replace(d3_requote_re, "\\$&");
+  };
+  var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
+  var d3_subclass = {}.__proto__ ? function(object, prototype) {
+    object.__proto__ = prototype;
+  } : function(object, prototype) {
+    for (var property in prototype) object[property] = prototype[property];
+  };
+  function d3_selection(groups) {
+    d3_subclass(groups, d3_selectionPrototype);
+    return groups;
   }
-  function d3_uninterpolateNumber(a, b) {
-    b = b - (a = +a) ? 1 / (b - a) : 0;
-    return function(x) {
-      return (x - a) * b;
+  var d3_select = function(s, n) {
+    return n.querySelector(s);
+  }, d3_selectAll = function(s, n) {
+    return n.querySelectorAll(s);
+  }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) {
+    return d3_selectMatcher.call(n, s);
+  };
+  if (typeof Sizzle === "function") {
+    d3_select = function(s, n) {
+      return Sizzle(s, n)[0] || null;
     };
-  }
-  function d3_uninterpolateClamp(a, b) {
-    b = b - (a = +a) ? 1 / (b - a) : 0;
-    return function(x) {
-      return Math.max(0, Math.min(1, (x - a) * b));
+    d3_selectAll = function(s, n) {
+      return Sizzle.uniqueSort(Sizzle(s, n));
     };
+    d3_selectMatches = Sizzle.matchesSelector;
   }
-  function d3_Color() {}
-  function d3_rgb(r, g, b) {
-    return new d3_Rgb(r, g, b);
-  }
-  function d3_Rgb(r, g, b) {
-    this.r = r;
-    this.g = g;
-    this.b = b;
-  }
-  function d3_rgb_hex(v) {
-    return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
-  }
-  function d3_rgb_parse(format, rgb, hsl) {
-    var r = 0, g = 0, b = 0, m1, m2, name;
-    m1 = /([a-z]+)\((.*)\)/i.exec(format);
-    if (m1) {
-      m2 = m1[2].split(",");
-      switch (m1[1]) {
-       case "hsl":
-        {
-          return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
-        }
-       case "rgb":
-        {
-          return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
+  d3.selection = function() {
+    return d3_selectionRoot;
+  };
+  var d3_selectionPrototype = d3.selection.prototype = [];
+  d3_selectionPrototype.select = function(selector) {
+    var subgroups = [], subgroup, subnode, group, node;
+    selector = d3_selection_selector(selector);
+    for (var j = -1, m = this.length; ++j < m; ) {
+      subgroups.push(subgroup = []);
+      subgroup.parentNode = (group = this[j]).parentNode;
+      for (var i = -1, n = group.length; ++i < n; ) {
+        if (node = group[i]) {
+          subgroup.push(subnode = selector.call(node, node.__data__, i, j));
+          if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
+        } else {
+          subgroup.push(null);
         }
       }
     }
-    if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b);
-    if (format != null && format.charAt(0) === "#") {
-      if (format.length === 4) {
-        r = format.charAt(1);
-        r += r;
-        g = format.charAt(2);
-        g += g;
-        b = format.charAt(3);
-        b += b;
-      } else if (format.length === 7) {
-        r = format.substring(1, 3);
-        g = format.substring(3, 5);
-        b = format.substring(5, 7);
-      }
-      r = parseInt(r, 16);
-      g = parseInt(g, 16);
-      b = parseInt(b, 16);
-    }
-    return rgb(r, g, b);
+    return d3_selection(subgroups);
+  };
+  function d3_selection_selector(selector) {
+    return typeof selector === "function" ? selector : function() {
+      return d3_select(selector, this);
+    };
   }
-  function d3_rgb_hsl(r, g, b) {
-    var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
-    if (d) {
-      s = l < .5 ? d / (max + min) : d / (2 - max - min);
-      if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
-      h *= 60;
-    } else {
-      s = h = 0;
+  d3_selectionPrototype.selectAll = function(selector) {
+    var subgroups = [], subgroup, node;
+    selector = d3_selection_selectorAll(selector);
+    for (var j = -1, m = this.length; ++j < m; ) {
+      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
+        if (node = group[i]) {
+          subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));
+          subgroup.parentNode = node;
+        }
+      }
     }
-    return d3_hsl(h, s, l);
+    return d3_selection(subgroups);
+  };
+  function d3_selection_selectorAll(selector) {
+    return typeof selector === "function" ? selector : function() {
+      return d3_selectAll(selector, this);
+    };
   }
-  function d3_rgb_lab(r, g, b) {
-    r = d3_rgb_xyz(r);
-    g = d3_rgb_xyz(g);
-    b = d3_rgb_xyz(b);
-    var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
-    return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
-  }
-  function d3_rgb_xyz(r) {
-    return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
-  }
-  function d3_rgb_parseNumber(c) {
-    var f = parseFloat(c);
-    return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
-  }
-  function d3_hsl(h, s, l) {
-    return new d3_Hsl(h, s, l);
-  }
-  function d3_Hsl(h, s, l) {
-    this.h = h;
-    this.s = s;
-    this.l = l;
-  }
-  function d3_hsl_rgb(h, s, l) {
-    function v(h) {
-      if (h > 360) h -= 360; else if (h < 0) h += 360;
-      if (h < 60) return m1 + (m2 - m1) * h / 60;
-      if (h < 180) return m2;
-      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
-      return m1;
+  var d3_nsPrefix = {
+    svg: "http://www.w3.org/2000/svg",
+    xhtml: "http://www.w3.org/1999/xhtml",
+    xlink: "http://www.w3.org/1999/xlink",
+    xml: "http://www.w3.org/XML/1998/namespace",
+    xmlns: "http://www.w3.org/2000/xmlns/"
+  };
+  d3.ns = {
+    prefix: d3_nsPrefix,
+    qualify: function(name) {
+      var i = name.indexOf(":"), prefix = name;
+      if (i >= 0) {
+        prefix = name.substring(0, i);
+        name = name.substring(i + 1);
+      }
+      return d3_nsPrefix.hasOwnProperty(prefix) ? {
+        space: d3_nsPrefix[prefix],
+        local: name
+      } : name;
     }
-    function vv(h) {
-      return Math.round(v(h) * 255);
+  };
+  d3_selectionPrototype.attr = function(name, value) {
+    if (arguments.length < 2) {
+      if (typeof name === "string") {
+        var node = this.node();
+        name = d3.ns.qualify(name);
+        return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);
+      }
+      for (value in name) this.each(d3_selection_attr(value, name[value]));
+      return this;
     }
-    var m1, m2;
-    h = h % 360;
-    if (h < 0) h += 360;
-    s = s < 0 ? 0 : s > 1 ? 1 : s;
-    l = l < 0 ? 0 : l > 1 ? 1 : l;
-    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
-    m1 = 2 * l - m2;
-    return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
-  }
-  function d3_hcl(h, c, l) {
-    return new d3_Hcl(h, c, l);
-  }
-  function d3_Hcl(h, c, l) {
-    this.h = h;
-    this.c = c;
-    this.l = l;
-  }
-  function d3_hcl_lab(h, c, l) {
-    return d3_lab(l, Math.cos(h *= Math.PI / 180) * c, Math.sin(h) * c);
-  }
-  function d3_lab(l, a, b) {
-    return new d3_Lab(l, a, b);
-  }
-  function d3_Lab(l, a, b) {
-    this.l = l;
-    this.a = a;
-    this.b = b;
-  }
-  function d3_lab_rgb(l, a, b) {
-    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
-    x = d3_lab_xyz(x) * d3_lab_X;
-    y = d3_lab_xyz(y) * d3_lab_Y;
-    z = d3_lab_xyz(z) * d3_lab_Z;
-    return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
-  }
-  function d3_lab_hcl(l, a, b) {
-    return d3_hcl(Math.atan2(b, a) / Math.PI * 180, Math.sqrt(a * a + b * b), l);
-  }
-  function d3_lab_xyz(x) {
-    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
-  }
-  function d3_xyz_lab(x) {
-    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
-  }
-  function d3_xyz_rgb(r) {
-    return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
-  }
-  function d3_selection(groups) {
-    d3_arraySubclass(groups, d3_selectionPrototype);
-    return groups;
-  }
-  function d3_selection_selector(selector) {
-    return function() {
-      return d3_select(selector, this);
-    };
-  }
-  function d3_selection_selectorAll(selector) {
-    return function() {
-      return d3_selectAll(selector, this);
-    };
-  }
+    return this.each(d3_selection_attr(name, value));
+  };
   function d3_selection_attr(name, value) {
+    name = d3.ns.qualify(name);
     function attrNull() {
       this.removeAttribute(name);
     }
@@ -398,13 +599,37 @@
       var x = value.apply(this, arguments);
       if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
     }
-    name = d3.ns.qualify(name);
     return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
   }
+  function d3_collapse(s) {
+    return s.trim().replace(/\s+/g, " ");
+  }
+  d3_selectionPrototype.classed = function(name, value) {
+    if (arguments.length < 2) {
+      if (typeof name === "string") {
+        var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;
+        if (value = node.classList) {
+          while (++i < n) if (!value.contains(name[i])) return false;
+        } else {
+          value = node.getAttribute("class");
+          while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;
+        }
+        return true;
+      }
+      for (value in name) this.each(d3_selection_classed(value, name[value]));
+      return this;
+    }
+    return this.each(d3_selection_classed(name, value));
+  };
   function d3_selection_classedRe(name) {
     return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
   }
+  function d3_selection_classes(name) {
+    return name.trim().split(/^|\s+/);
+  }
   function d3_selection_classed(name, value) {
+    name = d3_selection_classes(name).map(d3_selection_classedName);
+    var n = name.length;
     function classedConstant() {
       var i = -1;
       while (++i < n) name[i](this, value);
@@ -413,27 +638,34 @@
       var i = -1, x = value.apply(this, arguments);
       while (++i < n) name[i](this, x);
     }
-    name = name.trim().split(/\s+/).map(d3_selection_classedName);
-    var n = name.length;
     return typeof value === "function" ? classedFunction : classedConstant;
   }
   function d3_selection_classedName(name) {
     var re = d3_selection_classedRe(name);
     return function(node, value) {
       if (c = node.classList) return value ? c.add(name) : c.remove(name);
-      var c = node.className, cb = c.baseVal != null, cv = cb ? c.baseVal : c;
+      var c = node.getAttribute("class") || "";
       if (value) {
         re.lastIndex = 0;
-        if (!re.test(cv)) {
-          cv = d3_collapse(cv + " " + name);
-          if (cb) c.baseVal = cv; else node.className = cv;
-        }
-      } else if (cv) {
-        cv = d3_collapse(cv.replace(re, " "));
-        if (cb) c.baseVal = cv; else node.className = cv;
+        if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name));
+      } else {
+        node.setAttribute("class", d3_collapse(c.replace(re, " ")));
       }
     };
   }
+  d3_selectionPrototype.style = function(name, value, priority) {
+    var n = arguments.length;
+    if (n < 3) {
+      if (typeof name !== "string") {
+        if (n < 2) value = "";
+        for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
+        return this;
+      }
+      if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name);
+      priority = "";
+    }
+    return this.each(d3_selection_style(name, value, priority));
+  };
   function d3_selection_style(name, value, priority) {
     function styleNull() {
       this.style.removeProperty(name);
@@ -447,6 +679,14 @@
     }
     return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
   }
+  d3_selectionPrototype.property = function(name, value) {
+    if (arguments.length < 2) {
+      if (typeof name === "string") return this.node()[name];
+      for (value in name) this.each(d3_selection_property(value, name[value]));
+      return this;
+    }
+    return this.each(d3_selection_property(name, value));
+  };
   function d3_selection_property(name, value) {
     function propertyNull() {
       delete this[name];
@@ -460,2648 +700,5021 @@
     }
     return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
   }
-  function d3_selection_dataNode(data) {
-    return {
-      __data__: data
-    };
-  }
-  function d3_selection_filter(selector) {
-    return function() {
-      return d3_selectMatches(this, selector);
-    };
-  }
-  function d3_selection_sortComparator(comparator) {
-    if (!arguments.length) comparator = d3.ascending;
-    return function(a, b) {
-      return comparator(a && a.__data__, b && b.__data__);
+  d3_selectionPrototype.text = function(value) {
+    return arguments.length ? this.each(typeof value === "function" ? function() {
+      var v = value.apply(this, arguments);
+      this.textContent = v == null ? "" : v;
+    } : value == null ? function() {
+      this.textContent = "";
+    } : function() {
+      this.textContent = value;
+    }) : this.node().textContent;
+  };
+  d3_selectionPrototype.html = function(value) {
+    return arguments.length ? this.each(typeof value === "function" ? function() {
+      var v = value.apply(this, arguments);
+      this.innerHTML = v == null ? "" : v;
+    } : value == null ? function() {
+      this.innerHTML = "";
+    } : function() {
+      this.innerHTML = value;
+    }) : this.node().innerHTML;
+  };
+  d3_selectionPrototype.append = function(name) {
+    name = d3_selection_creator(name);
+    return this.select(function() {
+      return this.appendChild(name.apply(this, arguments));
+    });
+  };
+  function d3_selection_creator(name) {
+    return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() {
+      return this.ownerDocument.createElementNS(name.space, name.local);
+    } : function() {
+      return this.ownerDocument.createElementNS(this.namespaceURI, name);
     };
   }
-  function d3_selection_on(type, listener, capture) {
-    function onRemove() {
-      var wrapper = this[name];
-      if (wrapper) {
-        this.removeEventListener(type, wrapper, wrapper.$);
-        delete this[name];
-      }
-    }
-    function onAdd() {
-      function wrapper(e) {
-        var o = d3.event;
-        d3.event = e;
-        args[0] = node.__data__;
-        try {
-          listener.apply(node, args);
-        } finally {
-          d3.event = o;
+  d3_selectionPrototype.insert = function(name, before) {
+    name = d3_selection_creator(name);
+    before = d3_selection_selector(before);
+    return this.select(function() {
+      return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
+    });
+  };
+  d3_selectionPrototype.remove = function() {
+    return this.each(function() {
+      var parent = this.parentNode;
+      if (parent) parent.removeChild(this);
+    });
+  };
+  d3_selectionPrototype.data = function(value, key) {
+    var i = -1, n = this.length, group, node;
+    if (!arguments.length) {
+      value = new Array(n = (group = this[0]).length);
+      while (++i < n) {
+        if (node = group[i]) {
+          value[i] = node.__data__;
         }
       }
-      var node = this, args = arguments;
-      onRemove.call(this);
-      this.addEventListener(type, this[name] = wrapper, wrapper.$ = capture);
-      wrapper._ = listener;
-    }
-    var name = "__on" + type, i = type.indexOf(".");
-    if (i > 0) type = type.substring(0, i);
-    return listener ? onAdd : onRemove;
-  }
-  function d3_selection_each(groups, callback) {
-    for (var j = 0, m = groups.length; j < m; j++) {
-      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
-        if (node = group[i]) callback(node, i, j);
-      }
+      return value;
     }
-    return groups;
-  }
-  function d3_selection_enter(selection) {
-    d3_arraySubclass(selection, d3_selection_enterPrototype);
-    return selection;
-  }
-  function d3_transition(groups, id, time) {
-    d3_arraySubclass(groups, d3_transitionPrototype);
-    var tweens = new d3_Map, event = d3.dispatch("start", "end"), ease = d3_transitionEase;
-    groups.id = id;
-    groups.time = time;
-    groups.tween = function(name, tween) {
-      if (arguments.length < 2) return tweens.get(name);
-      if (tween == null) tweens.remove(name); else tweens.set(name, tween);
-      return groups;
-    };
-    groups.ease = function(value) {
-      if (!arguments.length) return ease;
-      ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
-      return groups;
-    };
-    groups.each = function(type, listener) {
-      if (arguments.length < 2) return d3_transition_each.call(groups, type);
-      event.on(type, listener);
-      return groups;
-    };
-    d3.timer(function(elapsed) {
-      return d3_selection_each(groups, function(node, i, j) {
-        function start(elapsed) {
-          if (lock.active > id) return stop();
-          lock.active = id;
-          tweens.forEach(function(key, value) {
-            if (value = value.call(node, d, i)) {
-              tweened.push(value);
-            }
-          });
-          event.start.call(node, d, i);
-          if (!tick(elapsed)) d3.timer(tick, 0, time);
-          return 1;
+    function bind(group, groupData) {
+      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
+      if (key) {
+        var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue;
+        for (i = -1; ++i < n; ) {
+          keyValue = key.call(node = group[i], node.__data__, i);
+          if (nodeByKeyValue.has(keyValue)) {
+            exitNodes[i] = node;
+          } else {
+            nodeByKeyValue.set(keyValue, node);
+          }
+          keyValues.push(keyValue);
         }
-        function tick(elapsed) {
-          if (lock.active !== id) return stop();
-          var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length;
-          while (n > 0) {
-            tweened[--n].call(node, e);
+        for (i = -1; ++i < m; ) {
+          keyValue = key.call(groupData, nodeData = groupData[i], i);
+          if (node = nodeByKeyValue.get(keyValue)) {
+            updateNodes[i] = node;
+            node.__data__ = nodeData;
+          } else if (!dataByKeyValue.has(keyValue)) {
+            enterNodes[i] = d3_selection_dataNode(nodeData);
           }
-          if (t >= 1) {
-            stop();
-            d3_transitionId = id;
-            event.end.call(node, d, i);
-            d3_transitionId = 0;
-            return 1;
+          dataByKeyValue.set(keyValue, nodeData);
+          nodeByKeyValue.remove(keyValue);
+        }
+        for (i = -1; ++i < n; ) {
+          if (nodeByKeyValue.has(keyValues[i])) {
+            exitNodes[i] = group[i];
           }
         }
-        function stop() {
-          if (!--lock.count) delete node.__transition__;
-          return 1;
+      } else {
+        for (i = -1; ++i < n0; ) {
+          node = group[i];
+          nodeData = groupData[i];
+          if (node) {
+            node.__data__ = nodeData;
+            updateNodes[i] = node;
+          } else {
+            enterNodes[i] = d3_selection_dataNode(nodeData);
+          }
         }
-        var tweened = [], delay = node.delay, duration = node.duration, lock = (node = node.node).__transition__ || (node.__transition__ = {
-          active: 0,
-          count: 0
-        }), d = node.__data__;
-        ++lock.count;
-        delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
-      });
-    }, 0, time);
-    return groups;
+        for (;i < m; ++i) {
+          enterNodes[i] = d3_selection_dataNode(groupData[i]);
+        }
+        for (;i < n; ++i) {
+          exitNodes[i] = group[i];
+        }
+      }
+      enterNodes.update = updateNodes;
+      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
+      enter.push(enterNodes);
+      update.push(updateNodes);
+      exit.push(exitNodes);
+    }
+    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
+    if (typeof value === "function") {
+      while (++i < n) {
+        bind(group = this[i], value.call(group, group.parentNode.__data__, i));
+      }
+    } else {
+      while (++i < n) {
+        bind(group = this[i], value);
+      }
+    }
+    update.enter = function() {
+      return enter;
+    };
+    update.exit = function() {
+      return exit;
+    };
+    return update;
+  };
+  function d3_selection_dataNode(data) {
+    return {
+      __data__: data
+    };
+  }
+  d3_selectionPrototype.datum = function(value) {
+    return arguments.length ? this.property("__data__", value) : this.property("__data__");
+  };
+  d3_selectionPrototype.filter = function(filter) {
+    var subgroups = [], subgroup, group, node;
+    if (typeof filter !== "function") filter = d3_selection_filter(filter);
+    for (var j = 0, m = this.length; j < m; j++) {
+      subgroups.push(subgroup = []);
+      subgroup.parentNode = (group = this[j]).parentNode;
+      for (var i = 0, n = group.length; i < n; i++) {
+        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
+          subgroup.push(node);
+        }
+      }
+    }
+    return d3_selection(subgroups);
+  };
+  function d3_selection_filter(selector) {
+    return function() {
+      return d3_selectMatches(this, selector);
+    };
+  }
+  d3_selectionPrototype.order = function() {
+    for (var j = -1, m = this.length; ++j < m; ) {
+      for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
+        if (node = group[i]) {
+          if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
+          next = node;
+        }
+      }
+    }
+    return this;
+  };
+  d3_selectionPrototype.sort = function(comparator) {
+    comparator = d3_selection_sortComparator.apply(this, arguments);
+    for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);
+    return this.order();
+  };
+  function d3_selection_sortComparator(comparator) {
+    if (!arguments.length) comparator = d3.ascending;
+    return function(a, b) {
+      return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
+    };
   }
-  function d3_transition_each(callback) {
-    var id = d3_transitionId, ease = d3_transitionEase, delay = d3_transitionDelay, duration = d3_transitionDuration;
-    d3_transitionId = this.id;
-    d3_transitionEase = this.ease();
-    d3_selection_each(this, function(node, i, j) {
-      d3_transitionDelay = node.delay;
-      d3_transitionDuration = node.duration;
-      callback.call(node = node.node, node.__data__, i, j);
+  d3_selectionPrototype.each = function(callback) {
+    return d3_selection_each(this, function(node, i, j) {
+      callback.call(node, node.__data__, i, j);
     });
-    d3_transitionId = id;
-    d3_transitionEase = ease;
-    d3_transitionDelay = delay;
-    d3_transitionDuration = duration;
+  };
+  function d3_selection_each(groups, callback) {
+    for (var j = 0, m = groups.length; j < m; j++) {
+      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
+        if (node = group[i]) callback(node, i, j);
+      }
+    }
+    return groups;
+  }
+  d3_selectionPrototype.call = function(callback) {
+    var args = d3_array(arguments);
+    callback.apply(args[0] = this, args);
     return this;
+  };
+  d3_selectionPrototype.empty = function() {
+    return !this.node();
+  };
+  d3_selectionPrototype.node = function() {
+    for (var j = 0, m = this.length; j < m; j++) {
+      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
+        var node = group[i];
+        if (node) return node;
+      }
+    }
+    return null;
+  };
+  d3_selectionPrototype.size = function() {
+    var n = 0;
+    this.each(function() {
+      ++n;
+    });
+    return n;
+  };
+  function d3_selection_enter(selection) {
+    d3_subclass(selection, d3_selection_enterPrototype);
+    return selection;
   }
-  function d3_tweenNull(d, i, a) {
-    return a != "" && d3_tweenRemove;
+  var d3_selection_enterPrototype = [];
+  d3.selection.enter = d3_selection_enter;
+  d3.selection.enter.prototype = d3_selection_enterPrototype;
+  d3_selection_enterPrototype.append = d3_selectionPrototype.append;
+  d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
+  d3_selection_enterPrototype.node = d3_selectionPrototype.node;
+  d3_selection_enterPrototype.call = d3_selectionPrototype.call;
+  d3_selection_enterPrototype.size = d3_selectionPrototype.size;
+  d3_selection_enterPrototype.select = function(selector) {
+    var subgroups = [], subgroup, subnode, upgroup, group, node;
+    for (var j = -1, m = this.length; ++j < m; ) {
+      upgroup = (group = this[j]).update;
+      subgroups.push(subgroup = []);
+      subgroup.parentNode = group.parentNode;
+      for (var i = -1, n = group.length; ++i < n; ) {
+        if (node = group[i]) {
+          subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));
+          subnode.__data__ = node.__data__;
+        } else {
+          subgroup.push(null);
+        }
+      }
+    }
+    return d3_selection(subgroups);
+  };
+  d3_selection_enterPrototype.insert = function(name, before) {
+    if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);
+    return d3_selectionPrototype.insert.call(this, name, before);
+  };
+  function d3_selection_enterInsertBefore(enter) {
+    var i0, j0;
+    return function(d, i, j) {
+      var group = enter[j].update, n = group.length, node;
+      if (j != j0) j0 = j, i0 = 0;
+      if (i >= i0) i0 = i + 1;
+      while (!(node = group[i0]) && ++i0 < n) ;
+      return node;
+    };
   }
-  function d3_tweenByName(b, name) {
-    return d3.tween(b, d3_interpolateByName(name));
+  d3_selectionPrototype.transition = function() {
+    var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || {
+      time: Date.now(),
+      ease: d3_ease_cubicInOut,
+      delay: 0,
+      duration: 250
+    };
+    for (var j = -1, m = this.length; ++j < m; ) {
+      subgroups.push(subgroup = []);
+      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
+        if (node = group[i]) d3_transitionNode(node, i, id, transition);
+        subgroup.push(node);
+      }
+    }
+    return d3_transition(subgroups, id);
+  };
+  d3_selectionPrototype.interrupt = function() {
+    return this.each(d3_selection_interrupt);
+  };
+  function d3_selection_interrupt() {
+    var lock = this.__transition__;
+    if (lock) ++lock.active;
   }
-  function d3_timer_step() {
-    var elapsed, now = Date.now(), t1 = d3_timer_queue;
-    while (t1) {
-      elapsed = now - t1.then;
-      if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
-      t1 = t1.next;
+  d3.select = function(node) {
+    var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ];
+    group.parentNode = d3_documentElement;
+    return d3_selection([ group ]);
+  };
+  d3.selectAll = function(nodes) {
+    var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes);
+    group.parentNode = d3_documentElement;
+    return d3_selection([ group ]);
+  };
+  var d3_selectionRoot = d3.select(d3_documentElement);
+  d3_selectionPrototype.on = function(type, listener, capture) {
+    var n = arguments.length;
+    if (n < 3) {
+      if (typeof type !== "string") {
+        if (n < 2) listener = false;
+        for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));
+        return this;
+      }
+      if (n < 2) return (n = this.node()["__on" + type]) && n._;
+      capture = false;
     }
-    var delay = d3_timer_flush() - now;
-    if (delay > 24) {
-      if (isFinite(delay)) {
-        clearTimeout(d3_timer_timeout);
-        d3_timer_timeout = setTimeout(d3_timer_step, delay);
+    return this.each(d3_selection_on(type, listener, capture));
+  };
+  function d3_selection_on(type, listener, capture) {
+    var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener;
+    if (i > 0) type = type.substring(0, i);
+    var filter = d3_selection_onFilters.get(type);
+    if (filter) type = filter, wrap = d3_selection_onFilter;
+    function onRemove() {
+      var l = this[name];
+      if (l) {
+        this.removeEventListener(type, l, l.$);
+        delete this[name];
       }
-      d3_timer_interval = 0;
-    } else {
-      d3_timer_interval = 1;
-      d3_timer_frame(d3_timer_step);
     }
+    function onAdd() {
+      var l = wrap(listener, d3_array(arguments));
+      onRemove.call(this);
+      this.addEventListener(type, this[name] = l, l.$ = capture);
+      l._ = listener;
+    }
+    function removeAll() {
+      var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match;
+      for (var name in this) {
+        if (match = name.match(re)) {
+          var l = this[name];
+          this.removeEventListener(match[1], l, l.$);
+          delete this[name];
+        }
+      }
+    }
+    return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;
   }
-  function d3_timer_flush() {
-    var t0 = null, t1 = d3_timer_queue, then = Infinity;
-    while (t1) {
-      if (t1.flush) {
-        delete d3_timer_byId[t1.callback.id];
-        t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
-      } else {
-        then = Math.min(then, t1.then + t1.delay);
-        t1 = (t0 = t1).next;
+  var d3_selection_onFilters = d3.map({
+    mouseenter: "mouseover",
+    mouseleave: "mouseout"
+  });
+  d3_selection_onFilters.forEach(function(k) {
+    if ("on" + k in d3_document) d3_selection_onFilters.remove(k);
+  });
+  function d3_selection_onListener(listener, argumentz) {
+    return function(e) {
+      var o = d3.event;
+      d3.event = e;
+      argumentz[0] = this.__data__;
+      try {
+        listener.apply(this, argumentz);
+      } finally {
+        d3.event = o;
+      }
+    };
+  }
+  function d3_selection_onFilter(listener, argumentz) {
+    var l = d3_selection_onListener(listener, argumentz);
+    return function(e) {
+      var target = this, related = e.relatedTarget;
+      if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {
+        l.call(target, e);
       }
+    };
+  }
+  var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0;
+  function d3_event_dragSuppress() {
+    var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault);
+    if (d3_event_dragSelect) {
+      var style = d3_documentElement.style, select = style[d3_event_dragSelect];
+      style[d3_event_dragSelect] = "none";
     }
-    return then;
+    return function(suppressClick) {
+      w.on(name, null);
+      if (d3_event_dragSelect) style[d3_event_dragSelect] = select;
+      if (suppressClick) {
+        function off() {
+          w.on(click, null);
+        }
+        w.on(click, function() {
+          d3_eventPreventDefault();
+          off();
+        }, true);
+        setTimeout(off, 0);
+      }
+    };
   }
+  d3.mouse = function(container) {
+    return d3_mousePoint(container, d3_eventSource());
+  };
+  var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0;
   function d3_mousePoint(container, e) {
+    if (e.changedTouches) e = e.changedTouches[0];
     var svg = container.ownerSVGElement || container;
     if (svg.createSVGPoint) {
       var point = svg.createSVGPoint();
-      if (d3_mouse_bug44083 < 0 && (window.scrollX || window.scrollY)) {
-        svg = d3.select(document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0);
+      if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) {
+        svg = d3.select("body").append("svg").style({
+          position: "absolute",
+          top: 0,
+          left: 0,
+          margin: 0,
+          padding: 0,
+          border: "none"
+        }, "important");
         var ctm = svg[0][0].getScreenCTM();
         d3_mouse_bug44083 = !(ctm.f || ctm.e);
         svg.remove();
       }
-      if (d3_mouse_bug44083) {
-        point.x = e.pageX;
-        point.y = e.pageY;
-      } else {
-        point.x = e.clientX;
-        point.y = e.clientY;
-      }
+      if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, 
+      point.y = e.clientY;
       point = point.matrixTransform(container.getScreenCTM().inverse());
       return [ point.x, point.y ];
     }
     var rect = container.getBoundingClientRect();
     return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
   }
-  function d3_noop() {}
-  function d3_scaleExtent(domain) {
-    var start = domain[0], stop = domain[domain.length - 1];
-    return start < stop ? [ start, stop ] : [ stop, start ];
-  }
-  function d3_scaleRange(scale) {
-    return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
-  }
-  function d3_scale_nice(domain, nice) {
-    var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
-    if (x1 < x0) {
-      dx = i0, i0 = i1, i1 = dx;
-      dx = x0, x0 = x1, x1 = dx;
-    }
-    if (nice = nice(x1 - x0)) {
-      domain[i0] = nice.floor(x0);
-      domain[i1] = nice.ceil(x1);
+  d3.touches = function(container, touches) {
+    if (arguments.length < 2) touches = d3_eventSource().touches;
+    return touches ? d3_array(touches).map(function(touch) {
+      var point = d3_mousePoint(container, touch);
+      point.identifier = touch.identifier;
+      return point;
+    }) : [];
+  };
+  d3.behavior.drag = function() {
+    var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), touchstart = dragstart(touchid, touchposition, "touchmove", "touchend");
+    function drag() {
+      this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart);
     }
-    return domain;
-  }
-  function d3_scale_niceDefault() {
-    return Math;
-  }
-  function d3_scale_linear(domain, range, interpolate, clamp) {
-    function rescale() {
-      var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
-      output = linear(domain, range, uninterpolate, interpolate);
-      input = linear(range, domain, uninterpolate, d3.interpolate);
-      return scale;
+    function touchid() {
+      return d3.event.changedTouches[0].identifier;
     }
-    function scale(x) {
-      return output(x);
+    function touchposition(parent, id) {
+      return d3.touches(parent).filter(function(p) {
+        return p.identifier === id;
+      })[0];
     }
-    var output, input;
-    scale.invert = function(y) {
-      return input(y);
-    };
-    scale.domain = function(x) {
-      if (!arguments.length) return domain;
-      domain = x.map(Number);
-      return rescale();
-    };
-    scale.range = function(x) {
-      if (!arguments.length) return range;
-      range = x;
-      return rescale();
-    };
-    scale.rangeRound = function(x) {
-      return scale.range(x).interpolate(d3.interpolateRound);
-    };
-    scale.clamp = function(x) {
-      if (!arguments.length) return clamp;
-      clamp = x;
-      return rescale();
-    };
-    scale.interpolate = function(x) {
-      if (!arguments.length) return interpolate;
-      interpolate = x;
-      return rescale();
-    };
-    scale.ticks = function(m) {
-      return d3_scale_linearTicks(domain, m);
-    };
-    scale.tickFormat = function(m) {
-      return d3_scale_linearTickFormat(domain, m);
-    };
-    scale.nice = function() {
-      d3_scale_nice(domain, d3_scale_linearNice);
-      return rescale();
-    };
-    scale.copy = function() {
-      return d3_scale_linear(domain, range, interpolate, clamp);
+    function dragstart(id, position, move, end) {
+      return function() {
+        var target = this, parent = target.parentNode, event_ = event.of(target, arguments), eventTarget = d3.event.target, eventId = id(), drag = eventId == null ? "drag" : "drag-" + eventId, origin_ = position(parent, eventId), dragged = 0, offset, w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), dragRestore = d3_event_dragSuppress();
+        if (origin) {
+          offset = origin.apply(target, arguments);
+          offset = [ offset.x - origin_[0], offset.y - origin_[1] ];
+        } else {
+          offset = [ 0, 0 ];
+        }
+        event_({
+          type: "dragstart"
+        });
+        function moved() {
+          var p = position(parent, eventId), dx = p[0] - origin_[0], dy = p[1] - origin_[1];
+          dragged |= dx | dy;
+          origin_ = p;
+          event_({
+            type: "drag",
+            x: p[0] + offset[0],
+            y: p[1] + offset[1],
+            dx: dx,
+            dy: dy
+          });
+        }
+        function ended() {
+          w.on(move + "." + drag, null).on(end + "." + drag, null);
+          dragRestore(dragged && d3.event.target === eventTarget);
+          event_({
+            type: "dragend"
+          });
+        }
+      };
+    }
+    drag.origin = function(x) {
+      if (!arguments.length) return origin;
+      origin = x;
+      return drag;
     };
-    return rescale();
+    return d3.rebind(drag, event, "on");
+  };
+  var π = Math.PI, τ = 2 * π, halfπ = π / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π;
+  function d3_sgn(x) {
+    return x > 0 ? 1 : x < 0 ? -1 : 0;
   }
-  function d3_scale_linearRebind(scale, linear) {
-    return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
+  function d3_cross2d(a, b, c) {
+    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
   }
-  function d3_scale_linearNice(dx) {
-    dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
-    return dx && {
-      floor: function(x) {
-        return Math.floor(x / dx) * dx;
-      },
-      ceil: function(x) {
-        return Math.ceil(x / dx) * dx;
-      }
-    };
+  function d3_acos(x) {
+    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
   }
-  function d3_scale_linearTickRange(domain, m) {
-    var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
-    if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
-    extent[0] = Math.ceil(extent[0] / step) * step;
-    extent[1] = Math.floor(extent[1] / step) * step + step * .5;
-    extent[2] = step;
-    return extent;
+  function d3_asin(x) {
+    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
   }
-  function d3_scale_linearTicks(domain, m) {
-    return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
+  function d3_sinh(x) {
+    return ((x = Math.exp(x)) - 1 / x) / 2;
   }
-  function d3_scale_linearTickFormat(domain, m) {
-    return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
+  function d3_cosh(x) {
+    return ((x = Math.exp(x)) + 1 / x) / 2;
   }
-  function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
-    var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
-    return function(x) {
-      return i(u(x));
-    };
+  function d3_tanh(x) {
+    return ((x = Math.exp(2 * x)) - 1) / (x + 1);
   }
-  function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
-    var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
-    if (domain[k] < domain[0]) {
-      domain = domain.slice().reverse();
-      range = range.slice().reverse();
-    }
-    while (++j <= k) {
-      u.push(uninterpolate(domain[j - 1], domain[j]));
-      i.push(interpolate(range[j - 1], range[j]));
-    }
-    return function(x) {
-      var j = d3.bisect(domain, x, 1, k) - 1;
-      return i[j](u[j](x));
-    };
+  function d3_haversin(x) {
+    return (x = Math.sin(x / 2)) * x;
   }
-  function d3_scale_log(linear, log) {
-    function scale(x) {
-      return linear(log(x));
+  var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
+  d3.interpolateZoom = function(p0, p1) {
+    var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
+    var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ;
+    function interpolate(t) {
+      var s = t * S;
+      if (dr) {
+        var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
+        return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
+      }
+      return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ];
     }
-    var pow = log.pow;
-    scale.invert = function(x) {
-      return pow(linear.invert(x));
-    };
-    scale.domain = function(x) {
-      if (!arguments.length) return linear.domain().map(pow);
-      log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
-      pow = log.pow;
-      linear.domain(x.map(log));
-      return scale;
-    };
-    scale.nice = function() {
-      linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
-      return scale;
-    };
-    scale.ticks = function() {
-      var extent = d3_scaleExtent(linear.domain()), ticks = [];
-      if (extent.every(isFinite)) {
-        var i = Math.floor(extent[0]), j = Math.ceil(extent[1]), u = pow(extent[0]), v = pow(extent[1]);
-        if (log === d3_scale_logn) {
-          ticks.push(pow(i));
-          for (; i++ < j; ) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
+    interpolate.duration = S * 1e3;
+    return interpolate;
+  };
+  d3.behavior.zoom = function() {
+    var view = {
+      x: 0,
+      y: 0,
+      k: 1
+    }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
+    function zoom(g) {
+      g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
+    }
+    zoom.event = function(g) {
+      g.each(function() {
+        var event_ = event.of(this, arguments), view1 = view;
+        if (d3_transitionInheritId) {
+          d3.select(this).transition().each("start.zoom", function() {
+            view = this.__chart__ || {
+              x: 0,
+              y: 0,
+              k: 1
+            };
+            zoomstarted(event_);
+          }).tween("zoom:zoom", function() {
+            var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
+            return function(t) {
+              var l = i(t), k = dx / l[2];
+              this.__chart__ = view = {
+                x: cx - l[0] * k,
+                y: cy - l[1] * k,
+                k: k
+              };
+              zoomed(event_);
+            };
+          }).each("end.zoom", function() {
+            zoomended(event_);
+          });
         } else {
-          for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
-          ticks.push(pow(i));
+          this.__chart__ = view;
+          zoomstarted(event_);
+          zoomed(event_);
+          zoomended(event_);
         }
-        for (i = 0; ticks[i] < u; i++) {}
-        for (j = ticks.length; ticks[j - 1] > v; j--) {}
-        ticks = ticks.slice(i, j);
-      }
-      return ticks;
-    };
-    scale.tickFormat = function(n, format) {
-      if (arguments.length < 2) format = d3_scale_logFormat;
-      if (arguments.length < 1) return format;
-      var k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil), e;
-      return function(d) {
-        return d / pow(f(log(d) + e)) <= k ? format(d) : "";
-      };
-    };
-    scale.copy = function() {
-      return d3_scale_log(linear.copy(), log);
-    };
-    return d3_scale_linearRebind(scale, linear);
-  }
-  function d3_scale_logp(x) {
-    return Math.log(x < 0 ? 0 : x) / Math.LN10;
-  }
-  function d3_scale_logn(x) {
-    return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
-  }
-  function d3_scale_pow(linear, exponent) {
-    function scale(x) {
-      return linear(powp(x));
-    }
-    var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
-    scale.invert = function(x) {
-      return powb(linear.invert(x));
-    };
-    scale.domain = function(x) {
-      if (!arguments.length) return linear.domain().map(powb);
-      linear.domain(x.map(powp));
-      return scale;
-    };
-    scale.ticks = function(m) {
-      return d3_scale_linearTicks(scale.domain(), m);
-    };
-    scale.tickFormat = function(m) {
-      return d3_scale_linearTickFormat(scale.domain(), m);
-    };
-    scale.nice = function() {
-      return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
-    };
-    scale.exponent = function(x) {
-      if (!arguments.length) return exponent;
-      var domain = scale.domain();
-      powp = d3_scale_powPow(exponent = x);
-      powb = d3_scale_powPow(1 / exponent);
-      return scale.domain(domain);
-    };
-    scale.copy = function() {
-      return d3_scale_pow(linear.copy(), exponent);
-    };
-    return d3_scale_linearRebind(scale, linear);
-  }
-  function d3_scale_powPow(e) {
-    return function(x) {
-      return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
-    };
-  }
-  function d3_scale_ordinal(domain, ranger) {
-    function scale(x) {
-      return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length];
-    }
-    function steps(start, step) {
-      return d3.range(domain.length).map(function(i) {
-        return start + step * i;
       });
-    }
-    var index, range, rangeBand;
-    scale.domain = function(x) {
-      if (!arguments.length) return domain;
-      domain = [];
-      index = new d3_Map;
-      var i = -1, n = x.length, xi;
-      while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
-      return scale[ranger.t].apply(scale, ranger.a);
     };
-    scale.range = function(x) {
-      if (!arguments.length) return range;
-      range = x;
-      rangeBand = 0;
-      ranger = {
-        t: "range",
-        a: arguments
+    zoom.translate = function(_) {
+      if (!arguments.length) return [ view.x, view.y ];
+      view = {
+        x: +_[0],
+        y: +_[1],
+        k: view.k
       };
-      return scale;
+      rescale();
+      return zoom;
     };
-    scale.rangePoints = function(x, padding) {
-      if (arguments.length < 2) padding = 0;
-      var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding);
-      range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
-      rangeBand = 0;
-      ranger = {
-        t: "rangePoints",
-        a: arguments
+    zoom.scale = function(_) {
+      if (!arguments.length) return view.k;
+      view = {
+        x: view.x,
+        y: view.y,
+        k: +_
       };
-      return scale;
+      rescale();
+      return zoom;
     };
-    scale.rangeBands = function(x, padding, outerPadding) {
-      if (arguments.length < 2) padding = 0;
-      if (arguments.length < 3) outerPadding = padding;
-      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
-      range = steps(start + step * outerPadding, step);
-      if (reverse) range.reverse();
-      rangeBand = step * (1 - padding);
-      ranger = {
-        t: "rangeBands",
-        a: arguments
-      };
-      return scale;
+    zoom.scaleExtent = function(_) {
+      if (!arguments.length) return scaleExtent;
+      scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];
+      return zoom;
     };
-    scale.rangeRoundBands = function(x, padding, outerPadding) {
-      if (arguments.length < 2) padding = 0;
-      if (arguments.length < 3) outerPadding = padding;
-      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step;
-      range = steps(start + Math.round(error / 2), step);
-      if (reverse) range.reverse();
-      rangeBand = Math.round(step * (1 - padding));
-      ranger = {
-        t: "rangeRoundBands",
-        a: arguments
-      };
-      return scale;
+    zoom.center = function(_) {
+      if (!arguments.length) return center;
+      center = _ && [ +_[0], +_[1] ];
+      return zoom;
     };
-    scale.rangeBand = function() {
-      return rangeBand;
+    zoom.size = function(_) {
+      if (!arguments.length) return size;
+      size = _ && [ +_[0], +_[1] ];
+      return zoom;
     };
-    scale.rangeExtent = function() {
-      return d3_scaleExtent(ranger.a[0]);
+    zoom.x = function(z) {
+      if (!arguments.length) return x1;
+      x1 = z;
+      x0 = z.copy();
+      view = {
+        x: 0,
+        y: 0,
+        k: 1
+      };
+      return zoom;
     };
-    scale.copy = function() {
-      return d3_scale_ordinal(domain, ranger);
+    zoom.y = function(z) {
+      if (!arguments.length) return y1;
+      y1 = z;
+      y0 = z.copy();
+      view = {
+        x: 0,
+        y: 0,
+        k: 1
+      };
+      return zoom;
     };
-    return scale.domain(domain);
-  }
-  function d3_scale_quantile(domain, range) {
+    function location(p) {
+      return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];
+    }
+    function point(l) {
+      return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];
+    }
+    function scaleTo(s) {
+      view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
+    }
+    function translateTo(p, l) {
+      l = point(l);
+      view.x += p[0] - l[0];
+      view.y += p[1] - l[1];
+    }
     function rescale() {
-      var k = 0, n = domain.length, q = range.length;
-      thresholds = [];
-      while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
-      return scale;
+      if (x1) x1.domain(x0.range().map(function(x) {
+        return (x - view.x) / view.k;
+      }).map(x0.invert));
+      if (y1) y1.domain(y0.range().map(function(y) {
+        return (y - view.y) / view.k;
+      }).map(y0.invert));
     }
-    function scale(x) {
-      if (isNaN(x = +x)) return NaN;
-      return range[d3.bisect(thresholds, x)];
+    function zoomstarted(event) {
+      event({
+        type: "zoomstart"
+      });
     }
-    var thresholds;
-    scale.domain = function(x) {
-      if (!arguments.length) return domain;
-      domain = x.filter(function(d) {
-        return !isNaN(d);
-      }).sort(d3.ascending);
-      return rescale();
-    };
-    scale.range = function(x) {
-      if (!arguments.length) return range;
-      range = x;
-      return rescale();
-    };
-    scale.quantiles = function() {
-      return thresholds;
-    };
-    scale.copy = function() {
-      return d3_scale_quantile(domain, range);
-    };
-    return rescale();
-  }
-  function d3_scale_quantize(x0, x1, range) {
-    function scale(x) {
-      return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
-    }
-    function rescale() {
-      kx = range.length / (x1 - x0);
-      i = range.length - 1;
-      return scale;
-    }
-    var kx, i;
-    scale.domain = function(x) {
-      if (!arguments.length) return [ x0, x1 ];
-      x0 = +x[0];
-      x1 = +x[x.length - 1];
-      return rescale();
-    };
-    scale.range = function(x) {
-      if (!arguments.length) return range;
-      range = x;
-      return rescale();
-    };
-    scale.copy = function() {
-      return d3_scale_quantize(x0, x1, range);
-    };
-    return rescale();
-  }
-  function d3_scale_threshold(domain, range) {
-    function scale(x) {
-      return range[d3.bisect(domain, x)];
+    function zoomed(event) {
+      rescale();
+      event({
+        type: "zoom",
+        scale: view.k,
+        translate: [ view.x, view.y ]
+      });
     }
-    scale.domain = function(_) {
-      if (!arguments.length) return domain;
-      domain = _;
-      return scale;
-    };
-    scale.range = function(_) {
-      if (!arguments.length) return range;
-      range = _;
-      return scale;
-    };
-    scale.copy = function() {
-      return d3_scale_threshold(domain, range);
-    };
-    return scale;
-  }
-  function d3_scale_identity(domain) {
-    function identity(x) {
-      return +x;
+    function zoomended(event) {
+      event({
+        type: "zoomend"
+      });
     }
-    identity.invert = identity;
-    identity.domain = identity.range = function(x) {
-      if (!arguments.length) return domain;
-      domain = x.map(identity);
-      return identity;
-    };
-    identity.ticks = function(m) {
-      return d3_scale_linearTicks(domain, m);
-    };
-    identity.tickFormat = function(m) {
-      return d3_scale_linearTickFormat(domain, m);
-    };
-    identity.copy = function() {
-      return d3_scale_identity(domain);
-    };
-    return identity;
-  }
-  function d3_svg_arcInnerRadius(d) {
-    return d.innerRadius;
-  }
-  function d3_svg_arcOuterRadius(d) {
-    return d.outerRadius;
-  }
-  function d3_svg_arcStartAngle(d) {
-    return d.startAngle;
-  }
-  function d3_svg_arcEndAngle(d) {
-    return d.endAngle;
-  }
-  function d3_svg_line(projection) {
-    function line(data) {
-      function segment() {
-        segments.push("M", interpolate(projection(points), tension));
+    function mousedowned() {
+      var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress();
+      d3_selection_interrupt.call(target);
+      zoomstarted(event_);
+      function moved() {
+        dragged = 1;
+        translateTo(d3.mouse(target), l);
+        zoomed(event_);
+      }
+      function ended() {
+        w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null);
+        dragRestore(dragged && d3.event.target === eventTarget);
+        zoomended(event_);
+      }
+    }
+    function touchstarted() {
+      var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
+      d3_selection_interrupt.call(target);
+      started();
+      zoomstarted(event_);
+      function relocate() {
+        var touches = d3.touches(target);
+        scale0 = view.k;
+        touches.forEach(function(t) {
+          if (t.identifier in locations0) locations0[t.identifier] = location(t);
+        });
+        return touches;
       }
-      var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
-      while (++i < n) {
-        if (defined.call(this, d = data[i], i)) {
-          points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
-        } else if (points.length) {
-          segment();
-          points = [];
+      function started() {
+        var changed = d3.event.changedTouches;
+        for (var i = 0, n = changed.length; i < n; ++i) {
+          locations0[changed[i].identifier] = null;
+        }
+        var touches = relocate(), now = Date.now();
+        if (touches.length === 1) {
+          if (now - touchtime < 500) {
+            var p = touches[0], l = locations0[p.identifier];
+            scaleTo(view.k * 2);
+            translateTo(p, l);
+            d3_eventPreventDefault();
+            zoomed(event_);
+          }
+          touchtime = now;
+        } else if (touches.length > 1) {
+          var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
+          distance0 = dx * dx + dy * dy;
         }
       }
-      if (points.length) segment();
-      return segments.length ? segments.join("") : null;
+      function moved() {
+        var touches = d3.touches(target), p0, l0, p1, l1;
+        for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
+          p1 = touches[i];
+          if (l1 = locations0[p1.identifier]) {
+            if (l0) break;
+            p0 = p1, l0 = l1;
+          }
+        }
+        if (l1) {
+          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
+          p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
+          l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
+          scaleTo(scale1 * scale0);
+        }
+        touchtime = null;
+        translateTo(p0, l0);
+        zoomed(event_);
+      }
+      function ended() {
+        if (d3.event.touches.length) {
+          var changed = d3.event.changedTouches;
+          for (var i = 0, n = changed.length; i < n; ++i) {
+            delete locations0[changed[i].identifier];
+          }
+          for (var identifier in locations0) {
+            return void relocate();
+          }
+        }
+        w.on(touchmove, null).on(touchend, null);
+        t.on(mousedown, mousedowned).on(touchstart, touchstarted);
+        dragRestore();
+        zoomended(event_);
+      }
+    }
+    function mousewheeled() {
+      var event_ = event.of(this, arguments);
+      if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), 
+      zoomstarted(event_);
+      mousewheelTimer = setTimeout(function() {
+        mousewheelTimer = null;
+        zoomended(event_);
+      }, 50);
+      d3_eventPreventDefault();
+      var point = center || d3.mouse(this);
+      if (!translate0) translate0 = location(point);
+      scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
+      translateTo(point, translate0);
+      zoomed(event_);
+    }
+    function mousewheelreset() {
+      translate0 = null;
     }
-    var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
-    line.x = function(_) {
-      if (!arguments.length) return x;
-      x = _;
-      return line;
-    };
-    line.y = function(_) {
-      if (!arguments.length) return y;
-      y = _;
-      return line;
-    };
-    line.defined = function(_) {
-      if (!arguments.length) return defined;
-      defined = _;
-      return line;
-    };
-    line.interpolate = function(_) {
-      if (!arguments.length) return interpolateKey;
-      if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
-      return line;
-    };
-    line.tension = function(_) {
-      if (!arguments.length) return tension;
-      tension = _;
-      return line;
-    };
-    return line;
+    function dblclicked() {
+      var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2;
+      zoomstarted(event_);
+      scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
+      translateTo(p, l);
+      zoomed(event_);
+      zoomended(event_);
+    }
+    return d3.rebind(zoom, event, "on");
+  };
+  var d3_behavior_zoomInfinity = [ 0, Infinity ];
+  var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() {
+    return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);
+  }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() {
+    return d3.event.wheelDelta;
+  }, "mousewheel") : (d3_behavior_zoomDelta = function() {
+    return -d3.event.detail;
+  }, "MozMousePixelScroll");
+  function d3_Color() {}
+  d3_Color.prototype.toString = function() {
+    return this.rgb() + "";
+  };
+  d3.hsl = function(h, s, l) {
+    return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l);
+  };
+  function d3_hsl(h, s, l) {
+    return new d3_Hsl(h, s, l);
   }
-  function d3_svg_lineX(d) {
-    return d[0];
+  function d3_Hsl(h, s, l) {
+    this.h = h;
+    this.s = s;
+    this.l = l;
   }
-  function d3_svg_lineY(d) {
-    return d[1];
+  var d3_hslPrototype = d3_Hsl.prototype = new d3_Color();
+  d3_hslPrototype.brighter = function(k) {
+    k = Math.pow(.7, arguments.length ? k : 1);
+    return d3_hsl(this.h, this.s, this.l / k);
+  };
+  d3_hslPrototype.darker = function(k) {
+    k = Math.pow(.7, arguments.length ? k : 1);
+    return d3_hsl(this.h, this.s, k * this.l);
+  };
+  d3_hslPrototype.rgb = function() {
+    return d3_hsl_rgb(this.h, this.s, this.l);
+  };
+  function d3_hsl_rgb(h, s, l) {
+    var m1, m2;
+    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
+    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
+    l = l < 0 ? 0 : l > 1 ? 1 : l;
+    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
+    m1 = 2 * l - m2;
+    function v(h) {
+      if (h > 360) h -= 360; else if (h < 0) h += 360;
+      if (h < 60) return m1 + (m2 - m1) * h / 60;
+      if (h < 180) return m2;
+      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
+      return m1;
+    }
+    function vv(h) {
+      return Math.round(v(h) * 255);
+    }
+    return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
   }
-  function d3_svg_lineLinear(points) {
-    return points.join("L");
+  d3.hcl = function(h, c, l) {
+    return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l);
+  };
+  function d3_hcl(h, c, l) {
+    return new d3_Hcl(h, c, l);
   }
-  function d3_svg_lineLinearClosed(points) {
-    return d3_svg_lineLinear(points) + "Z";
+  function d3_Hcl(h, c, l) {
+    this.h = h;
+    this.c = c;
+    this.l = l;
   }
-  function d3_svg_lineStepBefore(points) {
-    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
-    while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
-    return path.join("");
+  var d3_hclPrototype = d3_Hcl.prototype = new d3_Color();
+  d3_hclPrototype.brighter = function(k) {
+    return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
+  };
+  d3_hclPrototype.darker = function(k) {
+    return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
+  };
+  d3_hclPrototype.rgb = function() {
+    return d3_hcl_lab(this.h, this.c, this.l).rgb();
+  };
+  function d3_hcl_lab(h, c, l) {
+    if (isNaN(h)) h = 0;
+    if (isNaN(c)) c = 0;
+    return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);
   }
-  function d3_svg_lineStepAfter(points) {
-    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
-    while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
-    return path.join("");
+  d3.lab = function(l, a, b) {
+    return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b);
+  };
+  function d3_lab(l, a, b) {
+    return new d3_Lab(l, a, b);
   }
-  function d3_svg_lineCardinalOpen(points, tension) {
-    return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension));
+  function d3_Lab(l, a, b) {
+    this.l = l;
+    this.a = a;
+    this.b = b;
   }
-  function d3_svg_lineCardinalClosed(points, tension) {
-    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
+  var d3_lab_K = 18;
+  var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;
+  var d3_labPrototype = d3_Lab.prototype = new d3_Color();
+  d3_labPrototype.brighter = function(k) {
+    return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
+  };
+  d3_labPrototype.darker = function(k) {
+    return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
+  };
+  d3_labPrototype.rgb = function() {
+    return d3_lab_rgb(this.l, this.a, this.b);
+  };
+  function d3_lab_rgb(l, a, b) {
+    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
+    x = d3_lab_xyz(x) * d3_lab_X;
+    y = d3_lab_xyz(y) * d3_lab_Y;
+    z = d3_lab_xyz(z) * d3_lab_Z;
+    return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
   }
-  function d3_svg_lineCardinal(points, tension, closed) {
-    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
+  function d3_lab_hcl(l, a, b) {
+    return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l);
   }
-  function d3_svg_lineHermite(points, tangents) {
-    if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
-      return d3_svg_lineLinear(points);
-    }
-    var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
-    if (quad) {
-      path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
-      p0 = points[1];
-      pi = 2;
-    }
-    if (tangents.length > 1) {
-      t = tangents[1];
-      p = points[pi];
-      pi++;
-      path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
-      for (var i = 2; i < tangents.length; i++, pi++) {
-        p = points[pi];
-        t = tangents[i];
-        path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
-      }
-    }
-    if (quad) {
-      var lp = points[pi];
-      path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
-    }
-    return path;
+  function d3_lab_xyz(x) {
+    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
   }
-  function d3_svg_lineCardinalTangents(points, tension) {
-    var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
-    while (++i < n) {
-      p0 = p1;
-      p1 = p2;
-      p2 = points[i];
-      tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
-    }
-    return tangents;
+  function d3_xyz_lab(x) {
+    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
   }
-  function d3_svg_lineBasis(points) {
-    if (points.length < 3) return d3_svg_lineLinear(points);
-    var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0 ];
-    d3_svg_lineBasisBezier(path, px, py);
-    while (++i < n) {
-      pi = points[i];
-      px.shift();
-      px.push(pi[0]);
-      py.shift();
-      py.push(pi[1]);
-      d3_svg_lineBasisBezier(path, px, py);
-    }
-    i = -1;
-    while (++i < 2) {
-      px.shift();
-      px.push(pi[0]);
-      py.shift();
-      py.push(pi[1]);
-      d3_svg_lineB

<TRUNCATED>

[08/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: fix intendation


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e7763dfb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e7763dfb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e7763dfb

Branch: refs/heads/Update-Sidebar-Ui
Commit: e7763dfb2d2ad8119ee883002e60ec7edde791c7
Parents: f2153c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:25:17 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:27:50 2014 +0100

----------------------------------------------------------------------
 src/fauxton/app/addons/config/views.js | 37 +++++++++++++++--------------
 1 file changed, 19 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e7763dfb/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 8453d90..9f427ac 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -81,27 +81,28 @@ function(app, FauxtonAPI, Config, Components) {
     },
     saveAndRender: function (event) {
       var options = {};
-        $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
-        options[$input.attr('name')] = $input.val();
-
-        if ($input.attr('name')==='name'){
-          if (this.uniqueName($input.val())){
-            this.error = FauxtonAPI.addNotification({
-                msg: "This config already exists, enter a unique name",
-                type: "error",
-                clear: true
-            });
-          } else {
-            var newModel = this.model.clone();
-              newModel.save(options);
-              this.model.destroy();
-              this.model = newModel;
-              this.render();
-          }
+          $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
+
+      options[$input.attr('name')] = $input.val();
+
+      if ($input.attr('name')==='name'){
+        if (this.uniqueName($input.val())){
+          this.error = FauxtonAPI.addNotification({
+            msg: "This config already exists, enter a unique name",
+            type: "error",
+            clear: true
+          });
         } else {
+          var newModel = this.model.clone();
+          newModel.save(options);
+          this.model.destroy();
+          this.model = newModel;
+          this.render();
+        }
+      } else {
         this.model.save(options);
         this.render();
-        }
+      }
     }
 
   });


[18/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: Redirected to correct page after login

Fixes COUCHDB-2209


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/198bea34
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/198bea34
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/198bea34

Branch: refs/heads/Update-Sidebar-Ui
Commit: 198bea3479dfecac13ab1a3e95f902b8eba02f7d
Parents: 0f7be28
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Mar 25 17:54:33 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Mar 25 17:54:33 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/auth/base.js             |  3 ++-
 src/fauxton/app/addons/auth/resources.js        | 21 +++++++++++++++++++-
 src/fauxton/app/addons/auth/routes.js           | 13 ++++++++++--
 .../app/addons/auth/templates/noAccess.html     |  4 +++-
 src/fauxton/app/core/auth.js                    |  2 --
 5 files changed, 36 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
index c7bbb04..b8545fc 100644
--- a/src/fauxton/app/addons/auth/base.js
+++ b/src/fauxton/app/addons/auth/base.js
@@ -52,7 +52,8 @@ function(app, FauxtonAPI, Auth) {
     };
 
     var authDenied = function () {
-      FauxtonAPI.navigate('/noAccess', {replace: true});
+      var url = window.location.hash.replace('#','');
+      FauxtonAPI.navigate('/noAccess?urlback=' + url, {replace: true});
     };
 
     FauxtonAPI.auth.registerAuth(auth);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index 71744e3..edfd708 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -252,6 +252,9 @@ function (app, FauxtonAPI, CouchdbSession) {
 
   Auth.LoginView = FauxtonAPI.View.extend({
     template: 'addons/auth/templates/login',
+    initialize: function (options) {
+      this.urlBack = options.urlBack || "";
+    },
 
     events: {
       "submit #login": "login"
@@ -263,10 +266,16 @@ function (app, FauxtonAPI, CouchdbSession) {
       var that = this,
           username = this.$('#username').val(),
           password = this.$('#password').val(),
+          urlBack = this.urlBack,
           promise = this.model.login(username, password);
 
       promise.then(function () {
         FauxtonAPI.addNotification({msg:  FauxtonAPI.session.messages.loggedIn });
+
+        if (urlBack) {
+          return FauxtonAPI.navigate(urlBack);
+        }
+
         FauxtonAPI.navigate('/');
       });
 
@@ -346,7 +355,17 @@ function (app, FauxtonAPI, CouchdbSession) {
   });
 
   Auth.NoAccessView = FauxtonAPI.View.extend({
-    template: "addons/auth/templates/noAccess"
+    template: "addons/auth/templates/noAccess",
+
+    initialize: function (options) {
+      this.urlBack = options.urlBack || "";
+    },
+
+    serialize: function () {
+      return {
+        urlBack: this.urlBack
+      };
+    }
   });
 
   return Auth;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/routes.js b/src/fauxton/app/addons/auth/routes.js
index fe40a77..74395e8 100644
--- a/src/fauxton/app/addons/auth/routes.js
+++ b/src/fauxton/app/addons/auth/routes.js
@@ -21,15 +21,21 @@ function(app, FauxtonAPI, Auth) {
     layout: 'one_pane',
 
     routes: {
+      'login?*extra': 'login',
       'login': 'login',
       'logout': 'logout',
       'createAdmin': 'createAdmin',
+      'noAccess?*extra': 'noAccess',
       'noAccess': 'noAccess'
     },
 
     login: function () {
+      var urlBack = app.getParams().urlback;
       this.crumbs = [{name: 'Login', link:"#"}];
-      this.setView('#dashboard-content', new Auth.LoginView({model: FauxtonAPI.session}));
+      this.setView('#dashboard-content', new Auth.LoginView({
+        model: FauxtonAPI.session,
+        urlBack: urlBack
+      }));
     },
 
     logout: function () {
@@ -50,8 +56,11 @@ function(app, FauxtonAPI, Auth) {
     },
 
     noAccess: function () {
+      var urlBack = app.getParams().urlback;
       this.crumbs = [{name: 'Access Denied', link:"#"}];
-      this.setView('#dashboard-content', new Auth.NoAccessView());
+      this.setView('#dashboard-content', new Auth.NoAccessView({
+        urlBack: urlBack
+      }));
       this.apiUrl = 'noAccess';
     },
   });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/templates/noAccess.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/noAccess.html b/src/fauxton/app/addons/auth/templates/noAccess.html
index ceff992..ffa736e 100644
--- a/src/fauxton/app/addons/auth/templates/noAccess.html
+++ b/src/fauxton/app/addons/auth/templates/noAccess.html
@@ -15,6 +15,8 @@ the License.
 
 <div class="span12">
   <h2> Access Denied </h2>
-  <p> You do not have permission to view this page. <br/> You might need to <a href="#login"> login </a> to view this page/ </p>
+  <p> You do not have permission to view this page. <br/> 
+  You might need to <a href="#login<% if (urlBack){ %>?urlback=<%=urlBack%>  <% } %> "> login </a> to view this page/ 
+ </p>
   
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/core/auth.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/auth.js b/src/fauxton/app/core/auth.js
index 15cf566..19e4a8c 100644
--- a/src/fauxton/app/core/auth.js
+++ b/src/fauxton/app/core/auth.js
@@ -60,8 +60,6 @@ function(FauxtonAPI, Backbone) {
     }
   });
 
-//  FauxtonAPI.auth = new Auth();
-
   return Auth;
 });
 


[25/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Require.js config to support d3 v3 update.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/6301060f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/6301060f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/6301060f

Branch: refs/heads/Update-Sidebar-Ui
Commit: 6301060fdbb9d5505ffd43f8b0df52b6c303b6ef
Parents: 95d6d6b
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 15:02:28 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400

----------------------------------------------------------------------
 src/fauxton/app/config.js | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6301060f/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 98be9c6..d33f3b8 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -53,6 +53,8 @@ require.config({
       deps: ["jquery"],
       exports: "Bootstrap"
     },
+    
+    "nv.d3": ["d3.global"],
 
     "plugins/prettify": [],
     "plugins/beautify": [],
@@ -60,3 +62,9 @@ require.config({
     "plugins/jquery.form": ["jquery"]
   }
 });
+
+define("d3.global", ["d3"], function(_) {
+  d3 = _;
+});
+
+require(["d3", "nv.d3"], function(d3, nvd3) {});


[09/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Fauxton: fix global var


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ca5913ed
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ca5913ed
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ca5913ed

Branch: refs/heads/Update-Sidebar-Ui
Commit: ca5913eda5cb2d70d38ed7ed286bfd835a2b303d
Parents: e7763df
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:25:52 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:27:58 2014 +0100

----------------------------------------------------------------------
 src/fauxton/app/addons/config/views.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ca5913ed/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 9f427ac..7952182 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -80,7 +80,7 @@ function(app, FauxtonAPI, Config, Components) {
       return {option: this.model.toJSON()};
     },
     saveAndRender: function (event) {
-      var options = {};
+      var options = {},
           $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
 
       options[$input.attr('name')] = $input.val();


[23/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
Updating pie chart to reflect nvd3's removal of pie.values(), tweaking CSS to make pie chart fit all nice like.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7296e53c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7296e53c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7296e53c

Branch: refs/heads/Update-Sidebar-Ui
Commit: 7296e53c8dcd5d69d83bd04a4421887390c06816
Parents: b125530
Author: Christian Hogan <gi...@infliction.org>
Authored: Tue Mar 25 14:43:36 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400

----------------------------------------------------------------------
 src/fauxton/app/addons/stats/assets/less/stats.less   | 5 +++++
 src/fauxton/app/addons/stats/templates/pie_table.html | 6 +++++-
 src/fauxton/app/addons/stats/views.js                 | 7 +++----
 3 files changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/assets/less/stats.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/assets/less/stats.less b/src/fauxton/app/addons/stats/assets/less/stats.less
index 7ec88b9..43ddb3b 100644
--- a/src/fauxton/app/addons/stats/assets/less/stats.less
+++ b/src/fauxton/app/addons/stats/assets/less/stats.less
@@ -13,3 +13,8 @@
 .datatypes {
   padding: 0 15px;
 }
+
+.span5 {
+	height:450px;
+	min-width: 450px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/templates/pie_table.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/templates/pie_table.html b/src/fauxton/app/addons/stats/templates/pie_table.html
index 1fa781a..8c4682c 100644
--- a/src/fauxton/app/addons/stats/templates/pie_table.html
+++ b/src/fauxton/app/addons/stats/templates/pie_table.html
@@ -46,5 +46,9 @@ the License.
     </table>
   </div>
 
-  <svg id="<%= datatype %>_graph"></svg>
+  <div class="span5">
+    <center>
+      <svg id="<%= datatype %>_graph"></svg>
+    </center>
+  </div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/views.js b/src/fauxton/app/addons/stats/views.js
index 9dd9cbc..c8374ad 100644
--- a/src/fauxton/app/addons/stats/views.js
+++ b/src/fauxton/app/addons/stats/views.js
@@ -70,21 +70,20 @@ function(app, FauxtonAPI,Stats) {
         series = _.sortBy(series, function(d){return -d.y;});
 
         nv.addGraph(function() {
-            var width = 550,
-                height = 400;
+            var width = 440,
+                height = 440;
 
             var chart = nv.models.pieChart()
                 .x(function(d) { return d.key; })
                 .y(function(d) { return d.y; })
                 .showLabels(true)
                 .showLegend(false)
-                .values(function(d) { return d; })
                 .color(d3.scale.category10().range())
                 .width(width)
                 .height(height);
 
               d3.select(chartelem)
-                  .datum([series])
+                  .datum(series)
                 .transition().duration(300)
                   .attr('width', width)
                   .attr('height', height)


[28/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
clarified what a complex key is in view collation


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/1fb7cea2
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/1fb7cea2
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/1fb7cea2

Branch: refs/heads/Update-Sidebar-Ui
Commit: 1fb7cea25b60585b16bdd786cd3e2b299fa384df
Parents: bea5c94
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 16:45:50 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 16:45:54 2014 -0400

----------------------------------------------------------------------
 share/doc/src/couchapp/views/collation.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/1fb7cea2/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 9c2f5c7..9b11b15 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -32,8 +32,8 @@ property serves as the key, thus the result will be sorted by ``LastName``:
     }
   }
 
-CouchDB allows arbitrary JSON structures to be used as keys. You can use complex
-keys for fine-grained control over sorting and grouping.
+CouchDB allows arbitrary JSON structures to be used as keys. You can use JSON
+arrays as keys for fine-grained control over sorting and grouping.
 
 Examples
 ========


[35/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
s/max/max_count


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/83cc8136
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/83cc8136
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/83cc8136

Branch: refs/heads/Update-Sidebar-Ui
Commit: 83cc8136158dd526b74e6953ef2012704298cf57
Parents: 27cc89c
Author: Robert Newson <rn...@apache.org>
Authored: Thu Mar 27 13:05:22 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Mar 27 13:06:16 2014 +0000

----------------------------------------------------------------------
 src/couchdb/couch_httpd_misc_handlers.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/83cc8136/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 67e3a12..c86f5c7 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -105,7 +105,7 @@ handle_restart_req(Req) ->
 
 
 handle_uuids_req(#httpd{method='GET'}=Req) ->
-    Max = list_to_integer(couch_config:get("uuids","max","1000")),
+    Max = list_to_integer(couch_config:get("uuids","max_count","1000")),
     Count = list_to_integer(couch_httpd:qs_value(Req, "count", "1")),
     case Count > Max of
         true -> throw({forbidden, <<"count parameter too large">>});


[14/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to c1e1423

Posted by de...@apache.org.
fix wording in json-structure


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ebbee3c5
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ebbee3c5
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ebbee3c5

Branch: refs/heads/Update-Sidebar-Ui
Commit: ebbee3c58390430b5095ba9977720f7f409bab3f
Parents: a7a6d2e
Author: Andy Wenk <an...@nms.de>
Authored: Thu Jan 30 22:00:28 2014 +0100
Committer: Andy Wenk <an...@nms.de>
Committed: Fri Mar 21 22:54:29 2014 +0100

----------------------------------------------------------------------
 share/doc/src/json-structure.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ebbee3c5/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index ab3ae45..68137d2 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -481,10 +481,10 @@ Response object
 +--------------------------------+---------------------------------------------+
 
 .. warning::
-   The ``body``, ``base64`` and ``json`` object keys overlapp each other
-   where in the last one wins. Since most implementations of key-value objects do
-   not preserve the key order, confusing situations can emerge. The same applies,
-   when they are mixed. Try to use only one of them.
+   The ``body``, ``base64`` and ``json`` object keys are overlapping each other
+   where the last one wins. Since most realizations of key-value objects do
+   not preserve the key order or if they are mixed, confusing situations can
+   occure. Try to use only one of them.
 
 .. note::
    Any custom property makes CouchDB raise an internal exception.