You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ns...@apache.org on 2013/12/14 12:41:47 UTC

[41/51] [partial] Bring Fauxton directories together

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/fauxton/base.js b/share/www/fauxton/src/app/modules/fauxton/base.js
new file mode 100644
index 0000000..01c2928
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/fauxton/base.js
@@ -0,0 +1,276 @@
+// 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.
+
+define([
+       "app",
+       // Libs
+       "backbone",
+       "resizeColumns"
+
+],
+
+function(app, Backbone, resizeColumns) {
+
+
+   //resizeAnimation
+   app.resizeColumns = new resizeColumns({});
+   app.resizeColumns.onResizeHandler();
+
+  var Fauxton = app.module();
+
+  Fauxton.Breadcrumbs = Backbone.View.extend({
+    template: "templates/fauxton/breadcrumbs",
+
+    serialize: function() {
+      var crumbs = _.clone(this.crumbs);
+      return {
+        crumbs: crumbs
+      };
+    },
+
+    initialize: function(options) {
+      this.crumbs = options.crumbs;
+    }
+  });
+
+  Fauxton.VersionInfo = Backbone.Model.extend({
+    url: app.host
+  });
+
+  // TODO: this View should extend from FauxtonApi.View.
+  // Chicken and egg problem, api.js extends fauxton/base.js.
+  // Need to sort the loading order.
+  Fauxton.Footer = Backbone.View.extend({
+    template: "templates/fauxton/footer",
+
+    initialize: function() {
+      this.versionInfo = new Fauxton.VersionInfo();
+    },
+
+    establish: function() {
+      return [this.versionInfo.fetch()];
+    },
+
+    serialize: function() {
+      return {
+        version: this.versionInfo.get("version")
+      };
+    }
+  });
+
+  Fauxton.NavBar = Backbone.View.extend({
+    className:"navbar",
+    template: "templates/fauxton/nav_bar",
+    // TODO: can we generate this list from the router?
+    navLinks: [
+      {href:"#/_all_dbs", title:"Databases", icon: "fonticon-database", className: 'databases'}
+    ],
+
+    bottomNavLinks: [],
+    footerNavLinks: [],
+
+    serialize: function() {
+      return {
+        navLinks: this.navLinks,
+        bottomNavLinks: this.bottomNavLinks,
+        footerNavLinks: this.footerNavLinks
+      };
+    },
+
+    addLink: function(link) {
+      // link.top means it gets pushed to the top of the array,
+      // link.bottomNav means it goes to the additional bottom nav
+      // link.footerNav means goes to the footer nav
+      if (link.top && !link.bottomNav){
+        this.navLinks.unshift(link);
+      } else if (link.top && link.bottomNav){
+        this.bottomNavLinks.unshift(link);
+      } else if (link.bottomNav) {
+        this.bottomNavLinks.push(link);
+      } else if (link.footerNav) {
+        this.footerNavLinks.push(link);
+      } else {
+        this.navLinks.push(link);
+      }
+
+      //this.trigger("link:add");
+
+      //this.render();
+    },
+
+    removeLink: function (removeLink) {
+      var links = this.navlinks;
+
+      if (removeLink.bottomNav) {
+        links = this.bottomNavLinks;
+      } else if (removeLink.footerNav) {
+        links = this.footerNavLinks;
+      }
+
+      var foundIndex = -1;
+
+      _.each(links, function (link, index) {
+        if (link.title === removeLink.title) {
+          foundIndex = index;
+        }
+      });
+
+      if (foundIndex === -1) {return;}
+      links.splice(foundIndex, 1);
+      this.render();
+    },
+
+    afterRender: function(){
+
+      $('#primary-navbar li[data-nav-name="' + app.selectedHeader + '"]').addClass('active');
+
+      var menuOpen = true;
+      var $selectorList = $('body');
+      $('.brand').off();
+      $('.brand').on({
+        click: function(e){
+          if(!$(e.target).is('a')){
+            toggleMenu();
+          }
+         }
+      });
+
+      function toggleMenu(){
+        $selectorList.toggleClass('closeMenu');
+        menuOpen = $selectorList.hasClass('closeMenu');
+        app.resizeColumns.onResizeHandler();
+      }
+
+      $('#primary-navbar').on("click", ".nav a", function(){
+        if (!($selectorList.hasClass('closeMenu'))){
+        setTimeout(
+          function(){
+            $selectorList.addClass('closeMenu');
+            app.resizeColumns.onResizeHandler();
+          },3000);
+
+        }
+      });
+
+      app.resizeColumns.initialize();
+    },
+
+    beforeRender: function () {
+      this.addLinkViews();
+    },
+
+    addLinkViews: function () {
+      var that = this;
+
+      _.each(_.union(this.navLinks, this.bottomNavLinks), function (link) {
+        if (!link.view) { return; }
+
+        //TODO check if establish is a function
+        var establish = link.establish || [];
+        $.when.apply(null, establish).then( function () {
+          var selector =  link.bottomNav ? '#bottom-nav-links' : '#nav-links';
+          that.insertView(selector, link.view).render();
+        });
+      }, this);
+    }
+
+    // TODO: ADD ACTIVE CLASS
+  });
+
+  Fauxton.ApiBar = Backbone.View.extend({
+    template: "templates/fauxton/api_bar",
+    endpoint: '_all_docs',
+
+    documentation: 'docs',
+
+    events:  {
+      "click .api-url-btn" : "toggleAPIbar"
+    },
+
+    toggleAPIbar: function(e){
+      var $currentTarget = $(e.currentTarget).find('span');
+      if ($currentTarget.hasClass("fonticon-plus")){
+        $currentTarget.removeClass("fonticon-plus").addClass("fonticon-minus");
+      }else{
+        $currentTarget.removeClass("fonticon-minus").addClass("fonticon-plus");
+      }
+
+      $('.api-navbar').toggle();
+
+    },
+
+    serialize: function() {
+      return {
+        endpoint: this.endpoint,
+        documentation: this.documentation
+      };
+    },
+
+    hide: function(){
+      this.$el.addClass('hide');
+    },
+    show: function(){
+      this.$el.removeClass('hide');
+    },
+    update: function(endpoint) {
+      this.show();
+      this.endpoint = endpoint[0];
+      this.documentation = endpoint[1];
+      this.render();
+    }
+
+  });
+
+  Fauxton.Notification = Backbone.View.extend({
+    fadeTimer: 5000,
+
+    initialize: function(options) {
+      this.msg = options.msg;
+      this.type = options.type || "info";
+      this.selector = options.selector;
+      this.fade = options.fade === undefined ? true : options.fade;
+      this.clear = options.clear;
+      this.data = options.data || "";
+      this.template = options.template || "templates/fauxton/notification";
+    },
+
+    serialize: function() {
+      return {
+        data: this.data,
+        msg: this.msg,
+        type: this.type
+      };
+    },
+
+    delayedFade: function() {
+      var that = this;
+      if (this.fade) {
+        setTimeout(function() {
+          that.$el.fadeOut();
+        }, this.fadeTimer);
+      }
+    },
+
+    renderNotification: function(selector) {
+      selector = selector || this.selector;
+      if (this.clear) {
+        $(selector).html('');
+      }
+      this.render().$el.appendTo(selector);
+      this.delayedFade();
+      return this;
+    }
+  });
+
+  
+  return Fauxton;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/fauxton/components.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/fauxton/components.js b/share/www/fauxton/src/app/modules/fauxton/components.js
new file mode 100644
index 0000000..5255626
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/fauxton/components.js
@@ -0,0 +1,314 @@
+// 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.
+
+define('ace_configuration', ["app", "ace/ace"], function (app, ace) {
+  var path = app.host + app.root + 'js/ace';
+  var config = require("ace/config");
+  config.set("packaged", true);
+  config.set("workerPath",path);
+  config.set("modePath",path);
+  config.set("themePath", path);
+  return ace;
+});
+
+define([
+  "app",
+  // Libs
+  "api",
+  "ace_configuration",
+],
+
+function(app, FauxtonAPI, ace) {
+  var Components = app.module();
+
+  Components.Pagination = FauxtonAPI.View.extend({
+    template: "templates/fauxton/pagination",
+
+    initialize: function(options) {
+      this.page = parseInt(options.page, 10);
+      this.perPage = options.perPage;
+      this.total = options.total;
+      this.totalPages = Math.ceil(this.total / this.perPage);
+      this.urlFun = options.urlFun;
+    },
+
+    serialize: function() {
+      return {
+        page: this.page,
+        perPage: this.perPage,
+        total: this.total,
+        totalPages: this.totalPages,
+        urlFun: this.urlFun
+      };
+    }
+  });
+
+  Components.IndexPagination = FauxtonAPI.View.extend({
+    template: "templates/fauxton/index_pagination",
+    events: {
+      "click a": 'scrollTo',
+      "click a#next": 'nextClicked',
+      "click a#previous": 'previousClicked'
+    },
+
+    previousIds: [],
+
+    scrollTo: function () {
+      if (!this.scrollToSelector) { return; }
+      $(this.scrollToSelector).animate({ scrollTop: 0 }, 'slow');
+    },
+
+    initialize: function (options) {
+      this.previousUrlfn = options.previousUrlfn;
+      this.nextUrlfn = options.nextUrlfn;
+      this.canShowPreviousfn = options.canShowPreviousfn;
+      this.canShowNextfn = options.canShowNextfn;
+      this.scrollToSelector = options.scrollToSelector;
+      _.bindAll(this);
+    },
+
+    previousClicked: function (event) {
+      event.preventDefault();
+      if (!this.canShowPreviousfn()) { return; }
+      FauxtonAPI.navigate(this.previousUrlfn(), {trigger: false});
+      FauxtonAPI.triggerRouteEvent('paginate', 'previous');
+    },
+
+    nextClicked: function (event) {
+      event.preventDefault();
+      if (!this.canShowNextfn()) { return; }
+      var doc = this.collection.first();
+
+      if (doc) {
+        this.previousIds.push(doc.id);
+      }
+
+      FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
+      FauxtonAPI.triggerRouteEvent('paginate', 'next');
+    },
+
+    serialize: function () {
+      return {
+        canShowNextfn: this.canShowNextfn,
+        canShowPreviousfn: this.canShowPreviousfn,
+      };
+    }
+
+  });
+
+  //TODO allow more of the typeahead options.
+  //Current this just does what we need but we
+  //need to support the other typeahead options.
+  Components.Typeahead = FauxtonAPI.View.extend({
+
+    initialize: function (options) {
+      this.source = options.source;
+      _.bindAll(this);
+    },
+
+    afterRender: function () {
+      var onUpdate = this.onUpdate;
+
+      this.$el.typeahead({
+        source: this.source,
+        updater: function (item) {
+          if (onUpdate) {
+            onUpdate(item);
+          }
+
+          return item;
+        }
+      });
+    }
+
+  });
+
+
+  Components.DbSearchTypeahead = Components.Typeahead.extend({
+    initialize: function (options) {
+      this.dbLimit = options.dbLimit || 30;
+      this.onUpdate = options.onUpdate;
+      _.bindAll(this);
+    },
+    source: function(query, process) {
+      var url = [
+        app.host,
+        "/_all_dbs?startkey=%22",
+        query,
+        "%22&endkey=%22",
+        query,
+        "\u9999",
+        "%22&limit=",
+        this.dbLimit
+      ].join('');
+
+      if (this.ajaxReq) { this.ajaxReq.abort(); }
+
+      this.ajaxReq = $.ajax({
+        cache: false,
+        url: url,
+        dataType: 'json',
+        success: function(data) {
+          process(data);
+        }
+      });
+    }
+  });
+
+  Components.DocSearchTypeahead = Components.Typeahead.extend({
+    initialize: function (options) {
+      this.docLimit = options.docLimit || 30;
+      this.database = options.database;
+      _.bindAll(this);
+    },
+    source: function(query, process) {
+      var url = [
+        app.host,
+        "/",
+        this.database.id,
+        "/_all_docs?startkey=%22",
+        query,
+        "%22&endkey=%22",
+        query,
+        "\u9999",
+        "%22&limit=",
+        this.docLimit
+      ].join('');
+
+      if (this.ajaxReq) { this.ajaxReq.abort(); }
+
+      this.ajaxReq = $.ajax({
+        cache: false,
+        url: url,
+        dataType: 'json',
+        success: function(data) {
+          var ids = _.map(data.rows, function (row) {
+            return row.id;
+          });
+          process(ids);
+        }
+      });
+    }
+  });
+
+  Components.Editor = FauxtonAPI.View.extend({
+    initialize: function (options) {
+      this.editorId = options.editorId;
+      this.mode = options.mode || "json";
+      this.commands = options.commands;
+      this.theme = options.theme || 'crimson_editor';
+      this.couchJSHINT = options.couchJSHINT;
+      this.edited = false;
+    },
+
+    afterRender: function () {
+      this.editor = ace.edit(this.editorId);
+      this.setHeightToLineCount();
+      this.editor.setTheme("ace/theme/" + this.theme);
+      this.editor.getSession().setMode("ace/mode/" + this.mode);
+      this.editor.getSession().setUseWrapMode(true);
+      this.editor.setShowPrintMargin(false);
+      this.editor.gotoLine(2);
+      this.addCommands();
+
+      if (this.couchJSHINT) {
+        this.removeIncorrectAnnotations();
+      }
+
+      var that = this;
+      this.editor.getSession().on('change', function () {
+        that.setHeightToLineCount();
+        that.edited = true;
+      });
+
+      $(window).on('beforeunload.editor', function() {
+        if (that.edited) {
+          return 'Your changes have not been saved. Click cancel to return to the document.';
+        }
+      });
+
+      FauxtonAPI.beforeUnload("editor", function (deferred) {
+        if (that.edited) {
+          return 'Your changes have not been saved. Click cancel to return to the document.';
+        }
+      });
+    },
+
+    cleanup: function () {
+      $(window).off('beforeunload.editor');
+      FauxtonAPI.removeBeforeUnload("editor");
+    },
+
+    setHeightToLineCount: function () {
+      var lines = this.editor.getSession().getDocument().getLength();
+      this.editor.setOptions({
+        maxLines: lines
+      });
+
+      this.editor.resize();
+    },
+
+    addCommands: function () {
+      _.each(this.commands, function (command) {
+        this.editor.commands.addCommand(command);
+      }, this);
+    },
+
+    removeIncorrectAnnotations: function () {
+      var editor = this.editor;
+
+      this.editor.getSession().on("changeAnnotation", function(){
+        var annotations = editor.getSession().getAnnotations();
+
+        var newAnnotations = _.reduce(annotations, function (annotations, error) {
+          if (!FauxtonAPI.isIgnorableError(error.raw)) {
+            annotations.push(error);
+          }
+          return annotations;
+        }, []);
+
+        if (annotations.length !== newAnnotations.length) {
+          editor.getSession().setAnnotations(newAnnotations);
+        }
+      });
+    },
+
+    editSaved: function () {
+      this.edited = false;
+    },
+
+    setValue: function (data, lineNumber) {
+      lineNumber = lineNumber ? lineNumber : -1;
+      this.editor.setValue(data, lineNumber);
+    },
+
+    getValue: function () {
+      return this.editor.getValue();
+    },
+
+    getAnnotations: function () {
+      return this.editor.getSession().getAnnotations();
+    },
+
+    hadValidCode: function () {
+     var errors = this.getAnnotations();
+     // By default CouchDB view functions don't pass lint
+     return _.every(errors, function(error) {
+      return FauxtonAPI.isIgnorableError(error.raw);
+      },this);
+    }
+
+  });
+
+  return Components;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/fauxton/layout.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/fauxton/layout.js b/share/www/fauxton/src/app/modules/fauxton/layout.js
new file mode 100644
index 0000000..1422241
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/fauxton/layout.js
@@ -0,0 +1,98 @@
+// 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.
+
+define(["backbone"],
+
+function(Backbone) {
+
+  // A wrapper of the main Backbone.layoutmanager
+  // Allows the main layout of the page to be changed by any plugin.
+  // Exposes the different views:
+  //    navBar -> the top navigation bar
+  //    dashboardContent -> Main display view
+  //    breadcrumbs -> Breadcrumbs navigation section
+  var Layout = function (navBar, apiBar) {
+    this.navBar = navBar;
+    this.apiBar = apiBar;
+
+    this.layout = new Backbone.Layout({
+      template: "templates/layouts/with_sidebar",
+
+      views: {
+        "#primary-navbar": this.navBar,
+        "#api-navbar": this.apiBar
+      },
+      afterRender: function(){
+
+      }
+    });
+
+    this.layoutViews = {};
+    //this.hooks = {};
+
+    this.el = this.layout.el;
+  };
+
+  // creatings the dashboard object same way backbone does
+  _.extend(Layout.prototype, {
+    render: function () {
+      return this.layout.render();
+    },
+
+    setTemplate: function(template) {
+      if (template.prefix){
+        this.layout.template = template.prefix + template.name;
+      } else{
+        this.layout.template = "templates/layouts/" + template;
+      }
+      // If we're changing layouts all bets are off, so kill off all the
+      // existing views in the layout.
+      _.each(this.layoutViews, function(view){view.remove();});
+      this.layoutViews = {};
+      this.render();
+    },
+
+    setTabs: function(view){
+      // TODO: Not sure I like this - seems fragile/repetitive
+      this.tabs = this.layout.setView("#tabs", view);
+      this.tabs.render();
+    },
+
+    setBreadcrumbs: function(view) {
+      this.breadcrumbs = this.layout.setView("#breadcrumbs", view);
+      this.breadcrumbs.render();
+    },
+
+    clearBreadcrumbs: function () {
+      if (!this.breadcrumbs) {return ;}
+
+      this.breadcrumbs.remove();
+    },
+
+    setView: function(selector, view) {
+      this.layoutViews[selector] = this.layout.setView(selector, view, false);
+    },
+
+    renderView: function(selector) {
+      var view = this.layoutViews[selector];
+      if (!view) {
+        return false;
+      } else {
+        return view.render();
+      }
+    }
+
+  });
+
+  return Layout;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/pouchdb/base.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/pouchdb/base.js b/share/www/fauxton/src/app/modules/pouchdb/base.js
new file mode 100644
index 0000000..ee323a7
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/pouchdb/base.js
@@ -0,0 +1,47 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ */
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "modules/pouchdb/pouchdb.mapreduce.js"
+],
+
+function(app, FauxtonAPI, MapReduce) {
+  var Pouch = {};
+  Pouch.MapReduce = MapReduce;
+
+  Pouch.runViewQuery = function(fun, opts) {
+    /*docs = [
+      {_id: 'test_doc_1', foo: 'bar-1'},
+      {_id: 'test_doc_2', foo: 'bar-2'},
+      {_id: 'test_doc_3', foo: 'bar-3'},
+      {_id: 'test_doc_4', foo: 'bar-4'},
+      {_id: 'test_doc_5', foo: 'bar-5'},
+      {_id: 'test_doc_6', foo: 'bar-6'},
+      {_id: 'test_doc_7', foo: 'bar-7'},
+      {_id: 'test_doc_8', foo: 'bar-8'},
+      {_id: 'test_doc_9', foo: 'bar-9'},
+      {_id: 'test_doc_10', foo: 'bar-10'}
+    ];*/
+
+    var deferred = FauxtonAPI.Deferred();
+    var complete = function(resp, rows) {
+      deferred.resolve(rows);
+    };
+
+    var options = _.extend(opts, {complete: complete});
+
+    Pouch.MapReduce.query(fun, options);
+    return deferred;
+  };
+  //pdb.runViewQuery({map:function(doc) { emit(doc._id, doc.foo) }})
+  return Pouch;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/pouchdb/pouch.collate.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/pouchdb/pouch.collate.js b/share/www/fauxton/src/app/modules/pouchdb/pouch.collate.js
new file mode 100644
index 0000000..7cc5f9c
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/pouchdb/pouch.collate.js
@@ -0,0 +1,115 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ * Original file:
+ * https://github.com/daleharvey/pouchdb/blob/master/src/pouch.collate.js
+ */
+
+/*
+(function() {
+  // a few hacks to get things in the right place for node.js
+  if (typeof module !== 'undefined' && module.exports) {
+    module.exports = Pouch;
+  }
+*/
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "modules/pouchdb/pouch.collate.js"
+],
+
+function(app, FauxtonAPI, Collate) {
+  var Pouch = {};
+
+  Pouch.collate = function(a, b) {
+    var ai = collationIndex(a);
+    var bi = collationIndex(b);
+    if ((ai - bi) !== 0) {
+      return ai - bi;
+    }
+    if (a === null) {
+      return 0;
+    }
+    if (typeof a === 'number') {
+      return a - b;
+    }
+    if (typeof a === 'boolean') {
+      return a < b ? -1 : 1;
+    }
+    if (typeof a === 'string') {
+      return stringCollate(a, b);
+    }
+    if (Array.isArray(a)) {
+      return arrayCollate(a, b);
+    }
+    if (typeof a === 'object') {
+      return objectCollate(a, b);
+    }
+  };
+
+  var stringCollate = function(a, b) {
+    // See: https://github.com/daleharvey/pouchdb/issues/40
+    // This is incompatible with the CouchDB implementation, but its the
+    // best we can do for now
+    return (a === b) ? 0 : ((a > b) ? 1 : -1);
+  };
+
+  var objectCollate = function(a, b) {
+    var ak = Object.keys(a), bk = Object.keys(b);
+    var len = Math.min(ak.length, bk.length);
+    for (var i = 0; i < len; i++) {
+      // First sort the keys
+      var sort = Pouch.collate(ak[i], bk[i]);
+      if (sort !== 0) {
+        return sort;
+      }
+      // if the keys are equal sort the values
+      sort = Pouch.collate(a[ak[i]], b[bk[i]]);
+      if (sort !== 0) {
+        return sort;
+      }
+
+    }
+    return (ak.length === bk.length) ? 0 :
+      (ak.length > bk.length) ? 1 : -1;
+  };
+
+  var arrayCollate = function(a, b) {
+    var len = Math.min(a.length, b.length);
+    for (var i = 0; i < len; i++) {
+      var sort = Pouch.collate(a[i], b[i]);
+      if (sort !== 0) {
+        return sort;
+      }
+    }
+    return (a.length === b.length) ? 0 :
+      (a.length > b.length) ? 1 : -1;
+  };
+
+  // The collation is defined by erlangs ordered terms
+  // the atoms null, true, false come first, then numbers, strings,
+  // arrays, then objects
+  var collationIndex = function(x) {
+    var id = ['boolean', 'number', 'string', 'object'];
+    if (id.indexOf(typeof x) !== -1) {
+      if (x === null) {
+        return 1;
+      }
+      return id.indexOf(typeof x) + 2;
+    }
+    if (Array.isArray(x)) {
+      return 4.5;
+    }
+  };
+
+  return Pouch;
+
+//}).call(this);
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/modules/pouchdb/pouchdb.mapreduce.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/modules/pouchdb/pouchdb.mapreduce.js b/share/www/fauxton/src/app/modules/pouchdb/pouchdb.mapreduce.js
new file mode 100644
index 0000000..a2d0b91
--- /dev/null
+++ b/share/www/fauxton/src/app/modules/pouchdb/pouchdb.mapreduce.js
@@ -0,0 +1,324 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ * Original file:
+ * https://github.com/daleharvey/pouchdb/blob/master/src/plugins/pouchdb.mapreduce.js
+ */
+
+/*global Pouch: true */
+
+//"use strict";
+
+// This is the first implementation of a basic plugin, we register the
+// plugin object with pouch and it is mixin'd to each database created
+// (regardless of adapter), adapters can override plugins by providing
+// their own implementation. functions on the plugin object that start
+// with _ are reserved function that are called by pouchdb for special
+// notifications.
+
+// If we wanted to store incremental views we can do it here by listening
+// to the changes feed (keeping track of our last update_seq between page loads)
+// and storing the result of the map function (possibly using the upcoming
+// extracted adapter functions)
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "modules/pouchdb/pouch.collate.js"
+],
+
+function(app, FauxtonAPI, Collate) {
+  var Pouch = {};
+  Pouch.collate = Collate.collate;
+
+  //var MapReduce = function(db) {
+  var MapReduce = function() {
+
+    var builtInReduce = {
+      "_sum": function(keys, values){
+        return sum(values);
+      },
+
+      "_count": function(keys, values, rereduce){
+        if (rereduce){
+          return sum(values);
+        } else {
+          return values.length;
+        }
+      },
+
+      "_stats": function(keys, values, rereduce){
+        return {
+          'sum': sum(values),
+          'min': Math.min.apply(null, values),
+          'max': Math.max.apply(null, values),
+          'count': values.length,
+          'sumsqr': (function(){
+            _sumsqr = 0;
+            for(var idx in values){
+              _sumsqr += values[idx] * values[idx];
+            }
+            return _sumsqr;
+          })()
+        };
+      }
+    };
+
+    function viewQuery(fun, options) {
+      console.log("IN VIEW QUERY");
+      if (!options.complete) {
+        return;
+      }
+
+      function sum(values) {
+        return values.reduce(function(a, b) { return a + b; }, 0);
+      }
+
+      var results = [];
+      var current = null;
+      var num_started= 0;
+      var completed= false;
+
+      var emit = function(key, val) {
+        //console.log("IN EMIT: ", key, val, current);
+        var viewRow = {
+          id: current.doc._id,
+          key: key,
+          value: val
+        }; 
+        //console.log("VIEW ROW: ", viewRow);
+
+        if (options.startkey && Pouch.collate(key, options.startkey) < 0) return;
+        if (options.endkey && Pouch.collate(key, options.endkey) > 0) return;
+        if (options.key && Pouch.collate(key, options.key) !== 0) return;
+        num_started++;
+        if (options.include_docs) {
+          // TODO:: FIX
+          throw({error: "Include Docs not supported"});
+          /*
+
+          //in this special case, join on _id (issue #106)
+          if (val && typeof val === 'object' && val._id){
+            db.get(val._id,
+                function(_, joined_doc){
+                  if (joined_doc) {
+                    viewRow.doc = joined_doc;
+                  }
+                  results.push(viewRow);
+                  checkComplete();
+                });
+            return;
+          } else {
+            viewRow.doc = current.doc;
+          }
+          */
+        }
+        console.log("EMITTING: ", viewRow);
+        results.push(viewRow);
+      };
+
+      // ugly way to make sure references to 'emit' in map/reduce bind to the
+      // above emit
+      eval('fun.map = ' + fun.map.toString() + ';');
+      if (fun.reduce && options.reduce) {
+        if (builtInReduce[fun.reduce]) {
+          console.log('built in reduce');
+          fun.reduce = builtInReduce[fun.reduce];
+        }
+        eval('fun.reduce = ' + fun.reduce.toString() + ';');
+      }
+
+      // exclude  _conflicts key by default
+      // or to use options.conflicts if it's set when called by db.query
+      var conflicts = ('conflicts' in options ? options.conflicts : false);
+
+      //only proceed once all documents are mapped and joined
+      var checkComplete= function(){
+        console.log('check');
+        if (completed && results.length == num_started){
+          results.sort(function(a, b) {
+            return Pouch.collate(a.key, b.key);
+          });
+          if (options.descending) {
+            results.reverse();
+          }
+          if (options.reduce === false) {
+            return options.complete(null, {rows: results});
+          }
+
+          console.log('reducing', options);
+          var groups = [];
+          results.forEach(function(e) {
+            var last = groups[groups.length-1] || null;
+            if (last && Pouch.collate(last.key[0][0], e.key) === 0) {
+              last.key.push([e.key, e.id]);
+              last.value.push(e.value);
+              return;
+            }
+            groups.push({key: [[e.key, e.id]], value: [e.value]});
+          });
+          groups.forEach(function(e) {
+            e.value = fun.reduce(e.key, e.value) || null;
+            e.key = e.key[0][0];
+          });
+          console.log('GROUPs', groups);
+          options.complete(null, {rows: groups});
+        }
+      };
+
+      if (options.docs) {
+        //console.log("RUNNING MR ON DOCS: ", options.docs);
+        _.each(options.docs, function(doc) {
+          current = {doc: doc};
+          fun.map.call(this, doc);
+        }, this);
+        completed = true;
+        return checkComplete();//options.complete(null, {rows: results});
+      } else {
+        //console.log("COULD NOT FIND DOCS");
+        return false;
+      }
+
+      /*
+      db.changes({
+        conflicts: conflicts,
+        include_docs: true,
+        onChange: function(doc) {
+          if (!('deleted' in doc)) {
+            current = {doc: doc.doc};
+            fun.map.call(this, doc.doc);
+          }
+        },
+        complete: function() {
+          completed= true;
+          checkComplete();
+        }
+      });
+      */
+    }
+
+    /*
+    function httpQuery(fun, opts, callback) {
+
+      // List of parameters to add to the PUT request
+      var params = [];
+      var body = undefined;
+      var method = 'GET';
+
+      // If opts.reduce exists and is defined, then add it to the list
+      // of parameters.
+      // If reduce=false then the results are that of only the map function
+      // not the final result of map and reduce.
+      if (typeof opts.reduce !== 'undefined') {
+        params.push('reduce=' + opts.reduce);
+      }
+      if (typeof opts.include_docs !== 'undefined') {
+        params.push('include_docs=' + opts.include_docs);
+      }
+      if (typeof opts.limit !== 'undefined') {
+        params.push('limit=' + opts.limit);
+      }
+      if (typeof opts.descending !== 'undefined') {
+        params.push('descending=' + opts.descending);
+      }
+      if (typeof opts.startkey !== 'undefined') {
+        params.push('startkey=' + encodeURIComponent(JSON.stringify(opts.startkey)));
+      }
+      if (typeof opts.endkey !== 'undefined') {
+        params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
+      }
+      if (typeof opts.key !== 'undefined') {
+        params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
+      }
+
+      // If keys are supplied, issue a POST request to circumvent GET query string limits
+      // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+      if (typeof opts.keys !== 'undefined') {
+        method = 'POST';
+        body = JSON.stringify({keys:opts.keys});
+      }
+
+      // Format the list of parameters into a valid URI query string
+      params = params.join('&');
+      params = params === '' ? '' : '?' + params;
+
+      // We are referencing a query defined in the design doc
+      if (typeof fun === 'string') {
+        var parts = fun.split('/');
+        db.request({
+          method: method,
+          url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
+          body: body
+        }, callback);
+        return;
+      }
+
+      // We are using a temporary view, terrible for performance but good for testing
+      var queryObject = JSON.parse(JSON.stringify(fun, function(key, val) {
+        if (typeof val === 'function') {
+          return val + ''; // implicitly `toString` it
+        }
+        return val;
+      }));
+
+      db.request({
+        method:'POST',
+        url: '_temp_view' + params,
+        body: queryObject
+      }, callback);
+    }
+    */
+
+    function query(fun, opts, callback) {
+      if (typeof opts === 'function') {
+        callback = opts;
+        opts = {};
+      }
+
+      if (callback) {
+        opts.complete = callback;
+      }
+
+      /*
+      if (db.type() === 'http') {
+        return httpQuery(fun, opts, callback);
+      }
+      */
+
+      if (typeof fun === 'object') {
+        console.log("RUNNING VIEW QUERY", fun, opts, arguments);
+        return viewQuery(fun, opts);
+      }
+
+      throw({error: "Shouldn't have gotten here"});
+
+      /*
+      var parts = fun.split('/');
+      db.get('_design/' + parts[0], function(err, doc) {
+        if (err) {
+          if (callback) callback(err);
+          return;
+        }
+        viewQuery({
+          map: doc.views[parts[1]].map,
+          reduce: doc.views[parts[1]].reduce
+        }, opts);
+      });
+      */
+    }
+
+    return {'query': query};
+  };
+
+  // Deletion is a noop since we dont store the results of the view
+  MapReduce._delete = function() { };
+
+  //Pouch.plugin('mapreduce', MapReduce);
+
+  return MapReduce();
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/resizeColumns.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/resizeColumns.js b/share/www/fauxton/src/app/resizeColumns.js
new file mode 100644
index 0000000..9cf7115
--- /dev/null
+++ b/share/www/fauxton/src/app/resizeColumns.js
@@ -0,0 +1,87 @@
+// 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.
+
+
+// This file creates a set of helper functions that will be loaded for all html
+// templates. These functions should be self contained and not rely on any 
+// external dependencies as they are loaded prior to the application. We may
+// want to change this later, but for now this should be thought of as a
+// "purely functional" helper system.
+
+define([
+  "mixins"
+],
+
+function(mixins) {
+
+  var Resize = function(options){
+    this.options = options;
+    this.options.selectorElements = options.selectorElements || ".window-resizeable";
+  };
+
+  Resize.prototype = {
+    getPrimaryNavWidth: function(){
+      var primaryNavWidth  = $('body').hasClass('closeMenu')? 64:224;
+      return primaryNavWidth;
+    },
+    getPanelWidth: function(){
+      var sidebarWidth = $('#sidebar-content').length > 0 ? $('#sidebar-content').width(): 0;
+      return (this.getPrimaryNavWidth() + sidebarWidth); 
+    },
+    initialize: function(){
+     // $(window).off('resize');
+      var that = this;
+      //add throttler :) 
+      this.lazyLayout = _.debounce(that.onResizeHandler, 300).bind(this);
+      mixins.addWindowResize(this.lazyLayout,"animation");
+      mixins.initWindowResize();
+      this.onResizeHandler();
+    },
+    updateOptions:function(options){
+      this.options = {};
+      this.options = options;
+      this.options.selectorElements = options.selectorElements || ".window-resizeable";
+    },
+    turnOff:function(){
+      mixins.removeWindowResize("animation");
+    },
+    cleanupCallback: function(){
+      this.callback = null;
+    },
+    onResizeHandler: function (){
+      //if there is an override, do that instead
+      if (this.options.onResizeHandler){
+        this.options.onResizeHandler();
+      } else {
+        var combinedWidth = window.innerWidth - this.getPanelWidth(),
+        smallWidthConstraint = ($('#sidebar-content').length > 0)? 470:800,
+        panelWidth; 
+
+        if( combinedWidth > smallWidthConstraint  && combinedWidth < 1400){
+          panelWidth = window.innerWidth - this.getPanelWidth();
+        } else if (combinedWidth < smallWidthConstraint){
+          panelWidth = smallWidthConstraint;
+        } else if(combinedWidth > 1400){
+          panelWidth = 1400;
+        }
+
+        $(this.options.selectorElements).innerWidth(panelWidth);
+      }
+      //if there is a callback, run that
+      if(this.options.callback) {
+        this.options.callback();
+      }
+    } 
+  };
+
+  return Resize;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/router.js
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/router.js b/share/www/fauxton/src/app/router.js
new file mode 100644
index 0000000..e3a1636
--- /dev/null
+++ b/share/www/fauxton/src/app/router.js
@@ -0,0 +1,175 @@
+// 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.
+
+define([
+       // Load require for use in nested requiring
+       // as per the note in: http://requirejs.org/docs/api.html#multiversion
+       "require",
+
+       // Application.
+       "app",
+
+       // Initialize application
+       "initialize",
+
+       // Load Fauxton API
+       "api",
+
+       // Modules
+       "modules/fauxton/base",
+       // Layout
+       "modules/fauxton/layout",
+
+       // Routes return the module that they define routes for
+       "modules/databases/base",
+       "modules/documents/base",
+       "modules/pouchdb/base",
+
+
+       // this needs to be added as a plugin later
+       // "modules/logs/base",
+       // "modules/config/base",
+
+       "load_addons"
+],
+
+function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents, Pouch, LoadAddons) {
+
+  // TODO: auto generate this list if possible
+  var modules = [Databases, Documents];
+
+  var beforeUnloads = {};
+
+  var Router = app.router = Backbone.Router.extend({
+    routes: {},
+
+    beforeUnload: function (name, fn) {
+      beforeUnloads[name] = fn;
+    },
+
+    removeBeforeUnload: function (name) {
+      delete beforeUnloads[name];
+    },
+
+    navigate: function (fragment, trigger) {
+      var continueNav  = true,
+          msg = _.find(_.map(beforeUnloads, function (fn) { return fn(); }), function (beforeReturn) {
+            if (beforeReturn) { return true; }
+          });
+
+      if (msg) {
+        continueNav = window.confirm(msg);
+      }
+
+      if (continueNav) {
+        Backbone.Router.prototype.navigate(fragment, trigger);
+      }
+    },
+
+    addModuleRouteObject: function(RouteObject) {
+      var that = this;
+      var masterLayout = this.masterLayout,
+      routeUrls = RouteObject.prototype.getRouteUrls();
+
+      _.each(routeUrls, function(route) {
+        this.route(route, route.toString(), function() {
+          var args = Array.prototype.slice.call(arguments),
+          roles = RouteObject.prototype.getRouteRoles(route),
+          authPromise = app.auth.checkAccess(roles);
+
+          authPromise.then(function () {
+            if (!that.activeRouteObject || !that.activeRouteObject.hasRoute(route)) {
+              if (that.activeRouteObject) {
+                that.activeRouteObject.removeViews();
+              }
+              that.activeRouteObject = new RouteObject(route, masterLayout, args);
+            }
+
+            var routeObject = that.activeRouteObject;
+            routeObject.routeCallback(route, args);
+            routeObject.renderWith(route, masterLayout, args);
+          }, function () {
+            FauxtonAPI.auth.authDeniedCb();
+          });
+
+        }); 
+      }, this);
+    },
+
+    setModuleRoutes: function() {
+      _.each(modules, function(module) {
+        if (module){
+          _.each(module.RouteObjects, this.addModuleRouteObject, this);
+        }
+      }, this);
+      _.each(LoadAddons.addons, function(module) {
+        if (module){
+          module.initialize();
+          // This is pure routes the addon provides
+          if (module.RouteObjects) {
+            _.each(module.RouteObjects, this.addModuleRouteObject, this);
+          }
+        }
+      }, this);
+    },
+
+    /*setAddonHooks: function() {
+      _.each(LoadAddons.addons, function(module) {
+        // This is updates to views by the addon
+        if (module && module.hooks){
+          _.each(module.hooks, function(callback, route){
+            if (this.masterLayout.hooks[route]) {
+              this.masterLayout.hooks[route].push(callback);
+            } else {
+              this.masterLayout.hooks[route] = [callback];
+            }
+          }, this);
+        }
+      }, this);
+    },*/
+
+    initialize: function() {
+      //TODO: It would be nice to handle this with a router
+      this.navBar = app.navBar = new Fauxton.NavBar();
+      this.apiBar = app.apiBar = new Fauxton.ApiBar();
+      this.auth = app.auth = FauxtonAPI.auth;
+      app.session = FauxtonAPI.session;
+
+      app.masterLayout = this.masterLayout = new Layout(this.navBar, this.apiBar);
+      app.footer = new Fauxton.Footer({el: "#footer-content"});
+
+      // NOTE: This must be below creation of the layout
+      // FauxtonAPI header links and others depend on existence of the layout
+      //this.setAddonHooks();
+      this.setModuleRoutes();
+
+      $("#app-container").html(this.masterLayout.el);
+      this.masterLayout.render();
+
+      // TODO: move this to a proper Fauxton.View
+      $.when.apply(null, app.footer.establish()).done(function() {
+        app.footer.render();
+      });
+    },
+
+    triggerRouteEvent: function(event, args) {
+      if (this.activeRouteObject) {
+        var eventArgs = [event].concat(args);
+        this.activeRouteObject.trigger.apply(this.activeRouteObject, eventArgs );
+        this.activeRouteObject.renderWith(eventArgs, this.masterLayout, args);
+      }
+    }
+  });
+
+  return Router;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/databases/item.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/databases/item.html b/share/www/fauxton/src/app/templates/databases/item.html
new file mode 100644
index 0000000..701e58e
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/databases/item.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+
+<td>
+  <a href="#/database/<%=encoded%>/_all_docs?limit=<%=docLimit%>"><%= database.get("name") %></a>
+</td>
+<td><%= database.status.humanSize() %></td>
+<td><%= database.status.numDocs() %></td>
+<td><%= database.status.updateSeq() %></td>
+<td>
+  <a class="db-actions btn fonticon-replicate set-replication-start" href="#/replication/<%= database.get("name") %>"></a>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/databases/list.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/databases/list.html b/share/www/fauxton/src/app/templates/databases/list.html
new file mode 100644
index 0000000..2e5d78d
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/databases/list.html
@@ -0,0 +1,34 @@
+<!--
+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="result-tools" style="">
+  <div id="newButton" class="pull-left"></div>
+  <form class="navbar-form pull-right database-search">
+    <label class="fonticon-search">
+      <input type="text" class="search-query" placeholder="Search by database name">
+    </label>
+  </form>
+</div>
+<table class="databases table table-striped">
+  <thead>
+    <th>Name</th>
+    <th>Size</th>
+    <th># of Docs</th>
+    <th>Update Seq</th>
+    <th>Actions</th>
+  </thead>
+  <tbody>
+  </tbody>
+</table>
+<div id="database-pagination"></div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/databases/newdatabase.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/databases/newdatabase.html b/share/www/fauxton/src/app/templates/databases/newdatabase.html
new file mode 100644
index 0000000..b357e0b
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/databases/newdatabase.html
@@ -0,0 +1,17 @@
+<!--
+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.
+-->
+
+<a class="button new" id="new"><i class="icon fonticon-new-database"></i>Add New Database</a>
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/databases/sidebar.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/databases/sidebar.html b/share/www/fauxton/src/app/templates/databases/sidebar.html
new file mode 100644
index 0000000..a8bbd89
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/databases/sidebar.html
@@ -0,0 +1,31 @@
+<!--
+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="row-fluid">
+  <a href="http://couchdb.org" target="_blank"><img src="img/couchdblogo.png"/></a>
+  <br/>
+</div>
+<hr>
+<ul class="nav nav-list">
+  <!-- <li class="nav-header">Database types</li> -->
+  <li class="active"><a class="toggle-view" id="owned">Your databases</a></li>
+  <li><a class="btn new" id="new"><i class="icon-plus"></i> New database</a></li>
+</ul>
+<hr>
+
+<div>
+  <a class="twitter-timeline" data-dnt="true" href="https://twitter.com/CouchDB" data-widget-id="314360971646869505">Tweets by @CouchDB</a>
+<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/advanced_options.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/advanced_options.html b/share/www/fauxton/src/app/templates/documents/advanced_options.html
new file mode 100644
index 0000000..3562f7b
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/advanced_options.html
@@ -0,0 +1,97 @@
+<!--
+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="errors-container"></div>
+<form class="view-query-update custom-inputs">
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="key" class="span6" type="text" placeholder="Key">
+        <input name="keys" class="span6" type="text" placeholder="Keys">
+      </div>
+    </div>
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="startkey" class="span6" type="text" placeholder="Start Key">
+        <input name="endkey" class="span6" type="text" placeholder="End Key">
+      </div>
+    </div>
+  </div>
+  <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>
+        <% } %>
+
+        <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 selected="selected">10</option>
+            <option>25</option>
+            <option>50</option>
+            <option>100</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>
+    </div>
+  </div>
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div id="button-options" class="controls controls-row">
+        <button type="submit" class="button btn-primary btn-large">Query</button>
+        <% if (showPreview) { %>
+        <button class="button btn-info btn-large preview">Browser Preview</button>
+        <% } %>
+      </div>
+    </div>
+  </div>
+</form>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/all_docs_item.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/all_docs_item.html b/share/www/fauxton/src/app/templates/documents/all_docs_item.html
new file mode 100644
index 0000000..c0e61cf
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/all_docs_item.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<td class="select"><input type="checkbox" class="row-select"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%- doc.prettyJSON() %></pre>
+    <% if (doc.isEditable()) { %>
+      <div class="btn-group">
+        <a href="#<%= doc.url('app') %>" class="btn btn-small edits">Edit <%= doc.docType() %></a>
+        <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
+      </div>
+    <% } %>
+  </div>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/all_docs_layout.html b/share/www/fauxton/src/app/templates/documents/all_docs_layout.html
new file mode 100644
index 0000000..526c200
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/all_docs_layout.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 class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
+  <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-toggle="tab">Query Options</a></li>
+</ul>
+<div class="tab-content">
+  <div class="tab-pane" id="query">
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/all_docs_list.html b/share/www/fauxton/src/app/templates/documents/all_docs_list.html
new file mode 100644
index 0000000..335b040
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/all_docs_list.html
@@ -0,0 +1,43 @@
+<!--
+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="view show">
+  <% if (!viewList) { %>
+    <div class="row">
+      <div class="btn-toolbar span6">
+        <button type="button" class="btn all" data-toggle="button">✓ All</button>
+        <button class="btn btn-small disabled bulk-delete"><i class="icon-trash"></i></button>
+        <% if (expandDocs) { %>
+        <button id="collapse" class="btn"><i class="icon-minus"></i> Collapse</button>
+        <% } else { %>
+        <button id="collapse" class="btn"><i class="icon-plus"></i> Expand</button>
+        <% } %>
+      </div>
+    </div>
+  <% } %>
+  <p>
+
+  <div id="item-numbers"> </div>
+
+  <% if (requestDuration) { %>
+    <span class="view-request-duration">
+    View request duration: <strong> <%= requestDuration %> </strong> 
+    </span>
+  <% } %>
+  </p>
+  <table class="all-docs table table-striped table-condensed">
+    <tbody></tbody>
+  </table>
+  <div id="documents-pagination"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/all_docs_number.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/all_docs_number.html b/share/www/fauxton/src/app/templates/documents/all_docs_number.html
new file mode 100644
index 0000000..c4ea8f6
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/all_docs_number.html
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<% if (totalRows === "unknown"){ %>
+  Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
+<% } else { %>
+  Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+<%}%>
+<% if (updateSeq) { %>
+  -- Update Sequence: <%= updateSeq %>
+<% } %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/changes.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/changes.html b/share/www/fauxton/src/app/templates/documents/changes.html
new file mode 100644
index 0000000..9408979
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/changes.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<table id="changes-table" class="table">
+  <thead>
+    <th id="seq"> seq </th>
+    <th> id </th>
+    <th id="changes"> changes </th>
+    <th id="deleted"> deleted? </th>
+  </thead>
+  <tbody>
+  <% _.each(changes, function (change) { %>
+    <tr>
+      <td> <%= change.seq %> </td>
+      <% if (change.deleted) { %>
+        <td> <%= change.id %> </td>
+      <% } else { %>
+        <td> <a href="#<%= database.url('app') %>/<%= change.id %>"><%= change.id %></a> </td>
+      <% } %>
+        <td> 
+          <pre class="prettyprint">  <%- JSON.stringify({changes: change.changes, doc: change.doc}, null, " ") %> </pre>
+      </td>
+      <td><%= change.deleted ? "true" : "false" %></td>
+    </tr>
+  <% }); %>
+  </tbody>
+</table>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/ddoc_info.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/ddoc_info.html b/share/www/fauxton/src/app/templates/documents/ddoc_info.html
new file mode 100644
index 0000000..ed0aed6
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/ddoc_info.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>
+  <h2> Design Doc MetaData </h2>
+  <div class="row-fluid">
+	<% i=0; _.map(view_index, function (val, key) { %>
+		<% if(i%2==0){%>
+			<div class="row-fluid">
+		<% }; %>
+	    <div class="span6 well-item"><strong> <%= key %></strong> : <%= val %>  </div>
+	    <% if(i%2==1){%>
+			</div>
+		<% }; %>
+	  	<% ++i;
+	}); %>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/design_doc_selector.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/design_doc_selector.html b/share/www/fauxton/src/app/templates/documents/design_doc_selector.html
new file mode 100644
index 0000000..457b76c
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/design_doc_selector.html
@@ -0,0 +1,35 @@
+<!--
+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="span3">
+  <label for="ddoc">Save to Design Document <a href="<%=getDocUrl('design_doc')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+  <select id="ddoc">
+    <optgroup label="Select a document">
+      <option id="new-doc">New document</option>
+      <% ddocs.each(function(ddoc) { %>
+      <% if (ddoc.id === ddocName) { %>
+      <option selected="selected"><%= ddoc.id %></option>
+      <% } else { %>
+      <option><%= ddoc.id %></option>
+      <% } %>
+      <% }); %>
+    </optgroup>
+  </select>
+</div>
+
+<div id="new-ddoc-section" class="span5" style="display:none">
+  <label class="control-label" for="new-ddoc"> _design/ </label>
+  <div class="controls">
+    <input type="text" id="new-ddoc" placeholder="newDesignDoc">
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/doc.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/doc.html b/share/www/fauxton/src/app/templates/documents/doc.html
new file mode 100644
index 0000000..f83a1a9
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/doc.html
@@ -0,0 +1,51 @@
+<!--
+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 id="doc">
+  <div class="errors-container"></div>
+   
+<div class="btn-group" style="margin-bottom: 15px"> 
+  <% if (attachments) { %>
+    <a class="btn dropdown-toggle btn" data-toggle="dropdown" href="#">
+      View Attachments
+      <span class="caret"></span>
+    </a>
+    <ul class="dropdown-menu">
+      <%_.each(attachments, function (att) { %>
+      <li>
+      <a href="<%= att.url %>" target="_blank"> <strong> <%= att.fileName %> </strong> -
+        <span> <%= att.contentType %>, <%= formatSize(att.size)%> </span>
+      </a>
+      </li>
+      <% }) %>
+    </ul>
+
+  <% } %> 
+  <button class="btn btn-small upload"><i class="icon-circle-arrow-up"></i> Upload Attachment</button>
+  <button class="btn btn-small duplicate"><i class="icon-repeat"></i> Duplicate document</button>
+  <button class="btn btn-small delete"><i class="icon-trash"></i> Delete document</button>
+  </ul>
+
+<div id="upload-modal"> </div>
+<div id="duplicate-modal"> </div> 
+</div>
+
+  <div id="editor-container" class="doc-code"><%- JSON.stringify(doc.attributes, null, "  ") %></div>
+  <br />
+  <p>
+       <button class="save-doc button green btn-success btn-large save fonticon-circle-check" type="button">Save</button>
+       <button class="button gray btn-large cancel-button outlineGray fonticon-circle-x" type="button">Cancel</button>
+  </p>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/doc_field_editor.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/doc_field_editor.html b/share/www/fauxton/src/app/templates/documents/doc_field_editor.html
new file mode 100644
index 0000000..77d9278
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/doc_field_editor.html
@@ -0,0 +1,74 @@
+<!--
+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 id="doc-field-editor">
+  <div class="tools">
+
+    <div class="btn-toolbar pull-left">
+      <button class="btn btn-small all">&#x2713; All</button>
+      <button class="btn btn-small disabled delete"><i class="icon-trash"></i> Delete field</button>
+      <button class="btn btn-small new" style="margin-left: 64px"><i class="icon-plus"></i> New field</button>
+    </div>
+    <div class="btn-toolbar pull-right">
+      <button class="btn btn-small cancel button cancel-button outlineGray fonticon-circle-x">Cancel</button>
+      <button class="btn btn-small save button green fonticon-circle-check">Save</button>
+    </div>
+  </div>
+
+  <div class="clearfix"></div>
+  <!-- <hr style="margin-top: 0"/> -->
+
+  <table class="table table-striped  table-condensed">
+    <thead>
+      <tr>
+        <th class="select">
+        </th>
+        <th>Key</th>
+        <th>Value</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr style="display:none">
+        <td class="select"><input type="checkbox" /></td>
+        <td class="key"><input type="text" class="input-large" value='' /></td>
+        <td class="value"><input type="text" class="input-xxlarge" value='' /></td>
+      </tr>
+      <% _.each(doc, function(value, key) { %>
+        <tr>
+          <td class="select"><input type="checkbox" /></td>
+          <td class="key">
+            <input type="text" class="input-large" name="doc[<%= key %>]" value="<%= key %>" />
+          </td>
+          <td class="value"><input type="text" class="input-xxlarge" value='<%= JSON.stringify(value) %>' /></td>
+        </tr>
+      <% }); %>
+        <tr>
+          <th colspan="3">
+            Attachments
+          </th>
+        </tr>
+      <%_.each(attachments, function (att) { %>
+        <tr>
+          <td class="select"><input type="checkbox" /></td>
+          <td colspan="2">
+            <a href="<%= att.url %>" target="_blank"> <%= att.fileName %> </a>
+            <span> <%= att.contentType %>, <%= formatSize(att.size)%> </span>
+          </td>
+        </tr>
+      <% }) %>
+    </tbody>
+  </table>
+  <a class="btn btn-small new" style="margin-left: 64px"><i class="icon-plus"></i> New field</a>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/doc_field_editor_tabs.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/doc_field_editor_tabs.html b/share/www/fauxton/src/app/templates/documents/doc_field_editor_tabs.html
new file mode 100644
index 0000000..766647c
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/doc_field_editor_tabs.html
@@ -0,0 +1,19 @@
+<!--
+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 class="nav nav-tabs">
+  <li id="field_editor" class="<%= isSelectedClass('field_editor') %>"><a href="#<%= doc.url('app') %>/field_editor">Doc fields</a></li>
+  <li id="code_editor" class="<%= isSelectedClass('code_editor') %>"><a href="#<%= doc.url('app') %>/code_editor"><i class="icon-pencil"> </i> Code editor</a>
+  </li>
+</ul>-->

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/duplicate_doc_modal.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/duplicate_doc_modal.html b/share/www/fauxton/src/app/templates/documents/duplicate_doc_modal.html
new file mode 100644
index 0000000..3f374b6
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/duplicate_doc_modal.html
@@ -0,0 +1,36 @@
+<!--
+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="modal hide fade">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>Duplicate Document</h3>
+  </div>
+  <div class="modal-body">
+    <div id="modal-error" class="hide alert alert-error"/>
+    <form id="file-upload" class="form" method="post">
+      <p class="help-block">
+      Set new documents ID:
+      </p>
+      <input id="dup-id" type="text" class="input-xlarge">
+    </form>
+
+  </div>
+  <div class="modal-footer">
+    <a href="#" data-dismiss="modal" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
+    <a href="#" id="duplicate-btn" class="btn btn-primary button green save fonticon-circle-check">Duplicate</a>
+  </div>
+</div>
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/edit_tools.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/edit_tools.html b/share/www/fauxton/src/app/templates/documents/edit_tools.html
new file mode 100644
index 0000000..40c884d
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/edit_tools.html
@@ -0,0 +1,44 @@
+<!--
+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="view show">
+  <p>
+    Showing 1-<%= numModels %> of <%= totalRows %> rows
+    <% if (updateSeq) { %>
+      -- Update Sequence: <%= updateSeq %>
+    <% } %>
+    <% if (requestDuration) { %>
+  <span class="view-request-duration">
+    View request duration: <strong> <%= requestDuration %> </strong> 
+   </span>
+   <% } %>
+  </p>
+  <table class="all-docs table table-striped table-condensed">
+    <tbody></tbody>
+  </table>
+  <!--
+  <div class="pagination pagination-centered">
+    <ul>
+      <li class="disabled"><a href="#">&laquo;</a></li>
+      <li class="active"><a href="#">1</a></li>
+      <li><a href="#">2</a></li>
+      <li><a href="#">3</a></li>
+      <li><a href="#">4</a></li>
+      <li><a href="#">5</a></li>
+      <li><a href="#">&raquo;</a></li>
+    </ul>
+  </div>
+  -->
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/index_menu_item.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/index_menu_item.html b/share/www/fauxton/src/app/templates/documents/index_menu_item.html
new file mode 100644
index 0000000..1b141b2
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/index_menu_item.html
@@ -0,0 +1,17 @@
+<!--
+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.
+-->
+
+<a id="<%= ddoc %>_<%= index %>" href="#database/<%= database %>/_design/<%= ddoc %>/_view/<%= index %>" class="toggle-view">
+  <%= ddoc %><span class="divider">/</span><%= index %>
+</a>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/index_row_docular.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/index_row_docular.html b/share/www/fauxton/src/app/templates/documents/index_row_docular.html
new file mode 100644
index 0000000..3835453
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/index_row_docular.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<td class="select"><input type="checkbox"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%- doc.prettyJSON() %></pre>
+    <% if (doc.isEditable()) { %>
+      <div class="btn-group">
+        <a href="#<%= doc.url('app') %>" class="btn btn-small edits">Edit <%= doc.docType() %></a>
+        <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
+      </div>
+    <% } %>
+  </div>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/index_row_tabular.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/index_row_tabular.html b/share/www/fauxton/src/app/templates/documents/index_row_tabular.html
new file mode 100644
index 0000000..f5f68fa
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/index_row_tabular.html
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+
+<td class="select"><input type="checkbox"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%- JSON.stringify(doc.get("key")) %></pre>
+  </div>
+</td>
+<td>
+  <div>
+    <pre class="prettyprint"><%- JSON.stringify(doc.get("value")) %></pre>
+  </div>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/jumpdoc.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/jumpdoc.html b/share/www/fauxton/src/app/templates/documents/jumpdoc.html
new file mode 100644
index 0000000..c6f4652
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/jumpdoc.html
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+
+<form id="jump-to-doc" class="form-inline" >
+  <label id="jump-to-doc-label" class="fonticon-search">
+    <input type="text" id="jump-to-doc-id" class="input-large" placeholder="Document ID"></input>
+  </label>
+</form>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/search.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/search.html b/share/www/fauxton/src/app/templates/documents/search.html
new file mode 100644
index 0000000..bb84891
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/search.html
@@ -0,0 +1,15 @@
+<!--
+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.
+-->
+
+<input id="searchbox" type="text" class="span12" placeholder="Search by doc id, view key or search index">
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/sidebar.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/sidebar.html b/share/www/fauxton/src/app/templates/documents/sidebar.html
new file mode 100644
index 0000000..8a73ae9
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/sidebar.html
@@ -0,0 +1,67 @@
+<!--
+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 id="sidenav">
+  <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 class="icon-file" href="<%= db_url %>">Docs</a></li>
+          <li><a class="icon-lock" href="<%= permissions_url %>">Permissions</a></li>
+          <li><a class="icon-forward" href="<%= changes_url %>">Changes</a></li>
+          <% _.each(docLinks, function (link) { %>
+          <li><a class="<%= link.icon %>" href="<%= database_url + '/' + link.url %>"><%= link.title %></a></li>
+          <% }); %>
+        </ul>
+      </div>
+
+      <div class="btn-group">
+        <button class="btn dropdown-toggle dropdown-toggle-btn" data-toggle="dropdown">
+          New
+          <span class="caret"></span>
+        </button>
+        <ul class="dropdown-menu">
+          <!-- dropdown menu links -->
+          <li>
+          <a id="doc" href="#<%= database.url('app') %>/new">Document</a>
+          </li>
+          <li>
+          <a href="#<%= database.url('app') %>/new_view">Secondary Index</a>
+           <% _.each(newLinks, function (item) { %>
+           <a href="#<%= database.url('app') %>/<%=item.url%>"> <%= item.name %></a>
+           <% }); %>
+          </li>
+        </ul>
+      </div>
+        <button id="delete-database" class="btn"><i class="icon-trash"></i> Database</button>
+    </div>
+  </header>
+
+  <nav>
+    <ul class="nav nav-list">
+      <li class="active"><a id="all-docs" href="#<%= database.url('index') %>?limit=<%= docLimit %>" class="toggle-view"> All documents</a></li>
+      <li><a id="design-docs" href='#<%= database.url("index") %>?limit=<%= docLimit %>&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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/tabs.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/tabs.html b/share/www/fauxton/src/app/templates/documents/tabs.html
new file mode 100644
index 0000000..f8b0c4b
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/tabs.html
@@ -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.
+-->
+
+<ul class="nav nav-tabs">
+  <li class="active"><a href="<%= db_url %>">Docs</a></li>
+  <li id="changes"><a  href="<%= changes_url %>">Changes</a></li>
+</ul>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c14b2991/share/www/fauxton/src/app/templates/documents/upload_modal.html
----------------------------------------------------------------------
diff --git a/share/www/fauxton/src/app/templates/documents/upload_modal.html b/share/www/fauxton/src/app/templates/documents/upload_modal.html
new file mode 100644
index 0000000..05f129c
--- /dev/null
+++ b/share/www/fauxton/src/app/templates/documents/upload_modal.html
@@ -0,0 +1,42 @@
+<!--
+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="modal hide fade">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>Upload an Attachment</h3>
+  </div>
+  <div class="modal-body">
+    <div id="modal-error" class="alert alert-error hide" style="font-size: 16px;"> </div>
+    <form id="file-upload" class="form" method="post">
+      <p class="help-block">
+      Please select the file you want to upload as an attachment to this document. 
+      Please note that this will result in the immediate creation of a new revision of the document, 
+      so it's not necessary to save the document after the upload.
+      </p>
+      <input id="_attachments" type="file" name="_attachments">
+      <input id="_rev" type="hidden" name="_rev" value="" >
+      <br/>
+    </form>
+
+    <div class="progress progress-info">
+      <div class="bar" style="width: 0%"></div>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <a href="#" data-dismiss="modal" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
+    <a href="#" id="upload-btn" class="btn btn-primary button green save fonticon-circle-check">Upload</a>
+  </div>
+</div>
+