You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2013/07/22 12:25:18 UTC

[01/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Updated Branches:
  refs/heads/1684-feature-db-updates d405490d4 -> ea07223c2 (forced update)


Update CHANGES for 1.3.1

COUCHDB-1696


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

Branch: refs/heads/1684-feature-db-updates
Commit: cd42fa02b994f332f925685240290c1d3612b8fb
Parents: 6f1742e
Author: Dave Cottlehuber <dc...@apache.org>
Authored: Tue May 28 17:55:55 2013 +0200
Committer: Dave Cottlehuber <dc...@apache.org>
Committed: Tue May 28 17:55:55 2013 +0200

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


http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd42fa02/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 578efaa..08cb160 100644
--- a/CHANGES
+++ b/CHANGES
@@ -42,7 +42,7 @@ Apache CouchDB CHANGES
 # Misc:
 
 #  * Improve documentation: better structure, improve language, less duplication.
-#  * Improvements to test suite.
+#  * Improvements to test suite and VPATH build system.
 
 Version 1.3.0
 -------------


[45/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Mention docs in README, call out changelog.


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

Branch: refs/heads/1684-feature-db-updates
Commit: c89302f224297c5d07987e99f3d4cca89ac5043d
Parents: 89efb74
Author: Dirkjan Ochtman <dj...@apache.org>
Authored: Thu Jul 18 14:30:52 2013 +0200
Committer: Dirkjan Ochtman <dj...@apache.org>
Committed: Thu Jul 18 14:30:52 2013 +0200

----------------------------------------------------------------------
 README.rst | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c89302f2/README.rst
----------------------------------------------------------------------
diff --git a/README.rst b/README.rst
index 33b854d..9a43aa8 100644
--- a/README.rst
+++ b/README.rst
@@ -20,8 +20,16 @@ Follow the proper instructions to get CouchDB installed on your system.
 
 If you're having problems, skip to the next section.
 
-Troubleshooting
-----------------
+Documentation
+-------------
+
+We have documentation:
+
+    http://docs.couchdb.org/
+
+They include a changelog:
+
+    http://docs.couchdb.org/en/latest/changelog.html
 
 For troubleshooting, see:
 


[41/50] [abbrv] Improved development server

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/css-tests.css
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/css-tests.css b/src/fauxton/assets/less/bootstrap/tests/css-tests.css
deleted file mode 100644
index 9edaf69..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/css-tests.css
+++ /dev/null
@@ -1,139 +0,0 @@
-/*!
- * Bootstrap CSS Tests
- */
-
-
-/* Remove background image */
-body {
-  background-image: none;
-}
-
-/* Space out subhead */
-.subhead {
-  margin-bottom: 36px;
-}
-/*h4 {
-  margin-bottom: 5px;
-}
-*/
-
-.type-test {
-  margin-bottom: 20px;
-  padding: 0 20px 20px;
-  background: url(../../docs/assets/img/grid-baseline-20px.png);
-}
-.type-test h1,
-.type-test h2,
-.type-test h3,
-.type-test h4,
-.type-test h5,
-.type-test h6 {
-  background-color: rgba(255,0,0,.2);
-}
-
-
-/* colgroup tests */
-.col1 {
-  background-color: rgba(255,0,0,.1);
-}
-.col2 {
-  background-color: rgba(0,255,0,.1);
-}
-.col3 {
-  background-color: rgba(0,0,255,.1);
-}
-
-
-/* Fluid row inputs */
-#rowInputs .row > [class*=span],
-#fluidRowInputs .row-fluid > [class*=span] {
-  background-color: rgba(255,0,0,.1);
-}
-
-
-/* Fluid grid */
-.fluid-grid {
-  margin-bottom: 45px;
-}
-.fluid-grid .row {
-  height: 40px;
-  padding-top: 10px;
-  margin-top: 10px;
-  color: #ddd;
-  text-align: center;
-}
-.fluid-grid .span1 {
-  background-color: #999;
-}
-
-
-/* Gradients */
-
-[class^="gradient-"] {
-  width: 100%;
-  height: 400px;
-  margin: 20px 0;
-  -webkit-border-radius: 5px;
-     -moz-border-radius: 5px;
-          border-radius: 5px;
-}
-
-.gradient-horizontal {
-  background-color: #333333;
-  background-image: -moz-linear-gradient(left, #555555, #333333);
-  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#555555), to(#333333));
-  background-image: -webkit-linear-gradient(left, #555555, #333333);
-  background-image: -o-linear-gradient(left, #555555, #333333);
-  background-image: linear-gradient(to right, #555555, #333333);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff555555', endColorstr='#ff333333', GradientType=1);
-}
-
-.gradient-vertical {
-  background-color: #474747;
-  background-image: -moz-linear-gradient(top, #555555, #333333);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#333333));
-  background-image: -webkit-linear-gradient(top, #555555, #333333);
-  background-image: -o-linear-gradient(top, #555555, #333333);
-  background-image: linear-gradient(to bottom, #555555, #333333);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff555555', endColorstr='#ff333333', GradientType=0);
-}
-
-.gradient-directional {
-  background-color: #333333;
-  background-image: -moz-linear-gradient(45deg, #555555, #333333);
-  background-image: -webkit-linear-gradient(45deg, #555555, #333333);
-  background-image: -o-linear-gradient(45deg, #555555, #333333);
-  background-image: linear-gradient(45deg, #555555, #333333);
-  background-repeat: repeat-x;
-}
-
-.gradient-vertical-three {
-  background-color: #8940a5;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#00b3ee), color-stop(50%, #7a43b6), to(#c3325f));
-  background-image: -webkit-linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -moz-linear-gradient(top, #00b3ee, #7a43b6 50%, #c3325f);
-  background-image: -o-linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-image: linear-gradient(#00b3ee, #7a43b6 50%, #c3325f);
-  background-repeat: no-repeat;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff00b3ee', endColorstr='#ffc3325f', GradientType=0);
-}
-
-.gradient-radial {
-  background-color: #333333;
-  background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(#555555), to(#333333));
-  background-image: -webkit-radial-gradient(circle, #555555, #333333);
-  background-image: -moz-radial-gradient(circle, #555555, #333333);
-  background-image: -o-radial-gradient(circle, #555555, #333333);
-  background-repeat: no-repeat;
-}
-
-.gradient-striped {
-  background-color: #555555;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/css-tests.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/css-tests.html b/src/fauxton/assets/less/bootstrap/tests/css-tests.html
deleted file mode 100644
index c0cb148..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/css-tests.html
+++ /dev/null
@@ -1,1296 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>CSS Tests · Twitter Bootstrap</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <link href="../../docs/assets/css/docs.css" rel="stylesheet">
-    <link href="../../docs/assets/js/google-code-prettify/prettify.css" rel="stylesheet">
-
-    <!-- CSS just for the tests page -->
-    <link href="css-tests.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-
-  <!-- Navbar
-    ================================================== -->
-    <div class="navbar navbar-inverse navbar-fixed-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="brand" href="../../docs/index.html">Bootstrap</a>
-        </div>
-      </div>
-    </div>
-
-
-<!-- Masthead
-================================================== -->
-<header class="jumbotron subhead" id="overview">
-  <div class="container">
-    <h1>CSS Tests</h1>
-    <p class="lead">One stop shop for quick debugging and edge-case tests of CSS.</p>
-  </div>
-</header>
-
-
-<div class="bs-docs-canvas">
-
-  <div class="container">
-
-
-
-<!-- Typography
-================================================== -->
-
-<div class="page-header">
-  <h1>Typography</h1>
-</div>
-
-<div class="row">
-  <div class="span6">
-    <div class="type-test">
-      <h1>h1. Heading 1</h1>
-      <h2>h2. Heading 2</h2>
-      <h3>h3. Heading 3</h3>
-      <h4>h4. Heading 4</h4>
-      <h5>h5. Heading 5</h5>
-      <h6>h6. Heading 6</h6>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-    </div>
-  </div>
-  <div class="span6">
-    <div class="type-test">
-      <h1>h1. Heading 1</h1>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h2>h2. Heading 2</h2>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h3>h3. Heading 3</h3>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h4>h4. Heading 4</h4>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h5>h5. Heading 5</h5>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-      <h6>h6. Heading 6</h6>
-      <p>Sed posuere consectetur est at lobortis. Maecenas sed diam eget risus varius blandit sit amet non magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
-    </div>
-  </div>
-</div>
-
-
-
-<!-- Responsive images
-================================================== -->
-
-<div class="page-header">
-  <h1>Responsive images</h1>
-</div>
-
-<div class="row">
-  <div class="span4">
-    <img src="http://placehold.it/600x600" height="200">
-  </div>
-  <div class="span4">
-    <img src="http://placehold.it/600x600">
-  </div>
-  <div class="span4">
-    <img src="http://placehold.it/600x600">
-  </div>
-</div>
-
-<br>
-
-<div class="row">
-  <div class="span4">
-    <img src="http://placehold.it/600x900" style="width: 200px;">
-  </div>
-  <div class="span4">
-    <img src="http://placehold.it/200x300">
-  </div>
-  <div class="span4">
-    <img src="http://placehold.it/600x600">
-  </div>
-</div>
-
-<br><br>
-
-
-
-
-<!-- Fluid grid
-================================================== -->
-
-<div class="page-header">
-  <h1>Fluid grids</h1>
-</div>
-
-<div class="fluid-grid">
-  <div class="row">
-    <div class="span12">12
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span11">11
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span1">1
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span10">10
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span2">2
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span9">9
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span3">3
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span8">8
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span4">4
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span7">7
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span5">5
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-  <div class="row">
-    <div class="span6">6
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-    <div class="span6">6
-      <div class="row-fluid">
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-        <div class="span1">1</div>
-      </div>
-    </div>
-  </div>
-</div> <!-- fluid grids -->
-
-
-
-<!-- Tables
-================================================== -->
-
-<div class="page-header">
-  <h1>Tables</h1>
-</div>
-
-<div class="row">
-  <div class="span6">
-    <h4>Bordered without thead</h4>
-    <table class="table table-bordered">
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-    </table>
-    <h4>Bordered without thead, with caption</h4>
-    <table class="table table-bordered">
-      <caption>Table caption</caption>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-    </table>
-    <h4>Bordered without thead, with colgroup</h4>
-    <table class="table table-bordered">
-      <colgroup>
-        <col class="col1">
-        <col class="col2">
-        <col class="col3">
-      </colgroup>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-    <h4>Bordered with thead, with colgroup</h4>
-    <table class="table table-bordered">
-      <colgroup>
-        <col class="col1">
-        <col class="col2">
-        <col class="col3">
-      </colgroup>
-      <thead>
-        <tr>
-          <th>A</th>
-          <th>B</th>
-          <th>C</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-  </div><!--/span-->
-  <div class="span6">
-    <h4>Bordered with thead and caption</h4>
-    <table class="table table-bordered">
-      <caption>Table caption</caption>
-      <thead>
-        <tr>
-          <th>1</th>
-          <th>2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td>2</td>
-          <td>3</td>
-        </tr>
-      </tbody>
-      <tfoot>
-        <tr>
-          <td>3</td>
-          <td>6</td>
-          <td>9</td>
-        </tr>
-      </tfoot>
-    </table>
-    <h4>Bordered with rowspan and colspan</h4>
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th>1</th>
-          <th>2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div><!--/span-->
-</div><!--/row-->
-
-
-<h4>Grid sizing</h4>
-<div class="row">
-  <div class="span12">
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th class="span3">1</th>
-          <th class="span4">2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</div><!--/row-->
-
-<h4>Fluid grid sizing</h4>
-<div class="row-fluid">
-  <div class="span12">
-    <table class="table table-bordered">
-      <thead>
-        <tr>
-          <th class="span3">1</th>
-          <th class="span4">2</th>
-          <th>3</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td colspan="2">1 and 2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td>1</td>
-          <td rowspan="2">2</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td rowspan="2">1</td>
-          <td>3</td>
-        </tr>
-        <tr>
-          <td colspan="2">2 and 3</td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</div><!--/row-->
-
-
-
-<!-- Forms
-================================================== -->
-
-<div class="page-header">
-  <h1>Forms</h1>
-</div>
-
-<h4>Buttons and button groups</h4>
-<form class="form-inline">
-  <button class="btn btn-success">Save</button>
-  <button class="btn btn-info">Add new</button>
-  <div class="btn-group">
-    <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
-      <i class="icon-user"></i> User
-      <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Profile</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Sign Out</a></li>
-    </ul>
-  </div>
-</form>
-
-<h4>Horizontal form errors</h4>
-<form class="form-horizontal">
-  <div class="control-group error">
-    <label class="control-label" for="inputError">Radio with error</label>
-    <div class="controls">
-      <label class="radio">
-        <input type="radio" id="inputError"> Oh hai
-      </label>
-      <span class="help-inline">Please correct the error</span>
-    </div>
-  </div>
-</form>
-
-<div class="row">
-  <div class="span4">
-    <h4>Prepend and append on inputs</h4>
-    <form>
-      <div class="controls">
-        <div class="input-prepend">
-          <span class="add-on">@</span>
-          <input class="span2" id="prependedInput" size="16" type="text">
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-append">
-          <input class="span2" id="prependedInput" size="16" type="text">
-          <span class="add-on">@</span>
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-prepend input-append">
-          <span class="add-on">$</span>
-          <input class="span2" id="prependedInput" size="16" type="text">
-          <span class="add-on">.00</span>
-        </div>
-      </div>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <h4>Prepend and append with uneditable</h4>
-    <form>
-      <div class="input-prepend">
-        <span class="add-on">$</span>
-        <span class="span2 uneditable-input">Some value here</span>
-      </div>
-      <div class="input-append">
-        <span class="span2 uneditable-input">Some value here</span>
-        <span class="add-on">.00</span>
-      </div>
-      <div class="input-prepend input-append">
-        <span class="add-on">$</span>
-        <span class="span2 uneditable-input">Some value here</span>
-        <span class="add-on">.00</span>
-      </div>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <h4>Prepend with type="submit"</h4>
-    <form class="form-search">
-      <div class="input-append">
-        <input type="text" class="span2 search-query" value="" name="q">
-        <input type="submit" value="Search" class="btn">
-      </div>
-    </form>
-    <div class="input-append">
-      <input type="text" class="span2" value="" name="">
-      <input type="submit" value="Button" class="btn">
-    </div>
-    <div class="input-append">
-      <input type="text" size="16" id="appendedInputButtons" class="span2">
-      <input type="submit" value="Search" class="btn">
-      <button type="button" class="btn">Options</button>
-    </div>
-  </div><!--/span-->
-</div><!--/row-->
-
-<h4>Fluid prepended and appended inputs</h4>
-<div class="row-fluid">
-  <div class="span6">
-    <form>
-      <div class="controls">
-        <div class="input-prepend">
-          <span class="add-on">@</span><input class="span2" id="prependedInput" size="16" type="text">
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-append">
-          <input class="span2" id="prependedInput" size="16" type="text"><span class="add-on">@</span>
-        </div>
-      </div>
-      <div class="controls">
-        <div class="input-prepend input-append">
-          <span class="add-on">$</span><input class="span2" id="prependedInput" size="16" type="text"><span class="add-on">.00</span>
-        </div>
-      </div>
-    </form>
-  </div>
-</div>
-
-<h4>Fixed row with inputs</h4>
-<p>Inputs should not extend past the light red background, set on their parent, a <code>.span*</code> column.</p>
-
-<div class="rowInputs">
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span1" placeholder="span1">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span2" placeholder="span2">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span3" placeholder="span3">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span4" placeholder="span4">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span5" placeholder="span5">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span6" placeholder="span6">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span7" placeholder="span7">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span8" placeholder="span8">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span9" placeholder="span9">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span10" placeholder="span10">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span11" placeholder="span11">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row">
-    <div class="span12">
-      <input type="text" class="span12" placeholder="span12">
-    </div><!--/span-->
-  </div><!--/row-->
-</div>
-<br>
-
-<h4>Fluid row with inputs</h4>
-<p>Inputs should not extend past the light red background, set on their parent, a <code>.span*</code> column.</p>
-<div id="fluidRowInputs">
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span1" placeholder="span1">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span2" placeholder="span2">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span3" placeholder="span3">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span4" placeholder="span4">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span5" placeholder="span5">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span6" placeholder="span6">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span7" placeholder="span7">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span8" placeholder="span8">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span9" placeholder="span9">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span10" placeholder="span10">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span11" placeholder="span11">
-    </div><!--/span-->
-  </div><!--/row-->
-  <div class="row-fluid">
-    <div class="span12">
-      <input type="text" class="span12" placeholder="span12">
-    </div><!--/span-->
-  </div><!--/row-->
-</div>
-
-<br>
-
-<h4>Inline form in fluid row</h4>
-
-<div class="row-fluid">
-  <div class="span12">
-    <form class="form-inline">
-      <input type="text" class="span3" placeholder="Email">
-      <input type="password" class="span3" placeholder="Password">
-      <label class="checkbox">
-        <input type="checkbox"> Remember me
-      </label>
-      <button type="submit" class="btn">Sign in</button>
-    </form>
-  </div>
-</div>
-
-
-<br>
-
-
-<h4>Fluid textarea at .span12</h4>
-<div class="row-fluid">
-  <div class="span12">
-    <textarea class="span12"></textarea>
-  </div>
-</div>
-
-
-<br>
-
-
-<h4>Selects</h4>
-<form>
-  <select class="span4">
-    <option>Option</option>
-  </select>
-</form>
-
-
-<br>
-
-
-
-
-<!-- Dropdowns
-================================================== -->
-
-<div class="page-header">
-  <h1>Dropdowns</h1>
-</div>
-
-<h4>Dropdown link with hash URL</h4>
-<ul class="nav nav-pills">
-  <li class="active"><a href="#">Link</a></li>
-  <li><a href="#">Example link</a></li>
-  <li class="dropdown">
-    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
-      Dropdown <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Action</a></li>
-      <li><a href="#">Another action</a></li>
-      <li><a href="#">Something else here</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Separated link</a></li>
-    </ul>
-  </li>
-</ul>
-
-<h4>Dropdown link with custom URL and data-target</h4>
-<ul class="nav nav-pills">
-  <li class="active"><a href="#">Link</a></li>
-  <li><a href="#">Example link</a></li>
-  <li class="dropdown">
-    <a class="dropdown-toggle" data-toggle="dropdown" data-target="#" href="path/to/page.html">
-      Dropdown <span class="caret"></span>
-    </a>
-    <ul class="dropdown-menu">
-      <li><a href="#">Action</a></li>
-      <li><a href="#">Another action</a></li>
-      <li><a href="#">Something else here</a></li>
-      <li class="divider"></li>
-      <li><a href="#">Separated link</a></li>
-    </ul>
-  </li>
-</ul>
-
-<h4>Dropdown on a button</h4>
-<div style="position: relative;">
-  <button class="btn" type="button" data-toggle="dropdown">Dropdown <span class="caret"></span></button>
-  <ul class="dropdown-menu">
-    <li><a href="#">Action</a></li>
-    <li><a href="#">Another action</a></li>
-    <li><a href="#">Something else here</a></li>
-    <li class="divider"></li>
-    <li><a href="#">Separated link</a></li>
-  </ul>
-</div>
-
-<br>
-
-
-<!-- Thumbnails
-================================================== -->
-
-<div class="page-header">
-  <h1>Thumbnails</h1>
-</div>
-
-<h4>Default thumbnails (no grid sizing)</h4>
-<ul class="thumbnails">
-  <li class="thumbnail">
-    <img src="http://placehold.it/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img src="http://placehold.it/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img src="http://placehold.it/260x180" alt="">
-  </li>
-  <li class="thumbnail">
-    <img src="http://placehold.it/260x180" alt="">
-  </li>
-</ul>
-
-<!-- NOT CURRENTLY SUPPORTED
-<h4>Offset thumbnails</h4>
-<ul class="thumbnails">
-  <li class="span3 offset3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-</ul>
--->
-
-<h4>Standard grid sizing</h4>
-<ul class="thumbnails">
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3 offset3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-  <li class="span3">
-    <a href="#" class="thumbnail">
-      <img src="http://placehold.it/260x180" alt="">
-    </a>
-  </li>
-</ul>
-
-<h4>Fluid thumbnails</h4>
-<div class="row-fluid">
-  <div class="span8">
-    <ul class="thumbnails">
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img src="http://placehold.it/260x180" alt="">
-        </a>
-      </li>
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img src="http://placehold.it/260x180" alt="">
-        </a>
-      </li>
-      <li class="span4">
-        <a href="#" class="thumbnail">
-          <img src="http://placehold.it/260x180" alt="">
-        </a>
-      </li>
-    </ul>
-  </div>
-</div>
-
-
-
-<!-- Tabs
-================================================== -->
-
-<div class="page-header">
-  <h1>Tabs</h1>
-</div>
-
-<div class="tabbable tabs-left" style="margin-bottom: 18px;">
-  <ul class="nav nav-tabs">
-    <li class="active"><a href="#tab1" data-toggle="tab">Section 1</a></li>
-    <li><a href="#tab2" data-toggle="tab">Section 2</a></li>
-    <li><a href="#tab3" data-toggle="tab">Section 3</a></li>
-  </ul>
-  <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
-    <div class="tab-pane active" id="tab1">
-      <p>I'm in Section 1.</p>
-
-      <div class="tabbable" style="background: #f5f5f5; padding: 20px;">
-        <ul class="nav nav-tabs">
-          <li class="active"><a href="#tab1-1" data-toggle="tab">1.1</a></li>
-          <li><a href="#tab1-2" data-toggle="tab">1.2</a></li>
-          <li><a href="#tab1-3" data-toggle="tab">1.3</a></li>
-        </ul>
-        <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
-          <div class="tab-pane active" id="tab1-1">
-            <p>I'm in Section 1.1.</p>
-          </div>
-          <div class="tab-pane" id="tab1-2">
-            <p>I'm in Section 1.2.</p>
-          </div>
-          <div class="tab-pane" id="tab1-3">
-            <p>I'm in Section 1.3.</p>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="tab-pane" id="tab2">
-      <p>Howdy, I'm in Section 2.</p>
-    </div>
-    <div class="tab-pane" id="tab3">
-      <p>What up girl, this is Section 3.</p>
-    </div>
-  </div>
-</div> <!-- /tabbable -->
-
-<br>
-
-
-<!-- Labels
-================================================== -->
-
-<div class="page-header">
-  <h1>Labels</h1>
-</div>
-
-<div class="row">
-  <div class="span4">
-    <h4>Inline label</h4>
-    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam <span class="label label-warning">Label name</span> eget risus varius blandit sit amet non magna. Fusce <code>.class-name</code> dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
-  </div><!--/span-->
-  <div class="span4">
-    <form class="form-horizontal">
-      <label>Example label</label>
-      <input type="text" placeholder="Input"> <span class="help-inline"><span class="label">Hey!</span> Read this.</span>
-    </form>
-  </div><!--/span-->
-  <div class="span4">
-    <button class="btn">Action <span class="badge">2</span></button>
-    <button class="btn">Action <span class="label">2</span></button>
-  </div><!--/span-->
-</div><!--/row-->
-
-<br>
-
-
-<!-- Button groups
-================================================== -->
-
-<div class="page-header">
-  <h1>Buttons</h1>
-</div>
-
-<table class="table table-bordered">
-  <tbody>
-    <tr>
-      <td>
-        Maecenas faucibus mollis interdum. Nulla vitae elit libero, a pharetra augue. Donec ullamcorper nulla non metus auctor fringilla. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
-      </td>
-      <td>
-        <div class="btn-group">
-          <button class="btn">1</button>
-          <button class="btn">2</button>
-          <button class="btn">3</button>
-          <button class="btn">4</button>
-        </div>
-      </td>
-    </tr>
-  </tbody>
-</table>
-
-<h4>Mini buttons: text and icon</h4>
-<div class="btn-group">
-  <button class="btn btn-mini">Button text</button>
-  <button class="btn btn-mini"><i class="icon-cog"></i></button>
-</div>
-
-<br>
-
-
-
-<!-- Responsive utility classes
-================================================== -->
-
-<div class="page-header">
-  <h1>Responsive utility classes</h1>
-</div>
-
-<h4>Visible on...</h4>
-<ul class="responsive-utilities-test visible-on">
-  <li>Phone<span class="visible-phone">✔ Phone</span></li>
-  <li>Tablet<span class="visible-tablet">✔ Tablet</span></li>
-  <li>Desktop<span class="visible-desktop">✔ Desktop</span></li>
-</ul>
-<ul class="responsive-utilities-test visible-on">
-  <li>Phone + Tablet<span class="visible-phone visible-tablet">✔ Phone + Tablet</span></li>
-  <li>Tablet + Desktop<span class="visible-tablet visible-desktop">✔ Tablet + Desktop</span></li>
-  <li>All<span class="visible-phone visible-tablet visible-desktop">✔ All</span></li>
-</ul>
-
-<h4>Hidden on...</h4>
-<ul class="responsive-utilities-test hidden-on">
-  <li>Phone<span class="hidden-phone">✔ Phone</span></li>
-  <li>Tablet<span class="hidden-tablet">✔ Tablet</span></li>
-  <li>Desktop<span class="hidden-desktop">✔ Desktop</span></li>
-</ul>
-<ul class="responsive-utilities-test hidden-on">
-  <li>Phone + Tablet<span class="hidden-phone hidden-tablet">✔ Phone + Tablet</span></li>
-  <li>Tablet + Desktop<span class="hidden-tablet hidden-desktop">✔ Tablet + Desktop</span></li>
-  <li>All<span class="hidden-phone hidden-tablet hidden-desktop">✔ All</span></li>
-</ul>
-
-
-
-<!-- Gradients
-================================================== -->
-
-<div class="page-header">
-  <h1>Gradients</h1>
-</div>
-
-<h4>Horizontal</h4>
-<div class="gradient-horizontal"></div>
-
-<h4>Vertical</h4>
-<div class="gradient-vertical"></div>
-
-<h4>Directional</h4>
-<div class="gradient-directional"></div>
-
-<h4>Three colors</h4>
-<div class="gradient-vertical-three"></div>
-
-<h4>Radial</h4>
-<div class="gradient-radial"></div>
-
-<h4>Striped</h4>
-<div class="gradient-striped"></div>
-
-
-
-
-
-
-
-    </div><!-- /container -->
-
-
-
-    <!-- Footer
-    ================================================== -->
-    <footer class="footer">
-      <div class="container">
-        <p class="pull-right"><a href="#">Back to top</a></p>
-        <p>Designed and built with all the love in the world <a href="http://twitter.com/twitter" target="_blank">@twitter</a> by <a href="http://twitter.com/mdo" target="_blank">@mdo</a> and <a href="http://twitter.com/fat" target="_blank">@fat</a>.</p>
-        <p>Code licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License v2.0</a>. Documentation licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
-        <p>Icons from <a href="http://glyphicons.com">Glyphicons Free</a>, licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
-        <ul class="footer-links">
-          <li><a href="http://blog.getbootstrap.com">Read the blog</a></li>
-          <li><a href="https://github.com/twitter/bootstrap/issues?state=open">Submit issues</a></li>
-          <li><a href="https://github.com/twitter/bootstrap/wiki">Roadmap and changelog</a></li>
-        </ul>
-      </div>
-    </footer>
-
-</div>
-
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/google-code-prettify/prettify.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-    <script src="../../docs/assets/js/application.js"></script>
-
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/forms-responsive.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/forms-responsive.html b/src/fauxton/assets/less/bootstrap/tests/forms-responsive.html
deleted file mode 100644
index 846d5b4..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/forms-responsive.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <form class="container">
-
-      <div class="page-header">
-        <h1>Fixed grid</h1>
-      </div>
-
-      <h3>Vertical alignment</h3>
-      <input type="text" class="span2" placeholder="span2">
-      <select class="span2"><option>span2</option></select>
-      <span class="uneditable-input span2">span1</span>
-
-      <h3>Width across elements</h3>
-      <div>
-        <input type="text" class="span2" placeholder="span2">
-      </div>
-      <div>
-        <select class="span2"><option>span2</option></select>
-      </div>
-      <div>
-        <span class="uneditable-input span2">span2</span>
-      </div>
-
-
-      <div class="page-header">
-        <h1>Fluid grid</h1>
-      </div>
-
-      <div class="row-fluid">
-        <input type="text" class="span2" placeholder="span2">
-        <select class="span2"><option>span2</option></select>
-        <span class="uneditable-input span2">span1</span>
-      </div>
-
-    </form> <!-- /container -->
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/forms.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/forms.html b/src/fauxton/assets/less/bootstrap/tests/forms.html
deleted file mode 100644
index a63d728..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/forms.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <form class="container">
-
-      <div class="page-header">
-        <h1>Form controls</h1>
-      </div>
-
-      <div class="row">
-        <div class="span4">
-
-          <label>Select</label>
-          <select>
-            <option>Select</option>
-            <option>Option 2</option>
-            <option>Option 3</option>
-          </select>
-
-          <hr>
-
-          <label>textarea</label>
-          <textarea>Textarea</textarea>
-
-          <hr>
-
-          <label>text</label>
-          <input type="text" value="Text input">
-
-          <hr>
-
-          <label>password</label>
-          <input type="password" value="Password input">
-
-          <hr>
-
-          <label>checkbox</label>
-          <input type="checkbox" value="">
-
-          <hr>
-
-          <label>radio</label>
-          <input type="radio" value="">
-
-          <hr>
-
-          <label>button</label>
-          <input type="button" value="Button">
-
-          <hr>
-
-          <label>submit</label>
-          <input type="submit" value="Submit">
-
-          <hr>
-
-          <label>reset</label>
-          <input type="reset" value="Reset">
-
-        </div><!-- /span4 -->
-        <div class="span4">
-
-          <label>file</label>
-          <input type="file" value="">
-
-          <hr>
-
-          <label>hidden</label>
-          <input type="hidden" value="hidden">
-
-          <hr>
-
-          <label>image</label>
-          <input type="image" value="">
-
-          <hr>
-
-          <label>datetime</label>
-          <input type="datetime" value="">
-
-          <hr>
-
-          <label>datetime-local</label>
-          <input type="datetime-local" value="">
-
-          <hr>
-
-          <label>date</label>
-          <input type="date" value="">
-
-          <hr>
-
-          <label>month</label>
-          <input type="month" value="">
-
-          <hr>
-
-          <label>time</label>
-          <input type="time" value="">
-
-          <hr>
-
-          <label>week</label>
-          <input type="week" value="">
-
-        </div><!-- /span4 -->
-        <div class="span4">
-
-          <label>number</label>
-          <input type="number" value="">
-
-          <hr>
-
-          <label>range</label>
-          <input type="range" value="">
-
-          <hr>
-
-          <label>email</label>
-          <input type="email" value="">
-
-          <hr>
-
-          <label>url</label>
-          <input type="url" value="">
-
-          <hr>
-
-          <label>search</label>
-          <input type="search" value="">
-
-          <hr>
-
-          <label>tel</label>
-          <input type="tel" value="">
-
-          <hr>
-
-          <label>color</label>
-          <input type="color" value="">
-
-        </div><!-- /span4 -->
-      </div><!-- /row -->
-
-    </form> <!-- /container -->
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/navbar-fixed-top.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/navbar-fixed-top.html b/src/fauxton/assets/less/bootstrap/tests/navbar-fixed-top.html
deleted file mode 100644
index 97b86fd..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/navbar-fixed-top.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 60px;
-        padding-bottom: 30px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <!-- Fixed navbar -->
-    <div class="navbar navbar-fixed-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-          </a>
-          <a class="brand" href="#">Project name</a>
-          <div class="nav-collapse collapse">
-            <ul class="nav">
-              <li class="active"><a href="#">Home</a></li>
-              <li><a href="#about">About</a></li>
-              <li><a href="#contact">Contact</a></li>
-              <li class="dropdown">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                <ul class="dropdown-menu">
-                  <li><a href="#">Action</a></li>
-                  <li><a href="#">Another action</a></li>
-                  <li><a href="#">Something else here</a></li>
-                  <li class="divider"></li>
-                  <li class="nav-header">Nav header</li>
-                  <li><a href="#">Separated link</a></li>
-                  <li><a href="#">One more separated link</a></li>
-                </ul>
-              </li>
-            </ul>
-            <ul class="nav pull-right">
-              <li><a href="./navbar.html">Default</a></li>
-              <li><a href="./navbar-static-top.html">Static top</a></li>
-              <li class="active"><a href="./navbar-fixed-top.html">Fixed top</a></li>
-            </ul>
-          </div><!--/.nav-collapse -->
-        </div>
-      </div>
-    </div>
-
-    <div class="container">
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/navbar-static-top.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/navbar-static-top.html b/src/fauxton/assets/less/bootstrap/tests/navbar-static-top.html
deleted file mode 100644
index 505ecb6..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/navbar-static-top.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-bottom: 30px;
-      }
-      .hero-unit {
-        margin-top: 20px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <!-- Static navbar -->
-    <div class="navbar navbar-static-top">
-      <div class="navbar-inner">
-        <div class="container">
-          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-          </a>
-          <a class="brand" href="#">Project name</a>
-          <div class="nav-collapse collapse">
-            <ul class="nav">
-              <li class="active"><a href="#">Home</a></li>
-              <li><a href="#about">About</a></li>
-              <li><a href="#contact">Contact</a></li>
-              <li class="dropdown">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                <ul class="dropdown-menu">
-                  <li><a href="#">Action</a></li>
-                  <li><a href="#">Another action</a></li>
-                  <li><a href="#">Something else here</a></li>
-                  <li class="divider"></li>
-                  <li class="nav-header">Nav header</li>
-                  <li><a href="#">Separated link</a></li>
-                  <li><a href="#">One more separated link</a></li>
-                </ul>
-              </li>
-            </ul>
-          <ul class="nav pull-right">
-            <li><a href="./navbar.html">Default</a></li>
-            <li class="active"><a href="./navbar-static-top.html">Static top</a></li>
-            <li><a href="./navbar-fixed-top.html">Fixed top</a></li>
-          </ul>
-          </div><!--/.nav-collapse -->
-        </div>
-      </div>
-    </div>
-
-
-    <div class="container">
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/navbar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/navbar.html b/src/fauxton/assets/less/bootstrap/tests/navbar.html
deleted file mode 100644
index c72da71..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/navbar.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Bootstrap, from Twitter</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 0;
-        padding-bottom: 30px;
-      }
-      .navbar {
-        margin-top: 20px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <div class="container">
-
-      <!-- Static navbar -->
-      <div class="navbar">
-        <div class="navbar-inner">
-          <div class="container">
-            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-              <span class="icon-bar"></span>
-              <span class="icon-bar"></span>
-              <span class="icon-bar"></span>
-            </a>
-            <a class="brand" href="#">Project name</a>
-            <div class="nav-collapse collapse">
-              <ul class="nav">
-                <li class="active"><a href="#">Home</a></li>
-                <li><a href="#about">About</a></li>
-                <li><a href="#contact">Contact</a></li>
-                <li class="dropdown">
-                  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
-                  <ul class="dropdown-menu">
-                    <li><a href="#">Action</a></li>
-                    <li><a href="#">Another action</a></li>
-                    <li><a href="#">Something else here</a></li>
-                    <li class="divider"></li>
-                    <li class="nav-header">Nav header</li>
-                    <li><a href="#">Separated link</a></li>
-                    <li><a href="#">One more separated link</a></li>
-                  </ul>
-                </li>
-              </ul>
-              <ul class="nav pull-right">
-                <li class="active"><a href="./navbar.html">Default</a></li>
-                <li><a href="./navbar-static-top.html">Static top</a></li>
-                <li><a href="./navbar-fixed-top.html">Fixed top</a></li>
-              </ul>
-            </div><!--/.nav-collapse -->
-          </div>
-        </div>
-      </div>
-
-      <!-- Main hero unit for a primary marketing message or call to action -->
-      <div class="hero-unit">
-        <h1>Navbar example</h1>
-        <p>This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
-        <p>
-          <a class="btn btn-large btn-primary" href="../components.html#navbar">View navbar docs &raquo;</a>
-        </p>
-      </div>
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/package.json
----------------------------------------------------------------------
diff --git a/src/fauxton/package.json b/src/fauxton/package.json
index 5b63675..ad69f2f 100644
--- a/src/fauxton/package.json
+++ b/src/fauxton/package.json
@@ -11,21 +11,25 @@
     "grunt": "~0.4.1",
     "grunt-cli": "~0.1.6",
     "couchapp": "~0.9.1",
-    "grunt-contrib": "~0.5.0",
     "grunt-contrib-cssmin": "~0.5.0",
+    "grunt-contrib-clean": "~0.4.1",
+    "grunt-contrib-jshint": "~0.6.0",
+    "grunt-contrib-concat": "~0.3.0",
+    "grunt-contrib-less": "~0.5.0",
+    "grunt-contrib-jst": "~0.5.0",
+    "grunt-contrib-watch": "~0.4.4",
     "grunt-contrib-uglify": "~0.2.0",
+    "grunt-contrib-copy": "~0.4.1",
     "grunt-couchapp": "~0.1.0",
     "grunt-exec": "~0.4.0",
     "grunt-init": "~0.2.0",
-    "grunt-jasmine-task": "~0.2.3",
-    "grunt-requirejs": "~0.3.3",
+    "grunt-contrib-requirejs": "~0.4.1",
     "underscore": "~1.4.2",
     "url": "~0.7.9",
     "urls": "~0.0.3",
-    "express": "~3.0.6",
-    "http-proxy": "~0.10.2"
+    "http-proxy": "~0.10.2",
+    "send": "~0.1.1"
   },
-  "devDependencies": {},
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 9716ceb..910488b 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -7,12 +7,23 @@
   { "name": "auth" }
   ],
     "template": {
-      "src": "assets/index.underscore",
-      "dest": "dist/debug/index.html",
-      "variables": {
-        "assets_root": "./",
-        "requirejs": "require.js",
-        "base": null
+      "development": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "/assets/js/libs/require.js",
+          "css": "./css/index.css",
+          "base": null
+        }
+      },
+      "release": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "./js/require.js",
+          "css": "./css/index.css",
+          "base": null
+        }
       }
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/tasks/couchserver.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/couchserver.js b/src/fauxton/tasks/couchserver.js
index 0d1dc7a..baf2b30 100644
--- a/src/fauxton/tasks/couchserver.js
+++ b/src/fauxton/tasks/couchserver.js
@@ -13,17 +13,18 @@
 module.exports = function (grunt) {
   var log = grunt.log;
 
- grunt.registerTask("couchserver", 'Run a couch dev proxy server', function () {
+  grunt.registerTask("couchserver", 'Run a couch dev proxy server', function () {
     var fs = require("fs"),
-    path = require("path"),
-    httpProxy = require('http-proxy'),
-    express = require("express"),
-    options = grunt.config('couchserver'),
-    app = express();
+        path = require("path"),
+        http = require("http"),
+        httpProxy = require('http-proxy'),
+        send = require('send'),
+        options = grunt.config('couchserver');
 
     // Options
-    var dist_dir = options.dist || './dist/debug/';
-    var port = options.port || 8000;
+    var dist_dir = options.dist || './dist/debug/',
+        app_dir = './app',
+        port = options.port || 8000;
 
     // Proxy options with default localhost
     var proxy_settings = options.proxy || {
@@ -37,44 +38,56 @@ module.exports = function (grunt) {
     // inform grunt that this task is async
     var done = this.async();
 
-    // serve any javascript or css files from here
-    app.get(/\.css$|\.js$|img/, function (req, res) {
-      res.sendfile(path.join(dist_dir,req.url));
-    });
-
     // create proxy to couch for all couch requests
     var proxy = new httpProxy.HttpProxy(proxy_settings);
 
-    // serve main index file from here
-    // Also proxy out to the base CouchDB host for handle_welcome_req.
-    // We still need to reach the top level CouchDB host even through
-    // the proxy.
-    app.get('/', function (req, res) {
-      var accept = req.headers.accept.split(',');
-      if (accept[0] == 'application/json') {
-        proxy.proxyRequest(req, res);
-      } else {
-        res.sendfile(path.join(dist_dir, 'index.html'));
-      }
-    });
+    http.createServer(function (req, res) {
+      var url = req.url,
+          accept = req.headers.accept.split(','),
+          filePath;
+
+      if (!!url.match(/assets/)) {
+        // serve any javascript or css files from here assets dir
+        filePath = path.join('./',req.url);
+      } else if (!!url.match(/\.css|img/)) {
+        filePath = path.join(dist_dir,req.url);
+      } else if (!!url.match(/\/js/)) {
+        // serve any javascript or files from dist debug dir
+        filePath = path.join(dist_dir,req.url);
+      } else if (!!url.match(/\.js$|\.html$/)) {
+        // server js from app directory
+        filePath = path.join(app_dir,req.url.replace('/_utils/fauxton/app',''));
+      } else if (url === '/' && accept[0] !== 'application/json') {
+        // serve main index file from here
+        filePath = path.join(dist_dir, 'index.html');
+      };
+
+      if (filePath) {
+        return send(req, filePath)
+          .on('error', function (err) {
+            if (err.status === 404) {
+              log.writeln('Could not locate', filePath);
+            } else {
+              log.writeln('ERROR', filePath, err);
+            }
+          })
+          .pipe(res);
+      } 
 
-    app.all('*', function (req, res) {
       proxy.proxyRequest(req, res);
-    });
+    }).listen(port);
 
     // Fail this task if any errors have been logged
     if (grunt.errors) {
       return false;
     }
 
-    var watch = grunt.util.spawn({cmd: 'bbb', grunt: true, args: ['watch']}, function (error, result, code) {/* log.writeln(String(result));*/ });
+    var watch = grunt.util.spawn({cmd: 'grunt', grunt: true, args: ['watch']}, function (error, result, code) {/* log.writeln(String(result));*/ });
 
     watch.stdout.pipe(process.stdout);
     watch.stderr.pipe(process.stderr);
 
     log.writeln('Listening on ' + port);
-    app.listen(port);
-
   });
 
 };

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/tasks/fauxton.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/fauxton.js b/src/fauxton/tasks/fauxton.js
index a26f9f8..ac48cf3 100644
--- a/src/fauxton/tasks/fauxton.js
+++ b/src/fauxton/tasks/fauxton.js
@@ -20,7 +20,7 @@ module.exports = function(grunt) {
     grunt.file.write(data.dest, tmpl(data.variables));
   });
 
-  grunt.registerMultiTask('get_deps', 'Fetch external dependencies', function() {
+  grunt.registerMultiTask('get_deps', 'Fetch external dependencies', function(version) {
     grunt.log.writeln("Fetching external dependencies");
 
     var path = require('path');

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/tasks/helper.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/helper.js b/src/fauxton/tasks/helper.js
index a7eddbf..b3a9fbd 100644
--- a/src/fauxton/tasks/helper.js
+++ b/src/fauxton/tasks/helper.js
@@ -31,10 +31,12 @@ exports.init = function(grunt) {
       this.readSettingsFile().deps.forEach(callback);
     },
 
-    watchFiles: function (defaults) {
+    watchFiles: function (fileExtensions, defaults) {
       return _.reduce(this.readSettingsFile().deps, function (files, dep) { 
         if (dep.path) { 
-          files.push(path.join(dep.path, '**/*'));
+          _.each(fileExtensions, function (fileExtension) {
+            files.push(path.join(dep.path, '**/*' + fileExtension ));
+          });
         }
         return files
       }, defaults);


[21/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fix badrecord error in EXIT handling

The second item in the by_pid tuple is the name not a #db{} record.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 0bb6787cec9c986feb1f6c16a280f2c0506dec0d
Parents: a27adbf
Author: Robert Newson <rn...@apache.org>
Authored: Sat Jun 15 19:47:50 2013 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Sat Jun 15 19:47:50 2013 +0100

----------------------------------------------------------------------
 src/couchdb/couch_server.erl | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0bb6787c/src/couchdb/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_server.erl b/src/couchdb/couch_server.erl
index 8189761..4aceb55 100644
--- a/src/couchdb/couch_server.erl
+++ b/src/couchdb/couch_server.erl
@@ -428,8 +428,7 @@ handle_info({'EXIT', _Pid, config_change}, Server) ->
     {noreply, shutdown, Server};
 handle_info({'EXIT', Pid, Reason}, Server) ->
     Server2 = case ets:lookup(couch_dbs_by_pid, Pid) of
-    [{Pid, Db}] ->
-        DbName = Db#db.name,
+    [{Pid, DbName}] ->
 
         % If the Pid is known, the name should be as well.
         % If not, that's an error, which is why there is no [] clause.
@@ -440,7 +439,7 @@ handle_info({'EXIT', Pid, Reason}, Server) ->
                 io_lib:format(
                     "To open the database `~s`, Apache CouchDB "
                     "must be built with Erlang OTP R13B04 or higher.",
-                    [Db]
+                    [DbName]
                 );
             true ->
                 io_lib:format("Error opening database ~p: ~p", [DbName, Reason])
@@ -462,7 +461,7 @@ handle_info({'EXIT', Pid, Reason}, Server) ->
         true = ets:delete(couch_dbs_by_name, DbName),
 
         case ets:lookup(couch_sys_dbs, DbName) of
-        [{Db, _}] ->
+        [{DbName, _}] ->
             true = ets:delete(couch_sys_dbs, DbName),
             Server;
         [] ->


[25/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
fix perms on install instructions


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

Branch: refs/heads/1684-feature-db-updates
Commit: 9cf9b53d2cee9976a5b215af52672838abec0d6b
Parents: cbbd7d5
Author: Jan Lehnardt <ja...@apache.org>
Authored: Thu Jun 20 23:46:31 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Thu Jun 20 23:46:31 2013 +0200

----------------------------------------------------------------------
 INSTALL.Unix | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cf9b53d/INSTALL.Unix
----------------------------------------------------------------------
diff --git a/INSTALL.Unix b/INSTALL.Unix
index 854fd13..76ba8eb 100644
--- a/INSTALL.Unix
+++ b/INSTALL.Unix
@@ -230,10 +230,10 @@ Change the ownership of the CouchDB directories by running:
 
 Change the permission of the CouchDB directories by running:
 
-    chmod 0770 /usr/local/etc/couchdb
-    chmod 0770 /usr/local/var/lib/couchdb
-    chmod 0770 /usr/local/var/log/couchdb
-    chmod 0770 /usr/local/var/run/couchdb
+    chmod 0755 /usr/local/etc/couchdb
+    chmod 0755 /usr/local/var/lib/couchdb
+    chmod 0755 /usr/local/var/log/couchdb
+    chmod 0755 /usr/local/var/run/couchdb
 
 Running as a Daemon
 -------------------


[50/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Import couch_dbupdates from rcouch.

This creates a new top level API endpoint: `/_db_updates`
that returns a line of JSON for each database event along
with the database name.

A database event is one of `created`, `updated`, `deleted`.

The API endpoint supports a `?feed=` parameter with the
options: `longpoll`, `continuous` and `eventsource`.

A second parameter `timeout=` specifies when the server should
close the connection.

`longpoll` closes the connection after a single notification.
It is the default option.

`continuous` keeps a socket open until the specified `timeout`
or 60 seconds by default.

`heartbeat` decides whether to send a newline character on
`timeout` to avoid clients closing the connection prematurely.

`eventsource` works like continuous, but sends the data in
EventSource format. See http://dev.w3.org/html5/eventsource/

The parameters are modelled after the existing `/_changes` API
endpoint. Note that `/_db_updates` does not support resuming
of notifications via a sequence ID.

This is a port of the existing DbUpdateNotification interface
to the HTTP API.

Functional changes compared to rcouch:

 - make _db_updates an admin-only resource

Docs:

 - updated api/misc to include basic info on `/_db_updates`

License:

  Apache 2 license, updated LICENSE.

Notice:

  (c) 2012 Benoit Chesneau, updated NOTICE.

Tests:

 - only manual testing of the various API differences due to
   complications with asynchronous HTTP requests in the JS
   test suite and total annoyance of overly complicated
   ibrowse/httpc modules for writing etap tests.

Recommendation to ship this as EXPERIMENTAL until we have tests.


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

Branch: refs/heads/1684-feature-db-updates
Commit: ea07223c21c102b59099249f8702509f735b5c74
Parents: 7005818
Author: Jan Lehnardt <ja...@apache.org>
Authored: Mon Mar 4 12:02:24 2013 +0100
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Mon Jul 22 12:24:17 2013 +0200

----------------------------------------------------------------------
 LICENSE | 1 +
 NOTICE  | 1 +
 2 files changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ea07223c/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 31ed94d..e1cce03 100644
--- a/LICENSE
+++ b/LICENSE
@@ -606,6 +606,7 @@ For the share/server/coffee-script.js file
   OTHER DEALINGS IN THE SOFTWARE.
 
 <<<<<<< HEAD
+<<<<<<< HEAD
 For src/fauxton/apps/modules/pouchdb
 
   Copyright (c) 2012 Dale Harvey et al

http://git-wip-us.apache.org/repos/asf/couchdb/blob/ea07223c/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 0d1407e..3e9099c 100644
--- a/NOTICE
+++ b/NOTICE
@@ -87,6 +87,7 @@ This product also includes the following third-party components:
    Copyright 2012, Jeremy Ashkenas
 
 <<<<<<< HEAD
+<<<<<<< HEAD
  * almond.js (http://github.com/jrburke/almond)
 
   Copyright 2011, The Dojo Foundation


[23/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Spacing nits


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

Branch: refs/heads/1684-feature-db-updates
Commit: 85f3c8ed5a62ea48dd27c7f078ced6d3aa2c4dca
Parents: dfd39d5
Author: Russell Branca <ch...@gmail.com>
Authored: Thu May 30 11:02:42 2013 -0700
Committer: Russell Branca <ch...@gmail.com>
Committed: Mon Jun 17 16:19:11 2013 -0700

----------------------------------------------------------------------
 src/fauxton/app/modules/databases/routes.js | 8 ++++----
 src/fauxton/app/router.js                   | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/85f3c8ed/src/fauxton/app/modules/databases/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/routes.js b/src/fauxton/app/modules/databases/routes.js
index 7b45413..5772ee8 100644
--- a/src/fauxton/app/modules/databases/routes.js
+++ b/src/fauxton/app/modules/databases/routes.js
@@ -32,7 +32,7 @@ function(app, FauxtonAPI, Databases, Views) {
 
     routes: {
       "": "allDatabases",
-      "index.html": "allDatabases", 
+      "index.html": "allDatabases",
       "_all_dbs(:params)": "allDatabases"
     },
 
@@ -45,7 +45,7 @@ function(app, FauxtonAPI, Databases, Views) {
       this.deferred = FauxtonAPI.Deferred();
 
       this.sidebarView = this.setView("#sidebar-content", new Views.Sidebar({
-          collection: this.databases
+        collection: this.databases
       }));
     },
 
@@ -54,7 +54,7 @@ function(app, FauxtonAPI, Databases, Views) {
           dbPage = params.page;
 
       this.databasesView = this.setView("#dashboard-content", new Views.List({
-          collection: this.databases
+        collection: this.databases
       }));
 
       this.databasesView.setPage(dbPage);
@@ -75,7 +75,7 @@ function(app, FauxtonAPI, Databases, Views) {
       return [deferred];
     }
   });
-  
+
   Databases.RouteObjects = [AllDbsRouteObject];
 
   return Databases;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/85f3c8ed/src/fauxton/app/router.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/router.js b/src/fauxton/app/router.js
index fea1b32..e90e6e7 100644
--- a/src/fauxton/app/router.js
+++ b/src/fauxton/app/router.js
@@ -71,7 +71,7 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents
           authPromise.then(function () {
             routeObject.routeCallback(route, args);
             routeObject.renderWith(route, masterLayout, args);
-          }, function () { 
+          }, function () {
             FauxtonAPI.auth.authDeniedCb();
          });
 


[27/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
support R16B01

Due to non-OTP-ness, couch need to start its own OTP apps. R16B01
requires asn1 as a dependency for public_key.
Closes COUCHDB-1833.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 136b28991fa40b92cde6e544f49c8fd18b9340ab
Parents: 5b7e4bd
Author: Dave Cottlehuber <dc...@apache.org>
Authored: Fri Jun 21 15:12:26 2013 +0200
Committer: Dave Cottlehuber <dc...@apache.org>
Committed: Fri Jun 21 15:12:26 2013 +0200

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


http://git-wip-us.apache.org/repos/asf/couchdb/blob/136b2899/src/couchdb/couch_app.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_app.erl b/src/couchdb/couch_app.erl
index 24b2f3a..9644877 100644
--- a/src/couchdb/couch_app.erl
+++ b/src/couchdb/couch_app.erl
@@ -20,7 +20,7 @@
 
 start(_Type, DefaultIniFiles) ->
     IniFiles = get_ini_files(DefaultIniFiles),
-    case start_apps([crypto, public_key, sasl, inets, oauth, ssl, ibrowse, syntax_tools, compiler, xmerl, mochiweb, os_mon]) of
+    case start_apps([crypto, asn1, public_key, sasl, inets, oauth, ssl, ibrowse, syntax_tools, compiler, xmerl, mochiweb, os_mon]) of
     ok ->
         couch_server_sup:start_link(IniFiles);
     {error, Reason} ->


[17/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Ajax loader helper

Added disableLoader & loaderClassname attribute to views, for showing ajax spinners. Included default class and spinner image.
Added the loader to app-container as well, to run on the whole page while the routeObjects load.

fixes #1802


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

Branch: refs/heads/1684-feature-db-updates
Commit: 17413bca6494f727e55dd641a2f70f167b8b5aed
Parents: 7cb6442
Author: suelockwood <de...@gmail.com>
Authored: Thu Jun 6 11:12:38 2013 -0400
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Jun 10 10:22:58 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/api.js               |  22 ++++++++++++++++++----
 src/fauxton/assets/img/loader.gif    | Bin 0 -> 5193 bytes
 src/fauxton/assets/less/fauxton.less |   5 +++++
 3 files changed, 23 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/17413bca/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index e13a41d..58c413d 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -46,6 +46,10 @@ function(app, Fauxton) {
       return null;
     },
 
+    loaderClassname: 'loader',
+
+    disableLoader: false,
+
     hasRendered: function () {
       return !!this.__manager__.hasRendered;
     },
@@ -234,6 +238,8 @@ function(app, Fauxton) {
     crumbs: [],
     layout: "with_sidebar",
     apiUrl: null,
+    disableLoader: false,
+    loaderClassname: 'loader',
     renderedState: false,
     establish: function() {},
     route: function() {},
@@ -252,6 +258,11 @@ function(app, Fauxton) {
         masterLayout.setTemplate(this.layout);
       }
 
+      //add page loader. "app-container" shouldn't be overwritten. Even if a new index.underscore is provided in settings.json
+      if (!this.disableLoader) {
+        $('#app-container').addClass(this.loaderClassname);
+      }
+
       masterLayout.clearBreadcrumbs();
       var crumbs = this.get('crumbs');
 
@@ -262,14 +273,17 @@ function(app, Fauxton) {
       }
 
       FauxtonAPI.when(this.establish()).done(function(resp) {
+        if (!this.disableLoader) {
+          $('#app-container').removeClass(this.loaderClassname);
+        }
         _.each(routeObject.getViews(), function(view, selector) {
           if(view.hasRendered()) { return; }
-
+          if (!view.disableLoader){ $(selector).addClass(view.loaderClassname);}
           masterLayout.setView(selector, view);
-
           FauxtonAPI.when(view.establish()).then(function(resp) {
+            if (!view.disableLoader) $(selector).removeClass(view.loaderClassname);
             masterLayout.renderView(selector);
-          }, function(resp) {
+            }, function(resp) {
             view.establishError = {
               error: true,
               reason: resp
@@ -286,7 +300,7 @@ function(app, Fauxton) {
             }
           });
         });
-      });
+      }.bind(this));
 
       if (this.get('apiUrl')) masterLayout.apiBar.update(this.get('apiUrl'));
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/17413bca/src/fauxton/assets/img/loader.gif
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/img/loader.gif b/src/fauxton/assets/img/loader.gif
new file mode 100644
index 0000000..96ff188
Binary files /dev/null and b/src/fauxton/assets/img/loader.gif differ

http://git-wip-us.apache.org/repos/asf/couchdb/blob/17413bca/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 0bbde28..445b815 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -93,3 +93,8 @@ pre.view-code-error {
   height: auto;
   min-height: 50px;
 }
+
+.loader {
+  background: url('../img/loader.gif') center center no-repeat;
+  min-height:  100px;
+}


[34/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: Change select header to data attribute


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

Branch: refs/heads/1684-feature-db-updates
Commit: 2f5ae05136bc68a4753c5bb09b6cd2f9f4e6bcd0
Parents: 6e8f47c
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Jul 1 15:51:53 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Jul 1 15:51:53 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/config/base.js          | 2 +-
 src/fauxton/app/addons/config/routes.js        | 2 +-
 src/fauxton/app/addons/logs/base.js            | 2 +-
 src/fauxton/app/addons/logs/routes.js          | 2 +-
 src/fauxton/app/addons/stats/base.js           | 2 +-
 src/fauxton/app/addons/stats/routes.js         | 2 +-
 src/fauxton/app/api.js                         | 4 ++--
 src/fauxton/app/modules/databases/routes.js    | 2 +-
 src/fauxton/app/modules/fauxton/base.js        | 2 +-
 src/fauxton/app/templates/fauxton/nav_bar.html | 2 +-
 10 files changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/config/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/base.js b/src/fauxton/app/addons/config/base.js
index 6d3261c..f589b16 100644
--- a/src/fauxton/app/addons/config/base.js
+++ b/src/fauxton/app/addons/config/base.js
@@ -21,7 +21,7 @@ define([
 
 function(app, FauxtonAPI, Config) {
   Config.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Config", href: "#_config", id: "config"});
+    FauxtonAPI.addHeaderLink({title: "Config", href: "#_config"});
   };
 
   return Config;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/config/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/routes.js b/src/fauxton/app/addons/config/routes.js
index 3f8d7ac..f521c53 100644
--- a/src/fauxton/app/addons/config/routes.js
+++ b/src/fauxton/app/addons/config/routes.js
@@ -30,7 +30,7 @@ function(app, FauxtonAPI, Config) {
 
     roles: ["_admin"],
 
-    selectedHeaderId: "config",
+    selectedHeader: "Config",
 
     crumbs: [
       {"name": "Config","link": "_config"}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/logs/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/base.js b/src/fauxton/app/addons/logs/base.js
index dfecb03..c17e159 100644
--- a/src/fauxton/app/addons/logs/base.js
+++ b/src/fauxton/app/addons/logs/base.js
@@ -21,7 +21,7 @@ define([
 
 function(app, FauxtonAPI, Log) {
   Log.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Log", href: "#_log", id: "log"});
+    FauxtonAPI.addHeaderLink({title: "Log", href: "#_log"});
   };
 
   return Log;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/logs/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/routes.js b/src/fauxton/app/addons/logs/routes.js
index 0961f7b..7c498b0 100644
--- a/src/fauxton/app/addons/logs/routes.js
+++ b/src/fauxton/app/addons/logs/routes.js
@@ -32,7 +32,7 @@ function(app, FauxtonAPI, Log) {
       "_log": "showLog"
     },
 
-    selectedHeaderId: "log",
+    selectedHeader: "Log",
 
     roles: ["_admin"],
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/stats/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/base.js b/src/fauxton/app/addons/stats/base.js
index ac09437..4721399 100644
--- a/src/fauxton/app/addons/stats/base.js
+++ b/src/fauxton/app/addons/stats/base.js
@@ -19,7 +19,7 @@ define([
 function(app, FauxtonAPI, Stats) {
 
   Stats.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Statistics", href: "#stats", id: "stats"});
+    FauxtonAPI.addHeaderLink({title: "Statistics", href: "#stats"});
   };
 
   return Stats;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/addons/stats/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/routes.js b/src/fauxton/app/addons/stats/routes.js
index 994b4e2..5f1affe 100644
--- a/src/fauxton/app/addons/stats/routes.js
+++ b/src/fauxton/app/addons/stats/routes.js
@@ -26,7 +26,7 @@ function(app, FauxtonAPI, Stats) {
       "_stats": "showStats"
     },
 
-    selectedHeaderId: "stats",
+    selectedHeader: "Statistics",
 
     initialize: function () {
       this.stats = new Stats.Collection();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index b54a080..4732528 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -258,8 +258,8 @@ function(app, Fauxton) {
         masterLayout.setTemplate(this.layout);
           $('#nav-links li').removeClass('active');
 
-        if (this.selectedHeaderId) {
-          $('#nav-links li#' + this.selectedHeaderId).addClass('active');
+        if (this.selectedHeader) {
+          $('#nav-links li[data-nav-name="' + this.selectedHeader + '"]').addClass('active');
         }
       }
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/modules/databases/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/routes.js b/src/fauxton/app/modules/databases/routes.js
index 88c939f..fe1a441 100644
--- a/src/fauxton/app/modules/databases/routes.js
+++ b/src/fauxton/app/modules/databases/routes.js
@@ -40,7 +40,7 @@ function(app, FauxtonAPI, Databases, Views) {
       return this.databases.url();
     },
 
-    selectedHeaderId: "database",
+    selectedHeader: "Databases",
 
     initialize: function() {
       this.databases = new Databases.List();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
index 3d7d93d..716e9e7 100644
--- a/src/fauxton/app/modules/fauxton/base.js
+++ b/src/fauxton/app/modules/fauxton/base.js
@@ -64,7 +64,7 @@ function(app, Backbone) {
     template: "templates/fauxton/nav_bar",
     // TODO: can we generate this list from the router?
     navLinks: [
-      {href:"#/_all_dbs", title:"Databases", id: "database"}
+      {href:"#/_all_dbs", title:"Databases"}
     ],
 
     initialize: function() {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2f5ae051/src/fauxton/app/templates/fauxton/nav_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/nav_bar.html b/src/fauxton/app/templates/fauxton/nav_bar.html
index decc07a..75731e0 100644
--- a/src/fauxton/app/templates/fauxton/nav_bar.html
+++ b/src/fauxton/app/templates/fauxton/nav_bar.html
@@ -25,7 +25,7 @@ the License.
         <ul id="nav-links" class="nav pull-right">
           <% _.each(navLinks, function(link) { %>
             <% if (!link.view) { %>
-            <li id= "<%= link.id %>" ><a href="<%= link.href %>"><%= link.title %></a></li>
+            <li data-nav-name= "<%= link.title %>" ><a href="<%= link.href %>"><%= link.title %></a></li>
             <% } %>
           <% }); %>
         </ul>


[30/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: Set active nav tab

When a nav tab is clicked on that tab is now highlighted.
This fixes COUCHDB-1842


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

Branch: refs/heads/1684-feature-db-updates
Commit: bc4120a730eb18d671882a7684dd5460799139ee
Parents: f4b27ce
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Jun 27 17:09:20 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Jun 27 17:09:20 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/config/base.js          | 2 +-
 src/fauxton/app/addons/config/routes.js        | 2 ++
 src/fauxton/app/addons/logs/base.js            | 2 +-
 src/fauxton/app/addons/logs/routes.js          | 2 ++
 src/fauxton/app/addons/stats/base.js           | 2 +-
 src/fauxton/app/addons/stats/routes.js         | 2 ++
 src/fauxton/app/api.js                         | 5 +++++
 src/fauxton/app/modules/databases/routes.js    | 2 ++
 src/fauxton/app/modules/fauxton/base.js        | 3 +--
 src/fauxton/app/templates/fauxton/nav_bar.html | 2 +-
 10 files changed, 18 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/config/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/base.js b/src/fauxton/app/addons/config/base.js
index f589b16..6d3261c 100644
--- a/src/fauxton/app/addons/config/base.js
+++ b/src/fauxton/app/addons/config/base.js
@@ -21,7 +21,7 @@ define([
 
 function(app, FauxtonAPI, Config) {
   Config.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Config", href: "#_config"});
+    FauxtonAPI.addHeaderLink({title: "Config", href: "#_config", id: "config"});
   };
 
   return Config;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/config/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/routes.js b/src/fauxton/app/addons/config/routes.js
index d86715f..3f8d7ac 100644
--- a/src/fauxton/app/addons/config/routes.js
+++ b/src/fauxton/app/addons/config/routes.js
@@ -30,6 +30,8 @@ function(app, FauxtonAPI, Config) {
 
     roles: ["_admin"],
 
+    selectedHeaderId: "config",
+
     crumbs: [
       {"name": "Config","link": "_config"}
     ],

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/logs/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/base.js b/src/fauxton/app/addons/logs/base.js
index c17e159..dfecb03 100644
--- a/src/fauxton/app/addons/logs/base.js
+++ b/src/fauxton/app/addons/logs/base.js
@@ -21,7 +21,7 @@ define([
 
 function(app, FauxtonAPI, Log) {
   Log.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Log", href: "#_log"});
+    FauxtonAPI.addHeaderLink({title: "Log", href: "#_log", id: "log"});
   };
 
   return Log;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/logs/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/routes.js b/src/fauxton/app/addons/logs/routes.js
index 1023ffe..0961f7b 100644
--- a/src/fauxton/app/addons/logs/routes.js
+++ b/src/fauxton/app/addons/logs/routes.js
@@ -32,6 +32,8 @@ function(app, FauxtonAPI, Log) {
       "_log": "showLog"
     },
 
+    selectedHeaderId: "log",
+
     roles: ["_admin"],
 
     apiUrl: function() {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/stats/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/base.js b/src/fauxton/app/addons/stats/base.js
index 4721399..ac09437 100644
--- a/src/fauxton/app/addons/stats/base.js
+++ b/src/fauxton/app/addons/stats/base.js
@@ -19,7 +19,7 @@ define([
 function(app, FauxtonAPI, Stats) {
 
   Stats.initialize = function() {
-    FauxtonAPI.addHeaderLink({title: "Statistics", href: "#stats"});
+    FauxtonAPI.addHeaderLink({title: "Statistics", href: "#stats", id: "stats"});
   };
 
   return Stats;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/addons/stats/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/routes.js b/src/fauxton/app/addons/stats/routes.js
index 32017c3..994b4e2 100644
--- a/src/fauxton/app/addons/stats/routes.js
+++ b/src/fauxton/app/addons/stats/routes.js
@@ -26,6 +26,8 @@ function(app, FauxtonAPI, Stats) {
       "_stats": "showStats"
     },
 
+    selectedHeaderId: "stats",
+
     initialize: function () {
       this.stats = new Stats.Collection();
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index 58c413d..b54a080 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -256,6 +256,11 @@ function(app, Fauxton) {
       // Only want to redo the template if its a full render
       if (!this.renderedState) {
         masterLayout.setTemplate(this.layout);
+          $('#nav-links li').removeClass('active');
+
+        if (this.selectedHeaderId) {
+          $('#nav-links li#' + this.selectedHeaderId).addClass('active');
+        }
       }
 
       //add page loader. "app-container" shouldn't be overwritten. Even if a new index.underscore is provided in settings.json

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/modules/databases/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/routes.js b/src/fauxton/app/modules/databases/routes.js
index 5772ee8..88c939f 100644
--- a/src/fauxton/app/modules/databases/routes.js
+++ b/src/fauxton/app/modules/databases/routes.js
@@ -40,6 +40,8 @@ function(app, FauxtonAPI, Databases, Views) {
       return this.databases.url();
     },
 
+    selectedHeaderId: "database",
+
     initialize: function() {
       this.databases = new Databases.List();
       this.deferred = FauxtonAPI.Deferred();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
index b69f4ae..3d7d93d 100644
--- a/src/fauxton/app/modules/fauxton/base.js
+++ b/src/fauxton/app/modules/fauxton/base.js
@@ -64,11 +64,10 @@ function(app, Backbone) {
     template: "templates/fauxton/nav_bar",
     // TODO: can we generate this list from the router?
     navLinks: [
-      {href:"#/_all_dbs", title:"Databases"}
+      {href:"#/_all_dbs", title:"Databases", id: "database"}
     ],
 
     initialize: function() {
-      this.on("link:add", this.render, this);
     },
 
     serialize: function() {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bc4120a7/src/fauxton/app/templates/fauxton/nav_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/nav_bar.html b/src/fauxton/app/templates/fauxton/nav_bar.html
index ebe57d0..decc07a 100644
--- a/src/fauxton/app/templates/fauxton/nav_bar.html
+++ b/src/fauxton/app/templates/fauxton/nav_bar.html
@@ -25,7 +25,7 @@ the License.
         <ul id="nav-links" class="nav pull-right">
           <% _.each(navLinks, function(link) { %>
             <% if (!link.view) { %>
-              <li><a href="<%= link.href %>"><%= link.title %></a></li>
+            <li id= "<%= link.id %>" ><a href="<%= link.href %>"><%= link.title %></a></li>
             <% } %>
           <% }); %>
         </ul>


[10/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Create/edit and query views.

It is now also possible to preview views with pouch. Issue #1806


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

Branch: refs/heads/1684-feature-db-updates
Commit: 90e4da6ce6bda6cb72b325d2702fe9832e20ff59
Parents: eb364ff
Author: Garren Smith <ga...@gmail.com>
Authored: Thu May 16 08:34:54 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jun 4 15:46:38 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/api.js                          |   8 +-
 src/fauxton/app/modules/databases/resources.js  |   2 +-
 src/fauxton/app/modules/documents/resources.js  | 114 +++-
 src/fauxton/app/modules/documents/routes.js     | 186 +++---
 src/fauxton/app/modules/documents/views.js      | 591 ++++++++++++-------
 src/fauxton/app/modules/pouchdb/base.js         |  17 +-
 .../app/modules/pouchdb/pouchdb.mapreduce.js    |  50 +-
 .../app/templates/documents/all_docs_list.html  |  93 +--
 .../app/templates/documents/changes.html        |   4 +-
 .../app/templates/documents/view_editor.html    | 238 +++++---
 .../templates/layouts/with_tabs_sidebar.html    |   5 +-
 11 files changed, 790 insertions(+), 518 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index c506b1a..e13a41d 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -32,7 +32,8 @@ function(app, Fauxton) {
   // List of JSHINT errors to ignore
   // Gets around problem of anonymous functions not being a valid statement
   FauxtonAPI.excludedViewErrors = [
-    "Missing name in function declaration."
+    "Missing name in function declaration.",
+    "['{a}'] is better written in dot notation."
   ];
 
   FauxtonAPI.isIgnorableError = function(msg) {
@@ -54,8 +55,9 @@ function(app, Fauxton) {
     }
   });
 
-  FauxtonAPI.navigate = function(url) {
-    Backbone.history.navigate(url, true);
+  FauxtonAPI.navigate = function(url, _opts) {
+    var options = _.extend({trigger: true}, _opts );
+    app.router.navigate(url,options);
   };
 
   FauxtonAPI.addHeaderLink = function(link) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/resources.js b/src/fauxton/app/modules/databases/resources.js
index 6927fd5..04e6c1e 100644
--- a/src/fauxton/app/modules/databases/resources.js
+++ b/src/fauxton/app/modules/databases/resources.js
@@ -47,7 +47,7 @@ function(app, FauxtonAPI, Documents) {
       if (context === "index") {
         return "/database/" + this.id + "/_all_docs";
       } else if (context === "changes") {
-        return "/database/" + this.id + "/_changes?descending=true&limit=100";
+        return "/database/" + this.id + "/_changes?descending=true&limit=100&include_docs=true";
       } else if (context === "app") {
         return "/database/" + this.id;
       } else {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index f1a07c3..e313378 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -13,15 +13,10 @@
 define([
   "app",
 
-  "api",
-
-  // Views
-  "modules/documents/views"
-
-  // Plugins
+  "api"
 ],
 
-function(app, FauxtonAPI, Views) {
+function(app, FauxtonAPI) {
   var Documents = app.module();
 
   Documents.Doc = Backbone.Model.extend({
@@ -64,14 +59,61 @@ function(app, FauxtonAPI, Views) {
     hasViews: function() {
       if (!this.isDdoc()) return false;
       var doc = this.get('doc');
-      return doc && doc.views && _.keys(doc.views).length > 0;
+      if (doc) {
+        return doc && doc.views && _.keys(doc.views).length > 0;
+      }
+
+      var views = this.get('views');
+      return views && _.keys(views).length > 0;
     },
 
     getDdocView: function(view) {
       if (!this.isDdoc() || !this.hasViews()) return false;
 
       var doc = this.get('doc');
-      return doc.views[view];
+      if (doc) {
+        return doc.views[view];
+      }
+
+      return this.get('views')[view];
+    },
+
+    setDdocView: function (view, map, reduce) {
+      if (!this.isDdoc()) return false;
+      var views = this.get('views');
+
+      if (reduce) {
+        views[view] = {
+          map: map,
+          reduce: reduce
+        }; 
+      } else {
+        views[view].map = map;
+      }
+
+      this.set({views: views});
+
+      return true;
+    },
+
+    removeDdocView: function (viewName) {
+      if (!this.isDdoc()) return false;
+      var views = this.get('views');
+
+      delete views[viewName];
+      this.set({views: views});
+    },
+
+    dDocModel: function () {
+      if (!this.isDdoc()) return false;
+      var doc = this.get('doc');
+
+      if (doc) {
+        console.log('DOC', doc);
+        return new Documents.Doc(doc, {database: this.database});
+      } 
+
+      return this;
     },
 
     viewHasReduce: function(viewName) {
@@ -208,10 +250,10 @@ function(app, FauxtonAPI, Views) {
 
     initialize: function(_models, options) {
       this.database = options.database;
-      this.view = options.view;
-      this.design = options.design;
       this.params = _.extend({limit: 10, reduce: false}, options.params);
       this.idxType = "_view";
+      this.view = options.view;
+      this.design = options.design.replace('_design/','');
     },
 
     url: function() {
@@ -256,8 +298,56 @@ function(app, FauxtonAPI, Views) {
       return this.models;
     }
   });
+  
+  Documents.PouchIndexCollection = Backbone.Collection.extend({
+    model: Documents.ViewRow,
+
+    initialize: function(_models, options) {
+      this.database = options.database;
+      this.rows = options.rows;
+      this.view = options.view;
+      this.design = options.design.replace('_design/','');
+      this.params = _.extend({limit: 10, reduce: false}, options.params);
+      this.idxType = "_view";
+    },
+
+    url: function () {
+      return '';
+    },
+
+    fetch: function() {
+      var deferred = FauxtonAPI.Deferred();
+      this.reset(this.rows, {silent: true});
+
+      this.viewMeta = {
+        total_rows: this.rows.length,
+        offest: 0,
+        update_seq: false
+      };
+
+      deferred.resolve();
+      return deferred;
+    },
+
+    totalRows: function() {
+      console.log('rows');
+      console.log(this);
+      return this.viewMeta.total_rows || "unknown";
+    },
+
+    updateSeq: function() {
+      return this.viewMeta.update_seq || false;
+    },
+
+    buildAllDocs: function(){
+      this.fetch();
+    },
+
+    allDocs: function(){
+      return this.models;
+    }
+  });
 
-  Documents.Views = Views;
 
   return Documents;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 1a75559..e02ac93 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -16,7 +16,7 @@ define([
        "api",
 
        // Modules
-       "modules/documents/resources",
+       "modules/documents/views",
        "modules/databases/base"
 ],
 
@@ -32,7 +32,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       var databaseName = options[0], docID = options[1];
 
       this.database = this.database || new Databases.Model({id: databaseName});
-      this.doc = this.doc || new Documents.Doc({
+      this.doc = new Documents.Doc({
         _id: docID
       }, {
         database: this.database
@@ -62,7 +62,8 @@ function(app, FauxtonAPI, Documents, Databases) {
     code_editor: function (event) {
       this.tabsView.updateSelected('code_editor');
       this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({
-        model: this.doc
+        model: this.doc,
+        database: this.database
       }));
     },
 
@@ -78,96 +79,6 @@ function(app, FauxtonAPI, Documents, Databases) {
     }
   });
 
-  /*var newViewEditorCallback = function(databaseName) {
-    var data = {
-      database: new Databases.Model({id:databaseName})
-    };
-    data.designDocs = new Documents.AllDocs(null, {
-      database: data.database,
-      params: {startkey: '"_design"',
-        endkey: '"_design1"',
-        include_docs: true}
-    });
-
-    return {
-      layout: "with_tabs_sidebar",
-
-      data: data,
-
-      crumbs: [
-        {"name": "Databases", "link": "/_all_dbs"},
-        {"name": data.database.id, "link": data.database.url('app')}
-      ],
-
-      views: {
-        "#sidebar-content": new Documents.Views.Sidebar({
-          collection: data.designDocs
-        }),
-
-        "#tabs": new Documents.Views.Tabs({
-          collection: data.designDocs,
-          database: data.database
-        }),
-
-        "#dashboard-content": new Documents.Views.ViewEditor({
-          model: data.database,
-          ddocs: data.designDocs
-        })
-      },
-
-      apiUrl: data.database.url()
-    };
-  };*/
-
-  // HACK: this kind of works
-  // Basically need a way to share state between different routes, for
-  // instance making a new doc won't work for switching back and forth
-  // between code and field editors
-  /*var newDocCodeEditorCallback = function(databaseName) {
-    var data = {
-      database: new Databases.Model({id:databaseName}),
-      doc: new Documents.NewDoc(),
-      selected: "code_editor"
-    };
-    data.doc.database = data.database;
-    data.designDocs = new Documents.AllDocs(null, {
-      database: data.database,
-      params: {startkey: '"_design"',
-        endkey: '"_design1"',
-        include_docs: true}
-    });
-
-    var options = app.getParams();
-    options.include_docs = true;
-    data.database.buildAllDocs(options);
-
-    return {
-      layout: "one_pane",
-
-      data: data,
-
-      crumbs: [
-        {"name": "Databases", "link": "/_all_dbs"},
-        {"name": data.database.id, "link": Databases.databaseUrl(data.database)},
-        {"name": "new", "link": "#"}
-      ],
-
-      views: {
-        "#dashboard-content": new Documents.Views.Doc({
-          model: data.doc
-        }),
-
-        "#tabs": new Documents.Views.FieldEditorTabs({
-          selected: data.selected,
-          model: data.doc
-        })
-      },
-
-      apiUrl: data.doc.url()
-    };
-  };*/
-
-
   var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({
     layout: "with_tabs_sidebar",
 
@@ -180,6 +91,12 @@ function(app, FauxtonAPI, Documents, Databases) {
       "database/:database/new_view": "newViewEditor"
     },
 
+    events: {
+      "route:updateAllDocs": "updateAllDocsFromView",
+      "route:updatePreviewDocs": "updateAllDocsFromPreview",
+      "route:reloadDesignDocs": "reloadDesignDocs"
+    },
+
     initialize: function (route, masterLayout, options) {
       var docOptions = app.getParams();
       docOptions.include_docs = true;
@@ -207,6 +124,9 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
+    establish: function () {
+      return this.data.designDocs.fetch();
+    },
 
     allDocs: function(databaseName, options) {
       var docOptions = app.getParams(options);
@@ -220,7 +140,9 @@ function(app, FauxtonAPI, Documents, Databases) {
         this.sidebar.setSelectedTab('all-docs');
       }
 
-      this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({
+      if (this.viewEditor) { this.viewEditor.remove(); }
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         collection: this.data.database.allDocs
       }));
 
@@ -250,12 +172,22 @@ function(app, FauxtonAPI, Documents, Databases) {
         designDocs: this.data.designDocs
       };
 
-      this.setView("#dashboard-content", new Documents.Views.AllDocsList({
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        model: this.data.database,
+        ddocs: this.data.designDocs,
+        viewName: view,
+        params: params,
+        newView: false,
+        database: this.data.database,
+        ddocInfo: ddocInfo
+      }));
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: this.data.database,
         collection: this.data.indexedDocs,
         nestedView: Documents.Views.Row,
         viewList: true,
-        ddocInfo: ddocInfo,
-        params: params
+        ddocInfo: ddocInfo
       }));
 
       this.sidebar.setSelectedTab(ddoc + '_' + view);
@@ -271,17 +203,65 @@ function(app, FauxtonAPI, Documents, Databases) {
       this.apiUrl = this.data.indexedDocs.url();
     },
 
-    newViewEditor: function (event) {
-      // TODO: Get this working
-      this.setView("#dashboard-content", new Documents.Views.ViewEditor({
-        model: this.data.database,
-        ddocs: this.data.designDocs
+    newViewEditor: function () {
+      var params = app.getParams();
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
       }));
 
       this.sidebar.setSelectedTab('new-view');
+    },
 
-    }
+    updateAllDocsFromView: function (event) {
+      var view = event.view,
+          ddoc = event.ddoc;
+
+      this.data.indexedDocs = new Documents.IndexCollection(null, {
+        database: this.data.database,
+        design: ddoc,
+        view: view,
+        params: app.getParams()
+      });
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: this.data.database,
+        collection: this.data.indexedDocs,
+        nestedView: Documents.Views.Row,
+        viewList: true
+      }));
+    },
+
+    updateAllDocsFromPreview: function (event) {
+      var view = event.view,
+          rows = event.rows,
+          ddoc = event.ddoc;
 
+      this.data.indexedDocs = new Documents.PouchIndexCollection(null, {
+        database: this.data.database,
+        design: ddoc,
+        view: view,
+        rows: rows
+      });
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: this.data.database,
+        collection: this.data.indexedDocs,
+        nestedView: Documents.Views.Row,
+        viewList: true
+      }));
+    },
+
+    reloadDesignDocs: function (event) {
+      this.sidebar.forceRender();
+
+      if (event && event.selectedTab) {
+        this.sidebar.setSelectedTab(event.selectedTab);
+      }
+    }
   });
 
   var ChangesRouteObject = FauxtonAPI.RouteObject.extend({

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 17bf9af..f5cd882 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -11,20 +11,24 @@
 // the License.
 
 define([
-  "app",
+       "app",
 
-  "api",
+       "api",
 
-  // Libs
-  "codemirror",
-  "jshint",
+       "modules/documents/resources",
+       "modules/pouchdb/base",
+
+       // Libs
+       "codemirror",
+       "jshint",
+
+       // Plugins
+       "plugins/codemirror-javascript",
+       "plugins/prettify"
 
-  // Plugins
-  "plugins/codemirror-javascript",
-  "plugins/prettify"
 ],
 
-function(app, FauxtonAPI, Codemirror, JSHint) {
+function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
   var Views = {};
 
   Views.Tabs = FauxtonAPI.View.extend({
@@ -276,161 +280,50 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     template: "templates/documents/all_docs_list",
     events: {
       "click button.all": "selectAll",
-      "click button.bulk-delete": "bulkDelete",
-      "change form.view-query-update input": "updateFilters",
-      "change form.view-query-update select": "updateFilters",
-      "submit form.view-query-update": "updateView"
+      "click button.bulk-delete": "bulkDelete"
     },
 
     initialize: function(options){
       this.nestedView = options.nestedView || Views.Document;
       this.rows = {};
       this.viewList = !! options.viewList;
-      this.params = options.params;
+      this.database = options.database;
       if (options.ddocInfo) {
         this.designDocs = options.ddocInfo.designDocs;
         this.ddocID = options.ddocInfo.id;
       }
+      this.newView = options.newView || false;
     },
 
     establish: function() {
-      var deferreds = [
-        this.collection.fetch().error(function() {
-          // TODO: handle error requests that slip through
-          // This should just throw a notification, not break the page
-          console.log("ERROR: ", arguments);
-        })
-      ];
-      if (this.designDocs) {
-        deferreds.push(this.designDocs.fetch());
-      }
-      return deferreds;
+      if (this.newView) { return null; }
+
+      return this.collection.fetch().fail(function() {
+        // TODO: handle error requests that slip through
+        // This should just throw a notification, not break the page
+        console.log("ERROR: ", arguments);
+      });
     },
 
     selectAll: function(evt){
       $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
     },
 
-    // TODO:: HACK::
-    // Hack to grab info about the ddoc and current view to determine whether
-    // or not the view has a reduce function so we can display the advanced
-    // options appropriately.
-    //
-    // NOTE: we have this here temporarily because we have to wait for the
-    // design docs to be present.
-    //
-    // NOTE: We should probably refactor this View out into a separate View
-    // dedicated to displaying view query results.
-    // If nothing else, we should at least switch to something along the lines
-    // of fetchOnce to ensure we're not reloading the ddocs here in addition to
-    // the sidebar.
-    setDdocInfo: function() {
-      if (!this.ddoc && this.designDocs) {
-        this.ddoc = this.designDocs.get(this.ddocID);
-      }
-    },
-
     serialize: function() {
-      this.setDdocInfo();
-      var data = {
-        database: this.collection,
-        viewList: this.viewList,
-        hasReduce: false,
-        params: this.params,
-        ddocs: this.designDocs
-      };
-      if (this.ddoc) {
-        data.ddoc = this.ddoc;
-        data.hasReduce = this.ddoc.viewHasReduce(this.collection.view);
-      }
-      return data;
-    },
-
-    updateView: function(event) {
-      event.preventDefault();
-      var $form = $(event.currentTarget);
+      var totalRows = 0,
+      updateSeq = false;
 
-      // Ignore params without a value
-      var params = _.filter($form.serializeArray(), function(param) {
-        return param.value;
-      });
-
-      // Validate *key* params to ensure they're valid JSON
-      var keyParams = ["key","keys","startkey","endkey"];
-      var errorParams = _.filter(params, function(param) {
-        if (_.contains(keyParams, param.name)) {
-          try {
-            JSON.parse(param.value);
-            return false;
-          } catch(e) {
-            return true;
-          }
-        } else {
-          return false;
-        }
-      });
-
-      if (_.any(errorParams)) {
-        _.map(errorParams, function(param) {
-
-          // TODO: Where to add this error?
-          // bootstrap wants the error on a control-group div, but we're not using that
-          //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
-
-          return FauxtonAPI.addNotification({
-            msg: "JSON Parse Error on field: "+param.name,
-            type: "error",
-            selector: ".view.show .all-docs-list.errors-container"
-          });
-        });
-
-        FauxtonAPI.addNotification({
-          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
-          type: "warning",
-          selector: ".view.show .all-docs-list.errors-container"
-        });
-
-        return false;
+      if (!this.newView) {
+        totalRows = this.collection.totalRows();
+        updateSeq = this.collection.updateSeq();
       }
 
-      var fragment = window.location.hash.replace(/\?.*$/, '');
-      fragment = fragment + '?' + $.param(params);
-      FauxtonAPI.navigate(fragment);
-    },
-
-    updateFilters: function(event) {
-      event.preventDefault();
-      var $ele = $(event.currentTarget);
-      var name = $ele.attr('name');
-      this.updateFiltersFor(name, $ele);
-    },
-
-    updateFiltersFor: function(name, $ele) {
-      var $form = $ele.parents("form.view-query-update:first");
-      switch (name) {
-        // Reduce constraints
-        //   - Can't include_docs for reduce=true
-        //   - can't include group_level for reduce=false
-        case "reduce":
-          if ($ele.prop('checked') === true) {
-            if ($form.find("input[name=include_docs]").prop("checked") === true) {
-              $form.find("input[name=include_docs]").prop("checked", false);
-              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"
-              });
-            }
-            $form.find("input[name=include_docs]").prop("disabled", true);
-            $form.find("select[name=group_level]").prop("disabled", false);
-          } else {
-            $form.find("select[name=group_level]").prop("disabled", true);
-            $form.find("input[name=include_docs]").prop("disabled", false);
-          }
-          break;
-        case "include_docs":
-          break;
-      }
+      return {
+        updateSeq: updateSeq,
+        totalRows: totalRows,
+        numModels: this.collection.models.length,
+        viewList: this.viewList
+      };
     },
 
     /*
@@ -468,14 +361,6 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     },
 
     beforeRender: function() {
-      this.setDdocInfo();
-      if (this.viewList) {
-        this.viewEditorView = this.insertView("#edit-index-container", new Views.ViewEditor({
-          model: this.ddoc,
-          ddocs: this.designDocs,
-          viewCollection: this.collection
-        }));
-      }
       this.collection.each(function(doc) {
         this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
           model: doc
@@ -485,34 +370,6 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
 
     afterRender: function(){
       prettyPrint();
-      if (this.params) {
-        var $form = this.$el.find("form.view-query-update");
-        _.each(this.params, function(val, key) {
-          var $ele;
-          switch (key) {
-            case "limit":
-            case "group_level":
-              $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;
-            case "reduce":
-              $ele = $form.find("input[name='"+key+"']");
-              if (val == "true") {
-                $ele.prop('checked', true);
-              }
-              this.updateFiltersFor(key, $ele);
-              break;
-            default:
-              $form.find("input[name='"+key+"']").val(val);
-              break;
-          }
-        }, this);
-      }
     }
   });
 
@@ -523,6 +380,10 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       "click button.save-doc": "saveDoc"
     },
 
+    initialize: function (options) {
+      this.database = options.database;
+    },
+
     updateValues: function() {
       var notification;
       if (this.model.changedAttributes()) {
@@ -540,13 +401,15 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     },
 
     saveDoc: function(event) {
-      var json, notification;
+      var json, notification, that = this;
       if (this.hasValidCode()) {
         json = JSON.parse(this.editor.getValue());
         this.model.clear({silent:true});
         this.model.set(json);
         notification = FauxtonAPI.addNotification({msg: "Saving document."});
-        this.model.save().error(function(xhr) {
+        this.model.save().then(function () {
+          FauxtonAPI.navigate('/database/' + that.database.id + '/' + that.model.id);
+        }).fail(function(xhr) {
           var responseText = JSON.parse(xhr.responseText).reason;
           notification = FauxtonAPI.addNotification({
             msg: "Save failed: " + responseText,
@@ -607,7 +470,8 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          that.runJSHint();
+          //throwing errors at the moment
+          //that.runJSHint();
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveDoc(); },
@@ -646,6 +510,7 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     }
   });
 
+  //TODO split this into two smaller views, one for advance query options and other for index editing
   Views.ViewEditor = FauxtonAPI.View.extend({
     template: "templates/documents/view_editor",
     builtinReduces: ['_sum', '_count', '_stats'],
@@ -653,12 +518,17 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     events: {
       "click button.save": "saveView",
       "click button.preview": "previewView",
-      "change select#reduce-function-selector": "updateReduce"
+      "click button.delete": "deleteView",
+      "change select#reduce-function-selector": "updateReduce",
+      "change form.view-query-update input": "updateFilters",
+      "change form.view-query-update select": "updateFilters",
+      "change select#ddoc": "updateDesignDoc",
+      "submit form.view-query-update": "updateView"
     },
 
     langTemplates: {
       "javascript": {
-        map: "function(doc) {\n  emit(null, doc);\n}",
+        map: "function(doc) {\n  emit(doc.id, 1);\n}",
         reduce: "function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}"
       }
     },
@@ -666,10 +536,27 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     defaultLang: "javascript",
 
     initialize: function(options) {
+      this.newView = options.newView || false;
       this.ddocs = options.ddocs;
-      this.viewCollection = options.viewCollection;
-      this.reduceFunStr = this.model.viewHasReduce(this.viewCollection.view);
-      this.newView = false;
+      this.params = options.params;
+      this.database = options.database;
+      if (this.newView) {
+        this.viewName = 'newView';
+      } else {
+        this.ddocID = options.ddocInfo.id;
+        this.viewName = options.viewName;
+      } 
+    },
+
+    updateDesignDoc: function () {
+
+      if (this.$('#ddoc :selected').prop('id') === 'new-doc') {
+        this.$('#new-ddoc-section').show();
+
+      } else {
+        this.$('#new-ddoc-section').hide();
+      }
+
     },
 
     updateValues: function() {
@@ -694,43 +581,211 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       }
     },
 
-    establish: function() {
-      //return [this.ddocs.fetch(), this.model.fetch()];
-      return [];
+    queryParams: function () {
+      var $form = $(".view-query-update");
+      // Ignore params without a value
+      var params = _.filter($form.serializeArray(), function(param) {
+        return param.value;
+      });
+
+      // Validate *key* params to ensure they're valid JSON
+      var keyParams = ["key","keys","startkey","endkey"];
+      var errorParams = _.filter(params, function(param) {
+        if (_.contains(keyParams, param.name)) {
+          try {
+            JSON.parse(param.value);
+            return false;
+          } catch(e) {
+            return true;
+          }
+        } else {
+          return false;
+        }
+      });
+
+      return {params: params, errorParams: errorParams};
+    },
+
+    deleteView: function (event) {
+      event.preventDefault();
+
+      if (this.newView) { return alert('Cannot delete a new view.'); }
+      if (!confirm('Are you sure you want to delete this view?')) {return;}
+
+      var that = this,
+          promise,
+          viewName = this.$('#index-name').val();
+          ddocName = this.$('#ddoc :selected').val(),
+          ddoc = this.getCurrentDesignDoc();
+
+      ddoc.removeDdocView(viewName);
+
+      if (ddoc.hasViews()) {
+        promise = ddoc.save(); 
+      } else {
+        promise = ddoc.destroy();
+      }
+
+      promise.then(function () {
+        FauxtonAPI.navigate('/database/' + that.database.id + '/_all_docs?limit=100');
+        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
+      });
+    },
+
+    updateView: function(event) {
+      event.preventDefault();
+
+      if (this.newView) { return alert('Please save this new view before querying it.'); }
+
+      var paramInfo = this.queryParams(),
+          errorParams = paramInfo.errorParams,
+          params = paramInfo.params;
+
+      if (_.any(errorParams)) {
+        _.map(errorParams, function(param) {
+
+          // TODO: Where to add this error?
+          // bootstrap wants the error on a control-group div, but we're not using that
+          //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
+
+          return FauxtonAPI.addNotification({
+            msg: "JSON Parse Error on field: "+param.name,
+            type: "error",
+            selector: ".view.show .all-docs-list.errors-container"
+          });
+        });
+
+        FauxtonAPI.addNotification({
+          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
+          type: "warning",
+          selector: ".view.show .all-docs-list.errors-container"
+        });
+
+        return false;
+      }
+
+      var fragment = window.location.hash.replace(/\?.*$/, '');
+      fragment = fragment + '?' + $.param(params);
+      FauxtonAPI.navigate(fragment, {trigger: false});
+
+      FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
+    },
+
+    updateFilters: function(event) {
+      event.preventDefault();
+      var $ele = $(event.currentTarget);
+      var name = $ele.attr('name');
+      this.updateFiltersFor(name, $ele);
+    },
+
+    updateFiltersFor: function(name, $ele) {
+      var $form = $ele.parents("form.view-query-update:first");
+      switch (name) {
+        // Reduce constraints
+        //   - Can't include_docs for reduce=true
+        //   - can't include group_level for reduce=false
+        case "reduce":
+          if ($ele.prop('checked') === true) {
+          if ($form.find("input[name=include_docs]").prop("checked") === true) {
+            $form.find("input[name=include_docs]").prop("checked", false);
+            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"
+            });
+          }
+          $form.find("input[name=include_docs]").prop("disabled", true);
+          $form.find("select[name=group_level]").prop("disabled", false);
+        } else {
+          $form.find("select[name=group_level]").prop("disabled", true);
+          $form.find("input[name=include_docs]").prop("disabled", false);
+        }
+        break;
+        case "include_docs":
+          break;
+      }
     },
 
     previewView: function(event) {
+      var that = this,
+          mapVal = this.mapEditor.getValue(),
+          reduceVal = this.reduceVal(),
+          paramsArr = this.queryParams().params;
+
+      var params = _.reduce(paramsArr, function (params, param) {
+        params[param.name] = param.value;
+        return params;
+      }, {reduce: false});
+
+      event.preventDefault();
+
       FauxtonAPI.addNotification({
         msg: "<strong>Warning!</strong> Preview executes the Map/Reduce functions in your browser, and may behave differently from CouchDB.",
         type: "warning",
         selector: "#define-view .errors-container",
-        fade: false
+        fade: true
       });
-      FauxtonAPI.addNotification({
-        msg: "Preview Functionality Coming Soon",
-        type: "warning",
-        selector: "#define-view .errors-container"
+
+      var promise = FauxtonAPI.Deferred();
+
+      if (!this.database.allDocs) {
+        this.database.buildAllDocs({limit: "100", include_docs: true});
+        promise = this.database.allDocs.fetch();
+      } else {
+        promise.resolve();
+      }
+
+      promise.then(function () {
+        params.docs = that.database.allDocs.map(function (model) { return model.get('doc');}); 
+
+        var queryPromise = pouchdb.runViewQuery({map: mapVal, reduce: reduceVal}, params);
+        queryPromise.then(function (results) {
+          FauxtonAPI.triggerRouteEvent('updatePreviewDocs', {rows: results.rows, ddoc: that.getCurrentDesignDoc().id, view: that.viewName});
+        });
       });
     },
 
     saveView: function(event) {
-      var json, notification;
+      var json, notification,
+      that = this;
+
+      event.preventDefault();
+
       if (this.hasValidCode()) {
-        var mapVal = this.mapEditor.getValue();
-        var reduceVal = this.reduceEditor.getValue();
-        /*
+        var mapVal = this.mapEditor.getValue(), 
+            reduceVal = this.reduceVal(),
+            viewName = this.$('#index-name').val(),
+            ddoc = this.getCurrentDesignDoc(),
+            ddocName = ddoc.id;
+
+        this.viewName = viewName;
+
         notification = FauxtonAPI.addNotification({
           msg: "Saving document.",
           selector: "#define-view .errors-container"
         });
-        */
-        FauxtonAPI.addNotification({
-          msg: "Save Functionality Coming Soon",
-          type: "warning",
-          selector: "#define-view .errors-container"
-        });
-        /*
-        this.model.save().error(function(xhr) {
+
+        ddoc.setDdocView(viewName, mapVal, reduceVal);
+
+        ddoc.save().then(function () {
+          FauxtonAPI.addNotification({
+            msg: "View has been saved.",
+            type: "success",
+            selector: "#define-view .errors-container"
+          });
+
+          if (that.newView) {
+            var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; 
+
+            FauxtonAPI.navigate(fragment, {trigger: false});
+            FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName});
+
+            that.newView = false;
+          }
+
+          FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
+
+        }, function(xhr) {
           var responseText = JSON.parse(xhr.responseText).reason;
           notification = FauxtonAPI.addNotification({
             msg: "Save failed: " + responseText,
@@ -738,21 +793,51 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
             clear: true
           });
         });
-        */
       } else {
         notification = FauxtonAPI.addNotification({
-          msg: "Please fix the JSON errors and try again.",
+          msg: "Please fix the Javascript errors and try again.",
           type: "error",
           selector: "#define-view .errors-container"
         });
       }
     },
 
+    getCurrentDesignDoc: function () {
+      if (this.newDesignDoc()) {
+        var doc = {
+          _id: '_design/' + this.$('#new-ddoc').val(),
+          views: {},
+          language: "javascript"
+        };
+        return new Documents.Doc(doc, {database: this.database});
+      } else {
+        var ddocName = this.$('#ddoc').val();
+        return this.ddocs.find(function (ddoc) {
+          return ddoc.id === ddocName;
+        }).dDocModel();
+      }
+
+    },
+
+    newDesignDoc: function () {
+      return this.$('#ddoc :selected').prop('id') === 'new-doc';
+    },
+
     isCustomReduceEnabled: function() {
       return $("#reduce-function-selector").val() == "CUSTOM";
     },
 
     reduceVal: function() {
+      var reduceOption = this.$('#reduce-function-selector :selected').val(),
+      reduceVal = "";
+
+      if (reduceOption === 'CUSTOM') {
+        reduceVal = this.reduceEditor.getValue();
+      } else if ( reduceOption !== 'NONE') {
+        reduceVal = reduceOption;
+      }
+
+      return reduceVal;
     },
 
     hasValidCode: function() {
@@ -765,7 +850,7 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
         } else {
           // By default CouchDB view functions don't pass lint
           return _.every(JSHINT.errors, function(error) {
-            return FauxtonAPI.isIgnorableError(error.reason);
+            return FauxtonAPI.isIgnorableError(error.raw);
           });
         }
       }, this);
@@ -801,13 +886,15 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
 
     serialize: function() {
       return {
-        //database: this.model,
         ddocs: this.ddocs,
         ddoc: this.model,
-        viewCollection: this.viewCollection,
+        ddocName: this.model.id,
+        viewName: this.viewName,
         reduceFunStr: this.reduceFunStr,
+        hasReduce: this.reduceFunStr,
         isCustomReduce: this.hasCustomReduce(),
-        newView: this.newView
+        newView: this.newView,
+        langTemplates: this.langTemplates.javascript
       };
     },
 
@@ -815,6 +902,22 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
     },
 
+    beforeRender: function () {
+
+      if (this.newView) {
+        this.reduceFunStr = '_sum';
+        if (this.ddocs.length === 0) {
+          this.model = new Documents.Doc(null, {database: this.database});
+        } else {
+          this.model = this.ddocs.first().dDocModel();
+        }
+        this.ddocID = this.model.id;
+      } else {
+        this.model = this.ddocs.get(this.ddocID).dDocModel();
+        this.reduceFunStr = this.model.viewHasReduce(this.viewName);
+      }
+    },
+
     afterRender: function() {
       var that = this;
       var mapFun = $("#map-function");
@@ -823,13 +926,16 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
         mapFun.val(this.langTemplates[this.defaultLang].map);
         reduceFun.val(this.langTemplates[this.defaultLang].reduce);
       }
+
+      this.updateDesignDoc();
+
       this.mapEditor = Codemirror.fromTextArea(mapFun.get()[0], {
         mode: "javascript",
         lineNumbers: true,
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          that.runJSHint("mapEditor");
+          //that.runJSHint("mapEditor");
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveView(); },
@@ -842,7 +948,7 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          that.runJSHint("reduceEditor");
+          //that.runJSHint("reduceEditor");
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveView(); },
@@ -855,6 +961,36 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       if ( ! this.hasCustomReduce()) {
         $(".control-group.reduce-function").hide();
       }
+
+      if (this.params) {
+        var $form = this.$el.find("form.view-query-update");
+        _.each(this.params, function(val, key) {
+          var $ele;
+          switch (key) {
+            case "limit":
+              case "group_level":
+              $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;
+            case "reduce":
+              $ele = $form.find("input[name='"+key+"']");
+            if (val == "true") {
+              $ele.prop('checked', true);
+            }
+            this.updateFiltersFor(key, $ele);
+            break;
+            default:
+              $form.find("input[name='"+key+"']").val(val);
+            break;
+          }
+        }, this);
+      }
+
     }
   });
 
@@ -871,14 +1007,6 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       }
     },
 
-    establish: function() {
-      if (this.collection) {
-        return [this.collection.fetch()];
-      } else {
-        return null;
-      }
-    },
-
     serialize: function() {
       return {
         index: [1,2,3],
@@ -929,7 +1057,14 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
       }, this);
     },
 
+    afterRender: function () {
+      if (this.selectedTab) {
+        this.setSelectedTab(this.selectedTab);
+      }
+    },
+
     setSelectedTab: function (selectedTab) {
+      this.selectedTab = selectedTab;
       this.$('li').removeClass('active');
       this.$('#' + selectedTab).parent().addClass('active');
     }
@@ -942,20 +1077,24 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     template: "templates/documents/changes",
 
     establish: function() {
-      return [
-        this.model.changes.fetch()
-      ];
+      return [ this.model.changes.fetch()];
     },
 
     serialize: function () {
+      console.log('c', this.model.changes.toJSON());
       return {
         changes: this.model.changes.toJSON(),
         database: this.model
       };
+    },
+
+    afterRender: function(){
+      prettyPrint();
     }
 
-  });
 
+  });
 
-  return Views;
+  Documents.Views = Views;
+  return Documents;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/modules/pouchdb/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/pouchdb/base.js b/src/fauxton/app/modules/pouchdb/base.js
index 2b7cfc9..ddaf06d 100644
--- a/src/fauxton/app/modules/pouchdb/base.js
+++ b/src/fauxton/app/modules/pouchdb/base.js
@@ -31,8 +31,8 @@ function(app, FauxtonAPI, MapReduce) {
   var Pouch = {};
   Pouch.MapReduce = MapReduce;
 
-  Pouch.runViewQuery = function(fun, docs) {
-    docs = [
+  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'},
@@ -43,15 +43,18 @@ function(app, FauxtonAPI, MapReduce) {
       {_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) {
-      console.log("COMPLETE TRIGGERED", arguments);
+    var complete = function(resp, rows) {
+      deferred.resolve(rows);
     };
 
-    return Pouch.MapReduce.query(fun, {docs: docs, complete:complete});
-  };
+    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/90e4da6c/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js b/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
index b97eb7f..a2d0b91 100644
--- a/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
+++ b/src/fauxton/app/modules/pouchdb/pouchdb.mapreduce.js
@@ -39,6 +39,36 @@ function(app, FauxtonAPI, 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) {
@@ -55,13 +85,13 @@ function(app, FauxtonAPI, Collate) {
       var completed= false;
 
       var emit = function(key, val) {
-        console.log("IN EMIT: ", key, val, current);
+        //console.log("IN EMIT: ", key, val, current);
         var viewRow = {
           id: current.doc._id,
           key: key,
           value: val
         }; 
-        console.log("VIEW ROW: ", viewRow);
+        //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;
@@ -95,7 +125,11 @@ function(app, FauxtonAPI, Collate) {
       // 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) {
+      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() + ';');
       }
 
@@ -105,6 +139,7 @@ function(app, FauxtonAPI, Collate) {
 
       //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);
@@ -116,6 +151,7 @@ function(app, FauxtonAPI, Collate) {
             return options.complete(null, {rows: results});
           }
 
+          console.log('reducing', options);
           var groups = [];
           results.forEach(function(e) {
             var last = groups[groups.length-1] || null;
@@ -130,19 +166,21 @@ function(app, FauxtonAPI, Collate) {
             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);
+        //console.log("RUNNING MR ON DOCS: ", options.docs);
         _.each(options.docs, function(doc) {
           current = {doc: doc};
           fun.map.call(this, doc);
         }, this);
-        return options.complete(null, {rows: results});
+        completed = true;
+        return checkComplete();//options.complete(null, {rows: results});
       } else {
-        console.log("COULD NOT FIND DOCS");
+        //console.log("COULD NOT FIND DOCS");
         return false;
       }
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_list.html b/src/fauxton/app/templates/documents/all_docs_list.html
index 2f63af0..9f4ffdd 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -28,97 +28,10 @@ the License.
     </div>
   <% } %>
 
-  <div class="row">
-    <div class="all-docs-list errors-container"></div>
-    <div id="edit-index-container"></div>
-    <% if (viewList) { %>
-      <div class="accordion" id="advanced-options-accordion">
-        <div class="accordion-group">
-          <div class="accordion-heading">
-            <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#advanced-options-accordion" href="#collapse-advanced-options">
-              <i class="icon-plus"></i> Advanced Options
-            </a>
-          </div>
-          <div id="collapse-advanced-options" class="accordion-body collapse">
-            <div class="accordion-inner">
-              <form class="view-query-update">
-                <div class="controls controls-row">
-                  <label class="span3 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>
-                  <label class="span3 checkbox inline">
-                    <input name="include_docs" type="checkbox" value="true"> Include Docs
-                  </label>
-                  <% if (hasReduce) { %>
-                    <label class="span2 checkbox inline">
-                      <input name="reduce" type="checkbox" value="true"> Reduce
-                    </label>
-                    <label class="span4 inline">
-                      Group Level:
-                      <select 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>
-                  <% } %>
-                </div>
-
-                <div class="controls controls-row">
-                  <input name="key" class="span4" type="text" placeholder="Key">
-                  <input name="keys" class="span8" type="text" placeholder="Keys">
-                </div>
-                <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 class="controls controls-row">
-                  <label class="span2 checkbox inline">
-                    <input name="stale" type="checkbox" value="ok"> Stale
-                  </label>
-                  <label class="span2 checkbox inline">
-                    <input name="descending" type="checkbox" value="true"> Descending
-                  </label>
-                  <label class="span4 checkbox inline">
-                    <input name="inclusive_end" type="checkbox" value="false"> Disable Inclusive End
-                  </label>
-                  <label class="span4 checkbox inline">
-                    <input name="update_seq" type="checkbox" value="true"> Include Update Sequence
-                  </label>
-                </div>
-                <div class="controls controls-row">
-                  <button type="submit" class="btn btn-primary">Query</button>
-                </div>
-              </form>
-
-            </div>
-          </div>
-
-        </div>
-      </div>
-    <% } %>
-  </div>
-
-
   <p>
-    Showing 1-<%= database.models.length %> of <%= database.totalRows() %> rows
-    <% if (database.updateSeq()) { %>
-      -- Update Sequence: <%= database.updateSeq() %>
+    Showing 1-<%= numModels %> of <%= totalRows %> rows
+    <% if (updateSeq) { %>
+      -- Update Sequence: <%= updateSeq %>
     <% } %>
   </p>
   <table class="all-docs table table-striped table-condensed">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/templates/documents/changes.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/changes.html b/src/fauxton/app/templates/documents/changes.html
index 3e5009c..e528a1c 100644
--- a/src/fauxton/app/templates/documents/changes.html
+++ b/src/fauxton/app/templates/documents/changes.html
@@ -28,7 +28,9 @@ the License.
       <% } else { %>
         <td> <a href="#<%= database.url('app') %>/<%= change.id %>"><%= change.id %></a> </td>
       <% } %>
-      <td> <%= JSON.stringify(change.changes) %> </td>
+        <td> 
+          <pre class="prettyprint">  <%= JSON.stringify({changes: change.changes, doc: change.doc}, null, " ") %> </pre>
+      </td>
       <td><%= change.deleted ? "true" : "false" %></td>
     </tr>
   <% }); %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/templates/documents/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/view_editor.html b/src/fauxton/app/templates/documents/view_editor.html
index 4a8668e..a34ff0d 100644
--- a/src/fauxton/app/templates/documents/view_editor.html
+++ b/src/fauxton/app/templates/documents/view_editor.html
@@ -11,82 +11,184 @@ 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">
+  <div class="all-docs-list errors-container"></div>
+  <div id="edit-index-container">
 
-<div class="accordion" id="edit-index-accordion">
-  <div class="accordion-group">
-    <div class="accordion-heading">
-      <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#edit-index-accordion" href="#collapse-edit-index">
-        <i class="icon-wrench"></i> Edit Index
-      </a>
-    </div>
-    <div id="collapse-edit-index" class="accordion-body collapse">
-      <div class="accordion-inner">
-        <div id="define-view" class="ddoc-alert well">
-          <div class="errors-container"></div>
-          <form class="form-horizontal">
-            <h3>Define your index</h3>
-            <div class="control-group">
-              <label class="control-label" for="ddoc">Design document <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#design-docs"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <select id="ddoc">
-                  <optgroup label="Select a document">
-                    <option>New document</option>
-                    <% ddocs.each(function(ddoc) { %>
-                      <% if (ddoc.id == "_design/"+viewCollection.design) { %>
-                        <option selected="selected"><%= ddoc.id %></option>
-                      <% } else { %>
-                        <option><%= ddoc.id %></option>
-                      <% } %>
-                    <% }); %>
-                    <option selected="selected">_design/views101</option>
-                  </optgroup>
-                </select>
-              </div>
+    <div class="accordion" id="edit-index-accordion">
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#edit-index-accordion" href="#collapse-edit-index">
+            <i class="icon-wrench"></i> <% if (newView) { %> Create Index <% } else { %> Edit Index <% } %>
+          </a>
+        </div>
+        <div id="collapse-edit-index" class="accordion-body <% if (!newView) { %> collapse <% } %>">
+          <div class="accordion-inner">
+            <div id="define-view" class="ddoc-alert well">
+              <div class="errors-container"></div>
+              <form class="form-horizontal">
+                <h3>Define your index</h3>
+                <div class="control-group">
+                  <div class="row" style="margin-left:10px">
+                    <div class="span3">
+                      <label class="control-label" for="ddoc">Design document <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#design-docs"><i class="icon-question-sign"></i></a></label>
+                      <div class="controls">
+                        <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>
+                    <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>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="index-name">Index name <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#view-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <input type="text" id="index-name" value="<%= viewName %>" placeholder="Index name" />
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="map-function">Map function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#map-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <% if (newView) { %>
+                    <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea>
+                    <% } else { %>
+                    <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map %></textarea>
+                    <% } %>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="reduce-function-selector">Reduce function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs.html#reduce-and-rereduce-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <select id="reduce-function-selector">
+                      <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option>
+                      <% _.each(["_sum", "_count", "_stats"], function(reduce) { %>
+                      <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option>
+                      <% }) %>
+                      <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option>
+                    </select>
+                    <span class="help-block">Reduce functions are optional.</span>
+                  </div>
+                </div>
+                <div class="control-group reduce-function">
+                  <label class="control-label" for="reduce-function">Custom Reduce</label>
+                  <div class="controls">
+                    <% if (newView) { %>
+                    <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea>
+                    <% } else { %>
+                    <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce %></textarea>
+                    <% } %>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <hr />
+                  <div class="controls">
+                    <% if (!this.newView) { %>
+                    <button class="btn btn-small btn-danger delete">Delete</button>
+                    <% } %>
+                    <button class="btn btn-small btn-info preview">Preview</button>
+                    <button class="btn btn-primary save">Save</button>
+                  </div>
+                </div>
+                <div class="clearfix"></div>
+              </form>
             </div>
-            <div class="control-group">
-              <label class="control-label" for="index-name">Index name <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#view-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <input type="text" id="index-name" value="<%= viewCollection.view %>" placeholder="Index name" />
+          </div>
+        </div>
+
+      </div>
+    </div>
+    <div class="accordion" id="advanced-options-accordion">
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#advanced-options-accordion" href="#collapse-advanced-options">
+            <i class="icon-plus"></i> Advanced Options
+          </a>
+        </div>
+        <div id="collapse-advanced-options" class="accordion-body collapse">
+          <div class="accordion-inner">
+            <form class="view-query-update">
+              <div class="controls controls-row">
+                <label class="span3 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>
+                <label class="span3 checkbox inline">
+                  <input name="include_docs" type="checkbox" value="true"> Include Docs
+                </label>
+                <% if (hasReduce) { %>
+                <label class="span2 checkbox inline">
+                  <input name="reduce" type="checkbox" value="true"> Reduce
+                </label>
+                <label class="span4 inline">
+                  Group Level:
+                  <select 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>
+                <% } %>
               </div>
-            </div>
-            <div class="control-group">
-              <label class="control-label" for="map-function">Map function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#map-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <textarea class="js-editor" id="map-function"><%= ddoc.get('doc').views[viewCollection.view].map %></textarea>
+
+              <div class="controls controls-row">
+                <input name="key" class="span4" type="text" placeholder="Key">
+                <input name="keys" class="span8" type="text" placeholder="Keys">
               </div>
-            </div>
-            <div class="control-group">
-              <label class="control-label" for="reduce-function-selector">Reduce function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#reduce-and-rereduce-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <select id="reduce-function-selector">
-                  <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option>
-                  <% _.each(["_sum", "_count", "_stats"], function(reduce) { %>
-                    <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option>
-                  <% }) %>
-                  <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option>
-                </select>
-                <span class="help-block">Reduce functions are optional.</span>
+              <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 class="control-group reduce-function">
-              <label class="control-label" for="reduce-function">Custom Reduce</label>
-              <div class="controls">
-                <textarea class="js-editor" id="reduce-function"><%= ddoc.get('doc').views[viewCollection.view].reduce %></textarea>
+              <div class="controls controls-row">
+                <label class="span2 checkbox inline">
+                  <input name="stale" type="checkbox" value="ok"> Stale
+                </label>
+                <label class="span2 checkbox inline">
+                  <input name="descending" type="checkbox" value="true"> Descending
+                </label>
+                <label class="span4 checkbox inline">
+                  <input name="inclusive_end" type="checkbox" value="false"> Disable Inclusive End
+                </label>
+                <label class="span4 checkbox inline">
+                  <input name="update_seq" type="checkbox" value="true"> Include Update Sequence
+                </label>
               </div>
-            </div>
-            <div class="control-group">
-              <hr />
-              <div class="controls">
-                <button class="btn btn-small btn-inverse cancel">Cancel</button>
-                <button class="btn btn-small btn-info preview">Preview</button>
-                <button class="btn btn-primary save">Save</button>
+              <div class="controls controls-row">
+                <button type="submit" class="btn btn-primary">Query</button>
               </div>
-            </div>
-            <div class="clearfix"></div>
-          </form>
+            </form>
+
+          </div>
         </div>
+
       </div>
     </div>
-
   </div>
-</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/90e4da6c/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/layouts/with_tabs_sidebar.html b/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
index f78832f..0b5f2c7 100644
--- a/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
+++ b/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
@@ -21,7 +21,10 @@ the License.
 
   <div class="row-fluid">
     <div id="sidebar-content" class="sidebar span4"></div>
-    <div id="dashboard-content" class="list span8 pull-right"></div>
+    <div id="dashboard-content" class="list span8 pull-right">
+      <div id="dashboard-upper-content"></div>
+      <div id="dashboard-lower-content"></div>
+    </div>
   </div>
 </div>
 


[24/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Add live CouchDB version info to Fauxton


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

Branch: refs/heads/1684-feature-db-updates
Commit: cbbd7d56b52a44937adb35678aa4a0b200334399
Parents: 85f3c8e
Author: Russell Branca <ch...@gmail.com>
Authored: Mon Jun 17 16:52:56 2013 -0700
Committer: Russell Branca <ch...@gmail.com>
Committed: Mon Jun 17 16:52:56 2013 -0700

----------------------------------------------------------------------
 src/fauxton/app/initialize.js           |  2 +-
 src/fauxton/app/modules/fauxton/base.js | 18 +++++++++++++++++-
 src/fauxton/app/router.js               |  5 ++++-
 src/fauxton/tasks/couchserver.js        | 20 ++++++++++++++------
 4 files changed, 36 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/cbbd7d56/src/fauxton/app/initialize.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/initialize.js b/src/fauxton/app/initialize.js
index e5dbc73..6fed729 100644
--- a/src/fauxton/app/initialize.js
+++ b/src/fauxton/app/initialize.js
@@ -37,7 +37,7 @@ function(app, _, Bootstrap) {
     // Thanks to: http://stackoverflow.com/a/2880929
     getParams: function(queryString) {
       if (typeof queryString !== "undefined") {
-        // I think this could be combined into one if 
+        // I think this could be combined into one if
         if (queryString.substring(0,1) === "?") {
           queryString = queryString.substring(1);
         } else if (queryString.indexOf('?') > -1) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/cbbd7d56/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
index 46bde66..b69f4ae 100644
--- a/src/fauxton/app/modules/fauxton/base.js
+++ b/src/fauxton/app/modules/fauxton/base.js
@@ -35,11 +35,27 @@ function(app, Backbone) {
     }
   });
 
+  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: app.version
+        version: this.versionInfo.get("version")
       };
     }
   });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/cbbd7d56/src/fauxton/app/router.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/router.js b/src/fauxton/app/router.js
index e90e6e7..de1b7e4 100644
--- a/src/fauxton/app/router.js
+++ b/src/fauxton/app/router.js
@@ -129,7 +129,10 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents
       $("#app-container").html(this.masterLayout.el);
       this.masterLayout.render();
 
-      app.footer.render();
+      // TODO: move this to a proper Fauxton.View
+      $.when.apply(null, app.footer.establish()).done(function() {
+        app.footer.render();
+      });
     },
 
     triggerRouteEvent: function(event, args) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/cbbd7d56/src/fauxton/tasks/couchserver.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/couchserver.js b/src/fauxton/tasks/couchserver.js
index 576893b..0d1dc7a 100644
--- a/src/fauxton/tasks/couchserver.js
+++ b/src/fauxton/tasks/couchserver.js
@@ -18,7 +18,7 @@ module.exports = function (grunt) {
     path = require("path"),
     httpProxy = require('http-proxy'),
     express = require("express"),
-    options = grunt.config('couchserver'), 
+    options = grunt.config('couchserver'),
     app = express();
 
     // Options
@@ -42,20 +42,28 @@ module.exports = function (grunt) {
       res.sendfile(path.join(dist_dir,req.url));
     });
 
+    // create proxy to couch for all couch requests
+    var proxy = new httpProxy.HttpProxy(proxy_settings);
+
     // serve main index file from here
+    // Also proxy out to the base CouchDB host for handle_welcome_req.
+    // We still need to reach the top level CouchDB host even through
+    // the proxy.
     app.get('/', function (req, res) {
-      res.sendfile(path.join(dist_dir, 'index.html'));
+      var accept = req.headers.accept.split(',');
+      if (accept[0] == 'application/json') {
+        proxy.proxyRequest(req, res);
+      } else {
+        res.sendfile(path.join(dist_dir, 'index.html'));
+      }
     });
 
-    // create proxy to couch for all couch requests
-    var proxy = new httpProxy.HttpProxy(proxy_settings);
-
     app.all('*', function (req, res) {
       proxy.proxyRequest(req, res);
     });
 
     // Fail this task if any errors have been logged
-    if (grunt.errors) { 
+    if (grunt.errors) {
       return false;
     }
 


[47/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
fix configure, CHANGES is no more


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

Branch: refs/heads/1684-feature-db-updates
Commit: 77b44e0dc38b082a6218e49bde6cc6cf6569107b
Parents: 6ad181c
Author: Jan Lehnardt <ja...@apache.org>
Authored: Thu Jul 18 14:46:25 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Thu Jul 18 14:46:25 2013 +0200

----------------------------------------------------------------------
 configure.ac | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/77b44e0d/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 0a9a9e3..92a1643 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,6 @@ AC_INIT(
 
 AC_PREREQ([2.63])
 
-AC_CONFIG_SRCDIR([CHANGES])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 


[15/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
FIX BUILD: add license header to fauxton/templates/../ddoc_info.html


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

Branch: refs/heads/1684-feature-db-updates
Commit: 3cdaee1b8867e6c1ae524cc51e0f98bd39257c98
Parents: 055fd9f
Author: Jan Lehnardt <ja...@apache.org>
Authored: Wed Jun 5 22:11:17 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Wed Jun 5 22:11:17 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/templates/documents/ddoc_info.html | 13 +++++++++++++
 1 file changed, 13 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/3cdaee1b/src/fauxton/app/templates/documents/ddoc_info.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/ddoc_info.html b/src/fauxton/app/templates/documents/ddoc_info.html
index 18bf4d8..15dfe48 100644
--- a/src/fauxton/app/templates/documents/ddoc_info.html
+++ b/src/fauxton/app/templates/documents/ddoc_info.html
@@ -1,3 +1,16 @@
+<!--
+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="well" >
   <h2> Design Doc MetaData </h2>
   <ul style="list-style-type: none;">


[16/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton fix log not refreshing


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

Branch: refs/heads/1684-feature-db-updates
Commit: 7cb64422f97bca56f0a692ef64c81d93b39648a9
Parents: 3cdaee1
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Jun 6 09:25:35 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Jun 6 09:59:10 2013 +0200

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


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7cb64422/src/fauxton/app/addons/logs/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/resources.js b/src/fauxton/app/addons/logs/resources.js
index 955b3ec..b64f813 100644
--- a/src/fauxton/app/addons/logs/resources.js
+++ b/src/fauxton/app/addons/logs/resources.js
@@ -163,7 +163,7 @@ function (app, FauxtonAPI, Backbone) {
       // Interval already set
       if (this.intervalId) { return ; }
 
-      that.intervalId = setInterval(function () {
+      this.intervalId = setInterval(function () {
         collection.fetch();
       }, this.refreshTime);
 


[37/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Remove branch instructions from Fauxton readme


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

Branch: refs/heads/1684-feature-db-updates
Commit: 1da6773972c9776d90c75243966e970a0e90387f
Parents: c86d73f
Author: Russell Branca <ch...@gmail.com>
Authored: Tue Jul 2 16:26:18 2013 -0700
Committer: Russell Branca <ch...@gmail.com>
Committed: Tue Jul 2 16:26:18 2013 -0700

----------------------------------------------------------------------
 src/fauxton/readme.md | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/1da67739/src/fauxton/readme.md
----------------------------------------------------------------------
diff --git a/src/fauxton/readme.md b/src/fauxton/readme.md
index 85f1dce..af31676 100644
--- a/src/fauxton/readme.md
+++ b/src/fauxton/readme.md
@@ -23,7 +23,6 @@ A recent of [node.js](http://nodejs.org/) and npm is required.
 
     1. Clone the Couchdb repo: https://github.com/apache/couchdb.git or http://git-wip-us.apache.org/repos/asf/couchdb.git
     cd couchdb
-    git checkout fauxton
 
 ### Fauxton Setup ###
 


[18/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: Upload attachments

Can upload an attachment along with progress bar and view it in
the code and field editor.

Resolves COUCHDB-1811


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

Branch: refs/heads/1684-feature-db-updates
Commit: 785a342154678d2b19fe1efc13fa76090c8835fc
Parents: 17413bc
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jun 5 17:21:35 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jun 11 17:47:02 2013 +0200

----------------------------------------------------------------------
 LICENSE                                         |    1 +
 NOTICE                                          |    6 +
 src/fauxton/app/app.js                          |    3 +-
 src/fauxton/app/config.js                       |    4 +-
 src/fauxton/app/helpers.js                      |   14 +
 src/fauxton/app/modules/documents/routes.js     |    9 +
 src/fauxton/app/modules/documents/views.js      |  143 ++-
 src/fauxton/app/templates/documents/doc.html    |   17 +
 .../templates/documents/doc_field_editor.html   |   16 +-
 .../documents/doc_field_editor_tabs.html        |    3 +
 .../app/templates/documents/upload_modal.html   |   42 +
 src/fauxton/assets/js/plugins/jquery.form.js    | 1190 ++++++++++++++++++
 src/fauxton/package.json                        |    2 +-
 13 files changed, 1441 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 418b918..d488036 100644
--- a/LICENSE
+++ b/LICENSE
@@ -369,6 +369,7 @@ For the share/www/script/jquery-ui-* components:
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 For the share/www/script/jquery.form.js component:
+For the src/fauxton/assets/js/plugins/jquery.form.js component:
 
   http://malsup.com/jquery/form/
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 2010ba6..8379f97 100644
--- a/NOTICE
+++ b/NOTICE
@@ -137,3 +137,9 @@ This product also includes the following third-party components:
  * codemirror-javascript.js (https://github.com/marijnh/CodeMirror)
 
    Copyright (C) 2013 by Marijn Haverbeke <ma...@gmail.com>
+
+ * jquery.form.js (https://github.com/malsup/form/)
+
+   Copyright 2006-2013 (c) M. Alsup
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/app.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/app.js b/src/fauxton/app/app.js
index e754c5f..be0136d 100644
--- a/src/fauxton/app/app.js
+++ b/src/fauxton/app/app.js
@@ -7,7 +7,8 @@ define([
   "helpers",
 
   // Plugins.
-  "plugins/backbone.layoutmanager"
+  "plugins/backbone.layoutmanager",
+  "plugins/jquery.form"
 ],
 
 function($, _, Backbone, Helpers) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 5bf1f87..c7ae1d6 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -47,7 +47,9 @@ require.config({
 
     "plugins/codemirror-javascript": ["codemirror"],
 
-    "plugins/prettify": []
+    "plugins/prettify": [],
+
+    "plugins/jquery.form": ["jquery"]
   }
 
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/helpers.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/helpers.js b/src/fauxton/app/helpers.js
index 6b3a7cd..2ffe2fd 100644
--- a/src/fauxton/app/helpers.js
+++ b/src/fauxton/app/helpers.js
@@ -30,6 +30,20 @@ function() {
     return path;
   };
 
+  // File size pretty printing, taken from futon.format.js
+  Helpers.formatSize = function(size) {
+      var jump = 512;
+      if (size < jump) return size + " bytes";
+      var units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
+      var i = 0;
+      while (size >= jump && i < units.length) {
+        i += 1;
+        size /= 1024;
+      }
+      return size.toFixed(1) + ' ' + units[i - 1];
+    };
+
+
   return Helpers;
 });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 5a44c0e..a49fa91 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -51,6 +51,10 @@ function(app, FauxtonAPI, Documents, Databases) {
       "database/:database/:doc": "code_editor"
     },
 
+    events: {
+      "route:reRenderDoc": "reRenderDoc"
+    },
+
     crumbs: function() {
       return [
         {"name": "Databases", "link": "/_all_dbs"},
@@ -67,6 +71,11 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
+    reRenderDoc: function () {
+      this.docView.forceRender();
+      console.log('rerender');
+    },
+
     field_editor: function(events) {
       this.tabsView.updateSelected('field_editor');
       this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 93f06f1..59e3b7d 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -128,6 +128,94 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
     }
   });
 
+  Views.UploadModal = FauxtonAPI.View.extend({
+    template: "templates/documents/upload_modal",
+
+    initialize: function (options) {
+      _.bindAll(this);
+    },
+
+    events: {
+      "click a#upload-btn": "uploadFile"
+    },
+
+    uploadFile: function (event) {
+      event.preventDefault();
+
+      var docRev = this.model.get('_rev'),
+          $form = this.$('#file-upload');
+
+      if (!docRev) {
+        return this.set_error_msg('The document needs to be saved before adding an attachment.');
+      }
+
+      if ($('input[type="file"]')[0].files.length === 0) {
+        return this.set_error_msg('Selected a file to be uploaded.');
+      }
+
+      this.$('#_rev').val(docRev);
+
+      $form.ajaxSubmit({
+        url: this.model.url(),
+        type: 'POST',
+        beforeSend: this.beforeSend,
+        uploadProgress: this.uploadProgress,
+        success: this.success
+      });
+    },
+
+    success: function (resp) {
+      var hideModal = this.hideModal,
+          $form = this.$('#file-upload');
+
+      FauxtonAPI.triggerRouteEvent('reRenderDoc');
+      //slight delay to make this transistion a little more fluid and less jumpy
+      setTimeout(function () {
+        $form.clearForm();
+        hideModal();
+      }, 1000);
+    },
+
+    uploadProgress: function(event, position, total, percentComplete) {
+      this.$('.bar').css({width: percentComplete + '%'});
+    },
+
+    beforeSend: function () {
+     this.$('.progress').removeClass('hide');
+    },
+
+    showModal: function () {
+      this.$('.bar').css({width: '0%'});
+      this.$('.progress').addClass('hide');
+      this.clear_error_msg();
+      this.$('.modal').modal();
+      // hack to get modal visible 
+      $('.modal-backdrop').css('z-index',1025);
+    },
+
+    hideModal: function () {
+      this.$('.modal').modal('hide');
+    },
+
+    set_error_msg: function (msg) {
+      var text;
+      if (typeof(msg) == 'string') {
+        text = msg;
+      } else {
+        text = JSON.parse(msg.responseText).reason;
+      }
+      this.$('#modal-error').text(text).removeClass('hide');
+    },
+
+    clear_error_msg: function () {
+      this.$('#modal-error').text(' ').addClass('hide');
+    },
+
+    serialize: function () {
+      return this.model.toJSON();
+    }
+  });
+
   Views.FieldEditorTabs = FauxtonAPI.View.extend({
     template: "templates/documents/doc_field_editor_tabs",
 
@@ -137,7 +225,8 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
 
     events: {
       "click button.delete": "destroy",
-      "click button.duplicate": "duplicate"
+      "click button.duplicate": "duplicate",
+      "click button.upload": "upload"
     },
 
     destroy: function(event) {
@@ -160,6 +249,16 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
       });
     },
 
+    beforeRender: function () {
+      this.uploadModal = this.setView('#upload-modal', new Views.UploadModal({model: this.model}));
+      this.uploadModal.render();
+    },
+    
+    upload: function (event) {
+      event.preventDefault();
+      this.uploadModal.showModal();
+    },
+
     duplicate: function(event) {
       FauxtonAPI.addNotification({
         type: "warning",
@@ -463,10 +562,26 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
 
     serialize: function() {
       return {
-        doc: this.model
+        doc: this.model,
+        attachments: this.getAttachments()
       };
     },
 
+    getAttachments: function () {
+      var attachments = this.model.get('_attachments');
+
+      if (!attachments) { return false; }
+
+      return _.map(attachments, function (att, key) {
+        return {
+          fileName: key,
+          size: att.length,
+          contentType: att.content_type,
+          url: this.model.url() + '/' + key
+        };
+      }, this);
+    },
+
     afterRender: function() {
       this.model.on("sync", this.updateValues, this);
       var that = this;
@@ -507,12 +622,30 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
 
     serialize: function() {
       return {
-        doc: this.getModel()
+        doc: this.getModelWithoutAttachments(),
+        attachments: this.getAttachments()
       };
     },
 
-    getModel: function() {
-      return this.model;
+    getModelWithoutAttachments: function() {
+      var model = this.model.toJSON();
+      delete model._attachments;
+      return model;
+    },
+
+    getAttachments: function () {
+      var attachments = this.model.get('_attachments');
+
+      if (!attachments) { return []; }
+
+      return _.map(attachments, function (att, key) {
+        return {
+          fileName: key,
+          size: att.length,
+          contentType: att.content_type,
+          url: this.model.url() + '/' + key
+        };
+      }, this);
     },
 
     establish: function() {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/templates/documents/doc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/doc.html b/src/fauxton/app/templates/documents/doc.html
index 044866b..6cca488 100644
--- a/src/fauxton/app/templates/documents/doc.html
+++ b/src/fauxton/app/templates/documents/doc.html
@@ -14,6 +14,23 @@ the License.
 
 <div id="doc">
   <div class="errors-container"></div>
+  <% if (attachments) { %>
+  <div class="btn-group pull-right" style="margin-bottom: 15px">
+    <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>
+  </div>
+  <% } %>
 
   <textarea class="doc-code"><%= JSON.stringify(doc.attributes, null, "  ") %></textarea>
   <br />

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/templates/documents/doc_field_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/doc_field_editor.html b/src/fauxton/app/templates/documents/doc_field_editor.html
index 494e721..c9ce32b 100644
--- a/src/fauxton/app/templates/documents/doc_field_editor.html
+++ b/src/fauxton/app/templates/documents/doc_field_editor.html
@@ -44,7 +44,7 @@ the License.
         <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.attributes, function(value, key) { %>
+      <% _.each(doc, function(value, key) { %>
         <tr>
           <td class="select"><input type="checkbox" /></td>
           <td class="key">
@@ -53,6 +53,20 @@ the License.
           <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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
index 41bbe40..01cb8a9 100644
--- a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
+++ b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
@@ -18,9 +18,12 @@ the License.
   <ul class="nav pull-right" style="margin:5px 10px 0px 10px;">
     <li>
       <div class="btn-group">
+        <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>
       </div>
     </li>
   </ul>
 </ul>
+
+<div id="upload-modal"> </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/app/templates/documents/upload_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/upload_modal.html b/src/fauxton/app/templates/documents/upload_modal.html
new file mode 100644
index 0000000..d9cdbb0
--- /dev/null
+++ b/src/fauxton/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="hide alert alert-error"/>
+    <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="<%= _rev %>" >
+      <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">Cancel</a>
+    <a href="#" id="upload-btn" class="btn btn-primary">Upload</a>
+  </div>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/assets/js/plugins/jquery.form.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/jquery.form.js b/src/fauxton/assets/js/plugins/jquery.form.js
new file mode 100644
index 0000000..e3126ca
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/jquery.form.js
@@ -0,0 +1,1190 @@
+/*!
+ * jQuery Form Plugin
+ * version: 3.35.0-2013.05.23
+ * @requires jQuery v1.5 or later
+ * Copyright (c) 2013 M. Alsup
+ * Examples and documentation at: http://malsup.com/jquery/form/
+ * Project repository: https://github.com/malsup/form
+ * Dual licensed under the MIT and GPL licenses.
+ * https://github.com/malsup/form#copyright-and-license
+ */
+/*global ActiveXObject */
+;(function($) {
+"use strict";
+
+/*
+    Usage Note:
+    -----------
+    Do not use both ajaxSubmit and ajaxForm on the same form.  These
+    functions are mutually exclusive.  Use ajaxSubmit if you want
+    to bind your own submit handler to the form.  For example,
+
+    $(document).ready(function() {
+        $('#myForm').on('submit', function(e) {
+            e.preventDefault(); // <-- important
+            $(this).ajaxSubmit({
+                target: '#output'
+            });
+        });
+    });
+
+    Use ajaxForm when you want the plugin to manage all the event binding
+    for you.  For example,
+
+    $(document).ready(function() {
+        $('#myForm').ajaxForm({
+            target: '#output'
+        });
+    });
+
+    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
+    form does not have to exist when you invoke ajaxForm:
+
+    $('#myForm').ajaxForm({
+        delegation: true,
+        target: '#output'
+    });
+
+    When using ajaxForm, the ajaxSubmit function will be invoked for you
+    at the appropriate time.
+*/
+
+/**
+ * Feature detection
+ */
+var feature = {};
+feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
+feature.formdata = window.FormData !== undefined;
+
+var hasProp = !!$.fn.prop;
+
+// attr2 uses prop when it can but checks the return type for
+// an expected string.  this accounts for the case where a form 
+// contains inputs with names like "action" or "method"; in those
+// cases "prop" returns the element
+$.fn.attr2 = function() {
+    if ( ! hasProp )
+        return this.attr.apply(this, arguments);
+    var val = this.prop.apply(this, arguments);
+    if ( ( val && val.jquery ) || typeof val === 'string' )
+        return val;
+    return this.attr.apply(this, arguments);
+};
+
+/**
+ * ajaxSubmit() provides a mechanism for immediately submitting
+ * an HTML form using AJAX.
+ */
+$.fn.ajaxSubmit = function(options) {
+    /*jshint scripturl:true */
+
+    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
+    if (!this.length) {
+        log('ajaxSubmit: skipping submit process - no element selected');
+        return this;
+    }
+
+    var method, action, url, $form = this;
+
+    if (typeof options == 'function') {
+        options = { success: options };
+    }
+
+    method = options.type || this.attr2('method');
+    action = options.url  || this.attr2('action');
+
+    url = (typeof action === 'string') ? $.trim(action) : '';
+    url = url || window.location.href || '';
+    if (url) {
+        // clean url (don't include hash vaue)
+        url = (url.match(/^([^#]+)/)||[])[1];
+    }
+
+    options = $.extend(true, {
+        url:  url,
+        success: $.ajaxSettings.success,
+        type: method || 'GET',
+        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
+    }, options);
+
+    // hook for manipulating the form data before it is extracted;
+    // convenient for use with rich editors like tinyMCE or FCKEditor
+    var veto = {};
+    this.trigger('form-pre-serialize', [this, options, veto]);
+    if (veto.veto) {
+        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
+        return this;
+    }
+
+    // provide opportunity to alter form data before it is serialized
+    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
+        log('ajaxSubmit: submit aborted via beforeSerialize callback');
+        return this;
+    }
+
+    var traditional = options.traditional;
+    if ( traditional === undefined ) {
+        traditional = $.ajaxSettings.traditional;
+    }
+
+    var elements = [];
+    var qx, a = this.formToArray(options.semantic, elements);
+    if (options.data) {
+        options.extraData = options.data;
+        qx = $.param(options.data, traditional);
+    }
+
+    // give pre-submit callback an opportunity to abort the submit
+    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
+        log('ajaxSubmit: submit aborted via beforeSubmit callback');
+        return this;
+    }
+
+    // fire vetoable 'validate' event
+    this.trigger('form-submit-validate', [a, this, options, veto]);
+    if (veto.veto) {
+        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
+        return this;
+    }
+
+    var q = $.param(a, traditional);
+    if (qx) {
+        q = ( q ? (q + '&' + qx) : qx );
+    }
+    if (options.type.toUpperCase() == 'GET') {
+        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
+        options.data = null;  // data is null for 'get'
+    }
+    else {
+        options.data = q; // data is the query string for 'post'
+    }
+
+    var callbacks = [];
+    if (options.resetForm) {
+        callbacks.push(function() { $form.resetForm(); });
+    }
+    if (options.clearForm) {
+        callbacks.push(function() { $form.clearForm(options.includeHidden); });
+    }
+
+    // perform a load on the target only if dataType is not provided
+    if (!options.dataType && options.target) {
+        var oldSuccess = options.success || function(){};
+        callbacks.push(function(data) {
+            var fn = options.replaceTarget ? 'replaceWith' : 'html';
+            $(options.target)[fn](data).each(oldSuccess, arguments);
+        });
+    }
+    else if (options.success) {
+        callbacks.push(options.success);
+    }
+
+    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
+        var context = options.context || this ;    // jQuery 1.4+ supports scope context
+        for (var i=0, max=callbacks.length; i < max; i++) {
+            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
+        }
+    };
+
+    if (options.error) {
+        var oldError = options.error;
+        options.error = function(xhr, status, error) {
+            var context = options.context || this;
+            oldError.apply(context, [xhr, status, error, $form]);
+        };
+    }
+
+     if (options.complete) {
+        var oldComplete = options.complete;
+        options.complete = function(xhr, status) {
+            var context = options.context || this;
+            oldComplete.apply(context, [xhr, status, $form]);
+        };
+    }
+
+    // are there files to upload?
+
+    // [value] (issue #113), also see comment:
+    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
+    var fileInputs = $('input[type=file]:enabled[value!=""]', this);
+
+    var hasFileInputs = fileInputs.length > 0;
+    var mp = 'multipart/form-data';
+    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
+
+    var fileAPI = feature.fileapi && feature.formdata;
+    log("fileAPI :" + fileAPI);
+    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
+
+    var jqxhr;
+
+    // options.iframe allows user to force iframe mode
+    // 06-NOV-09: now defaulting to iframe mode if file input is detected
+    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
+        // hack to fix Safari hang (thanks to Tim Molendijk for this)
+        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
+        if (options.closeKeepAlive) {
+            $.get(options.closeKeepAlive, function() {
+                jqxhr = fileUploadIframe(a);
+            });
+        }
+        else {
+            jqxhr = fileUploadIframe(a);
+        }
+    }
+    else if ((hasFileInputs || multipart) && fileAPI) {
+        jqxhr = fileUploadXhr(a);
+    }
+    else {
+        jqxhr = $.ajax(options);
+    }
+
+    $form.removeData('jqxhr').data('jqxhr', jqxhr);
+
+    // clear element array
+    for (var k=0; k < elements.length; k++)
+        elements[k] = null;
+
+    // fire 'notify' event
+    this.trigger('form-submit-notify', [this, options]);
+    return this;
+
+    // utility fn for deep serialization
+    function deepSerialize(extraData){
+        var serialized = $.param(extraData, options.traditional).split('&');
+        var len = serialized.length;
+        var result = [];
+        var i, part;
+        for (i=0; i < len; i++) {
+            // #252; undo param space replacement
+            serialized[i] = serialized[i].replace(/\+/g,' ');
+            part = serialized[i].split('=');
+            // #278; use array instead of object storage, favoring array serializations
+            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
+        }
+        return result;
+    }
+
+     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
+    function fileUploadXhr(a) {
+        var formdata = new FormData();
+
+        for (var i=0; i < a.length; i++) {
+            formdata.append(a[i].name, a[i].value);
+        }
+
+        if (options.extraData) {
+            var serializedData = deepSerialize(options.extraData);
+            for (i=0; i < serializedData.length; i++)
+                if (serializedData[i])
+                    formdata.append(serializedData[i][0], serializedData[i][1]);
+        }
+
+        options.data = null;
+
+        var s = $.extend(true, {}, $.ajaxSettings, options, {
+            contentType: false,
+            processData: false,
+            cache: false,
+            type: method || 'POST'
+        });
+
+        if (options.uploadProgress) {
+            // workaround because jqXHR does not expose upload property
+            s.xhr = function() {
+                var xhr = jQuery.ajaxSettings.xhr();
+                if (xhr.upload) {
+                    xhr.upload.addEventListener('progress', function(event) {
+                        var percent = 0;
+                        var position = event.loaded || event.position; /*event.position is deprecated*/
+                        var total = event.total;
+                        if (event.lengthComputable) {
+                            percent = Math.ceil(position / total * 100);
+                        }
+                        options.uploadProgress(event, position, total, percent);
+                    }, false);
+                }
+                return xhr;
+            };
+        }
+
+        s.data = null;
+            var beforeSend = s.beforeSend;
+            s.beforeSend = function(xhr, o) {
+                o.data = formdata;
+                if(beforeSend)
+                    beforeSend.call(this, xhr, o);
+        };
+        return $.ajax(s);
+    }
+
+    // private function for handling file uploads (hat tip to YAHOO!)
+    function fileUploadIframe(a) {
+        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
+        var deferred = $.Deferred();
+
+        if (a) {
+            // ensure that every serialized input is still enabled
+            for (i=0; i < elements.length; i++) {
+                el = $(elements[i]);
+                if ( hasProp )
+                    el.prop('disabled', false);
+                else
+                    el.removeAttr('disabled');
+            }
+        }
+
+        s = $.extend(true, {}, $.ajaxSettings, options);
+        s.context = s.context || s;
+        id = 'jqFormIO' + (new Date().getTime());
+        if (s.iframeTarget) {
+            $io = $(s.iframeTarget);
+            n = $io.attr2('name');
+            if (!n)
+                 $io.attr2('name', id);
+            else
+                id = n;
+        }
+        else {
+            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
+            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
+        }
+        io = $io[0];
+
+
+        xhr = { // mock object
+            aborted: 0,
+            responseText: null,
+            responseXML: null,
+            status: 0,
+            statusText: 'n/a',
+            getAllResponseHeaders: function() {},
+            getResponseHeader: function() {},
+            setRequestHeader: function() {},
+            abort: function(status) {
+                var e = (status === 'timeout' ? 'timeout' : 'aborted');
+                log('aborting upload... ' + e);
+                this.aborted = 1;
+
+                try { // #214, #257
+                    if (io.contentWindow.document.execCommand) {
+                        io.contentWindow.document.execCommand('Stop');
+                    }
+                }
+                catch(ignore) {}
+
+                $io.attr('src', s.iframeSrc); // abort op in progress
+                xhr.error = e;
+                if (s.error)
+                    s.error.call(s.context, xhr, e, status);
+                if (g)
+                    $.event.trigger("ajaxError", [xhr, s, e]);
+                if (s.complete)
+                    s.complete.call(s.context, xhr, e);
+            }
+        };
+
+        g = s.global;
+        // trigger ajax global events so that activity/block indicators work like normal
+        if (g && 0 === $.active++) {
+            $.event.trigger("ajaxStart");
+        }
+        if (g) {
+            $.event.trigger("ajaxSend", [xhr, s]);
+        }
+
+        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
+            if (s.global) {
+                $.active--;
+            }
+            deferred.reject();
+            return deferred;
+        }
+        if (xhr.aborted) {
+            deferred.reject();
+            return deferred;
+        }
+
+        // add submitting element to data if we know it
+        sub = form.clk;
+        if (sub) {
+            n = sub.name;
+            if (n && !sub.disabled) {
+                s.extraData = s.extraData || {};
+                s.extraData[n] = sub.value;
+                if (sub.type == "image") {
+                    s.extraData[n+'.x'] = form.clk_x;
+                    s.extraData[n+'.y'] = form.clk_y;
+                }
+            }
+        }
+
+        var CLIENT_TIMEOUT_ABORT = 1;
+        var SERVER_ABORT = 2;
+                
+        function getDoc(frame) {
+            /* it looks like contentWindow or contentDocument do not
+             * carry the protocol property in ie8, when running under ssl
+             * frame.document is the only valid response document, since
+             * the protocol is know but not on the other two objects. strange?
+             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
+             */
+            
+            var doc = null;
+            
+            // IE8 cascading access check
+            try {
+                if (frame.contentWindow) {
+                    doc = frame.contentWindow.document;
+                }
+            } catch(err) {
+                // IE8 access denied under ssl & missing protocol
+                log('cannot get iframe.contentWindow document: ' + err);
+            }
+
+            if (doc) { // successful getting content
+                return doc;
+            }
+
+            try { // simply checking may throw in ie8 under ssl or mismatched protocol
+                doc = frame.contentDocument ? frame.contentDocument : frame.document;
+            } catch(err) {
+                // last attempt
+                log('cannot get iframe.contentDocument: ' + err);
+                doc = frame.document;
+            }
+            return doc;
+        }
+
+        // Rails CSRF hack (thanks to Yvan Barthelemy)
+        var csrf_token = $('meta[name=csrf-token]').attr('content');
+        var csrf_param = $('meta[name=csrf-param]').attr('content');
+        if (csrf_param && csrf_token) {
+            s.extraData = s.extraData || {};
+            s.extraData[csrf_param] = csrf_token;
+        }
+
+        // take a breath so that pending repaints get some cpu time before the upload starts
+        function doSubmit() {
+            // make sure form attrs are set
+            var t = $form.attr2('target'), a = $form.attr2('action');
+
+            // update form attrs in IE friendly way
+            form.setAttribute('target',id);
+            if (!method) {
+                form.setAttribute('method', 'POST');
+            }
+            if (a != s.url) {
+                form.setAttribute('action', s.url);
+            }
+
+            // ie borks in some cases when setting encoding
+            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
+                $form.attr({
+                    encoding: 'multipart/form-data',
+                    enctype:  'multipart/form-data'
+                });
+            }
+
+            // support timout
+            if (s.timeout) {
+                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
+            }
+
+            // look for server aborts
+            function checkState() {
+                try {
+                    var state = getDoc(io).readyState;
+                    log('state = ' + state);
+                    if (state && state.toLowerCase() == 'uninitialized')
+                        setTimeout(checkState,50);
+                }
+                catch(e) {
+                    log('Server abort: ' , e, ' (', e.name, ')');
+                    cb(SERVER_ABORT);
+                    if (timeoutHandle)
+                        clearTimeout(timeoutHandle);
+                    timeoutHandle = undefined;
+                }
+            }
+
+            // add "extra" data to form if provided in options
+            var extraInputs = [];
+            try {
+                if (s.extraData) {
+                    for (var n in s.extraData) {
+                        if (s.extraData.hasOwnProperty(n)) {
+                           // if using the $.param format that allows for multiple values with the same name
+                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
+                               extraInputs.push(
+                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
+                                   .appendTo(form)[0]);
+                           } else {
+                               extraInputs.push(
+                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
+                                   .appendTo(form)[0]);
+                           }
+                        }
+                    }
+                }
+
+                if (!s.iframeTarget) {
+                    // add iframe to doc and submit the form
+                    $io.appendTo('body');
+                    if (io.attachEvent)
+                        io.attachEvent('onload', cb);
+                    else
+                        io.addEventListener('load', cb, false);
+                }
+                setTimeout(checkState,15);
+
+                try {
+                    form.submit();
+                } catch(err) {
+                    // just in case form has element with name/id of 'submit'
+                    var submitFn = document.createElement('form').submit;
+                    submitFn.apply(form);
+                }
+            }
+            finally {
+                // reset attrs and remove "extra" input elements
+                form.setAttribute('action',a);
+                if(t) {
+                    form.setAttribute('target', t);
+                } else {
+                    $form.removeAttr('target');
+                }
+                $(extraInputs).remove();
+            }
+        }
+
+        if (s.forceSync) {
+            doSubmit();
+        }
+        else {
+            setTimeout(doSubmit, 10); // this lets dom updates render
+        }
+
+        var data, doc, domCheckCount = 50, callbackProcessed;
+
+        function cb(e) {
+            if (xhr.aborted || callbackProcessed) {
+                return;
+            }
+            
+            doc = getDoc(io);
+            if(!doc) {
+                log('cannot access response document');
+                e = SERVER_ABORT;
+            }
+            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
+                xhr.abort('timeout');
+                deferred.reject(xhr, 'timeout');
+                return;
+            }
+            else if (e == SERVER_ABORT && xhr) {
+                xhr.abort('server abort');
+                deferred.reject(xhr, 'error', 'server abort');
+                return;
+            }
+
+            if (!doc || doc.location.href == s.iframeSrc) {
+                // response not received yet
+                if (!timedOut)
+                    return;
+            }
+            if (io.detachEvent)
+                io.detachEvent('onload', cb);
+            else
+                io.removeEventListener('load', cb, false);
+
+            var status = 'success', errMsg;
+            try {
+                if (timedOut) {
+                    throw 'timeout';
+                }
+
+                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
+                log('isXml='+isXml);
+                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
+                    if (--domCheckCount) {
+                        // in some browsers (Opera) the iframe DOM is not always traversable when
+                        // the onload callback fires, so we loop a bit to accommodate
+                        log('requeing onLoad callback, DOM not available');
+                        setTimeout(cb, 250);
+                        return;
+                    }
+                    // let this fall through because server response could be an empty document
+                    //log('Could not access iframe DOM after mutiple tries.');
+                    //throw 'DOMException: not available';
+                }
+
+                //log('response detected');
+                var docRoot = doc.body ? doc.body : doc.documentElement;
+                xhr.responseText = docRoot ? docRoot.innerHTML : null;
+                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
+                if (isXml)
+                    s.dataType = 'xml';
+                xhr.getResponseHeader = function(header){
+                    var headers = {'content-type': s.dataType};
+                    return headers[header];
+                };
+                // support for XHR 'status' & 'statusText' emulation :
+                if (docRoot) {
+                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
+                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
+                }
+
+                var dt = (s.dataType || '').toLowerCase();
+                var scr = /(json|script|text)/.test(dt);
+                if (scr || s.textarea) {
+                    // see if user embedded response in textarea
+                    var ta = doc.getElementsByTagName('textarea')[0];
+                    if (ta) {
+                        xhr.responseText = ta.value;
+                        // support for XHR 'status' & 'statusText' emulation :
+                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
+                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
+                    }
+                    else if (scr) {
+                        // account for browsers injecting pre around json response
+                        var pre = doc.getElementsByTagName('pre')[0];
+                        var b = doc.getElementsByTagName('body')[0];
+                        if (pre) {
+                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
+                        }
+                        else if (b) {
+                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
+                        }
+                    }
+                }
+                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
+                    xhr.responseXML = toXml(xhr.responseText);
+                }
+
+                try {
+                    data = httpData(xhr, dt, s);
+                }
+                catch (err) {
+                    status = 'parsererror';
+                    xhr.error = errMsg = (err || status);
+                }
+            }
+            catch (err) {
+                log('error caught: ',err);
+                status = 'error';
+                xhr.error = errMsg = (err || status);
+            }
+
+            if (xhr.aborted) {
+                log('upload aborted');
+                status = null;
+            }
+
+            if (xhr.status) { // we've set xhr.status
+                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
+            }
+
+            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
+            if (status === 'success') {
+                if (s.success)
+                    s.success.call(s.context, data, 'success', xhr);
+                deferred.resolve(xhr.responseText, 'success', xhr);
+                if (g)
+                    $.event.trigger("ajaxSuccess", [xhr, s]);
+            }
+            else if (status) {
+                if (errMsg === undefined)
+                    errMsg = xhr.statusText;
+                if (s.error)
+                    s.error.call(s.context, xhr, status, errMsg);
+                deferred.reject(xhr, 'error', errMsg);
+                if (g)
+                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
+            }
+
+            if (g)
+                $.event.trigger("ajaxComplete", [xhr, s]);
+
+            if (g && ! --$.active) {
+                $.event.trigger("ajaxStop");
+            }
+
+            if (s.complete)
+                s.complete.call(s.context, xhr, status);
+
+            callbackProcessed = true;
+            if (s.timeout)
+                clearTimeout(timeoutHandle);
+
+            // clean up
+            setTimeout(function() {
+                if (!s.iframeTarget)
+                    $io.remove();
+                xhr.responseXML = null;
+            }, 100);
+        }
+
+        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
+            if (window.ActiveXObject) {
+                doc = new ActiveXObject('Microsoft.XMLDOM');
+                doc.async = 'false';
+                doc.loadXML(s);
+            }
+            else {
+                doc = (new DOMParser()).parseFromString(s, 'text/xml');
+            }
+            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
+        };
+        var parseJSON = $.parseJSON || function(s) {
+            /*jslint evil:true */
+            return window['eval']('(' + s + ')');
+        };
+
+        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
+
+            var ct = xhr.getResponseHeader('content-type') || '',
+                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
+                data = xml ? xhr.responseXML : xhr.responseText;
+
+            if (xml && data.documentElement.nodeName === 'parsererror') {
+                if ($.error)
+                    $.error('parsererror');
+            }
+            if (s && s.dataFilter) {
+                data = s.dataFilter(data, type);
+            }
+            if (typeof data === 'string') {
+                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
+                    data = parseJSON(data);
+                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
+                    $.globalEval(data);
+                }
+            }
+            return data;
+        };
+
+        return deferred;
+    }
+};
+
+/**
+ * ajaxForm() provides a mechanism for fully automating form submission.
+ *
+ * The advantages of using this method instead of ajaxSubmit() are:
+ *
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
+ *    is used to submit the form).
+ * 2. This method will include the submit element's name/value data (for the element that was
+ *    used to submit the form).
+ * 3. This method binds the submit() method to the form for you.
+ *
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
+ * passes the options argument along after properly binding events for submit elements and
+ * the form itself.
+ */
+$.fn.ajaxForm = function(options) {
+    options = options || {};
+    options.delegation = options.delegation && $.isFunction($.fn.on);
+
+    // in jQuery 1.3+ we can fix mistakes with the ready state
+    if (!options.delegation && this.length === 0) {
+        var o = { s: this.selector, c: this.context };
+        if (!$.isReady && o.s) {
+            log('DOM not ready, queuing ajaxForm');
+            $(function() {
+                $(o.s,o.c).ajaxForm(options);
+            });
+            return this;
+        }
+        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
+        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
+        return this;
+    }
+
+    if ( options.delegation ) {
+        $(document)
+            .off('submit.form-plugin', this.selector, doAjaxSubmit)
+            .off('click.form-plugin', this.selector, captureSubmittingElement)
+            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
+            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
+        return this;
+    }
+
+    return this.ajaxFormUnbind()
+        .bind('submit.form-plugin', options, doAjaxSubmit)
+        .bind('click.form-plugin', options, captureSubmittingElement);
+};
+
+// private event handlers
+function doAjaxSubmit(e) {
+    /*jshint validthis:true */
+    var options = e.data;
+    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
+        e.preventDefault();
+        $(this).ajaxSubmit(options);
+    }
+}
+
+function captureSubmittingElement(e) {
+    /*jshint validthis:true */
+    var target = e.target;
+    var $el = $(target);
+    if (!($el.is("[type=submit],[type=image]"))) {
+        // is this a child element of the submit el?  (ex: a span within a button)
+        var t = $el.closest('[type=submit]');
+        if (t.length === 0) {
+            return;
+        }
+        target = t[0];
+    }
+    var form = this;
+    form.clk = target;
+    if (target.type == 'image') {
+        if (e.offsetX !== undefined) {
+            form.clk_x = e.offsetX;
+            form.clk_y = e.offsetY;
+        } else if (typeof $.fn.offset == 'function') {
+            var offset = $el.offset();
+            form.clk_x = e.pageX - offset.left;
+            form.clk_y = e.pageY - offset.top;
+        } else {
+            form.clk_x = e.pageX - target.offsetLeft;
+            form.clk_y = e.pageY - target.offsetTop;
+        }
+    }
+    // clear form vars
+    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
+}
+
+
+// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
+$.fn.ajaxFormUnbind = function() {
+    return this.unbind('submit.form-plugin click.form-plugin');
+};
+
+/**
+ * formToArray() gathers form element data into an array of objects that can
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
+ * Each object in the array has both a 'name' and 'value' property.  An example of
+ * an array for a simple login form might be:
+ *
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * It is this array that is passed to pre-submit callback functions provided to the
+ * ajaxSubmit() and ajaxForm() methods.
+ */
+$.fn.formToArray = function(semantic, elements) {
+    var a = [];
+    if (this.length === 0) {
+        return a;
+    }
+
+    var form = this[0];
+    var els = semantic ? form.getElementsByTagName('*') : form.elements;
+    if (!els) {
+        return a;
+    }
+
+    var i,j,n,v,el,max,jmax;
+    for(i=0, max=els.length; i < max; i++) {
+        el = els[i];
+        n = el.name;
+        if (!n || el.disabled) {
+            continue;
+        }
+
+        if (semantic && form.clk && el.type == "image") {
+            // handle image inputs on the fly when semantic == true
+            if(form.clk == el) {
+                a.push({name: n, value: $(el).val(), type: el.type });
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+            }
+            continue;
+        }
+
+        v = $.fieldValue(el, true);
+        if (v && v.constructor == Array) {
+            if (elements)
+                elements.push(el);
+            for(j=0, jmax=v.length; j < jmax; j++) {
+                a.push({name: n, value: v[j]});
+            }
+        }
+        else if (feature.fileapi && el.type == 'file') {
+            if (elements)
+                elements.push(el);
+            var files = el.files;
+            if (files.length) {
+                for (j=0; j < files.length; j++) {
+                    a.push({name: n, value: files[j], type: el.type});
+                }
+            }
+            else {
+                // #180
+                a.push({ name: n, value: '', type: el.type });
+            }
+        }
+        else if (v !== null && typeof v != 'undefined') {
+            if (elements)
+                elements.push(el);
+            a.push({name: n, value: v, type: el.type, required: el.required});
+        }
+    }
+
+    if (!semantic && form.clk) {
+        // input type=='image' are not found in elements array! handle it here
+        var $input = $(form.clk), input = $input[0];
+        n = input.name;
+        if (n && !input.disabled && input.type == 'image') {
+            a.push({name: n, value: $input.val()});
+            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+        }
+    }
+    return a;
+};
+
+/**
+ * Serializes form data into a 'submittable' string. This method will return a string
+ * in the format: name1=value1&amp;name2=value2
+ */
+$.fn.formSerialize = function(semantic) {
+    //hand off to jQuery.param for proper encoding
+    return $.param(this.formToArray(semantic));
+};
+
+/**
+ * Serializes all field elements in the jQuery object into a query string.
+ * This method will return a string in the format: name1=value1&amp;name2=value2
+ */
+$.fn.fieldSerialize = function(successful) {
+    var a = [];
+    this.each(function() {
+        var n = this.name;
+        if (!n) {
+            return;
+        }
+        var v = $.fieldValue(this, successful);
+        if (v && v.constructor == Array) {
+            for (var i=0,max=v.length; i < max; i++) {
+                a.push({name: n, value: v[i]});
+            }
+        }
+        else if (v !== null && typeof v != 'undefined') {
+            a.push({name: this.name, value: v});
+        }
+    });
+    //hand off to jQuery.param for proper encoding
+    return $.param(a);
+};
+
+/**
+ * Returns the value(s) of the element in the matched set.  For example, consider the following form:
+ *
+ *  <form><fieldset>
+ *      <input name="A" type="text" />
+ *      <input name="A" type="text" />
+ *      <input name="B" type="checkbox" value="B1" />
+ *      <input name="B" type="checkbox" value="B2"/>
+ *      <input name="C" type="radio" value="C1" />
+ *      <input name="C" type="radio" value="C2" />
+ *  </fieldset></form>
+ *
+ *  var v = $('input[type=text]').fieldValue();
+ *  // if no values are entered into the text inputs
+ *  v == ['','']
+ *  // if values entered into the text inputs are 'foo' and 'bar'
+ *  v == ['foo','bar']
+ *
+ *  var v = $('input[type=checkbox]').fieldValue();
+ *  // if neither checkbox is checked
+ *  v === undefined
+ *  // if both checkboxes are checked
+ *  v == ['B1', 'B2']
+ *
+ *  var v = $('input[type=radio]').fieldValue();
+ *  // if neither radio is checked
+ *  v === undefined
+ *  // if first radio is checked
+ *  v == ['C1']
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If this value is false the value(s)
+ * for each element is returned.
+ *
+ * Note: This method *always* returns an array.  If no valid value can be determined the
+ *    array will be empty, otherwise it will contain one or more values.
+ */
+$.fn.fieldValue = function(successful) {
+    for (var val=[], i=0, max=this.length; i < max; i++) {
+        var el = this[i];
+        var v = $.fieldValue(el, successful);
+        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
+            continue;
+        }
+        if (v.constructor == Array)
+            $.merge(val, v);
+        else
+            val.push(v);
+    }
+    return val;
+};
+
+/**
+ * Returns the value of the field element.
+ */
+$.fieldValue = function(el, successful) {
+    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
+    if (successful === undefined) {
+        successful = true;
+    }
+
+    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
+        (t == 'checkbox' || t == 'radio') && !el.checked ||
+        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
+        tag == 'select' && el.selectedIndex == -1)) {
+            return null;
+    }
+
+    if (tag == 'select') {
+        var index = el.selectedIndex;
+        if (index < 0) {
+            return null;
+        }
+        var a = [], ops = el.options;
+        var one = (t == 'select-one');
+        var max = (one ? index+1 : ops.length);
+        for(var i=(one ? index : 0); i < max; i++) {
+            var op = ops[i];
+            if (op.selected) {
+                var v = op.value;
+                if (!v) { // extra pain for IE...
+                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
+                }
+                if (one) {
+                    return v;
+                }
+                a.push(v);
+            }
+        }
+        return a;
+    }
+    return $(el).val();
+};
+
+/**
+ * Clears the form data.  Takes the following actions on the form's input fields:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ */
+$.fn.clearForm = function(includeHidden) {
+    return this.each(function() {
+        $('input,select,textarea', this).clearFields(includeHidden);
+    });
+};
+
+/**
+ * Clears the selected form elements.
+ */
+$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
+    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
+    return this.each(function() {
+        var t = this.type, tag = this.tagName.toLowerCase();
+        if (re.test(t) || tag == 'textarea') {
+            this.value = '';
+        }
+        else if (t == 'checkbox' || t == 'radio') {
+            this.checked = false;
+        }
+        else if (tag == 'select') {
+            this.selectedIndex = -1;
+        }
+		else if (t == "file") {
+			if (/MSIE/.test(navigator.userAgent)) {
+				$(this).replaceWith($(this).clone(true));
+			} else {
+				$(this).val('');
+			}
+		}
+        else if (includeHidden) {
+            // includeHidden can be the value true, or it can be a selector string
+            // indicating a special test; for example:
+            //  $('#myForm').clearForm('.special:hidden')
+            // the above would clean hidden inputs that have the class of 'special'
+            if ( (includeHidden === true && /hidden/.test(t)) ||
+                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
+                this.value = '';
+        }
+    });
+};
+
+/**
+ * Resets the form data.  Causes all form elements to be reset to their original value.
+ */
+$.fn.resetForm = function() {
+    return this.each(function() {
+        // guard against an input with the name of 'reset'
+        // note that IE reports the reset function as an 'object'
+        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
+            this.reset();
+        }
+    });
+};
+
+/**
+ * Enables or disables any matching elements.
+ */
+$.fn.enable = function(b) {
+    if (b === undefined) {
+        b = true;
+    }
+    return this.each(function() {
+        this.disabled = !b;
+    });
+};
+
+/**
+ * Checks/unchecks any matching checkboxes or radio buttons and
+ * selects/deselects and matching option elements.
+ */
+$.fn.selected = function(select) {
+    if (select === undefined) {
+        select = true;
+    }
+    return this.each(function() {
+        var t = this.type;
+        if (t == 'checkbox' || t == 'radio') {
+            this.checked = select;
+        }
+        else if (this.tagName.toLowerCase() == 'option') {
+            var $sel = $(this).parent('select');
+            if (select && $sel[0] && $sel[0].type == 'select-one') {
+                // deselect all other options
+                $sel.find('option').selected(false);
+            }
+            this.selected = select;
+        }
+    });
+};
+
+// expose debug var
+$.fn.ajaxSubmit.debug = false;
+
+// helper fn for console logging
+function log() {
+    if (!$.fn.ajaxSubmit.debug)
+        return;
+    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
+    if (window.console && window.console.log) {
+        window.console.log(msg);
+    }
+    else if (window.opera && window.opera.postError) {
+        window.opera.postError(msg);
+    }
+}
+
+})(jQuery);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/785a3421/src/fauxton/package.json
----------------------------------------------------------------------
diff --git a/src/fauxton/package.json b/src/fauxton/package.json
index 2a09f69..5b63675 100644
--- a/src/fauxton/package.json
+++ b/src/fauxton/package.json
@@ -23,7 +23,7 @@
     "url": "~0.7.9",
     "urls": "~0.0.3",
     "express": "~3.0.6",
-    "http-proxy": "~0.9.1"
+    "http-proxy": "~0.10.2"
   },
   "devDependencies": {},
   "scripts": {


[28/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Add a configurable whitelist of public user props

By default no user properties are public and attempts to view a users
document other than your own will return a 404. If the public_fields
setting of the users_db config section is set to a list of field
names, however, you will see that subset of fields for any user.

Also, if `public_fields` is set and non-empty,
`_users/_all_docs?include_docs=true` will return documents with stripped
field.

Contributed with code parts from @indutny


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

Branch: refs/heads/1684-feature-db-updates
Commit: 8d7ab8b18dd20f8785e69f4420c6f93a2edbfa60
Parents: 136b289
Author: Robert Newson <rn...@apache.org>
Authored: Fri Jun 21 11:01:13 2013 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Jun 21 22:49:46 2013 +0100

----------------------------------------------------------------------
 etc/couchdb/default.ini.tpl.in             |  2 ++
 share/www/script/test/users_db_security.js | 44 +++++++++++++++++++++++++
 src/couch_mrview/src/couch_mrview_http.erl | 43 ++++++++++++++++++++++--
 src/couchdb/couch_users_db.erl             | 15 +++++++--
 4 files changed, 99 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/8d7ab8b1/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index 736d9cd..5eb7ebc 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -67,6 +67,8 @@ timeout = 600 ; number of seconds before automatic logout
 auth_cache_size = 50 ; size is number of cache entries
 allow_persistent_cookies = false ; set to true to allow persistent cookies
 iterations = 10 ; iterations for password hashing
+; comma-separated list of public fields, 404 if empty
+; public_fields =
 
 [cors]
 credentials = false

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8d7ab8b1/share/www/script/test/users_db_security.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/users_db_security.js b/share/www/script/test/users_db_security.js
index d439fcb..cdc3f17 100644
--- a/share/www/script/test/users_db_security.js
+++ b/share/www/script/test/users_db_security.js
@@ -256,6 +256,50 @@ couchTests.users_db_security = function(debug) {
       // log in one last time so run_on_modified_server can clean up the admin account
       TEquals(true, CouchDB.login("jan", "apple").ok);
     });
+
+    run_on_modified_server([
+        {
+          section: "couch_httpd_auth",
+          key: "iterations",
+          value: "1"
+        },
+        {
+          section: "couch_httpd_auth",
+          key: "public_fields",
+          value: "name,type"
+        },
+        {
+          section: "admins",
+          key: "jan",
+          value: "apple"
+        }
+      ], function() {
+        var res = usersDb.open("org.couchdb.user:jchris");
+        TEquals("jchris", res.name);
+        TEquals("user", res.type);
+        TEquals(undefined, res.roles);
+        TEquals(undefined, res.salt);
+        TEquals(undefined, res.password_scheme);
+        TEquals(undefined, res.derived_key);
+
+        // log in one last time so run_on_modified_server can clean up the admin account
+        TEquals(true, CouchDB.login("jan", "apple").ok);
+
+        var all = usersDb.allDocs({ include_docs: true });
+        T(all.rows);
+        if (all.rows) {
+          T(all.rows.every(function(row) {
+            T(row.doc);
+            if (row.doc) {
+              return Object.keys(row.doc).every(function(key) {
+                return key === 'name' || key === 'type';
+              });
+            } else {
+              return false;
+            }
+          }));
+        }
+    });
   };
 
   usersDb.deleteDb();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8d7ab8b1/src/couch_mrview/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview/src/couch_mrview_http.erl b/src/couch_mrview/src/couch_mrview_http.erl
index 91587f1..61db4c0 100644
--- a/src/couch_mrview/src/couch_mrview_http.erl
+++ b/src/couch_mrview/src/couch_mrview_http.erl
@@ -106,8 +106,22 @@ all_docs_req(Req, Db, Keys) ->
         ok ->
             do_all_docs_req(Req, Db, Keys);
         _ ->
-            throw({forbidden, <<"Only admins can access _all_docs",
-                " of system databases.">>})
+            DbName = ?b2l(Db#db.name),
+            case couch_config:get("couch_httpd_auth",
+                                  "authentication_db",
+                                  "_users") of
+            DbName ->
+                case couch_config:get("couch_httpd_auth", "public_fields") of
+                undefined ->
+                    throw({forbidden, <<"Only admins can access _all_docs",
+                                        " of system databases.">>});
+                _ ->
+                    do_all_docs_req(Req, Db, Keys)
+                end;
+            _ ->
+                throw({forbidden, <<"Only admins can access _all_docs",
+                                    " of system databases.">>})
+            end
         end;
     false ->
         do_all_docs_req(Req, Db, Keys)
@@ -126,7 +140,16 @@ do_all_docs_req(Req, Db, Keys) ->
     Args = Args0#mrargs{preflight_fun=ETagFun},
     {ok, Resp} = couch_httpd:etag_maybe(Req, fun() ->
         VAcc0 = #vacc{db=Db, req=Req},
-        couch_mrview:query_all_docs(Db, Args, fun view_cb/2, VAcc0)
+        DbName = ?b2l(Db#db.name),
+        Callback = case couch_config:get("couch_httpd_auth",
+                                         "authentication_db",
+                                         "_users") of
+        DbName ->
+            fun filtered_view_cb/2;
+        _ ->
+            fun view_cb/2
+        end,
+        couch_mrview:query_all_docs(Db, Args, Callback, VAcc0)
     end),
     case is_record(Resp, vacc) of
         true -> {ok, Resp#vacc.resp};
@@ -154,6 +177,20 @@ design_doc_view(Req, Db, DDoc, ViewName, Keys) ->
     end.
 
 
+filtered_view_cb({row, Row0}, Acc) ->
+  Row1 = lists:map(fun({doc, null}) ->
+        {doc, null};
+    ({doc, Body}) ->
+        Doc = couch_users_db:strip_non_public_fields(#doc{body=Body}),
+        {doc, Doc#doc.body};
+    (KV) ->
+        KV
+    end, Row0),
+    view_cb({row, Row1}, Acc);
+filtered_view_cb(Obj, Acc) ->
+    view_cb(Obj, Acc).
+
+
 view_cb({meta, Meta}, #vacc{resp=undefined}=Acc) ->
     Headers = [{"ETag", Acc#vacc.etag}],
     {ok, Resp} = couch_httpd:start_json_response(Acc#vacc.req, 200, Headers),

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8d7ab8b1/src/couchdb/couch_users_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_users_db.erl b/src/couchdb/couch_users_db.erl
index de76142..9b875ba 100644
--- a/src/couchdb/couch_users_db.erl
+++ b/src/couchdb/couch_users_db.erl
@@ -12,7 +12,7 @@
 
 -module(couch_users_db).
 
--export([before_doc_update/2, after_doc_read/2]).
+-export([before_doc_update/2, after_doc_read/2, strip_non_public_fields/1]).
 
 -include("couch_db.hrl").
 
@@ -101,10 +101,21 @@ after_doc_read(Doc, #db{user_ctx = UserCtx} = Db) ->
     _ when Name =:= DocName ->
         Doc;
     _ ->
-        throw(not_found)
+        Doc1 = strip_non_public_fields(Doc),
+        case Doc1 of
+          #doc{body={[]}} ->
+              throw(not_found);
+          _ ->
+              Doc1
+        end
     end.
 
 get_doc_name(#doc{id= <<"org.couchdb.user:", Name/binary>>}) ->
     Name;
 get_doc_name(_) ->
     undefined.
+
+strip_non_public_fields(#doc{body={Props}}=Doc) ->
+    Public = re:split(couch_config:get("couch_httpd_auth", "public_fields", ""),
+                      "\\s*,\\s*", [{return, binary}]),
+    Doc#doc{body={[{K, V} || {K, V} <- Props, lists:member(K, Public)]}}.


[05/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Add Vagrantfile

This patch allows us to develop and test couchdb using vagrant
(http://www.vagrantup.com) .

Since we don't have any good debian packaging for now this image is only
useful for developers or those who want to use latest couchdb version.

To use it run the following commad:

    $ vagrant up
    $ vagrant ssh
    $ cd /vagrant

then you can play with the code and build your own distribution of
couch. This image is supporting lxc, ec2 and rackspace providers for
vagrant.


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

Branch: refs/heads/1684-feature-db-updates
Commit: f15f54d56149d3119ca2c06bcd63991071fbbe40
Parents: 86dd4ea
Author: Benoit Chesneau <bc...@gmail.com>
Authored: Wed May 29 14:53:55 2013 +0200
Committer: Benoit Chesneau <bc...@gmail.com>
Committed: Wed May 29 14:53:55 2013 +0200

----------------------------------------------------------------------
 Vagrantfile | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/f15f54d5/Vagrantfile
----------------------------------------------------------------------
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..465d5a6
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,70 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+BOX_NAME = ENV['BOX_NAME'] || "ubuntu"
+BOX_URI = ENV['BOX_URI'] || "http://files.vagrantup.com/precise64.box"
+AWS_REGION = ENV['AWS_REGION'] || "us-east-1"
+AWS_AMI    = ENV['AWS_AMI']    || "ami-d0f89fb9"
+
+Vagrant::Config.run do |config|
+  # Setup virtual machine box. This VM configuration code is always executed.
+  config.vm.box = BOX_NAME
+  config.vm.box_url = BOX_URI
+
+  # Install couchdb dependencies if deployment was not done
+  if Dir.glob("#{File.dirname(__FILE__)}/.vagrant/machines/default/*/id").empty?
+    # install build-essential
+    pkg_cmd = "apt-get update -qq; apt-get install -q -y build-essential git " 
+        "autoconf autoconf-archive gnu-standards help2man textinfo; "
+
+    # Install erlang
+    pkg_cmd << "apt-get install -q -y erlang-base-hipe erlang-dev " \
+        "erlang-manpages erlang-eunit erlang-nox erlang-xmerl erlang-inets; "
+
+    # couchdb developper dependencies
+    pkg_cmd << "apt-get install -q -y libmozjs185-dev libicu-dev " \
+        "curl libcurl4-gnutls-dev libtool; "
+
+    # doc dependencies
+    pkg_cmd << "apt-get install -q -y apt-get install -q -y help2man " \
+        "textinfo python-sphix python-pip; " \
+        "pip install -U pygments; "
+
+    config.vm.provision :shell, :inline => pkg_cmd
+  end
+end
+
+
+# Providers were added on Vagrant >= 1.1.0
+Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
+  config.vm.provider :aws do |aws, override|
+    aws.access_key_id = ENV["AWS_ACCESS_KEY_ID"]
+    aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
+    aws.keypair_name = ENV["AWS_KEYPAIR_NAME"]
+    override.ssh.private_key_path = ENV["AWS_SSH_PRIVKEY"]
+    override.ssh.username = "ubuntu"
+    aws.region = AWS_REGION
+    aws.ami    = AWS_AMI
+    aws.instance_type = "t1.micro"
+  end
+
+  config.vm.provider :rackspace do |rs|
+    config.ssh.private_key_path = ENV["RS_PRIVATE_KEY"]
+    rs.username = ENV["RS_USERNAME"]
+    rs.api_key  = ENV["RS_API_KEY"]
+    rs.public_key_path = ENV["RS_PUBLIC_KEY"]
+    rs.flavor   = /512MB/
+    rs.image    = /Ubuntu/
+  end
+
+  config.vm.provider :virtualbox do |vb|
+    config.vm.box = BOX_NAME
+    config.vm.box_url = BOX_URI
+  end
+
+  config.vm.provider :lxc do |lxc|
+    config.vm.box = BOX_NAME
+    config.vm.box_url = BOX_URI
+    lxc.customize 'cgroup.memory.limit_in_bytes', '1024M'
+  end
+end


[06/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Allow storing a pre-hashed admin password

When duplicating a couch, it is difficult to copy the _config/admins/*
values. Storing the encoded value does not work because that value is
re-hashed when stored. (Your password is the literal string
"-pbkdf2-abcdef...".)

This change will store any config setting unmodified if ?raw=true is
in the query string.

Updating _config/admins/* already requires admin privileges, so there is
no change to the security.


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

Branch: refs/heads/1684-feature-db-updates
Commit: c98ba5612e313b252e5b7ac91b3772c226b82217
Parents: f15f54d
Author: Jason Smith (work) <jh...@nodejitsu.com>
Authored: Fri May 31 18:06:25 2013 +0000
Committer: Jason Smith (work) <jh...@nodejitsu.com>
Committed: Fri May 31 18:06:25 2013 +0000

----------------------------------------------------------------------
 share/doc/src/configuring.rst             | 26 ++++++++++++++
 share/www/script/test/config.js           | 48 ++++++++++++++++++++++++++
 src/couchdb/couch_httpd_misc_handlers.erl | 42 ++++++++++++++++++----
 3 files changed, 109 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c98ba561/share/doc/src/configuring.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/configuring.rst b/share/doc/src/configuring.rst
index 4b8bb11..8d3e704 100644
--- a/share/doc/src/configuring.rst
+++ b/share/doc/src/configuring.rst
@@ -240,6 +240,32 @@ supports querying, deleting or creating new admin accounts:
             "architect": "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
         }
 
+If you already have a salted, encrypted password string (for example,
+from an old ``local.ini`` file, or from a different CouchDB server), then
+you can store the "raw" encrypted string, without having CouchDB doubly
+encrypt it.
+
+.. code-block:: bash
+
+    shell> PUT /_config/admins/architect?raw=true HTTP/1.1
+        Accept: application/json
+        Content-Type: application/json
+        Content-Length: 89
+        Host: localhost:5984
+
+        "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
+
+    HTTP/1.1 200 OK
+        Cache-Control: must-revalidate
+        Content-Length: 89
+        Content-Type: application/json
+        Date: Fri, 30 Nov 2012 11:39:18 GMT
+        Server: CouchDB/1.3.0 (Erlang OTP/R15B02)
+
+.. code-block:: json
+
+        "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
+
 Further details are available in ``security_``, including configuring the
 work factor for ``PBKDF2``, and the algorithm itself at
 `PBKDF2 (RFC-2898) <http://tools.ietf.org/html/rfc2898>`_.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c98ba561/share/www/script/test/config.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/config.js b/share/www/script/test/config.js
index 5382778..193aa89 100644
--- a/share/www/script/test/config.js
+++ b/share/www/script/test/config.js
@@ -72,6 +72,54 @@ couchTests.config = function(debug) {
   config = JSON.parse(xhr.responseText);
   T(config == "bar");
 
+  // Server-side password hashing, and raw updates disabling that.
+  var password_plain = 's3cret';
+  var password_hashed = null;
+
+  xhr = CouchDB.request("PUT", "/_config/admins/administrator",{
+    body : JSON.stringify(password_plain),
+    headers: {"X-Couch-Persist": "false"}
+  });
+  TEquals(200, xhr.status, "Create an admin in the config");
+
+  T(CouchDB.login("administrator", password_plain).ok);
+
+  xhr = CouchDB.request("GET", "/_config/admins/administrator");
+  password_hashed = JSON.parse(xhr.responseText);
+  T(password_hashed.match(/^-pbkdf2-/) || password_hashed.match(/^-hashed-/),
+    "Admin password is hashed");
+
+  xhr = CouchDB.request("PUT", "/_config/admins/administrator?raw=nothanks",{
+    body : JSON.stringify(password_hashed),
+    headers: {"X-Couch-Persist": "false"}
+  });
+  TEquals(400, xhr.status, "CouchDB rejects an invalid 'raw' option");
+
+  xhr = CouchDB.request("PUT", "/_config/admins/administrator?raw=true",{
+    body : JSON.stringify(password_hashed),
+    headers: {"X-Couch-Persist": "false"}
+  });
+  TEquals(200, xhr.status, "Set an raw, pre-hashed admin password");
+
+  xhr = CouchDB.request("PUT", "/_config/admins/administrator?raw=false",{
+    body : JSON.stringify(password_hashed),
+    headers: {"X-Couch-Persist": "false"}
+  });
+  TEquals(200, xhr.status, "Set an admin password with raw=false");
+
+  // The password is literally the string "-pbkdf2-abcd...".
+  T(CouchDB.login("administrator", password_hashed).ok);
+
+  xhr = CouchDB.request("GET", "/_config/admins/administrator");
+  T(password_hashed != JSON.parse(xhr.responseText),
+    "Hashed password was not stored as a raw string");
+
+  xhr = CouchDB.request("DELETE", "/_config/admins/administrator",{
+    headers: {"X-Couch-Persist": "false"}
+  });
+  TEquals(200, xhr.status, "Delete an admin from the config");
+  T(CouchDB.logout().ok);
+
   // Non-term whitelist values allow further modification of the whitelist.
   xhr = CouchDB.request("PUT", "/_config/httpd/config_whitelist",{
     body : JSON.stringify("!This is an invalid Erlang term!"),

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c98ba561/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 d1f947d..96a05c6 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -219,13 +219,35 @@ handle_config_req(Req) ->
 
 % PUT /_config/Section/Key
 % "value"
-handle_approved_config_req(#httpd{method='PUT', path_parts=[_, Section, Key]}=Req, Persist) ->
-    Value = case Section of
-    <<"admins">> ->
-        couch_passwords:hash_admin_password(couch_httpd:json_body(Req));
-    _ ->
-        couch_httpd:json_body(Req)
+handle_approved_config_req(Req, Persist) ->
+    Query = couch_httpd:qs(Req),
+    UseRawValue = case lists:keyfind("raw", 1, Query) of
+    false            -> false; % Not specified
+    {"raw", ""}      -> false; % Specified with no value, i.e. "?raw" and "?raw="
+    {"raw", "false"} -> false;
+    {"raw", "true"}  -> true;
+    {"raw", InvalidValue} -> InvalidValue
+    end,
+    handle_approved_config_req(Req, Persist, UseRawValue).
+
+handle_approved_config_req(#httpd{method='PUT', path_parts=[_, Section, Key]}=Req,
+                           Persist, UseRawValue)
+        when UseRawValue =:= false orelse UseRawValue =:= true ->
+    RawValue = couch_httpd:json_body(Req),
+    Value = case UseRawValue of
+    true ->
+        % Client requests no change to the provided value.
+        RawValue;
+    false ->
+        % Pre-process the value as necessary.
+        case Section of
+        <<"admins">> ->
+            couch_passwords:hash_admin_password(RawValue);
+        _ ->
+            RawValue
+        end
     end,
+
     OldValue = couch_config:get(Section, Key, ""),
     case couch_config:set(Section, Key, ?b2l(Value), Persist) of
     ok ->
@@ -233,8 +255,14 @@ handle_approved_config_req(#httpd{method='PUT', path_parts=[_, Section, Key]}=Re
     Error ->
         throw(Error)
     end;
+
+handle_approved_config_req(#httpd{method='PUT'}=Req, _Persist, UseRawValue) ->
+    Err = io_lib:format("Bad value for 'raw' option: ~s", [UseRawValue]),
+    send_json(Req, 400, {[{error, ?l2b(Err)}]});
+
 % DELETE /_config/Section/Key
-handle_approved_config_req(#httpd{method='DELETE',path_parts=[_,Section,Key]}=Req, Persist) ->
+handle_approved_config_req(#httpd{method='DELETE',path_parts=[_,Section,Key]}=Req,
+                           Persist, _UseRawValue) ->
     case couch_config:get(Section, Key, null) of
     null ->
         throw({not_found, unknown_config_value});


[14/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
FIX BUILD: add Vagrantfile to license.skip


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

Branch: refs/heads/1684-feature-db-updates
Commit: 055fd9f91b6ed15af9b6714481f5c36e4270a20a
Parents: e78ce41
Author: Jan Lehnardt <ja...@apache.org>
Authored: Wed Jun 5 22:10:40 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Wed Jun 5 22:10:40 2013 +0200

----------------------------------------------------------------------
 license.skip | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/055fd9f9/license.skip
----------------------------------------------------------------------
diff --git a/license.skip b/license.skip
index f1df589..db08c31 100644
--- a/license.skip
+++ b/license.skip
@@ -140,3 +140,4 @@
 ^utils/Makefile.in
 ^var/Makefile
 ^var/Makefile.in
+^Vagrantfile


[40/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: move log filtered collection to serialize


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

Branch: refs/heads/1684-feature-db-updates
Commit: 03d1b7e0c8c438d0a604c691575f9c7c15757004
Parents: 65e5074
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jul 9 15:29:49 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jul 9 15:29:49 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/logs/resources.js | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/03d1b7e0/src/fauxton/app/addons/logs/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/resources.js b/src/fauxton/app/addons/logs/resources.js
index b64f813..072290b 100644
--- a/src/fauxton/app/addons/logs/resources.js
+++ b/src/fauxton/app/addons/logs/resources.js
@@ -97,10 +97,9 @@ function (app, FauxtonAPI, Backbone) {
       Log.events.on("log:remove", this.removeFilterLogs, this);
 
       this.filters = [];
-      this.filteredCollection = new Log.Collection(this.collection.toJSON());
 
       this.collection.on("add", function () {
-        this.createFilteredCollection();
+        this.render();
       }, this);
     },
 
@@ -109,7 +108,7 @@ function (app, FauxtonAPI, Backbone) {
     },
 
     serialize: function () {
-      return { logs: this.filteredCollection};
+      return { logs: new Log.Collection(this.createFilteredCollection())};
     },
 
     afterRender: function () {
@@ -122,18 +121,13 @@ function (app, FauxtonAPI, Backbone) {
 
     filterLogs: function (filter) {
       this.filters.push(filter);
-      this.createFilteredCollection();
-    },
-
-    resetFilterCollectionAndRender: function (logs) {
-      this.filteredCollection.reset(logs);
       this.render();
     },
 
     createFilteredCollection: function () {
       var that = this;
 
-      var filtered = _.reduce(this.filters, function (logs, filter) {
+      return _.reduce(this.filters, function (logs, filter) {
 
         return _.filter(logs, function (log) {
           var match = false;
@@ -149,12 +143,11 @@ function (app, FauxtonAPI, Backbone) {
 
       }, this.collection.toJSON(), this);
 
-      this.resetFilterCollectionAndRender(filtered);
     },
 
     removeFilterLogs: function (filter) {
       this.filters.splice(this.filters.indexOf(filter), 1);
-      this.createFilteredCollection();
+      this.render();
     },
 
     startRefreshInterval: function () {


[35/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: watch assets path


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

Branch: refs/heads/1684-feature-db-updates
Commit: 5f86eca6fe514c4ce31b68269c729e15f6820440
Parents: 2f5ae05
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jul 2 09:30:02 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jul 2 09:30:02 2013 +0200

----------------------------------------------------------------------
 src/fauxton/Gruntfile.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5f86eca6/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 700246f..7c9d4ec 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -206,7 +206,7 @@ module.exports = function(grunt) {
     },
 
     watch: {
-      files: helper.watchFiles(["./app/**/*"]),
+      files: helper.watchFiles(["./app/**/*", "./assets/**/*"]),
       tasks: ['debug', 'template']
     },
 


[46/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Remove NEWS and CHANGES files, in favor of docs.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 6ad181c96b91c13dec5134f743456f818d131320
Parents: c89302f
Author: Dirkjan Ochtman <dj...@apache.org>
Authored: Thu Jul 18 14:31:15 2013 +0200
Committer: Dirkjan Ochtman <dj...@apache.org>
Committed: Thu Jul 18 14:31:15 2013 +0200

----------------------------------------------------------------------
 CHANGES | 1145 ----------------------------------------------------------
 NEWS    |  515 --------------------------
 2 files changed, 1660 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ad181c9/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
deleted file mode 100644
index 269ace0..0000000
--- a/CHANGES
+++ /dev/null
@@ -1,1145 +0,0 @@
-Apache CouchDB CHANGES
-======================
-
-# Version 1.4.0
-# -------------
-#
-# This version has not been released yet.
-#
-# Test Suite:
-#
-#  * Split up replicator_db tests into multiple independent tests.
-#
-# Futon:
-#
-#  * Disabled the link to the Futon test suite.
-#
-# Dependencies:
-#
-#  * Support Erlang/OTP R16.
-#  * Bump Mochiweb dependency to v2.4.2.
-#  * Minimum Erlang/OTP version is now R14B.
-
-Version 1.3.1
--------------
-
-Replicator:
-
- * Tolerate missing source and target fields in _replicator docs (COUCHDB-1788).
-
-Log System:
-
- * Don't log about missing .compact files.
- * Fix bug in WARN level logging from 1.3.0 (COUCHDB-1794).
-
-View Server:
-
- * Fix the -S option to couchjs to increase memory limits (COUCHDB-1792).
-
-Misc:
-
- * Improve documentation: better structure, improve language, less duplication.
- * Improvements to test suite and VPATH build system.
-
-Version 1.3.0
--------------
-
-HTTP Interface:
-
- * No longer rewrites the X-CouchDB-Requested-Path during recursive calls to the
-   rewriter.
- * Limit recursion depth in the URL rewriter. Defaults to a maximum of 100
-   invocations but is configurable.
- * Fix _session for IE7.
- * Added Server-Sent Events protocol to db changes API. See
-   http://www.w3.org/TR/eventsource/ for details.
- * Make password hashing synchronous when using the /_config/admins API.
- * Include user name in show/list ETags.
- * Experimental support for Cross-Origin Resource Sharing (CORS). See 
-   http://www.w3.org/TR/cors/ for details.
-
-Replicator:
-
- * The replicator will use a new server-wide UUID in checkpoint IDs to
-   improve the chances of an efficient resume.
-
-Storage System:
-
- * Fixed unnecessary conflict when deleting and creating a
-   document in the same batch.
-
-View Server:
-
- * Additional response headers may be varied prior to send().
- * GetRow() is now side-effect free.
-
-Futon:
-
- * Disabled the link to the Futon test suite. These tests were causing problems
-   when run from a browser, and are now available via the CLI instead.
- * Added view request duration to Futon.
- * Disable buttons for actions that the user doesn't have permissions to.
-
-Docs:
-
- * Import initial documentation and converted to RST format.
- * Set up Sphinx configuration and integrated into the build system.
- * Serve up HTML manual from Futon, with a link in the sidebar.
- * PDF and info version of the manual also installed.
-  
-Security:
-
- * Passwords are now hashed using the PBKDF2 algorithm with a configurable work
-   factor.
-
-Test Suite:
-
- * Moved the JS test suite to the CLI.
- * Improved tracebacks printed by the JS CLI tests.
- * Improved the reliability of a number of tests.
-
-UUID Algorithms:
-
- * Added the utc_id algorithm.
-
-URL Rewriter & Vhosts:
-
- * Database name is encoded during rewriting (allowing embedded /'s, etc).
- * Reset rewrite counter on new request, avoiding unnecessary request failures
-   due to bogus rewrite limit reports.
-
-Build System:
-
- * C/C++ compiler detection has been improved.
- * Autoconf v2.63 is now required if building from Git checkout directly. See
-   DEVELOPERS file for more details.
- * Fixed issue in couchdb script where stopped status returns before process
-   exits.
-
-Version 1.2.2
--------------
-
-HTTP Interface:
-
- * Reset rewrite counter on new request, avoiding unnecessary request failures
-   due to bogus rewrite limit reports.
-
-Build System:
-
- * Fixed issue in couchdb script where stopped status returns before process
-   exits.
-
-Version 1.2.1
--------------
-
-Security:
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with Adobe
-   Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
-
-HTTP Interface:
-
- * No longer rewrites the X-CouchDB-Requested-Path during recursive
-   calls to the rewriter.
- * Limit recursion depth in the URL rewriter. Defaults to a maximum
-   of 100 invocations but is configurable.
-
-Build System:
-
- * Fix couchdb start script.
- * Win: fix linker invocations.
-
-Futon:
-
- * Disable buttons that aren't available for the logged-in user.
-
-Replication:
-
- * Fix potential timeouts.
-
-View System:
-
- * Change use of signals to avoid broken view groups.
-
-Version 1.2.0
--------------
-
-Authentication:
-
- * Fix use of OAuth with VHosts and URL rewriting.
- * OAuth secrets can now be stored in the users system database
-   as an alternative to key value pairs in the .ini configuration.
-   By default this is disabled (secrets are stored in the .ini)
-   but can be enabled via the .ini configuration key `use_users_db`
-   in the `couch_httpd_oauth` section.
- * Documents in the _users database are no longer publicly
-   readable.
- * Confidential information in the _replication database is no
-   longer publicly readable.
- * Password hashes are now calculated by CouchDB. Clients are no
-   longer required to do this manually.
- * Cookies used for authentication can be made persistent by enabling
-   the .ini configuration key `allow_persistent_cookies' in the
-   `couch_httpd_auth` section.
-
-Build System:
-
- * cURL is no longer required to build CouchDB as it is only
-   used by the command line JS test runner. If cURL is available
-   when building CouchJS you can enable the HTTP bindings by
-   passing -H on the command line.
- * Temporarily made `make check` pass with R15B. A more thorough
-   fix is in the works (COUCHDB-1424).
- * Fixed --with-js-include and --with-js-lib options.
- * Added --with-js-lib-name option.
-
-HTTP Interface:
-
- * Added a native JSON parser.
- * The _active_tasks API now offers more granular fields. Each
-   task type is now able to expose different properties.
- * Added built-in changes feed filter `_view`.
- * Fixes to the `_changes` feed heartbeat option which caused
-   heartbeats to be missed when used with a filter. This caused
-   timeouts of continuous pull replications with a filter.
- * Properly restart the SSL socket on configuration changes.
-
-Replicator:
-
- * A new replicator implementation. It offers more performance and
-   configuration options.
- * Passing non-string values to query_params is now a 400 bad
-   request. This is to reduce the surprise that all parameters
-   are converted to strings internally.
- * Added optional field `since_seq` to replication objects/documents.
-   It allows to bootstrap a replication from a specific source sequence
-   number.
- * Simpler replication cancellation. In addition to the current method,
-   replications can now be canceled by specifying the replication ID
-   instead of the original replication object/document.
-
-Storage System:
-
- * Added optional database and view index file compression (using Google's
-   snappy or zlib's deflate). This feature is enabled by default, but it
-   can be disabled by adapting local.ini accordingly. The on-disk format
-   is upgraded on compaction and new DB/view creation to support this.
- * Several performance improvements, most notably regarding database writes
-   and view indexing.
- * Computation of the size of the latest MVCC snapshot data and all its
-   supporting metadata, both for database and view index files. This
-   information is exposed as the `data_size` attribute in the database and
-   view group information URIs.
- * The size of the buffers used for database and view compaction is now
-   configurable.
- * Added support for automatic database and view compaction. This feature
-   is disabled by default, but it can be enabled via the .ini configuration.
- * Performance improvements for the built-in changes feed filters `_doc_ids`
-   and `_design'.
-
-View Server:
-
- * Add CoffeeScript (http://coffeescript.org/) as a first class view server
-   language.
- * Fixed old index file descriptor leaks after a view cleanup.
- * The requested_path property keeps the pre-rewrite path even when no VHost
-   configuration is matched.
- * Fixed incorrect reduce query results when using pagination parameters.
- * Made icu_driver work with Erlang R15B and later.
- * Avoid invalidating view indexes when running out of file descriptors
-   (COUCHDB-1445).
-
-OAuth:
-
- * Updated bundled erlang_oauth library to the latest version.
-
-Futon:
-
- * The `Status` screen (active tasks) now displays two new task status
-   fields: `Started on` and `Updated on`.
- * Futon remembers view code every time it is saved, allowing to save an
-   edit that amounts to a revert.
-
-Log System:
-
- * Log correct stacktrace in all cases.
- * Improvements to log messages for file-related errors.
-
-Version 1.1.2
--------------
-
-Security:
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with
-   Adobe Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
-
-HTTP Interface:
-
- * ETag of attachment changes only when the attachment changes, not
-   the document.
- * Fix retrieval of headers larger than 4k.
- * Allow OPTIONS HTTP method for list requests.
- * Don't attempt to encode invalid json.
-
-Replicator:
-
- * Fix pull replication of documents with many revisions.
- * Fix replication from an HTTP source to an HTTP target.
-
-View Server:
-
- * Avoid invalidating view indexes when running out of file descriptors.
-
-Log System:
-
- * Improvements to log messages for file-related errors.
-
-Build System:
-
- * Don't `ln` the `couchjs` install target on Windows
- * Remove ICU version dependency on Windows.
- * Improve SpiderMonkey version detection.
-
-Version 1.1.1
--------------
-
-HTTP Interface:
-
- * Add configurable maximum to the number of bytes returned by _log.
- * ETags for views include current sequence if include_docs=true.
- * Fix bug where duplicates can appear in _changes feed.
- * Fix missing revisions in _changes?style=all_docs.
- * JSONP responses now send "text/javascript" for Content-Type.
- * Permit forward slashes in path to update functions.
- * Status code can be specified in update handlers.
- * _view_cleanup when ddoc has no views now removes all index files.
- * Fixes to the document multipart PUT API.
-
-Core Database:
-
- * Fixes regarding file descriptor leaks for databases with views.
- * Fix bug where update handlers break after conflict resolution.
- * Fix file descriptor leak in _log
- * Improve handling of compaction at max_dbs_open limit.
- * Fix crashes when compacting large views.
-
-Query Server:
-
- * Support SpiderMonkey 1.8.5
- * Support provides() in show functions.
- * Fix deadlock when assigning couchjs processes to serve requests.
- * Allow CommonJS modules to be an empty string.
- * Reap couchjs processes that hit reduce_overflow error.
-
-Replicator:
-
- * max_replication_retry_count now supports "infinity".
- * Fix replication crash when source database has a document with empty ID.
- * Fix bug with _replicator where include "filter" could crash couch.
-
-Misc:
-
- * Bump minimum Erlang version to R13B02.
- * Link to ICU 4.2 on Windows.
- * Do not run deleted validate_doc_update functions.
-
-Version 1.1.0
--------------
-
-All CHANGES for 1.0.2 and 1.0.3 also apply to 1.1.0.
-
-HTTP Interface:
-
- * Native SSL support.
- * Added support for HTTP range requests for attachments.
- * Added built-in filters for `_changes`: `_doc_ids` and `_design`.
- * Added configuration option for TCP_NODELAY aka "Nagle".
- * Allow POSTing arguments to `_changes`.
- * Allow `keys` parameter for GET requests to views.
- * Allow wildcards in vhosts definitions.
- * More granular ETag support for views.
- * More flexible URL rewriter.
- * Added support for recognizing "Q values" and media parameters in
-   HTTP Accept headers.
- * Validate doc ids that come from a PUT to a URL.
-
-Externals:
-
- * Added OS Process module to manage daemons outside of CouchDB.
- * Added HTTP Proxy handler for more scalable externals.
-
-Replicator:
-
- * Added `_replicator` database to manage replications.
- * Fixed issues when an endpoint is a remote database accessible via SSL.
- * Added support for continuous by-doc-IDs replication.
- * Fix issue where revision info was omitted when replicating attachments.
- * Integrity of attachment replication is now verified by MD5.
-
-Storage System:
-
- * Multiple micro-optimizations when reading data.
-
-View Server:
-
- * Added CommonJS support to map functions.
- * Added `stale=update_after` query option that triggers a view update after
-   returning a `stale=ok` response.
- * Warn about empty result caused by `startkey` and `endkey` limiting.
- * Built-in reduce function `_sum` now accepts lists of integers as input.
- * Added view query aliases start_key, end_key, start_key_doc_id and
-   end_key_doc_id.
-
-Futon:
-
- * Added a "change password"-feature to Futon.
-
-URL Rewriter & Vhosts:
-
- * Fix for variable substituion
-
-Version 1.0.4
--------------
-
-Security:
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with
-   Adobe Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
-
-Log System:
-
- * Fix file descriptor leak in _log.
-
-HTTP Interface:
-
- * Fix missing revisions in _changes?style=all_docs.
- * Fix validation of attachment names.
-
-View System:
-
- * Avoid invalidating view indexes when running out of file descriptors.
-
-Replicator:
-
- * Fix a race condition where replications can go stale
-
-Version 1.0.3
--------------
-
-General:
-
- * Fixed compatibility issues with Erlang R14B02.
-
-HTTP Interface:
-
- * Fix bug that allows invalid UTF-8 after valid escapes.
- * The query parameter `include_docs` now honors the parameter `conflicts`.
-   This applies to queries against map views, _all_docs and _changes.
- * Added support for inclusive_end with reduce views.
-
-Storage System:
-
- * More performant queries against _changes and _all_docs when using the
-  `include_docs` parameter.
-
-Replicator:
-
- * Enabled replication over IPv6.
- * Fixed for crashes in continuous and filtered changes feeds.
- * Fixed error when restarting replications in OTP R14B02.
- * Upgrade ibrowse to version 2.2.0.
- * Fixed bug when using a filter and a limit of 1.
-
-Security:
-
- * Fixed OAuth signature computation in OTP R14B02.
- * Handle passwords with : in them.
-
-Futon:
-
- * Made compatible with jQuery 1.5.x.
-
-Etap Test Suite:
-
- * Etap tests no longer require use of port 5984. They now use a randomly
-   selected port so they won't clash with a running CouchDB.
-
-Windows:
-
- * Windows builds now require ICU >= 4.4.0 and Erlang >= R14B03. See
-   COUCHDB-1152, and COUCHDB-963 + OTP-9139 for more information.
-
-Version 1.0.2
--------------
-
-Security:
-
- * Fixed CVE-2010-3854: Apache CouchDB Cross Site Scripting Issue
-
-Futon:
-
- * Make test suite work with Safari and Chrome.
- * Fixed animated progress spinner.
- * Fix raw view document link due to overzealous URI encoding.
- * Spell javascript correctly in loadScript(uri).
-
-Storage System:
-
- * Fix leaking file handles after compacting databases and views.
- * Fix databases forgetting their validation function after compaction.
- * Fix occasional timeout errors after successfully compacting large databases.
- * Fix ocassional error when writing to a database that has just been compacted.
- * Fix occasional timeout errors on systems with slow or heavily loaded IO.
- * Fix for OOME when compactions include documents with many conflicts.
- * Fix for missing attachment compression when MIME types included parameters.
- * Preserve purge metadata during compaction to avoid spurious view rebuilds.
- * Fix spurious conflicts introduced when uploading an attachment after
-   a doc has been in a conflict. See COUCHDB-902 for details.
- * Fix for frequently edited documents in multi-master deployments being
-   duplicated in _changes and _all_docs.  See COUCHDDB-968 for details on how
-   to repair.
- * Significantly higher read and write throughput against database and
-   view index files.
-
-Log System:
-
- * Reduce lengthy stack traces.
- * Allow logging of native <xml> types.
-
-HTTP Interface:
-
- * Allow reduce=false parameter in map-only views.
- * Fix parsing of Accept headers.
- * Fix for multipart GET APIs when an attachment was created during a
-   local-local replication. See COUCHDB-1022 for details.
-
-Replicator:
-
- * Updated ibrowse library to 2.1.2 fixing numerous replication issues.
- * Make sure that the replicator respects HTTP settings defined in the config.
- * Fix error when the ibrowse connection closes unexpectedly.
- * Fix authenticated replication (with HTTP basic auth) of design documents
-   with attachments.
- * Various fixes to make replication more resilient for edge-cases.
-
-View Server:
-
- * Don't trigger view updates when requesting `_design/doc/_info`.
- * Fix for circular references in CommonJS requires.
- * Made isArray() function available to functions executed in the query server.
- * Documents are now sealed before being passed to map functions.
- * Force view compaction failure when duplicated document data exists. When
-   this error is seen in the logs users should rebuild their views from
-   scratch to fix the issue. See COUCHDB-999 for details.
-
-Version 1.0.1
--------------
-
-Security:
-
- * Fixed CVE-2010-2234: Apache CouchDB Cross Site Request Forgery Attack
-
-Storage System:
-
- * Fix data corruption bug COUCHDB-844. Please see
-   http://couchdb.apache.org/notice/1.0.1.html for details.
-
-Replicator:
-
- * Added support for replication via an HTTP/HTTPS proxy.
- * Fix pull replication of attachments from 0.11 to 1.0.x.
- * Make the _changes feed work with non-integer seqnums.
-
-HTTP Interface:
-
- * Expose `committed_update_seq` for monitoring purposes.
- * Show fields saved along with _deleted=true. Allows for auditing of deletes.
- * More robust Accept-header detection.
-
-Authentication:
-
- * Enable basic-auth popup when required to access the server, to prevent
-   people from getting locked out.
-
-Futon:
-
- * User interface element for querying stale (cached) views.
-
-Build and System Integration:
-
- * Included additional source files for distribution.
-
-Version 1.0.0
--------------
-
-Security:
-
- * Added authentication caching, to avoid repeated opening and closing of the
-   users database for each request requiring authentication.
-
-Storage System:
-
- * Small optimization for reordering result lists.
- * More efficient header commits.
- * Use O_APPEND to save lseeks.
- * Faster implementation of pread_iolist(). Further improves performance on
-   concurrent reads.
-
-View Server:
-
- * Faster default view collation.
- * Added option to include update_seq in view responses.
-
-Version 0.11.2
---------------
-
-Security:
-
- * Fixed CVE-2010-2234: Apache CouchDB Cross Site Request Forgery Attack
- * Avoid potential DOS attack by guarding all creation of atoms.
-
-Replicator:
-
- * Fix bug when pushing design docs by non-admins, which was hanging the
-   replicator for no good reason.
- * Fix bug when pulling design documents from a source that requires
-   basic-auth.
-
-HTTP Interface:
-
- * Better error messages on invalid URL requests.
-
-Authentication:
-
- * User documents can now be deleted by admins or the user.
-
-Futon:
-
- * Add some Futon files that were missing from the Makefile.
-
-Version 0.11.1
---------------
-
-HTTP Interface:
-
- * Mask passwords in active tasks and logging.
- * Update mochijson2 to allow output of BigNums not in float form.
- * Added support for X-HTTP-METHOD-OVERRIDE.
- * Better error message for database names.
- * Disable jsonp by default.
- * Accept gzip encoded standalone attachments.
- * Made max_concurrent_connections configurable.
- * Made changes API more robust.
- * Send newly generated document rev to callers of an update function.
-
-Futon:
-
- * Use "expando links" for over-long document values in Futon.
- * Added continuous replication option.
- * Added option to replicating test results anonymously to a community
-   CouchDB instance.
- * Allow creation and deletion of config entries.
- * Fixed display issues with doc ids that have escaped characters.
- * Fixed various UI issues.
-
-Build and System Integration:
-
- * Output of `couchdb --help` has been improved.
- * Fixed compatibility with the Erlang R14 series.
- * Fixed warnings on Linux builds.
- * Fixed build error when aclocal needs to be called during the build.
- * Require ICU 4.3.1.
- * Fixed compatibility with Solaris.
-
-Security:
-
- * Added authentication redirect URL to log in clients.
- * Fixed query parameter encoding issue in oauth.js.
- * Made authentication timeout configurable.
- * Temporary views are now admin-only resources.
-
-Storage System:
-
- * Don't require a revpos for attachment stubs.
- * Added checking to ensure when a revpos is sent with an attachment stub,
-   it's correct.
- * Make file deletions async to avoid pauses during compaction and db
-   deletion.
- * Fixed for wrong offset when writing headers and converting them to blocks,
-   only triggered when header is larger than 4k.
- * Preserve _revs_limit and instance_start_time after compaction.
-
-Configuration System:
-
- * Fixed timeout with large .ini files.
-
-JavaScript Clients:
-
- * Added tests for couch.js and jquery.couch.js
- * Added changes handler to jquery.couch.js.
- * Added cache busting to jquery.couch.js if the user agent is msie.
- * Added support for multi-document-fetch (via _all_docs) to jquery.couch.js.
- * Added attachment versioning to jquery.couch.js.
- * Added option to control ensure_full_commit to jquery.couch.js.
- * Added list functionality to jquery.couch.js.
- * Fixed issues where bulkSave() wasn't sending a POST body.
-
-View Server:
-
- * Provide a UUID to update functions (and all other functions) that they can
-   use to create new docs.
- * Upgrade CommonJS modules support to 1.1.1.
- * Fixed erlang filter funs and normalize filter fun API.
- * Fixed hang in view shutdown.
-
-Log System:
-
- * Log HEAD requests as HEAD, not GET.
- * Keep massive JSON blobs out of the error log.
- * Fixed a timeout issue.
-
-Replication System:
-
- * Refactored various internal APIs related to attachment streaming.
- * Fixed hanging replication.
- * Fixed keepalive issue.
-
-URL Rewriter & Vhosts:
-
- * Allow more complex keys in rewriter.
- * Allow global rewrites so system defaults are available in vhosts.
- * Allow isolation of databases with vhosts.
- * Fix issue with passing variables to query parameters.
-
-Test Suite:
-
- * Made the test suite overall more reliable.
-
-Version 0.11.0
---------------
-
-Security:
-
- * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability.
- * Added default cookie-authentication and users database.
- * Added Futon user interface for user signup and login.
- * Added per-database reader access control lists.
- * Added per-database security object for configuration data in validation
-   functions.
- * Added proxy authentication handler
-
-HTTP Interface:
-
- * Provide Content-MD5 header support for attachments.
- * Added URL Rewriter handler.
- * Added virtual host handling.
-
-View Server:
-
- * Added optional 'raw' binary collation for faster view builds where Unicode
-   collation is not important.
- * Improved view index build time by reducing ICU collation callouts.
- * Improved view information objects.
- * Bug fix for partial updates during view builds.
- * Move query server to a design-doc based protocol.
- * Use json2.js for JSON serialization for compatiblity with native JSON.
- * Major refactoring of couchjs to lay the groundwork for disabling cURL
-   support. The new HTTP interaction acts like a synchronous XHR. Example usage
-   of the new system is in the JavaScript CLI test runner.
-
-Replication:
-
- * Added option to implicitly create replication target databases.
- * Avoid leaking file descriptors on automatic replication restarts.
- * Added option to replicate a list of documents by id.
- * Allow continuous replication to be cancelled.
-
-Storage System:
-
- * Adds batching of multiple updating requests, to improve throughput with many
-   writers. Removed the now redundant couch_batch_save module.
- * Adds configurable compression of attachments.
-
-Runtime Statistics:
-
- * Statistics are now calculated for a moving window instead of non-overlapping
-   timeframes.
- * Fixed a problem with statistics timers and system sleep.
- * Moved statistic names to a term file in the priv directory.
-
-Futon:
-
- * Added a button for view compaction.
- * JSON strings are now displayed as-is in the document view, without the escaping of
-   new-lines and quotes. That dramatically improves readability of multi-line
-   strings.
- * Same goes for editing of JSON string values. When a change to a field value is
-   submitted, and the value is not valid JSON it is assumed to be a string. This
-   improves editing of multi-line strings a lot.
- * Hitting tab in textareas no longer moves focus to the next form field, but simply
-   inserts a tab character at the current caret position.
- * Fixed some font declarations.
-
-Build and System Integration:
-
- * Updated and improved source documentation.
- * Fixed distribution preparation for building on Mac OS X.
- * Added support for building a Windows installer as part of 'make dist'.
- * Bug fix for building couch.app's module list.
- * ETap tests are now run during make distcheck. This included a number of
-   updates to the build system to properly support VPATH builds.
- * Gavin McDonald setup a build-bot instance. More info can be found at
-   http://ci.apache.org/buildbot.html
-
-Version 0.10.2
---------------
-
-Security:
-
- * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability
-
-Replicator:
-
- * Avoid leaking file descriptors on automatic replication restarts.
-
-Build and System Integration:
-
- * Fixed distribution preparation for building on Mac OS X.
-
-Version 0.10.1
---------------
-
-Replicator:
-
- * Stability enhancements regarding redirects, timeouts, OAuth.
-
-Query Server:
-
- * Avoid process leaks
- * Allow list and view to span languages
-
-Stats:
-
- * Eliminate new process flood on system wake
-
-Build and System Integration:
-
- * Test suite now works with the distcheck target.
-
-Version 0.10.0
---------------
-
-Storage Format:
-
- * Add move headers with checksums to the end of database files for extra robust
-   storage and faster storage.
-
-View Server:
-
- * Added native Erlang views for high-performance applications.
-
-HTTP Interface:
-
- * Added optional cookie-based authentication handler.
- * Added optional two-legged OAuth authentication handler.
-
-Build and System Integration:
-
- * Changed `couchdb` script configuration options.
- * Added default.d and local.d configuration directories to load sequence.
-
-
-Version 0.9.2
--------------
-
-Replication:
-
- * Fix replication with 0.10 servers initiated by an 0.9 server (COUCHDB-559).
-
-Build and System Integration:
-
- * Remove branch callbacks to allow building couchjs against newer versions of
-   Spidermonkey.
-
-Version 0.9.1
--------------
-
-Build and System Integration:
-
- * PID file directory is now created by the SysV/BSD daemon scripts.
- * Fixed the environment variables shown by the configure script.
- * Fixed the build instructions shown by the configure script.
- * Updated ownership and permission advice in `README` for better security.
-
-Configuration and stats system:
-
- * Corrected missing configuration file error message.
- * Fixed incorrect recording of request time.
-
-Database Core:
-
- * Document validation for underscore prefixed variables.
- * Made attachment storage less sparse.
- * Fixed problems when a database with delayed commits pending is considered
-   idle, and subject to losing changes when shutdown. (COUCHDB-334)
-
-External Handlers:
-
- * Fix POST requests.
-
-Futon:
-
- * Redirect when loading a deleted view URI from the cookie.
-
-HTTP Interface:
-
- * Attachment requests respect the "rev" query-string parameter.
-
-JavaScript View Server:
-
- * Useful JavaScript Error messages.
-
-Replication:
-
- * Added support for Unicode characters transmitted as UTF-16 surrogate pairs.
- * URL-encode attachment names when necessary.
- * Pull specific revisions of an attachment, instead of just the latest one.
- * Work around a rare chunk-merging problem in ibrowse.
- * Work with documents containing Unicode characters outside the Basic
-   Multilingual Plane.
-
-Version 0.9.0
--------------
-
-Futon:
-
- * Added pagination to the database listing page.
- * Implemented attachment uploading from the document page.
- * Added page that shows the current configuration, and allows modification of
-   option values.
- * Added a JSON "source view" for document display.
- * JSON data in view rows is now syntax highlighted.
- * Removed the use of an iframe for better integration with browser history and
-   bookmarking.
- * Full database listing in the sidebar has been replaced by a short list of
-   recent databases.
- * The view editor now allows selection of the view language if there is more
-   than one configured.
- * Added links to go to the raw view or document URI.
- * Added status page to display currently running tasks in CouchDB.
- * JavaScript test suite split into multiple files.
- * Pagination for reduce views.
-
-Design Document Resource Paths:
-
- * Added httpd_design_handlers config section.
- * Moved _view to httpd_design_handlers.
- * Added ability to render documents as non-JSON content-types with _show and
-   _list functions, which are also httpd_design_handlers.
-
-HTTP Interface:
-
- * Added client side UUIDs for idempotent document creation
- * HTTP COPY for documents
- * Streaming of chunked attachment PUTs to disk
- * Remove negative count feature
- * Add include_docs option for view queries
- * Add multi-key view post for views
- * Query parameter validation
- * Use stale=ok to request potentially cached view index
- * External query handler module for full-text or other indexers.
- * Etags for attachments, views, shows and lists
- * Show and list functions for rendering documents and views as developer
-   controlled content-types.
- * Attachment names may use slashes to allow uploading of nested directories
-   (useful for static web hosting).
- * Option for a view to run over design documents.
- * Added newline to JSON responses. Closes bike-shed.
-
-Replication:
-
- * Using ibrowse.
- * Checkpoint replications so failures are less expensive.
- * Automatically retry of failed replications.
- * Stream attachments in pull-replication.
-
-Database Core:
-
- * Faster B-tree implementation.
- * Changed internal JSON term format.
- * Improvements to Erlang VM interactions under heavy load.
- * User context and administrator role.
- * Update validations with design document validation functions.
- * Document purge functionality.
- * Ref-counting for database file handles.
-
-Build and System Integration:
-
- * The `couchdb` script now supports system chainable configuration files.
- * The Mac OS X daemon script now redirects STDOUT and STDERR like SysV/BSD.
- * The build and system integration have been improved for portability.
- * Added COUCHDB_OPTIONS to etc/default/couchdb file.
- * Remove COUCHDB_INI_FILE and COUCHDB_PID_FILE from etc/default/couchdb file.
- * Updated `configure.ac` to manually link `libm` for portability.
- * Updated `configure.ac` to extended default library paths.
- * Removed inets configuration files.
- * Added command line test runner.
- * Created dev target for make.
-
-Configuration and stats system:
-
- * Separate default and local configuration files.
- * HTTP interface for configuration changes.
- * Statistics framework with HTTP query API.
-
-Version 0.8.1-incubating
-------------------------
-
-Database Core:
-
- * Fix for replication problems where the write queues can get backed up if the
-   writes aren't happening fast enough to keep up with the reads. For a large
-   replication, this can exhaust memory and crash, or slow down the machine
-   dramatically. The fix keeps only one document in the write queue at a time.
- * Fix for databases sometimes incorrectly reporting that they contain 0
-   documents after compaction.
- * CouchDB now uses ibrowse instead of inets for its internal HTTP client
-   implementation. This means better replication stability.
-
-HTTP Interface:
-
- * Fix for chunked responses where chunks were always being split into multiple
-   TCP packets, which caused problems with the test suite under Safari, and in
-   some other cases.
- * Fix for an invalid JSON response body being returned for some kinds of
-   views. (COUCHDB-84)
- * Fix for connections not getting closed after rejecting a chunked request.
-   (COUCHDB-55)
- * CouchDB can now be bound to IPv6 addresses.
- * The HTTP `Server` header now contains the versions of CouchDB and Erlang.
-
-JavaScript View Server:
-
- * Sealing of documents has been disabled due to an incompatibility with
-   SpiderMonkey 1.9.
- * Improve error handling for undefined values emitted by map functions.
-   (COUCHDB-83)
-
-Build and System Integration:
-
- * The `couchdb` script no longer uses `awk` for configuration checks as this
-   was causing portability problems.
- * Updated `sudo` example in `README` to use the `-i` option, this fixes
-   problems when invoking from a directory the `couchdb` user cannot access.
-
-Futon:
-
- * The view selector dropdown should now work in Opera and Internet Explorer
-   even when it includes optgroups for design documents. (COUCHDB-81)
-
-Version 0.8.0-incubating
-------------------------
-
-Database Core:
-
- * The view engine has been completely decoupled from the storage engine. Index
-   data is now stored in separate files, and the format of the main database
-   file has changed.
- * Databases can now be compacted to reclaim space used for deleted documents
-   and old document revisions.
- * Support for incremental map/reduce views has been added.
- * To support map/reduce, the structure of design documents has changed. View
-   values are now JSON objects containing at least a `map` member, and
-   optionally a `reduce` member.
- * View servers are now identified by name (for example `javascript`) instead of
-   by media type.
- * Automatically generated document IDs are now based on proper UUID generation
-   using the crypto module.
- * The field `content-type` in the JSON representation of attachments has been
-   renamed to `content_type` (underscore).
-
-HTTP Interface:
-
- * CouchDB now uses MochiWeb instead of inets for the HTTP server
-   implementation. Among other things, this means that the extra configuration
-   files needed for inets (such as `couch_httpd.conf`) are no longer used.
- * The HTTP interface now completely supports the `HEAD` method. (COUCHDB-3)
- * Improved compliance of `Etag` handling with the HTTP specification.
-   (COUCHDB-13)
- * Etags are no longer included in responses to document `GET` requests that
-   include query string parameters causing the JSON response to change without
-   the revision or the URI having changed.
- * The bulk document update API has changed slightly on both the request and the
-   response side. In addition, bulk updates are now atomic.
- * CouchDB now uses `TCP_NODELAY` to fix performance problems with persistent
-   connections on some platforms due to nagling.
- * Including a `?descending=false` query string parameter in requests to views
-   no longer raises an error.
- * Requests to unknown top-level reserved URLs (anything with a leading
-   underscore) now return a `unknown_private_path` error instead of the
-   confusing `illegal_database_name`.
- * The Temporary view handling now expects a JSON request body, where the JSON
-   is an object with at least a `map` member, and optional `reduce` and
-   `language` members.
- * Temporary views no longer determine the view server based on the Content-Type
-   header of the `POST` request, but rather by looking for a `language` member
-   in the JSON body of the request.
- * The status code of responses to `DELETE` requests is now 200 to reflect that
-   that the deletion is performed synchronously.
-
-JavaScript View Server:
-
- * SpiderMonkey is no longer included with CouchDB, but rather treated as a
-   normal external dependency. A simple C program (`_couchjs`) is provided that
-   links against an existing SpiderMonkey installation and uses the interpreter
-   embedding API.
- * View functions using the default JavaScript view server can now do logging
-   using the global `log(message)` function. Log messages are directed into the
-   CouchDB log at `INFO` level. (COUCHDB-59)
- * The global `map(key, value)` function made available to view code has been
-   renamed to `emit(key, value)`.
- * Fixed handling of exceptions raised by view functions.
-
-Build and System Integration:
-
- * CouchDB can automatically respawn following a server crash.
- * Database server no longer refuses to start with a stale PID file.
- * System logrotate configuration provided.
- * Improved handling of ICU shared libraries.
- * The `couchdb` script now automatically enables SMP support in Erlang.
- * The `couchdb` and `couchjs` scripts have been improved for portability.
- * The build and system integration have been improved for portability.
-
-Futon:
-
- * When adding a field to a document, Futon now just adds a field with an
-   autogenerated name instead of prompting for the name with a dialog. The name
-   is automatically put into edit mode so that it can be changed immediately.
- * Fields are now sorted alphabetically by name when a document is displayed.
- * Futon can be used to create and update permanent views.
- * The maximum number of rows to display per page on the database page can now
-   be adjusted.
- * Futon now uses the XMLHTTPRequest API asynchronously to communicate with the
-   CouchDB HTTP server, so that most operations no longer block the browser.
- * View results sorting can now be switched between ascending and descending by
-   clicking on the `Key` column header.
- * Fixed a bug where documents that contained a `@` character could not be
-   viewed. (COUCHDB-12)
- * The database page now provides a `Compact` button to trigger database
-   compaction. (COUCHDB-38)
- * Fixed portential double encoding of document IDs and other URI segments in
-   many instances. (COUCHDB-39)
- * Improved display of attachments.
- * The JavaScript Shell has been removed due to unresolved licensing issues.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ad181c9/NEWS
----------------------------------------------------------------------
diff --git a/NEWS b/NEWS
deleted file mode 100644
index b040194..0000000
--- a/NEWS
+++ /dev/null
@@ -1,515 +0,0 @@
-Apache CouchDB NEWS
-===================
-
-For details about backwards incompatible changes, see:
-
-  http://wiki.apache.org/couchdb/Breaking_changes
-
-Each release section notes when backwards incompatible changes have been made.
-
-# Version 1.4.0
-# -------------
-#
-# This version has not been released yet.
-#
-#  * Support Erlang/OTP R16.
-#  * Bump Mochiweb dependency to v2.4.2.
-#  * Minimum Erlang/OTP version is now R14B.
-
-Version 1.3.1
--------------
-
- * Tolerate missing source and target fields in _replicator docs.
- * Don't log about missing .compact files.
- * Fix bug in WARN level logging from 1.3.0.
- * Improve documentation: better structure, improve language, less duplication.
- * Improvements to test suite.
-
-Version 1.3.0
--------------
-
- * Added view request duration to Futon.
- * Removed the Futon test suite in favour of the CLI test suite.
- * Added documentation. HTML, PDF, and info versions. Accessible via Futon.
- * Fixed unnecessary conflict when deleting and creating a document in the same
-   batch.
- * New and updated passwords are hashed using PBKDF2.
- * Fix various bugs in the URL rewriter when recursion is involved.
- * Added Server-Sent Events protocol to db changes API.
- * Moved the JS test suite to the CLI.
- * Make password hashing synchronous when using the /_config/admins API.
- * Added utc_id UUID algorithm.
- * Encode database name during URL rewriting.
- * Include user name in show/list ETags.
- * Server-wide UUID in some replication ids.
- * E4X support in views is now deprecated and will be removed in a future
-   version.
- * Experimental support for Cross-Origin Resource Sharing (CORS).
-
-Version 1.2.2
--------------
-
- * Fixed rewrite counter bug.
-
-Version 1.2.1
--------------
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with Adobe
-   Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
- * Fix various bugs in the URL rewriter when recursion is involved.
- * Fix couchdb start script.
- * Futon: Disable buttons that aren't available for the logged-in user.
- * Fix potential replication timeouts.
- * Change use of signals to avoid broken view groups.
-
-Version 1.2.0
--------------
-
-This release contains backwards incompatible changes.
-
- * Updated bundled erlang_oauth library to the latest version.
- * cURL is no longer required to build CouchDB as it is only
-   required by the command line JS test runner.
- * Added a native JSON parser.
- * Optional file compression (database and view index files). This feature
-   is enabled by default.
- * Several performance improvements, especially regarding database
-   writes and view indexing.
- * Added a `data_size` property to database and view group
-   information URIs.
- * Added support for automatic compaction. This feature is disabled
-   by default, but it can be enabled via the .ini configuration.
- * A new replicator implementation that offers more performance
-   and configuration options.
- * Added optional field `since_seq` to replication objects/documents.
- * Simpler replication cancelation.
- * The _active_tasks API now exposes more granular fields for each
-   task type.
- * Futon's `Status` screen (active tasks) now displays two new task
-   status fields: `Started on` and `Updated on`.
- * Added built-in changes feed filter `_view`.
- * Fixed old index file descriptor leaks after a view cleanup.
- * Performance improvements for the built-in changes feed filters
-   `_doc_ids` and `_design`.
- * Fixes to the `_changes` feed heartbeat option when combined with
-   a filter. It affected continuous pull replications with a filter.
- * Fix use of OAuth with VHosts and URL rewriting.
- * OAuth secrets can now be stored in the users system database.
- * Documents in the _users database can no longer be read by everyone.
- * Confidential information in the _replication database can no longer
-   be read by everyone.
- * Password hashes are now calculated by CouchDB instead of the client.
- * Allow persistent authentication cookies.
- * The requested_path property of query server request objects now has
-   the path requested by clients before VHosts and rewriting.
- * Fixed incorrect reduce query results when using pagination parameters.
- * Made icu_driver work with Erlang R15B and later.
- * Improvements to the build system and etap test suite.
- * Improvements to log messages for file-related errors.
- * Avoid invalidating view indexes when running out of file descriptors.
- * Log correct stacktrace in all cases.
-
-Version 1.1.2
--------------
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with
-   Adobe Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
- * ETag of attachment changes only when the attachment changes, not
-   the document.
- * Fix pull replication of documents with many revisions.
- * Fix replication with an HTTP source and target
- * Avoid invalidating view indexes when running out of file descriptors.
- * Improvements to log messages for file-related errors.
- * Fix retrieval of headers larger than 4k.
- * Allow OPTIONS HTTP method for list requests.
- * Don't attempt to encode invalid json.
- * Improve SpiderMonkey version detection.
-
-Version 1.1.1
--------------
-
- * Support SpiderMonkey 1.8.5
- * Add configurable maximum to the number of bytes returned by _log.
- * Allow CommonJS modules to be an empty string.
- * Bump minimum Erlang version to R13B02.
- * Do not run deleted validate_doc_update functions.
- * ETags for views include current sequence if include_docs=true.
- * Fix bug where duplicates can appear in _changes feed.
- * Fix bug where update handlers break after conflict resolution.
- * Fix bug with _replicator where include "filter" could crash couch.
- * Fix crashes when compacting large views.
- * Fix file descriptor leak in _log
- * Fix missing revisions in _changes?style=all_docs.
- * Improve handling of compaction at max_dbs_open limit.
- * JSONP responses now send "text/javascript" for Content-Type.
- * Link to ICU 4.2 on Windows.
- * Permit forward slashes in path to update functions.
- * Reap couchjs processes that hit reduce_overflow error.
- * Status code can be specified in update handlers.
- * Support provides() in show functions.
- * _view_cleanup when ddoc has no views now removes all index files.
- * max_replication_retry_count now supports "infinity".
- * Fix replication crash when source database has a document with empty ID.
- * Fix deadlock when assigning couchjs processes to serve requests.
- * Fixes to the document multipart PUT API.
- * Fixes regarding file descriptor leaks for databases with views.
-
-Version 1.1.0
--------------
-
-All NEWS for 1.0.2 also apply to 1.1.0.
-
-This release contains backwards incompatible changes.
-
- * Native SSL support.
- * Added support for HTTP range requests for attachments.
- * Added built-in filters for `_changes`: `_doc_ids` and `_design`.
- * Added configuration option for TCP_NODELAY aka "Nagle".
- * Allow wildcards in vhosts definitions.
- * More granular ETag support for views.
- * More flexible URL rewriter.
- * Added OS Process module to manage daemons outside of CouchDB.
- * Added HTTP Proxy handler for more scalable externals.
- * Added `_replicator` database to manage replications.
- * Multiple micro-optimizations when reading data.
- * Added CommonJS support to map functions.
- * Added `stale=update_after` query option that triggers a view update after
-   returning a `stale=ok` response.
- * More explicit error messages when it's not possible to access a file due
-   to lack of permissions.
- * Added a "change password"-feature to Futon.
-
-Version 1.0.4
--------------
-
- * Fixed CVE-2012-5641: Apache CouchDB Information disclosure via unescaped
-   backslashes in URLs on Windows
- * Fixed CVE-2012-5649: Apache CouchDB JSONP arbitrary code execution with
-   Adobe Flash
- * Fixed CVE-2012-5650: Apache CouchDB DOM based Cross-Site Scripting via Futon
-   UI
- * Fix file descriptor leak in _log.
- * Fix missing revisions in _changes?style=all_docs.
- * Fix validation of attachment names.
- * Avoid invalidating view indexes when running out of file descriptors.
- * Fix a race condition where replications can go stale
-
-Version 1.0.3
--------------
-
- * Fixed compatibility issues with Erlang R14B02.
- * Fix bug that allows invalid UTF-8 after valid escapes.
- * Enabled replication over IPv6.
- * Fixed for crashes in continuous and filtered changes feeds.
- * Changes feeds now honor conflicts=true parameter.
- * Fixed error when restarting replications in OTP R14B02.
- * Fixed error with filter replication with a limit of 1.
- * Upgrade ibrowse to version 2.2.0.
- * Fixed OAuth signature computation in OTP R14B02.
- * Handle passwords with : in them.
- * Made compatible with jQuery 1.5.x.
- * Added support for inclusive_end with reduce views.
- * Etap tests no longer require use of port 5984.
- * Windows builds now require ICU >= 4.4.0 and Erlang >= R14B03.
-
-Version 1.0.2
--------------
-
- * Fixed CVE-2010-3854: Apache CouchDB Cross Site Scripting Issue
- * Make test suite work with Safari and Chrome.
- * Fix leaking file handles after compacting databases and views.
- * Fix databases forgetting their validation function after compaction.
- * Fix occasional timeout errors.
- * Reduce lengthy stack traces.
- * Allow logging of native <xml> types.
- * Updated ibrowse library to 2.1.2 fixing numerous replication issues.
- * Fix authenticated replication of design documents with attachments.
- * Fix multipart GET APIs by always sending attachments in compressed
-   form when the source attachment is compressed on disk. Fixes a possible
-   edge case when an attachment underwent local-local replication.
- * Various fixes to make replicated more resilient for edge-cases.
- * Don't trigger a view update when requesting `_design/doc/_info`.
- * Fix for circular references in CommonJS requires.
- * Fix for frequently edited documents in multi-master deployments being
-   duplicated in _changes and _all_docs.
- * Fix spurious conflict generation during attachment uploads.
- * Fix for various bugs in Futon.
-
-Version 1.0.1
--------------
-
- * Fixed CVE-2010-2234: Apache CouchDB Cross Site Request Forgery Attack
- * Fix data corruption bug COUCHDB-844. Please see
-   http://couchdb.apache.org/notice/1.0.1.html for details.
- * Added support for replication via an HTTP/HTTPS proxy.
- * Fixed various replicator bugs for interop with older CouchDB versions.
- * Show fields saved along with _deleted=true. Allows for auditing of deletes.
- * Enable basic-auth popup when required to access the server, to prevent
-   people from getting locked out.
- * User interface element for querying stale (cached) views.
-
-Version 1.0.0
--------------
-
- * More efficient header commits.
- * Use O_APPEND to save lseeks.
- * Faster implementation of pread_iolist(). Further improves performance on
-   concurrent reads.
- * Added authentication caching
- * Faster default view collation.
- * Added option to include update_seq in view responses.
-
-Version 0.11.2
---------------
-
- * Fixed CVE-2010-2234: Apache CouchDB Cross Site Request Forgery Attack
- * Avoid potential DOS attack by guarding all creation of atoms.
- * Replicator buxfixes for replicating design documents from secured databases.
- * Better error messages on invalid URL requests.
- * User documents can now be deleted by admins or the user.
- * Some Futon and JavaScript library bugfixes.
-
-Version 0.11.1
---------------
-
- * Mask passwords in active tasks and logging.
- * Update mochijson2 to allow output of BigNums not in float form.
- * Added support for X-HTTP-METHOD-OVERRIDE.
- * Disable jsonp by default.
- * Accept gzip encoded standalone attachments.
- * Made max_concurrent_connections configurable.
- * Added continuous replication option to Futon.
- * Added option to replicating test results anonymously to a community
-   CouchDB instance.
- * Allow creation and deletion of config entries in Futon.
- * Fixed various UI issues in Futon.
- * Fixed compatibility with the Erlang R14 series.
- * Fixed warnings on Linux builds.
- * Fixed build error when aclocal needs to be called during the build.
- * Require ICU 4.3.1.
- * Fixed compatibility with Solaris.
- * Added authentication redirect URL to log in clients.
- * Added authentication caching, to avoid repeated opening and closing of the
-   users database for each request requiring authentication.
- * Made authentication timeout configurable.
- * Temporary views are now admin-only resources.
- * Don't require a revpos for attachment stubs.
- * Make file deletions async to avoid pauses during compaction and db
-   deletion.
- * Fixed for wrong offset when writing headers and converting them to blocks,
-   only triggered when header is larger than 4k.
- * Preserve _revs_limit and instance_start_time after compaction.
- * Fixed timeout with large .ini files.
- * Added tests for couch.js and jquery.couch.js
- * Added various API features to jquery.couch.js
- * Faster default view collation.
- * Upgrade CommonJS modules support to 1.1.1.
- * Added option to include update_seq in view responses.
- * Fixed erlang filter funs and normalize filter fun API.
- * Fixed hang in view shutdown.
- * Refactored various internal APIs related to attachment streaming.
- * Fixed hanging replication.
- * Fixed keepalive issue.
- * Allow global rewrites so system defaults are available in vhosts.
- * Allow isolation of databases with vhosts.
- * Made the test suite overall more reliable.
-
-Version 0.11.0
---------------
-
-This version is a feature-freeze release candidate for Apache CouchDB 1.0.
-
- * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability.
- * Added support for building a Windows installer as part of 'make dist'.
- * Added optional 'raw' binary collation for faster view builds where Unicode
-   collation is not important.
- * Improved view index build time by reducing ICU collation callouts.
- * Added option to implicitly create replication target databases.
- * Improved view information objects.
- * Bug fix for partial updates during view builds.
- * Bug fix for building couch.app's module list.
- * Fixed a problem with statistics timers and system sleep.
- * Improved the statistics calculations to use an online moving window
-   algorithm.
- * Adds batching of multiple updating requests, to improve throughput with many
-   writers.
- * Removed the now redundant couch_batch_save module.
- * Bug fix for premature termination of chunked responses.
- * Improved speed and concurrency of config lookups.
- * Fixed an edge case for HTTP redirects during replication.
- * Fixed HTTP timeout handling for replication.
- * Fixed query parameter handling in OAuth'd replication.
- * Fixed a bug preventing mixing languages with lists and views.
- * Avoid OS process leaks in lists.
- * Avoid leaking file descriptors on automatic replication restarts.
- * Various improvements to the Futon UI.
- * Provide Content-MD5 header support for attachments.
- * Adds configurable compression of attachments.
- * Added default cookie-authentication and users db.
- * Added per-db reader access control lists.
- * Added per-db security object for configuration data in validation functions.
- * Added URL Rewriter handler.
- * Added proxy authentication handler.
- * Added ability to replicate documents by id.
- * Added virtual host handling.
- * Uses json2.js for JSON serialization compatiblity with native JSON.
- * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability.
-
-Version 0.10.2
---------------
-
- * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability.
-
-Version 0.10.1
---------------
-
- * Fixed test suite to work with build system.
- * Fixed a problem with statistics timers and system sleep.
- * Fixed an edge case for HTTP redirects during replication.
- * Fixed HTTP timeout handling for replication.
- * Fixed query parameter handling in OAuth'd replication.
- * Fixed a bug preventing mixing languages with lists and views.
- * Avoid OS process leaks in lists.
-
-Version 0.10.0
---------------
-
-This release contains backwards incompatible changes.
-
- * General performance improvements.
- * View index generation speedups.
- * Even more robust storage format.
- * Native Erlang Views for high-performance applications.
- * More robust push and pull replication.
- * Two-legged OAuth support for applications and replication (three-legged in
-   preparation).
- * Cookie authentication.
- * API detail improvements.
- * Better RFC 2616 (HTTP 1.1) compliance.
- * Added modular configuration file directories.
- * Miscellaneous improvements to build, system integration, and portability.
-
-Version 0.9.2
--------------
-
- * Remove branch callbacks to allow building couchjs against newer versions of
-   Spidermonkey.
- * Fix replication with 0.10 servers initiated by an 0.9 server.
-
-Version 0.9.1
--------------
-
- * Various bug fixes for the build system, configuration, statistics reporting,
-   database core, external handlers, Futon interface, HTTP interface,
-   JavaScript View Server and replicator.
-
-Version 0.9.0
--------------
-
-This release contains backwards incompatible changes.
-
- * Modular configuration.
- * Performance enhancements for document and view access.
- * More resilient replication process.
- * Replication streams binary attachments.
- * Administrator role and basic authentication.
- * Document validation functions in design documents.
- * Show and list functions for rendering documents and views as developer
-   controlled content-types.
- * External process server module.
- * Attachment uploading from Futon.
- * Etags for views, lists, shows, document and attachment requests.
- * Miscellaneous improvements to build, system integration, and portability.
-
-Version 0.8.1-incubating
-------------------------
-
- * Various bug fixes for replication, compaction, the HTTP interface and the
-   JavaScript View Server.
-
-Version 0.8.0-incubating
-------------------------
-
-This release contains backwards incompatible changes.
-
- * Changed core licensing to the Apache Software License 2.0.
- * Refactoring of the core view and storage engines.
- * Added support for incremental map/reduce views.
- * Changed database file format.
- * Many improvements to Futon, the web administration interface.
- * Miscellaneous improvements to build, system integration, and portability.
- * Swapped out Erlang's inets HTTP server for the Mochiweb HTTP server.
- * SpiderMonkey is no longer included with CouchDB, but rather treated as an
-   external dependency.
- * Added bits of awesome.
-
-Version 0.7.2
--------------
-
- * Small changes to build process and `couchdb` command.
- * Database server official port is now 5984 TCP/UDP instead of 8888.
-
-Version 0.7.1
--------------
-
- * Small compatibility issue with Firefox 3 fixed.
-
-Version 0.7.0
--------------
-
- * Infrastructure rewritten to use the GNU build system for portability.
- * The built-in database browsing tool has been rewritten to provide a much
-   nicer interface for interacting directly with CouchDB from your web browser.
- * XML and Fabric have been replaced with JSON and JavaScript for data
-   transport and View definitions.
-
-Version 0.6.0
--------------
-
- * A replication facility is now available.
- * CouchPeek can now create, delete and view documents.
- * Building from source is easier and less error prone.
-
-Version 0.5.0
--------------
-
- * A built-in CouchPeek utility.
- * A full install kit buildable from a single command.
- * A new GNU/Linux version is available. An OS X version is coming soon.
-
-Version 0.4.0
--------------
-
- * Non-existent variables are now nil lists.
- * Couch error codes and messages are no longer sent in the HTTP fields,
-   instead they are exclusively returned in the XML body. This is to avoid HTTP
-   header parsing problems with oddly formed error messages.
- * Returned error messages are now logged at the server at the `info` level to
-   make general debugging easier.
- * Fixed a problem where big table builds caused timeout errors.
- * Lots of changes in the low level machinery. Most formulas will continue to
-   function the same.
- * Added full compiler support for extended characters in formula source.
- * Support for Perl/Ruby like regular expressions.
- * Added `total_rows` and `result_start` attributes to tables.
-
-Version 0.3.0
--------------
-
- * CouchDB now fully supports Unicode and locale specific collation via the ICU
-   library, both in the Fabric engine and computed tables.
- * The `in` operator has been added to Fabric.
- * The `startdoc` query string variable specifies the starting document to use
-   if there are multiple rows with identical startkeys.
- * The `skip` query string variable specifies the number of rows to skip before
-   returning results. The `skip` value must be a positive integer. If used with
-   a `count` variable the skipped rows aren't counted as output.
- * Various changes to the output XML format.


[03/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Remove 1.2.3 sections


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

Branch: refs/heads/1684-feature-db-updates
Commit: fed33028605a7803c9d94a9f60c6e875297cd890
Parents: 06b9aa5
Author: Noah Slater <ns...@apache.org>
Authored: Tue May 28 21:04:46 2013 +0100
Committer: Noah Slater <ns...@apache.org>
Committed: Tue May 28 21:04:46 2013 +0100

----------------------------------------------------------------------
 CHANGES | 5 -----
 NEWS    | 5 -----
 2 files changed, 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/fed33028/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index fd8187b..269ace0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -116,11 +116,6 @@ Build System:
  * Fixed issue in couchdb script where stopped status returns before process
    exits.
 
-# Version 1.2.3
-# -------------
-#
-# This version has not been released yet.
-
 Version 1.2.2
 -------------
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fed33028/NEWS
----------------------------------------------------------------------
diff --git a/NEWS b/NEWS
index ee45eff..b040194 100644
--- a/NEWS
+++ b/NEWS
@@ -46,11 +46,6 @@ Version 1.3.0
    version.
  * Experimental support for Cross-Origin Resource Sharing (CORS).
 
-# Version 1.2.3
-# -------------
-#
-# This version has not been released yet.
-
 Version 1.2.2
 -------------
 


[20/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
[TESTS] [HOTFIX] correct error in auth cache test


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

Branch: refs/heads/1684-feature-db-updates
Commit: a27adbf2723eae4dc0f16c8d2fd64ce1ddd28dde
Parents: e6d95ae
Author: Jan Lehnardt <ja...@apache.org>
Authored: Sat Jun 15 13:26:04 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Sat Jun 15 13:26:10 2013 +0200

----------------------------------------------------------------------
 test/etap/075-auth-cache.t | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/a27adbf2/test/etap/075-auth-cache.t
----------------------------------------------------------------------
diff --git a/test/etap/075-auth-cache.t b/test/etap/075-auth-cache.t
index 7a8b824..623884b 100755
--- a/test/etap/075-auth-cache.t
+++ b/test/etap/075-auth-cache.t
@@ -272,5 +272,5 @@ open_auth_db(DbName) ->
 
 
 delete_db(Name) ->
-    ok = couch_server:delete(
+    couch_server:delete(
         Name, [{user_ctx, #user_ctx{roles = [<<"_admin">>]}}]).


[22/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Restore rev handling for _bulk_docs with all_or_nothing

Commit 5b1430c120904181313848444dbfcdb60e42568b added this hunk;

-        {aborted, lists:map(
-            fun({{Id,{Pos, [RevId|_]}}, Error}) ->
-                {{Id, {Pos, RevId}}, Error};
-            ({{Id,{0, []}}, Error}) ->
-                {{Id, {0, <<>>}}, Error}
-            end, PreCommitFailures)};
+        {aborted,
+         lists:foldl(fun({#doc{id=Id,revs={Pos, RevIds}}, Ref},Acc) ->
+                         case lists:keyfind(Ref,1,PreCommitFailures) of
+                         {Ref, Error} ->
+                             [{{Id,{Pos,RevIds}}, Error} | Acc];
+                         false ->
+                             Acc
+                         end
+                     end,[],Docs3)};
+

This causes the full list of revisions to be passed to revid_to_str/1;

revid_to_str(RevId) when size(RevId) =:= 16 ->
    ?l2b(couch_util:to_hex(RevId));
revid_to_str(RevId) ->
    RevId.

This falls through to the second case, which in turn leads to invalid
JSON output when we convert the presumed iolist.

This patch restores the code that takes only the head of the revisions
list when present, and an artificial "0-" when it is not (in the case
that the validation fails for a new document rather than an update).

BugzID: 1772


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

Branch: refs/heads/1684-feature-db-updates
Commit: dfd39d570f5f841ae5e003fc8b4a2073c267e89a
Parents: 0bb6787
Author: Robert Newson <rn...@apache.org>
Authored: Mon Jun 17 11:05:01 2013 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Mon Jun 17 15:29:16 2013 +0100

----------------------------------------------------------------------
 src/couchdb/couch_db.erl | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/dfd39d57/src/couchdb/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index 96f6719..11ea0fd 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -756,10 +756,15 @@ update_docs(Db, Docs, Options, interactive_edit) ->
 
     if (AllOrNothing) and (PreCommitFailures /= []) ->
         {aborted,
-         lists:foldl(fun({#doc{id=Id,revs={Pos, RevIds}}, Ref},Acc) ->
+         lists:foldl(fun({#doc{id=Id,revs=Revs}, Ref},Acc) ->
                          case lists:keyfind(Ref,1,PreCommitFailures) of
                          {Ref, Error} ->
-                             [{{Id,{Pos,RevIds}}, Error} | Acc];
+                             case Revs of
+                             {Pos, [RevId|_]} ->
+                                 [{{Id,{Pos, RevId}}, Error} | Acc];
+                             {0, []} ->
+                                 [{{Id,{0, <<>>}}, Error} | Acc]
+                             end;
                          false ->
                              Acc
                          end


[42/50] [abbrv] Improved development server

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/js/libs/require.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/require.js b/src/fauxton/assets/js/libs/require.js
index 0c6f152..2109a25 100644
--- a/src/fauxton/assets/js/libs/require.js
+++ b/src/fauxton/assets/js/libs/require.js
@@ -1,25 +1,28 @@
 /** vim: et:ts=4:sw=4:sts=4
- * @license RequireJS 2.0.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ * @license RequireJS 2.1.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
  * Available via the MIT or new BSD license.
  * see: http://github.com/jrburke/requirejs for details
  */
-/*jslint regexp: true, nomen: true */
-/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
+//Not using strict: uneven strict support in browsers, #392, and causes
+//problems with requirejs.exec()/transpiler plugins that may not be strict.
+/*jslint regexp: true, nomen: true, sloppy: true */
+/*global window, navigator, document, importScripts, setTimeout, opera */
 
 var requirejs, require, define;
 (function (global) {
-    'use strict';
-
-    var version = '2.0.2',
+    var req, s, head, baseElement, dataMain, src,
+        interactiveScript, currentlyAddingScript, mainScript, subPath,
+        version = '2.1.6',
         commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
-        cjsRequireRegExp = /require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
+        cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
         jsSuffixRegExp = /\.js$/,
         currDirRegExp = /^\.\//,
-        ostring = Object.prototype.toString,
+        op = Object.prototype,
+        ostring = op.toString,
+        hasOwn = op.hasOwnProperty,
         ap = Array.prototype,
-        aps = ap.slice,
         apsp = ap.splice,
-        isBrowser = !!(typeof window !== 'undefined' && navigator && document),
+        isBrowser = !!(typeof window !== 'undefined' && navigator && window.document),
         isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
         //PS3 indicates loaded and complete, but need to wait for complete
         //specifically. Sequence is 'loading', 'loaded', execution,
@@ -33,9 +36,7 @@ var requirejs, require, define;
         contexts = {},
         cfg = {},
         globalDefQueue = [],
-        useInteractive = false,
-        req, s, head, baseElement, dataMain, src,
-        interactiveScript, currentlyAddingScript, mainScript, subPath;
+        useInteractive = false;
 
     function isFunction(it) {
         return ostring.call(it) === '[object Function]';
@@ -76,7 +77,11 @@ var requirejs, require, define;
     }
 
     function hasProp(obj, prop) {
-        return obj.hasOwnProperty(prop);
+        return hasOwn.call(obj, prop);
+    }
+
+    function getOwn(obj, prop) {
+        return hasProp(obj, prop) && obj[prop];
     }
 
     /**
@@ -87,7 +92,7 @@ var requirejs, require, define;
     function eachProp(obj, func) {
         var prop;
         for (prop in obj) {
-            if (obj.hasOwnProperty(prop)) {
+            if (hasProp(obj, prop)) {
                 if (func(obj[prop], prop)) {
                     break;
                 }
@@ -98,9 +103,6 @@ var requirejs, require, define;
     /**
      * Simple function to mix in properties from source into target,
      * but only if target does not already have a property of the same name.
-     * This is not robust in IE for transferring methods that match
-     * Object.prototype names, but the uses of mixin here seem unlikely to
-     * trigger a problem related to that.
      */
     function mixin(target, source, force, deepStringMixin) {
         if (source) {
@@ -132,6 +134,10 @@ var requirejs, require, define;
         return document.getElementsByTagName('script');
     }
 
+    function defaultOnError(err) {
+        throw err;
+    }
+
     //Allow getting a global that expressed in
     //dot notation, like 'a.b.c'.
     function getGlobal(value) {
@@ -145,41 +151,6 @@ var requirejs, require, define;
         return g;
     }
 
-    function makeContextModuleFunc(func, relMap, enableBuildCallback) {
-        return function () {
-            //A version of a require function that passes a moduleName
-            //value for items that may need to
-            //look up paths relative to the moduleName
-            var args = aps.call(arguments, 0), lastArg;
-            if (enableBuildCallback &&
-                isFunction((lastArg = args[args.length - 1]))) {
-                lastArg.__requireJsBuild = true;
-            }
-            args.push(relMap);
-            return func.apply(null, args);
-        };
-    }
-
-    function addRequireMethods(req, context, relMap) {
-        each([
-            ['toUrl'],
-            ['undef'],
-            ['defined', 'requireDefined'],
-            ['specified', 'requireSpecified']
-        ], function (item) {
-            var prop = item[1] || item[0];
-            req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) :
-                //If no context, then use default context. Reference from
-                //contexts instead of early binding to default context, so
-                //that during builds, the latest instance of the default
-                //context with its config gets used.
-                function () {
-                    var ctx = contexts[defContextName];
-                    return ctx[prop].apply(ctx, arguments);
-                };
-        });
-    }
-
     /**
      * Constructs an error with a pointer to an URL with more information.
      * @param {String} id the error ID that maps to an ID on a web page.
@@ -221,27 +192,30 @@ var requirejs, require, define;
     }
 
     function newContext(contextName) {
-        var config = {
+        var inCheckLoaded, Module, context, handlers,
+            checkLoadedTimeoutId,
+            config = {
+                //Defaults. Do not set a default for map
+                //config to speed up normalize(), which
+                //will run faster if there is no default.
                 waitSeconds: 7,
                 baseUrl: './',
                 paths: {},
                 pkgs: {},
-                shim: {}
+                shim: {},
+                config: {}
             },
             registry = {},
+            //registry of just enabled modules, to speed
+            //cycle breaking code when lots of modules
+            //are registered, but not activated.
+            enabledRegistry = {},
             undefEvents = {},
             defQueue = [],
             defined = {},
             urlFetched = {},
             requireCounter = 1,
-            unnormalizedCounter = 1,
-            //Used to track the order in which modules
-            //should be executed, by the order they
-            //load. Important for consistent cycle resolution
-            //behavior.
-            waitAry = [],
-            inCheckLoaded, Module, context, handlers,
-            checkLoadedTimeoutId;
+            unnormalizedCounter = 1;
 
         /**
          * Trims the . and .. from an array of path segments.
@@ -254,7 +228,7 @@ var requirejs, require, define;
          */
         function trimDots(ary) {
             var i, part;
-            for (i = 0; ary[i]; i+= 1) {
+            for (i = 0; ary[i]; i += 1) {
                 part = ary[i];
                 if (part === '.') {
                     ary.splice(i, 1);
@@ -287,11 +261,12 @@ var requirejs, require, define;
          * @returns {String} normalized name
          */
         function normalize(name, baseName, applyMap) {
-            var baseParts = baseName && baseName.split('/'),
+            var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
+                foundMap, foundI, foundStarMap, starI,
+                baseParts = baseName && baseName.split('/'),
+                normalizedBaseParts = baseParts,
                 map = config.map,
-                starMap = map && map['*'],
-                pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
-                foundMap;
+                starMap = map && map['*'];
 
             //Adjust any relative paths.
             if (name && name.charAt(0) === '.') {
@@ -299,25 +274,25 @@ var requirejs, require, define;
                 //otherwise, assume it is a top-level require that will
                 //be relative to baseUrl in the end.
                 if (baseName) {
-                    if (config.pkgs[baseName]) {
+                    if (getOwn(config.pkgs, baseName)) {
                         //If the baseName is a package name, then just treat it as one
                         //name to concat the name with.
-                        baseParts = [baseName];
+                        normalizedBaseParts = baseParts = [baseName];
                     } else {
                         //Convert baseName to array, and lop off the last part,
                         //so that . matches that 'directory' and not name of the baseName's
                         //module. For instance, baseName of 'one/two/three', maps to
                         //'one/two/three.js', but we want the directory, 'one/two' for
                         //this normalization.
-                        baseParts = baseParts.slice(0, baseParts.length - 1);
+                        normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
                     }
 
-                    name = baseParts.concat(name.split('/'));
+                    name = normalizedBaseParts.concat(name.split('/'));
                     trimDots(name);
 
                     //Some use of packages may use a . path to reference the
                     //'main' module name, so normalize for that.
-                    pkgConfig = config.pkgs[(pkgName = name[0])];
+                    pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));
                     name = name.join('/');
                     if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
                         name = pkgName;
@@ -330,7 +305,7 @@ var requirejs, require, define;
             }
 
             //Apply map config if available.
-            if (applyMap && (baseParts || starMap) && map) {
+            if (applyMap && map && (baseParts || starMap)) {
                 nameParts = name.split('/');
 
                 for (i = nameParts.length; i > 0; i -= 1) {
@@ -340,30 +315,43 @@ var requirejs, require, define;
                         //Find the longest baseName segment match in the config.
                         //So, do joins on the biggest to smallest lengths of baseParts.
                         for (j = baseParts.length; j > 0; j -= 1) {
-                            mapValue = map[baseParts.slice(0, j).join('/')];
+                            mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
 
-                            //baseName segment has  config, find if it has one for
+                            //baseName segment has config, find if it has one for
                             //this name.
                             if (mapValue) {
-                                mapValue = mapValue[nameSegment];
+                                mapValue = getOwn(mapValue, nameSegment);
                                 if (mapValue) {
                                     //Match, update name to the new value.
                                     foundMap = mapValue;
+                                    foundI = i;
                                     break;
                                 }
                             }
                         }
                     }
 
-                    if (!foundMap && starMap && starMap[nameSegment]) {
-                        foundMap = starMap[nameSegment];
-                    }
-
                     if (foundMap) {
-                        nameParts.splice(0, i, foundMap);
-                        name = nameParts.join('/');
                         break;
                     }
+
+                    //Check for a star map match, but just hold on to it,
+                    //if there is a shorter segment match later in a matching
+                    //config, then favor over this star map.
+                    if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
+                        foundStarMap = getOwn(starMap, nameSegment);
+                        starI = i;
+                    }
+                }
+
+                if (!foundMap && foundStarMap) {
+                    foundMap = foundStarMap;
+                    foundI = starI;
+                }
+
+                if (foundMap) {
+                    nameParts.splice(0, foundI, foundMap);
+                    name = nameParts.join('/');
                 }
             }
 
@@ -374,7 +362,7 @@ var requirejs, require, define;
             if (isBrowser) {
                 each(scripts(), function (scriptNode) {
                     if (scriptNode.getAttribute('data-requiremodule') === name &&
-                        scriptNode.getAttribute('data-requirecontext') === context.contextName) {
+                            scriptNode.getAttribute('data-requirecontext') === context.contextName) {
                         scriptNode.parentNode.removeChild(scriptNode);
                         return true;
                     }
@@ -383,18 +371,31 @@ var requirejs, require, define;
         }
 
         function hasPathFallback(id) {
-            var pathConfig = config.paths[id];
+            var pathConfig = getOwn(config.paths, id);
             if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
                 removeScript(id);
                 //Pop off the first array value, since it failed, and
                 //retry
                 pathConfig.shift();
-                context.undef(id);
+                context.require.undef(id);
                 context.require([id]);
                 return true;
             }
         }
 
+        //Turns a plugin!resource to [plugin, resource]
+        //with the plugin being undefined if the name
+        //did not have a plugin prefix.
+        function splitPrefix(name) {
+            var prefix,
+                index = name ? name.indexOf('!') : -1;
+            if (index > -1) {
+                prefix = name.substring(0, index);
+                name = name.substring(index + 1, name.length);
+            }
+            return [prefix, name];
+        }
+
         /**
          * Creates a module mapping that includes plugin prefix, module
          * name, and path. If parentModuleMap is provided it will
@@ -411,13 +412,12 @@ var requirejs, require, define;
          * @returns {Object}
          */
         function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
-            var index = name ? name.indexOf('!') : -1,
+            var url, pluginModule, suffix, nameParts,
                 prefix = null,
                 parentName = parentModuleMap ? parentModuleMap.name : null,
                 originalName = name,
                 isDefine = true,
-                normalizedName = '',
-                url, pluginModule, suffix;
+                normalizedName = '';
 
             //If no name, then it means it is a require call, generate an
             //internal name.
@@ -426,14 +426,13 @@ var requirejs, require, define;
                 name = '_@r' + (requireCounter += 1);
             }
 
-            if (index !== -1) {
-                prefix = name.substring(0, index);
-                name = name.substring(index + 1, name.length);
-            }
+            nameParts = splitPrefix(name);
+            prefix = nameParts[0];
+            name = nameParts[1];
 
             if (prefix) {
                 prefix = normalize(prefix, parentName, applyMap);
-                pluginModule = defined[prefix];
+                pluginModule = getOwn(defined, prefix);
             }
 
             //Account for relative paths if there is a base name.
@@ -451,16 +450,15 @@ var requirejs, require, define;
                     //A regular module.
                     normalizedName = normalize(name, parentName, applyMap);
 
-                    //Calculate url for the module, if it has a name.
-                    //Use name here since nameToUrl also calls normalize,
-                    //and for relative names that are outside the baseUrl
-                    //this causes havoc. Was thinking of just removing
-                    //parentModuleMap to avoid extra normalization, but
-                    //normalize() still does a dot removal because of
-                    //issue #142, so just pass in name here and redo
-                    //the normalization. Paths outside baseUrl are just
-                    //messy to support.
-                    url = context.nameToUrl(name, null, parentModuleMap);
+                    //Normalized name may be a plugin ID due to map config
+                    //application in normalize. The map config values must
+                    //already be normalized, so do not need to redo that part.
+                    nameParts = splitPrefix(normalizedName);
+                    prefix = nameParts[0];
+                    normalizedName = nameParts[1];
+                    isNormalized = true;
+
+                    url = context.nameToUrl(normalizedName);
                 }
             }
 
@@ -480,14 +478,14 @@ var requirejs, require, define;
                 originalName: originalName,
                 isDefine: isDefine,
                 id: (prefix ?
-                    prefix + '!' + normalizedName :
-                    normalizedName) + suffix
+                        prefix + '!' + normalizedName :
+                        normalizedName) + suffix
             };
         }
 
         function getModule(depMap) {
             var id = depMap.id,
-                mod = registry[id];
+                mod = getOwn(registry, id);
 
             if (!mod) {
                 mod = registry[id] = new context.Module(depMap);
@@ -498,15 +496,20 @@ var requirejs, require, define;
 
         function on(depMap, name, fn) {
             var id = depMap.id,
-                mod = registry[id];
+                mod = getOwn(registry, id);
 
             if (hasProp(defined, id) &&
-                (!mod || mod.defineEmitComplete)) {
+                    (!mod || mod.defineEmitComplete)) {
                 if (name === 'defined') {
                     fn(defined[id]);
                 }
             } else {
-                getModule(depMap).on(name, fn);
+                mod = getModule(depMap);
+                if (mod.error && name === 'error') {
+                    fn(mod.error);
+                } else {
+                    mod.on(name, fn);
+                }
             }
         }
 
@@ -518,7 +521,7 @@ var requirejs, require, define;
                 errback(err);
             } else {
                 each(ids, function (id) {
-                    var mod = registry[id];
+                    var mod = getOwn(registry, id);
                     if (mod) {
                         //Set error on module, so it skips timeout checks.
                         mod.error = err;
@@ -551,170 +554,89 @@ var requirejs, require, define;
             }
         }
 
-        /**
-         * Helper function that creates a require function object to give to
-         * modules that ask for it as a dependency. It needs to be specific
-         * per module because of the implication of path mappings that may
-         * need to be relative to the module name.
-         */
-        function makeRequire(mod, enableBuildCallback, altRequire) {
-            var relMap = mod && mod.map,
-                modRequire = makeContextModuleFunc(altRequire || context.require,
-                                                   relMap,
-                                                   enableBuildCallback);
-
-            addRequireMethods(modRequire, context, relMap);
-            modRequire.isBrowser = isBrowser;
-
-            return modRequire;
-        }
-
         handlers = {
             'require': function (mod) {
-                return makeRequire(mod);
+                if (mod.require) {
+                    return mod.require;
+                } else {
+                    return (mod.require = context.makeRequire(mod.map));
+                }
             },
             'exports': function (mod) {
                 mod.usingExports = true;
                 if (mod.map.isDefine) {
-                    return (mod.exports = defined[mod.map.id] = {});
+                    if (mod.exports) {
+                        return mod.exports;
+                    } else {
+                        return (mod.exports = defined[mod.map.id] = {});
+                    }
                 }
             },
             'module': function (mod) {
-                return (mod.module = {
-                    id: mod.map.id,
-                    uri: mod.map.url,
-                    config: function () {
-                        return (config.config && config.config[mod.map.id]) || {};
-                    },
-                    exports: defined[mod.map.id]
-                });
+                if (mod.module) {
+                    return mod.module;
+                } else {
+                    return (mod.module = {
+                        id: mod.map.id,
+                        uri: mod.map.url,
+                        config: function () {
+                            var c,
+                                pkg = getOwn(config.pkgs, mod.map.id);
+                            // For packages, only support config targeted
+                            // at the main module.
+                            c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) :
+                                      getOwn(config.config, mod.map.id);
+                            return  c || {};
+                        },
+                        exports: defined[mod.map.id]
+                    });
+                }
             }
         };
 
-        function removeWaiting(id) {
+        function cleanRegistry(id) {
             //Clean up machinery used for waiting modules.
             delete registry[id];
-
-            each(waitAry, function (mod, i) {
-                if (mod.map.id === id) {
-                    waitAry.splice(i, 1);
-                    if (!mod.defined) {
-                        context.waitCount -= 1;
-                    }
-                    return true;
-                }
-            });
-        }
-
-        function findCycle(mod, traced) {
-            var id = mod.map.id,
-                depArray = mod.depMaps,
-                foundModule;
-
-            //Do not bother with unitialized modules or not yet enabled
-            //modules.
-            if (!mod.inited) {
-                return;
-            }
-
-            //Found the cycle.
-            if (traced[id]) {
-                return mod;
-            }
-
-            traced[id] = true;
-
-            //Trace through the dependencies.
-            each(depArray, function (depMap) {
-                var depId = depMap.id,
-                    depMod = registry[depId];
-
-                if (!depMod) {
-                    return;
-                }
-
-                if (!depMod.inited || !depMod.enabled) {
-                    //Dependency is not inited, so this cannot
-                    //be used to determine a cycle.
-                    foundModule = null;
-                    delete traced[id];
-                    return true;
-                }
-
-                //mixin traced to a new object for each dependency, so that
-                //sibling dependencies in this object to not generate a
-                //false positive match on a cycle. Ideally an Object.create
-                //type of prototype delegation would be used here, but
-                //optimizing for file size vs. execution speed since hopefully
-                //the trees are small for circular dependency scans relative
-                //to the full app perf.
-                return (foundModule = findCycle(depMod, mixin({}, traced)));
-            });
-
-            return foundModule;
+            delete enabledRegistry[id];
         }
 
-        function forceExec(mod, traced, uninited) {
-            var id = mod.map.id,
-                depArray = mod.depMaps;
-
-            if (!mod.inited || !mod.map.isDefine) {
-                return;
-            }
-
-            if (traced[id]) {
-                return defined[id];
-            }
-
-            traced[id] = mod;
-
-            each(depArray, function(depMap) {
-                var depId = depMap.id,
-                    depMod = registry[depId],
-                    value;
-
-                if (handlers[depId]) {
-                    return;
-                }
-
-                if (depMod) {
-                    if (!depMod.inited || !depMod.enabled) {
-                        //Dependency is not inited,
-                        //so this module cannot be
-                        //given a forced value yet.
-                        uninited[id] = true;
-                        return;
-                    }
-
-                    //Get the value for the current dependency
-                    value = forceExec(depMod, traced, uninited);
+        function breakCycle(mod, traced, processed) {
+            var id = mod.map.id;
 
-                    //Even with forcing it may not be done,
-                    //in particular if the module is waiting
-                    //on a plugin resource.
-                    if (!uninited[depId]) {
-                        mod.defineDepById(depId, value);
+            if (mod.error) {
+                mod.emit('error', mod.error);
+            } else {
+                traced[id] = true;
+                each(mod.depMaps, function (depMap, i) {
+                    var depId = depMap.id,
+                        dep = getOwn(registry, depId);
+
+                    //Only force things that have not completed
+                    //being defined, so still in the registry,
+                    //and only if it has not been matched up
+                    //in the module already.
+                    if (dep && !mod.depMatched[i] && !processed[depId]) {
+                        if (getOwn(traced, depId)) {
+                            mod.defineDep(i, defined[depId]);
+                            mod.check(); //pass false?
+                        } else {
+                            breakCycle(dep, traced, processed);
+                        }
                     }
-                }
-            });
-
-            mod.check(true);
-
-            return defined[id];
-        }
-
-        function modCheck(mod) {
-            mod.check();
+                });
+                processed[id] = true;
+            }
         }
 
         function checkLoaded() {
-            var waitInterval = config.waitSeconds * 1000,
+            var map, modId, err, usingPathFallback,
+                waitInterval = config.waitSeconds * 1000,
                 //It is possible to disable the wait interval by using waitSeconds of 0.
                 expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
                 noLoads = [],
+                reqCalls = [],
                 stillLoading = false,
-                needCycleCheck = true,
-                map, modId, err, usingPathFallback;
+                needCycleCheck = true;
 
             //Do not bother if this call was a result of a cycle break.
             if (inCheckLoaded) {
@@ -724,7 +646,7 @@ var requirejs, require, define;
             inCheckLoaded = true;
 
             //Figure out the state of all the modules.
-            eachProp(registry, function (mod) {
+            eachProp(enabledRegistry, function (mod) {
                 map = mod.map;
                 modId = map.id;
 
@@ -733,6 +655,10 @@ var requirejs, require, define;
                     return;
                 }
 
+                if (!map.isDefine) {
+                    reqCalls.push(mod);
+                }
+
                 if (!mod.error) {
                     //If the module should be executed, and it has not
                     //been inited and time is up, remember it.
@@ -767,31 +693,9 @@ var requirejs, require, define;
 
             //Not expired, check for a cycle.
             if (needCycleCheck) {
-
-                each(waitAry, function (mod) {
-                    if (mod.defined) {
-                        return;
-                    }
-
-                    var cycleMod = findCycle(mod, {}),
-                        traced = {};
-
-                    if (cycleMod) {
-                        forceExec(cycleMod, traced, {});
-
-                        //traced modules may have been
-                        //removed from the registry, but
-                        //their listeners still need to
-                        //be called.
-                        eachProp(traced, modCheck);
-                    }
+                each(reqCalls, function (mod) {
+                    breakCycle(mod, {}, {});
                 });
-
-                //Now that dependencies have
-                //been satisfied, trigger the
-                //completion check that then
-                //notifies listeners.
-                eachProp(registry, modCheck);
             }
 
             //If still waiting on loads, and the waiting load is something
@@ -812,9 +716,9 @@ var requirejs, require, define;
         }
 
         Module = function (map) {
-            this.events = undefEvents[map.id] || {};
+            this.events = getOwn(undefEvents, map.id) || {};
             this.map = map;
-            this.shim = config.shim[map.id];
+            this.shim = getOwn(config.shim, map.id);
             this.depExports = [];
             this.depMaps = [];
             this.depMatched = [];
@@ -828,7 +732,7 @@ var requirejs, require, define;
         };
 
         Module.prototype = {
-            init: function(depMaps, factory, errback, options) {
+            init: function (depMaps, factory, errback, options) {
                 options = options || {};
 
                 //Do not do more inits if already done. Can happen if there
@@ -857,7 +761,6 @@ var requirejs, require, define;
                 //doing a direct modification of the depMaps array
                 //would affect that config.
                 this.depMaps = depMaps && depMaps.slice(0);
-                this.depMaps.rjsSkipMap = depMaps.rjsSkipMap;
 
                 this.errback = errback;
 
@@ -879,20 +782,6 @@ var requirejs, require, define;
                 }
             },
 
-            defineDepById: function (id, depExports) {
-                var i;
-
-                //Find the index for this dependency.
-                each(this.depMaps, function (map, index) {
-                    if (map.id === id) {
-                        i = index;
-                        return true;
-                    }
-                });
-
-                return this.defineDep(i, depExports);
-            },
-
             defineDep: function (i, depExports) {
                 //Because of cycles, defined callback for a given
                 //export can be called more than once.
@@ -916,7 +805,9 @@ var requirejs, require, define;
                 //If the manager is for a plugin managed resource,
                 //ask the plugin to load it now.
                 if (this.shim) {
-                    makeRequire(this, true)(this.shim.deps || [], bind(this, function () {
+                    context.makeRequire(this.map, {
+                        enableBuildCallback: true
+                    })(this.shim.deps || [], bind(this, function () {
                         return map.prefix ? this.callPlugin() : this.load();
                     }));
                 } else {
@@ -925,7 +816,7 @@ var requirejs, require, define;
                 }
             },
 
-            load: function() {
+            load: function () {
                 var url = this.map.url;
 
                 //Regular dependency.
@@ -936,21 +827,19 @@ var requirejs, require, define;
             },
 
             /**
-             * Checks is the module is ready to define itself, and if so,
-             * define it. If the silent argument is true, then it will just
-             * define, but not notify listeners, and not ask for a context-wide
-             * check of all loaded modules. That is useful for cycle breaking.
+             * Checks if the module is ready to define itself, and if so,
+             * define it.
              */
-            check: function (silent) {
+            check: function () {
                 if (!this.enabled || this.enabling) {
                     return;
                 }
 
-                var id = this.map.id,
+                var err, cjsModule,
+                    id = this.map.id,
                     depExports = this.depExports,
                     exports = this.exports,
-                    factory = this.factory,
-                    err, cjsModule;
+                    factory = this.factory;
 
                 if (!this.inited) {
                     this.fetch();
@@ -966,8 +855,13 @@ var requirejs, require, define;
                     if (this.depCount < 1 && !this.defined) {
                         if (isFunction(factory)) {
                             //If there is an error listener, favor passing
-                            //to that instead of throwing an error.
-                            if (this.events.error) {
+                            //to that instead of throwing an error. However,
+                            //only do it for define()'d  modules. require
+                            //errbacks should not be called for failures in
+                            //their callbacks (#699). However if a global
+                            //onError is set, use that.
+                            if ((this.events.error && this.map.isDefine) ||
+                                req.onError !== defaultOnError) {
                                 try {
                                     exports = context.execCb(id, factory, depExports, exports);
                                 } catch (e) {
@@ -983,9 +877,9 @@ var requirejs, require, define;
                                 //favor a non-undefined return value over exports use.
                                 cjsModule = this.module;
                                 if (cjsModule &&
-                                    cjsModule.exports !== undefined &&
-                                    //Make sure it is not already the exports value
-                                    cjsModule.exports !== this.exports) {
+                                        cjsModule.exports !== undefined &&
+                                        //Make sure it is not already the exports value
+                                        cjsModule.exports !== this.exports) {
                                     exports = cjsModule.exports;
                                 } else if (exports === undefined && this.usingExports) {
                                     //exports already set the defined value.
@@ -995,8 +889,8 @@ var requirejs, require, define;
 
                             if (err) {
                                 err.requireMap = this.map;
-                                err.requireModules = [this.map.id];
-                                err.requireType = 'define';
+                                err.requireModules = this.map.isDefine ? [this.map.id] : null;
+                                err.requireType = this.map.isDefine ? 'define' : 'require';
                                 return onError((this.error = err));
                             }
 
@@ -1016,14 +910,9 @@ var requirejs, require, define;
                         }
 
                         //Clean up
-                        delete registry[id];
+                        cleanRegistry(id);
 
                         this.defined = true;
-                        context.waitCount -= 1;
-                        if (context.waitCount === 0) {
-                            //Clear the wait array used for cycles.
-                            waitAry = [];
-                        }
                     }
 
                     //Finished the define stage. Allow calling check again
@@ -1031,25 +920,32 @@ var requirejs, require, define;
                     //cycle.
                     this.defining = false;
 
-                    if (!silent) {
-                        if (this.defined && !this.defineEmitted) {
-                            this.defineEmitted = true;
-                            this.emit('defined', this.exports);
-                            this.defineEmitComplete = true;
-                        }
+                    if (this.defined && !this.defineEmitted) {
+                        this.defineEmitted = true;
+                        this.emit('defined', this.exports);
+                        this.defineEmitComplete = true;
                     }
+
                 }
             },
 
-            callPlugin: function() {
+            callPlugin: function () {
                 var map = this.map,
                     id = map.id,
-                    pluginMap = makeModuleMap(map.prefix, null, false, true);
+                    //Map already normalized the prefix.
+                    pluginMap = makeModuleMap(map.prefix);
+
+                //Mark this as a dependency for this plugin, so it
+                //can be traced for cycles.
+                this.depMaps.push(pluginMap);
 
                 on(pluginMap, 'defined', bind(this, function (plugin) {
-                    var name = this.map.name,
+                    var load, normalizedMap, normalizedMod,
+                        name = this.map.name,
                         parentName = this.map.parentMap ? this.map.parentMap.name : null,
-                        load, normalizedMap, normalizedMod;
+                        localRequire = context.makeRequire(map.parentMap, {
+                            enableBuildCallback: true
+                        });
 
                     //If current map is not normalized, wait for that
                     //normalized name to load instead of continuing.
@@ -1061,19 +957,24 @@ var requirejs, require, define;
                             }) || '';
                         }
 
+                        //prefix and name should already be normalized, no need
+                        //for applying map config again either.
                         normalizedMap = makeModuleMap(map.prefix + '!' + name,
-                                                      this.map.parentMap,
-                                                      false,
-                                                      true);
+                                                      this.map.parentMap);
                         on(normalizedMap,
-                           'defined', bind(this, function (value) {
-                            this.init([], function () { return value; }, null, {
-                                enabled: true,
-                                ignore: true
-                            });
-                        }));
-                        normalizedMod = registry[normalizedMap.id];
+                            'defined', bind(this, function (value) {
+                                this.init([], function () { return value; }, null, {
+                                    enabled: true,
+                                    ignore: true
+                                });
+                            }));
+
+                        normalizedMod = getOwn(registry, normalizedMap.id);
                         if (normalizedMod) {
+                            //Mark this as a dependency for this plugin, so it
+                            //can be traced for cycles.
+                            this.depMaps.push(normalizedMap);
+
                             if (this.events.error) {
                                 normalizedMod.on('error', bind(this, function (err) {
                                     this.emit('error', err);
@@ -1100,7 +1001,7 @@ var requirejs, require, define;
                         //since they will never be resolved otherwise now.
                         eachProp(registry, function (mod) {
                             if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
-                                removeWaiting(mod.map.id);
+                                cleanRegistry(mod.map.id);
                             }
                         });
 
@@ -1109,9 +1010,19 @@ var requirejs, require, define;
 
                     //Allow plugins to load other code without having to know the
                     //context or how to 'complete' the load.
-                    load.fromText = function (moduleName, text) {
+                    load.fromText = bind(this, function (text, textAlt) {
                         /*jslint evil: true */
-                        var hasInteractive = useInteractive;
+                        var moduleName = map.name,
+                            moduleMap = makeModuleMap(moduleName),
+                            hasInteractive = useInteractive;
+
+                        //As of 2.1.0, support just passing the text, to reinforce
+                        //fromText only being called once per resource. Still
+                        //support old style of passing moduleName but discard
+                        //that moduleName in favor of the internal ref.
+                        if (textAlt) {
+                            text = textAlt;
+                        }
 
                         //Turn off interactive script matching for IE for any define
                         //calls in the text, then turn it back on at the end.
@@ -1121,25 +1032,43 @@ var requirejs, require, define;
 
                         //Prime the system by creating a module instance for
                         //it.
-                        getModule(makeModuleMap(moduleName));
+                        getModule(moduleMap);
 
-                        req.exec(text);
+                        //Transfer any config to this other module.
+                        if (hasProp(config.config, id)) {
+                            config.config[moduleName] = config.config[id];
+                        }
+
+                        try {
+                            req.exec(text);
+                        } catch (e) {
+                            return onError(makeError('fromtexteval',
+                                             'fromText eval for ' + id +
+                                            ' failed: ' + e,
+                                             e,
+                                             [id]));
+                        }
 
                         if (hasInteractive) {
                             useInteractive = true;
                         }
 
+                        //Mark this as a dependency for the plugin
+                        //resource
+                        this.depMaps.push(moduleMap);
+
                         //Support anonymous modules.
                         context.completeLoad(moduleName);
-                    };
+
+                        //Bind the value of that module to the value for this
+                        //resource ID.
+                        localRequire([moduleName], load);
+                    });
 
                     //Use parentName here since the plugin's name is not reliable,
                     //could be some weird string with no path that actually wants to
                     //reference the parentName's path.
-                    plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb) {
-                        deps.rjsSkipMap = true;
-                        return context.require(deps, cb);
-                    }), load, config);
+                    plugin.load(map.name, localRequire, load, config);
                 }));
 
                 context.enable(pluginMap, this);
@@ -1147,14 +1076,9 @@ var requirejs, require, define;
             },
 
             enable: function () {
+                enabledRegistry[this.map.id] = this;
                 this.enabled = true;
 
-                if (!this.waitPushed) {
-                    waitAry.push(this);
-                    context.waitCount += 1;
-                    this.waitPushed = true;
-                }
-
                 //Set flag mentioning that the module is enabling,
                 //so that immediate calls to the defined callbacks
                 //for dependencies do not trigger inadvertent load
@@ -1171,10 +1095,10 @@ var requirejs, require, define;
                         depMap = makeModuleMap(depMap,
                                                (this.map.isDefine ? this.map : this.map.parentMap),
                                                false,
-                                               !this.depMaps.rjsSkipMap);
+                                               !this.skipMap);
                         this.depMaps[i] = depMap;
 
-                        handler = handlers[depMap.id];
+                        handler = getOwn(handlers, depMap.id);
 
                         if (handler) {
                             this.depExports[i] = handler(this);
@@ -1189,7 +1113,7 @@ var requirejs, require, define;
                         }));
 
                         if (this.errback) {
-                            on(depMap, 'error', this.errback);
+                            on(depMap, 'error', bind(this, this.errback));
                         }
                     }
 
@@ -1199,7 +1123,7 @@ var requirejs, require, define;
                     //Skip special modules like 'require', 'exports', 'module'
                     //Also, don't call enable if it is already enabled,
                     //important in circular dependency cases.
-                    if (!handlers[id] && mod && !mod.enabled) {
+                    if (!hasProp(handlers, id) && mod && !mod.enabled) {
                         context.enable(depMap, this);
                     }
                 }));
@@ -1207,7 +1131,7 @@ var requirejs, require, define;
                 //Enable each plugin that is used in
                 //a dependency
                 eachProp(this.pluginMaps, bind(this, function (pluginMap) {
-                    var mod = registry[pluginMap.id];
+                    var mod = getOwn(registry, pluginMap.id);
                     if (mod && !mod.enabled) {
                         context.enable(pluginMap, this);
                     }
@@ -1218,7 +1142,7 @@ var requirejs, require, define;
                 this.check();
             },
 
-            on: function(name, cb) {
+            on: function (name, cb) {
                 var cbs = this.events[name];
                 if (!cbs) {
                     cbs = this.events[name] = [];
@@ -1233,14 +1157,17 @@ var requirejs, require, define;
                 if (name === 'error') {
                     //Now that the error handler was triggered, remove
                     //the listeners, since this broken Module instance
-                    //can stay around for a while in the registry/waitAry.
+                    //can stay around for a while in the registry.
                     delete this.events[name];
                 }
             }
         };
 
         function callGetModule(args) {
-            getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
+            //Skip modules already defined.
+            if (!hasProp(defined, args[0])) {
+                getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
+            }
         }
 
         function removeListener(node, func, name, ieName) {
@@ -1280,16 +1207,36 @@ var requirejs, require, define;
             };
         }
 
-        return (context = {
+        function intakeDefines() {
+            var args;
+
+            //Any defined modules in the global queue, intake them now.
+            takeGlobalQueue();
+
+            //Make sure any remaining defQueue items get properly processed.
+            while (defQueue.length) {
+                args = defQueue.shift();
+                if (args[0] === null) {
+                    return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
+                } else {
+                    //args are id, deps, factory. Should be normalized by the
+                    //define() function.
+                    callGetModule(args);
+                }
+            }
+        }
+
+        context = {
             config: config,
             contextName: contextName,
             registry: registry,
             defined: defined,
             urlFetched: urlFetched,
-            waitCount: 0,
             defQueue: defQueue,
             Module: Module,
             makeModuleMap: makeModuleMap,
+            nextTick: req.nextTick,
+            onError: onError,
 
             /**
              * Set a configuration for the context.
@@ -1307,20 +1254,26 @@ var requirejs, require, define;
                 //they are additive.
                 var pkgs = config.pkgs,
                     shim = config.shim,
-                    paths = config.paths,
-                    map = config.map;
-
-                //Mix in the config values, favoring the new values over
-                //existing ones in context.config.
-                mixin(config, cfg, true);
-
-                //Merge paths.
-                config.paths = mixin(paths, cfg.paths, true);
+                    objs = {
+                        paths: true,
+                        config: true,
+                        map: true
+                    };
 
-                //Merge map
-                if (cfg.map) {
-                    config.map = mixin(map || {}, cfg.map, true, true);
-                }
+                eachProp(cfg, function (value, prop) {
+                    if (objs[prop]) {
+                        if (prop === 'map') {
+                            if (!config.map) {
+                                config.map = {};
+                            }
+                            mixin(config[prop], value, true, true);
+                        } else {
+                            mixin(config[prop], value, true);
+                        }
+                    } else {
+                        config[prop] = value;
+                    }
+                });
 
                 //Merge shim
                 if (cfg.shim) {
@@ -1331,8 +1284,8 @@ var requirejs, require, define;
                                 deps: value
                             };
                         }
-                        if (value.exports && !value.exports.__buildReady) {
-                            value.exports = context.makeShimExports(value.exports);
+                        if ((value.exports || value.init) && !value.exportsFn) {
+                            value.exportsFn = context.makeShimExports(value);
                         }
                         shim[id] = value;
                     });
@@ -1371,7 +1324,12 @@ var requirejs, require, define;
                 //update the maps for them, since their info, like URLs to load,
                 //may have changed.
                 eachProp(registry, function (mod, id) {
-                    mod.map = makeModuleMap(id);
+                    //If module already has init called, since it is too
+                    //late to modify them, and ignore unnormalized ones
+                    //since they are transient.
+                    if (!mod.inited && !mod.map.unnormalized) {
+                        mod.map = makeModuleMap(id);
+                    }
                 });
 
                 //If a deps array or a config callback is specified, then call
@@ -1382,130 +1340,158 @@ var requirejs, require, define;
                 }
             },
 
-            makeShimExports: function (exports) {
-                var func;
-                if (typeof exports === 'string') {
-                    func = function () {
-                        return getGlobal(exports);
-                    };
-                    //Save the exports for use in nodefine checking.
-                    func.exports = exports;
-                    return func;
-                } else {
-                    return function () {
-                        return exports.apply(global, arguments);
-                    };
+            makeShimExports: function (value) {
+                function fn() {
+                    var ret;
+                    if (value.init) {
+                        ret = value.init.apply(global, arguments);
+                    }
+                    return ret || (value.exports && getGlobal(value.exports));
                 }
+                return fn;
             },
 
-            requireDefined: function (id, relMap) {
-                return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
-            },
+            makeRequire: function (relMap, options) {
+                options = options || {};
 
-            requireSpecified: function (id, relMap) {
-                id = makeModuleMap(id, relMap, false, true).id;
-                return hasProp(defined, id) || hasProp(registry, id);
-            },
+                function localRequire(deps, callback, errback) {
+                    var id, map, requireMod;
 
-            require: function (deps, callback, errback, relMap) {
-                var moduleName, id, map, requireMod, args;
-                if (typeof deps === 'string') {
-                    if (isFunction(callback)) {
-                        //Invalid call
-                        return onError(makeError('requireargs', 'Invalid require call'), errback);
+                    if (options.enableBuildCallback && callback && isFunction(callback)) {
+                        callback.__requireJsBuild = true;
                     }
 
-                    //Synchronous access to one module. If require.get is
-                    //available (as in the Node adapter), prefer that.
-                    //In this case deps is the moduleName and callback is
-                    //the relMap
-                    if (req.get) {
-                        return req.get(context, deps, callback);
-                    }
+                    if (typeof deps === 'string') {
+                        if (isFunction(callback)) {
+                            //Invalid call
+                            return onError(makeError('requireargs', 'Invalid require call'), errback);
+                        }
+
+                        //If require|exports|module are requested, get the
+                        //value for them from the special handlers. Caveat:
+                        //this only works while module is being defined.
+                        if (relMap && hasProp(handlers, deps)) {
+                            return handlers[deps](registry[relMap.id]);
+                        }
 
-                    //Just return the module wanted. In this scenario, the
-                    //second arg (if passed) is just the relMap.
-                    moduleName = deps;
-                    relMap = callback;
+                        //Synchronous access to one module. If require.get is
+                        //available (as in the Node adapter), prefer that.
+                        if (req.get) {
+                            return req.get(context, deps, relMap, localRequire);
+                        }
 
-                    //Normalize module name, if it contains . or ..
-                    map = makeModuleMap(moduleName, relMap, false, true);
-                    id = map.id;
+                        //Normalize module name, if it contains . or ..
+                        map = makeModuleMap(deps, relMap, false, true);
+                        id = map.id;
 
-                    if (!hasProp(defined, id)) {
-                        return onError(makeError('notloaded', 'Module name "' +
-                                    id +
-                                    '" has not been loaded yet for context: ' +
-                                    contextName));
+                        if (!hasProp(defined, id)) {
+                            return onError(makeError('notloaded', 'Module name "' +
+                                        id +
+                                        '" has not been loaded yet for context: ' +
+                                        contextName +
+                                        (relMap ? '' : '. Use require([])')));
+                        }
+                        return defined[id];
                     }
-                    return defined[id];
-                }
 
-                //Callback require. Normalize args. if callback or errback is
-                //not a function, it means it is a relMap. Test errback first.
-                if (errback && !isFunction(errback)) {
-                    relMap = errback;
-                    errback = undefined;
-                }
-                if (callback && !isFunction(callback)) {
-                    relMap = callback;
-                    callback = undefined;
-                }
+                    //Grab defines waiting in the global queue.
+                    intakeDefines();
 
-                //Any defined modules in the global queue, intake them now.
-                takeGlobalQueue();
+                    //Mark all the dependencies as needing to be loaded.
+                    context.nextTick(function () {
+                        //Some defines could have been added since the
+                        //require call, collect them.
+                        intakeDefines();
 
-                //Make sure any remaining defQueue items get properly processed.
-                while (defQueue.length) {
-                    args = defQueue.shift();
-                    if (args[0] === null) {
-                        return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
-                    } else {
-                        //args are id, deps, factory. Should be normalized by the
-                        //define() function.
-                        callGetModule(args);
-                    }
-                }
+                        requireMod = getModule(makeModuleMap(null, relMap));
 
-                //Mark all the dependencies as needing to be loaded.
-                requireMod = getModule(makeModuleMap(null, relMap));
+                        //Store if map config should be applied to this require
+                        //call for dependencies.
+                        requireMod.skipMap = options.skipMap;
 
-                requireMod.init(deps, callback, errback, {
-                    enabled: true
-                });
+                        requireMod.init(deps, callback, errback, {
+                            enabled: true
+                        });
 
-                checkLoaded();
+                        checkLoaded();
+                    });
 
-                return context.require;
-            },
+                    return localRequire;
+                }
 
-            undef: function (id) {
-                var map = makeModuleMap(id, null, true),
-                    mod = registry[id];
+                mixin(localRequire, {
+                    isBrowser: isBrowser,
+
+                    /**
+                     * Converts a module name + .extension into an URL path.
+                     * *Requires* the use of a module name. It does not support using
+                     * plain URLs like nameToUrl.
+                     */
+                    toUrl: function (moduleNamePlusExt) {
+                        var ext,
+                            index = moduleNamePlusExt.lastIndexOf('.'),
+                            segment = moduleNamePlusExt.split('/')[0],
+                            isRelative = segment === '.' || segment === '..';
+
+                        //Have a file extension alias, and it is not the
+                        //dots from a relative path.
+                        if (index !== -1 && (!isRelative || index > 1)) {
+                            ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
+                            moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
+                        }
 
-                delete defined[id];
-                delete urlFetched[map.url];
-                delete undefEvents[id];
+                        return context.nameToUrl(normalize(moduleNamePlusExt,
+                                                relMap && relMap.id, true), ext,  true);
+                    },
 
-                if (mod) {
-                    //Hold on to listeners in case the
-                    //module will be attempted to be reloaded
-                    //using a different config.
-                    if (mod.events.defined) {
-                        undefEvents[id] = mod.events;
+                    defined: function (id) {
+                        return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
+                    },
+
+                    specified: function (id) {
+                        id = makeModuleMap(id, relMap, false, true).id;
+                        return hasProp(defined, id) || hasProp(registry, id);
                     }
+                });
+
+                //Only allow undef on top level require calls
+                if (!relMap) {
+                    localRequire.undef = function (id) {
+                        //Bind any waiting define() calls to this context,
+                        //fix for #408
+                        takeGlobalQueue();
+
+                        var map = makeModuleMap(id, relMap, true),
+                            mod = getOwn(registry, id);
+
+                        delete defined[id];
+                        delete urlFetched[map.url];
+                        delete undefEvents[id];
+
+                        if (mod) {
+                            //Hold on to listeners in case the
+                            //module will be attempted to be reloaded
+                            //using a different config.
+                            if (mod.events.defined) {
+                                undefEvents[id] = mod.events;
+                            }
 
-                    removeWaiting(id);
+                            cleanRegistry(id);
+                        }
+                    };
                 }
+
+                return localRequire;
             },
 
             /**
              * Called to enable a module if it is still in the registry
-             * awaiting enablement. parent module is passed in for context,
-             * used by the optimizer.
+             * awaiting enablement. A second arg, parent, the parent module,
+             * is passed in for context, when this method is overriden by
+             * the optimizer. Not shown here to keep code compact.
              */
-            enable: function (depMap, parent) {
-                var mod = registry[depMap.id];
+            enable: function (depMap) {
+                var mod = getOwn(registry, depMap.id);
                 if (mod) {
                     getModule(depMap).enable();
                 }
@@ -1518,9 +1504,9 @@ var requirejs, require, define;
              * @param {String} moduleName the name of the module to potentially complete.
              */
             completeLoad: function (moduleName) {
-                var shim = config.shim[moduleName] || {},
-                shExports = shim.exports && shim.exports.exports,
-                found, args, mod;
+                var found, args, mod,
+                    shim = getOwn(config.shim, moduleName) || {},
+                    shExports = shim.exports;
 
                 takeGlobalQueue();
 
@@ -1545,11 +1531,9 @@ var requirejs, require, define;
 
                 //Do this after the cycle of callGetModule in case the result
                 //of those calls/init calls changes the registry.
-                mod = registry[moduleName];
+                mod = getOwn(registry, moduleName);
 
-                if (!found &&
-                    !defined[moduleName] &&
-                    mod && !mod.inited) {
+                if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
                     if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
                         if (hasPathFallback(moduleName)) {
                             return;
@@ -1562,7 +1546,7 @@ var requirejs, require, define;
                     } else {
                         //A script that does not call define(), so just simulate
                         //the call for it.
-                        callGetModule([moduleName, (shim.deps || []), shim.exports]);
+                        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
                     }
                 }
 
@@ -1570,33 +1554,16 @@ var requirejs, require, define;
             },
 
             /**
-             * Converts a module name + .extension into an URL path.
-             * *Requires* the use of a module name. It does not support using
-             * plain URLs like nameToUrl.
-             */
-            toUrl: function (moduleNamePlusExt, relModuleMap) {
-                var index = moduleNamePlusExt.lastIndexOf('.'),
-                    ext = null;
-
-                if (index !== -1) {
-                    ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
-                    moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
-                }
-
-                return context.nameToUrl(moduleNamePlusExt, ext, relModuleMap);
-            },
-
-            /**
              * Converts a module name to a file path. Supports cases where
              * moduleName may actually be just an URL.
+             * Note that it **does not** call normalize on the moduleName,
+             * it is assumed to have already been normalized. This is an
+             * internal API, not a public one. Use toUrl for the public API.
              */
-            nameToUrl: function (moduleName, ext, relModuleMap) {
+            nameToUrl: function (moduleName, ext, skipExt) {
                 var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
                     parentPath;
 
-                //Normalize module name if have a base relative module name to work from.
-                moduleName = normalize(moduleName, relModuleMap && relModuleMap.id, true);
-
                 //If a colon is in the URL, it indicates a protocol is used and it is just
                 //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
                 //or ends with .js, then assume the user meant to use an url and not a module id.
@@ -1617,8 +1584,8 @@ var requirejs, require, define;
                     //and work up from it.
                     for (i = syms.length; i > 0; i -= 1) {
                         parentModule = syms.slice(0, i).join('/');
-                        pkg = pkgs[parentModule];
-                        parentPath = paths[parentModule];
+                        pkg = getOwn(pkgs, parentModule);
+                        parentPath = getOwn(paths, parentModule);
                         if (parentPath) {
                             //If an array, it means there are a few choices,
                             //Choose the one that is desired
@@ -1641,7 +1608,8 @@ var requirejs, require, define;
                     }
 
                     //Join the path parts together, then figure out if baseUrl is needed.
-                    url = syms.join('/') + (ext || '.js');
+                    url = syms.join('/');
+                    url += (ext || (/\?/.test(url) || skipExt ? '' : '.js'));
                     url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
                 }
 
@@ -1657,7 +1625,7 @@ var requirejs, require, define;
             },
 
             /**
-             * Executes a module callack function. Broken out as a separate function
+             * Executes a module callback function. Broken out as a separate function
              * solely to allow the build system to sequence the files in the built
              * layer in the right sequence.
              *
@@ -1678,7 +1646,7 @@ var requirejs, require, define;
                 //all old browsers will be supported, but this one was easy enough
                 //to support and still makes sense.
                 if (evt.type === 'load' ||
-                    (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
+                        (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
                     //Reset interactive script so a script node is not held onto for
                     //to long.
                     interactiveScript = null;
@@ -1695,10 +1663,13 @@ var requirejs, require, define;
             onScriptError: function (evt) {
                 var data = getScriptData(evt);
                 if (!hasPathFallback(data.id)) {
-                    return onError(makeError('scripterror', 'Script error', evt, [data.id]));
+                    return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
                 }
             }
-        });
+        };
+
+        context.require = context.makeRequire();
+        return context;
     }
 
     /**
@@ -1718,8 +1689,8 @@ var requirejs, require, define;
     req = requirejs = function (deps, callback, errback, optional) {
 
         //Find the right context, use default
-        var contextName = defContextName,
-            context, config;
+        var context, config,
+            contextName = defContextName;
 
         // Determine if have config object in the call.
         if (!isArray(deps) && typeof deps !== 'string') {
@@ -1739,7 +1710,7 @@ var requirejs, require, define;
             contextName = config.context;
         }
 
-        context = contexts[contextName];
+        context = getOwn(contexts, contextName);
         if (!context) {
             context = contexts[contextName] = req.s.newContext(contextName);
         }
@@ -1760,6 +1731,16 @@ var requirejs, require, define;
     };
 
     /**
+     * Execute something after the current tick
+     * of the event loop. Override for other envs
+     * that have a better solution than setTimeout.
+     * @param  {Function} fn function to execute later.
+     */
+    req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
+        setTimeout(fn, 4);
+    } : function (fn) { fn(); };
+
+    /**
      * Export require as a global, but only if it does not already exist.
      */
     if (!require) {
@@ -1779,9 +1760,21 @@ var requirejs, require, define;
     //Create default context.
     req({});
 
-    //Exports some context-sensitive methods on global require, using
-    //default context if no context specified.
-    addRequireMethods(req);
+    //Exports some context-sensitive methods on global require.
+    each([
+        'toUrl',
+        'undef',
+        'defined',
+        'specified'
+    ], function (prop) {
+        //Reference from contexts instead of early binding to default context,
+        //so that during builds, the latest instance of the default context
+        //with its config gets used.
+        req[prop] = function () {
+            var ctx = contexts[defContextName];
+            return ctx.require[prop].apply(ctx, arguments);
+        };
+    });
 
     if (isBrowser) {
         head = s.head = document.getElementsByTagName('head')[0];
@@ -1799,9 +1792,7 @@ var requirejs, require, define;
      * function. Intercept/override it if you want custom error handling.
      * @param {Error} err the error object.
      */
-    req.onError = function (err) {
-        throw err;
-    };
+    req.onError = defaultOnError;
 
     /**
      * Does the request to load a module for the browser case.
@@ -1818,10 +1809,11 @@ var requirejs, require, define;
         if (isBrowser) {
             //In the browser so use a script tag
             node = config.xhtml ?
-                   document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
-                   document.createElement('script');
+                    document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
+                    document.createElement('script');
             node.type = config.scriptType || 'text/javascript';
             node.charset = 'utf-8';
+            node.async = true;
 
             node.setAttribute('data-requirecontext', context.contextName);
             node.setAttribute('data-requiremodule', moduleName);
@@ -1835,15 +1827,15 @@ var requirejs, require, define;
             //UNFORTUNATELY Opera implements attachEvent but does not follow the script
             //script execution mode.
             if (node.attachEvent &&
-                //Check if node.attachEvent is artificially added by custom script or
-                //natively supported by browser
-                //read https://github.com/jrburke/requirejs/issues/187
-                //if we can NOT find [native code] then it must NOT natively supported.
-                //in IE8, node.attachEvent does not have toString()
-                //Note the test for "[native code" with no closing brace, see:
-                //https://github.com/jrburke/requirejs/issues/273
-                !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
-                !isOpera) {
+                    //Check if node.attachEvent is artificially added by custom script or
+                    //natively supported by browser
+                    //read https://github.com/jrburke/requirejs/issues/187
+                    //if we can NOT find [native code] then it must NOT natively supported.
+                    //in IE8, node.attachEvent does not have toString()
+                    //Note the test for "[native code" with no closing brace, see:
+                    //https://github.com/jrburke/requirejs/issues/273
+                    !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
+                    !isOpera) {
                 //Probably IE. IE (at least 6-8) do not fire
                 //script onload right after executing the script, so
                 //we cannot tie the anonymous define call to a name.
@@ -1854,7 +1846,7 @@ var requirejs, require, define;
                 node.attachEvent('onreadystatechange', context.onScriptLoad);
                 //It would be great to add an error handler here to catch
                 //404s in IE9+. However, onreadystatechange will fire before
-                //the error handler, so that does not help. If addEvenListener
+                //the error handler, so that does not help. If addEventListener
                 //is used, then IE will fire error before load, but we cannot
                 //use that pathway given the connect.microsoft.com issue
                 //mentioned above about not doing the 'script execute,
@@ -1883,16 +1875,24 @@ var requirejs, require, define;
 
             return node;
         } else if (isWebWorker) {
-            //In a web worker, use importScripts. This is not a very
-            //efficient use of importScripts, importScripts will block until
-            //its script is downloaded and evaluated. However, if web workers
-            //are in play, the expectation that a build has been done so that
-            //only one script needs to be loaded anyway. This may need to be
-            //reevaluated if other use cases become common.
-            importScripts(url);
-
-            //Account for anonymous modules
-            context.completeLoad(moduleName);
+            try {
+                //In a web worker, use importScripts. This is not a very
+                //efficient use of importScripts, importScripts will block until
+                //its script is downloaded and evaluated. However, if web workers
+                //are in play, the expectation that a build has been done so that
+                //only one script needs to be loaded anyway. This may need to be
+                //reevaluated if other use cases become common.
+                importScripts(url);
+
+                //Account for anonymous modules
+                context.completeLoad(moduleName);
+            } catch (e) {
+                context.onError(makeError('importscripts',
+                                'importScripts failed for ' +
+                                    moduleName + ' at ' + url,
+                                e,
+                                [moduleName]));
+            }
         }
     };
 
@@ -1924,24 +1924,31 @@ var requirejs, require, define;
             //baseUrl, if it is not already set.
             dataMain = script.getAttribute('data-main');
             if (dataMain) {
-
-                //Pull off the directory of data-main for use as the
-                //baseUrl.
-                src = dataMain.split('/');
-                mainScript = src.pop();
-                subPath = src.length ? src.join('/')  + '/' : './';
+                //Preserve dataMain in case it is a path (i.e. contains '?')
+                mainScript = dataMain;
 
                 //Set final baseUrl if there is not already an explicit one.
                 if (!cfg.baseUrl) {
+                    //Pull off the directory of data-main for use as the
+                    //baseUrl.
+                    src = mainScript.split('/');
+                    mainScript = src.pop();
+                    subPath = src.length ? src.join('/')  + '/' : './';
+
                     cfg.baseUrl = subPath;
                 }
 
-                //Strip off any trailing .js since dataMain is now
+                //Strip off any trailing .js since mainScript is now
                 //like a module name.
-                dataMain = mainScript.replace(jsSuffixRegExp, '');
+                mainScript = mainScript.replace(jsSuffixRegExp, '');
+
+                 //If mainScript is still a path, fall back to dataMain
+                if (req.jsExtRegExp.test(mainScript)) {
+                    mainScript = dataMain;
+                }
 
                 //Put the data-main script in the files to load.
-                cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
+                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
 
                 return true;
             }
@@ -1958,7 +1965,7 @@ var requirejs, require, define;
     define = function (name, deps, callback) {
         var node, context;
 
-        //Allow for anonymous functions
+        //Allow for anonymous modules
         if (typeof name !== 'string') {
             //Adjust args appropriately
             callback = deps;
@@ -1969,12 +1976,13 @@ var requirejs, require, define;
         //This module may not have dependencies
         if (!isArray(deps)) {
             callback = deps;
-            deps = [];
+            deps = null;
         }
 
         //If no name, and callback is a function, then figure out if it a
         //CommonJS thing with dependencies.
-        if (!deps.length && isFunction(callback)) {
+        if (!deps && isFunction(callback)) {
+            deps = [];
             //Remove comments from the callback string,
             //look for require calls, and pull them into the dependencies,
             //but only if there are function args.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/less/bootstrap/tests/buttons.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/tests/buttons.html b/src/fauxton/assets/less/bootstrap/tests/buttons.html
deleted file mode 100644
index 5fe7f66..0000000
--- a/src/fauxton/assets/less/bootstrap/tests/buttons.html
+++ /dev/null
@@ -1,139 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Buttons &middot; Bootstrap</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
-    <meta name="author" content="">
-
-    <!-- Le styles -->
-    <link href="../../docs/assets/css/bootstrap.css" rel="stylesheet">
-    <style>
-      body {
-        padding-top: 30px;
-        padding-bottom: 30px;
-      }
-    </style>
-    <link href="../../docs/assets/css/bootstrap-responsive.css" rel="stylesheet">
-
-    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
-    <!--[if lt IE 9]>
-      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
-    <![endif]-->
-
-    <!-- Le fav and touch icons -->
-    <link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
-    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
-    <link rel="apple-touch-icon-precomposed" href="../../docs/assets/ico/apple-touch-icon-57-precomposed.png">
-  </head>
-
-  <body>
-
-    <div class="container">
-
-      <h2>Dropups</h2>
-      <div class="btn-toolbar">
-        <div class="btn-group dropup">
-          <button class="btn">Dropup</button>
-          <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-primary">Dropup</button>
-          <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-danger">Dropup</button>
-          <button class="btn btn-danger dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-warning">Dropup</button>
-          <button class="btn btn-warning dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-success">Dropup</button>
-          <button class="btn btn-success dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-info">Dropup</button>
-          <button class="btn btn-info dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-        <div class="btn-group dropup">
-          <button class="btn btn-inverse">Dropup</button>
-          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
-          <ul class="dropdown-menu">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li class="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div><!-- /btn-group -->
-      </div><!-- /btn-toolbar -->
-
-
-    </div> <!-- /container -->
-
-    <!-- Le javascript
-    ================================================== -->
-    <!-- Placed at the end of the document so the pages load faster -->
-    <script src="../../docs/assets/js/jquery.js"></script>
-    <script src="../../docs/assets/js/bootstrap-transition.js"></script>
-    <script src="../../docs/assets/js/bootstrap-alert.js"></script>
-    <script src="../../docs/assets/js/bootstrap-modal.js"></script>
-    <script src="../../docs/assets/js/bootstrap-dropdown.js"></script>
-    <script src="../../docs/assets/js/bootstrap-scrollspy.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tab.js"></script>
-    <script src="../../docs/assets/js/bootstrap-tooltip.js"></script>
-    <script src="../../docs/assets/js/bootstrap-popover.js"></script>
-    <script src="../../docs/assets/js/bootstrap-button.js"></script>
-    <script src="../../docs/assets/js/bootstrap-collapse.js"></script>
-    <script src="../../docs/assets/js/bootstrap-carousel.js"></script>
-    <script src="../../docs/assets/js/bootstrap-typeahead.js"></script>
-
-  </body>
-</html>


[33/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: Add dependancies to watch path instead of custom watch path


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

Branch: refs/heads/1684-feature-db-updates
Commit: 6e8f47c7f504abbfdef3ddfa63aa9a8826e94445
Parents: e204f0d
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Jul 1 15:24:00 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Jul 1 15:24:00 2013 +0200

----------------------------------------------------------------------
 src/fauxton/Gruntfile.js          |  2 +-
 src/fauxton/settings.json.default |  4 ----
 src/fauxton/tasks/helper.js       | 14 +++++++++++++-
 3 files changed, 14 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e8f47c7/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 35a2c67..700246f 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -206,7 +206,7 @@ module.exports = function(grunt) {
     },
 
     watch: {
-      files: helper.readSettingsFile().watch.files,
+      files: helper.watchFiles(["./app/**/*"]),
       tasks: ['debug', 'template']
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e8f47c7/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 051e3fb..9716ceb 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -24,9 +24,5 @@
           "okay_if_missing": true
         }
       }
-    },
-
-    "watch": {
-      "files": ["./app/**/*"]
     }
 }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e8f47c7/src/fauxton/tasks/helper.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/helper.js b/src/fauxton/tasks/helper.js
index 5178ee2..a7eddbf 100644
--- a/src/fauxton/tasks/helper.js
+++ b/src/fauxton/tasks/helper.js
@@ -10,9 +10,11 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-var fs = require('fs');
+var fs = require('fs'),
+    path = require('path');
 
 exports.init = function(grunt) {
+  var _ = grunt.util._;
 
   return { 
     readSettingsFile: function () {
@@ -27,6 +29,16 @@ exports.init = function(grunt) {
 
     processAddons: function (callback) {
       this.readSettingsFile().deps.forEach(callback);
+    },
+
+    watchFiles: function (defaults) {
+      return _.reduce(this.readSettingsFile().deps, function (files, dep) { 
+        if (dep.path) { 
+          files.push(path.join(dep.path, '**/*'));
+        }
+        return files
+      }, defaults);
+
     }
   };
 };


[07/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Move 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/e0f7d3ef
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e0f7d3ef
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e0f7d3ef

Branch: refs/heads/1684-feature-db-updates
Commit: e0f7d3ef48c0b55e62fa5bbb2c26c8ce083db981
Parents: c98ba56
Author: Alexander Shorin <kx...@apache.org>
Authored: Mon Jun 3 09:50:50 2013 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Mon Jun 3 09:50:50 2013 +0400

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


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e0f7d3ef/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index f0c8bf7..dd44fda 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -23,5 +23,6 @@ documentation or developing software. Some of these people are:
  * Joan Touzet <jo...@ieee.org>
  * Dale Harvey <da...@apache.org>
  * Dirkjan Ochtman <dj...@apache.org>
+ * Alexander Shorin <kx...@apache.org>
 
 For a list of other credits see the `THANKS` file.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/e0f7d3ef/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index 046a6fa..d82c23d 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -81,7 +81,6 @@ suggesting improvements or submitting changes. Some of these people are:
  * Andrey Somov <tr...@gmail.com>
  * Chris Coulson <chrisccoulson.googlemail.com>
  * Trond Norbye <tr...@gmail.com>
- * Alexander Shorin <kx...@gmail.com>
  * Christopher Bonhage <qu...@me.com>
  * Christian Carter <cd...@gmail.com>
  * Lukasz Mielicki <mi...@gmail.com>


[38/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Expanded description of the validate_doc_update function


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

Branch: refs/heads/1684-feature-db-updates
Commit: ef9ac4699b9d68bdf1d5f0ae0169867af593795c
Parents: 1da6773
Author: Paul Mietz Egli <pa...@obscure.com>
Authored: Wed Jul 3 22:28:00 2013 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Wed Jul 3 22:28:00 2013 +0400

----------------------------------------------------------------------
 share/doc/src/ddocs.rst | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ef9ac469/share/doc/src/ddocs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/ddocs.rst b/share/doc/src/ddocs.rst
index ada5b0d..0bb2c9d 100644
--- a/share/doc/src/ddocs.rst
+++ b/share/doc/src/ddocs.rst
@@ -575,14 +575,41 @@ Validate document update functions
    :param secObj: :ref:`security_object`
 
    :throws: ``forbidden`` error to gracefully prevent document storing.
+   :throws: ``unauthorized`` error to prevent storage and allow the user to
+            re-auth.
+
+A design document may contain a function named `validate_doc_update`
+which can be used to prevent invalid or unauthorized document update requests
+from being stored.  The function is passed the new document from the update
+request, the current document stored in the database, a :ref:`userctx_object`
+containing information about the user writing the document (if present), and
+a :ref:`security_object` with lists of database security roles.
+
+Validation functions typically examine the structure of the new document to
+ensure that required fields are present and to verify that the requesting user
+should be allowed to make changes to the document properties.  For example,
+an application may require that a user must be authenticated in order to create
+a new document or that specific document fields be present when a document
+is updated. The validation function can abort the pending document write
+by throwing one of two error objects:
 
-To perform validate operations on document saving there is a special design
-function type called `validate_doc_update`.
+.. code-block:: javascript
 
-Instead of thousands words take a look at the next example of validate
-function - this function is used in ``_design/_auth`` ddoc from `_users`
-database to control users documents required field set and modification
-permissions:
+  // user is not authorized to make the change but may re-authenticate
+  throw({ unauthorized: 'Error message here.' });
+  
+  // change is not allowed
+  throw({ forbidden: 'Error message here.' });
+
+Document validation is optional, and each design document in the database may
+have at most one validation function.  When a write request is received for
+a given database, the validation function in each design document in that
+database is called in an unspecified order.  If any of the validation functions
+throw an error, the write will not succeed.
+
+**Example**: The ``_design/_auth`` ddoc from `_users` database uses a validation
+function to ensure that documents contain some required fields and are only
+modified by a user with the ``_admin`` role:
 
 .. code-block:: javascript
 


[19/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
[TESTS] Make tests run more reliably. Delete test-auth-dbs before tests.


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

Branch: refs/heads/1684-feature-db-updates
Commit: e6d95ae5de7ba021c32021d955d718198e209da9
Parents: 785a342
Author: Jan Lehnardt <ja...@apache.org>
Authored: Thu Jun 13 19:36:38 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Thu Jun 13 19:37:34 2013 +0200

----------------------------------------------------------------------
 test/etap/075-auth-cache.t | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e6d95ae5/test/etap/075-auth-cache.t
----------------------------------------------------------------------
diff --git a/test/etap/075-auth-cache.t b/test/etap/075-auth-cache.t
index 2bb17c8..7a8b824 100755
--- a/test/etap/075-auth-cache.t
+++ b/test/etap/075-auth-cache.t
@@ -72,6 +72,8 @@ test() ->
     couch_config:set(
         "couch_httpd_auth", "authentication_db",
         binary_to_list(auth_db_name()), false),
+    delete_db(auth_db_name()),
+    delete_db(auth_db_2_name()),
 
     test_auth_db_crash(),
 


[31/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
[tests] tidy up etap stream test output

Closes COUCHDB-1082.


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

Branch: refs/heads/1684-feature-db-updates
Commit: ba3adb11f4fc3c7aa215224779c1142dfb6b676d
Parents: bc4120a
Author: Andrey Somov <tr...@gmail.com>
Authored: Fri Jun 28 11:23:59 2013 +0200
Committer: Dave Cottlehuber <dc...@apache.org>
Committed: Fri Jun 28 11:27:24 2013 +0200

----------------------------------------------------------------------
 test/etap/050-stream.t | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/ba3adb11/test/etap/050-stream.t
----------------------------------------------------------------------
diff --git a/test/etap/050-stream.t b/test/etap/050-stream.t
index 676f1e4..0251f00 100755
--- a/test/etap/050-stream.t
+++ b/test/etap/050-stream.t
@@ -47,12 +47,12 @@ test() ->
     etap:is(Length, 8, "Close also returns the number of bytes written."),
     etap:is(<<"foodfoob">>, read_all(Fd, Ptrs), "Returned pointers are valid."),
 
-    % Remeber where we expect the pointer to be.
+    % Remember where we expect the pointer to be.
     {ok, ExpPtr} = couch_file:bytes(Fd),
     {ok, Stream2} = couch_stream:open(Fd),
     OneBits = <<1:(8*10)>>,
     etap:is(ok, couch_stream:write(Stream2, OneBits),
-        "Successfully wrote 80 1 bits."),
+        "Successfully wrote 79 zero bits and 1 one bit."),
 
     ZeroBits = <<0:(8*10)>>,
     etap:is(ok, couch_stream:write(Stream2, ZeroBits),


[08/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Add documentation on replication

Previously replication.rst described only the _replicator database, but did
not provide an overall view on replication.


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

Branch: refs/heads/1684-feature-db-updates
Commit: eb364ff3a2a85bdc15aaa4f5b8c69aa987aea6f8
Parents: e0f7d3e
Author: Stefan Kögl <st...@skoegl.net>
Authored: Mon Jun 3 10:10:36 2013 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Mon Jun 3 10:10:36 2013 +0400

----------------------------------------------------------------------
 share/doc/build/Makefile.am      |   3 +
 share/doc/src/index.rst          |   1 +
 share/doc/src/json-structure.rst |  14 ++
 share/doc/src/replication.rst    | 406 +++++-----------------------------
 share/doc/src/replicator.rst     | 383 ++++++++++++++++++++++++++++++++
 5 files changed, 460 insertions(+), 347 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/eb364ff3/share/doc/build/Makefile.am
----------------------------------------------------------------------
diff --git a/share/doc/build/Makefile.am b/share/doc/build/Makefile.am
index 9988cf1..97fef79 100644
--- a/share/doc/build/Makefile.am
+++ b/share/doc/build/Makefile.am
@@ -65,6 +65,7 @@ html_files = \
     html/_sources/json-structure.txt \
     html/_sources/query-servers.txt \
     html/_sources/replication.txt \
+    html/_sources/replicator.txt \
     html/_static/ajax-loader.gif \
     html/_static/basic.css \
     html/_static/comment-bright.png \
@@ -107,6 +108,7 @@ html_files = \
     html/json-structure.html \
     html/query-servers.html \
     html/replication.html \
+    html/replicator.html \
     html/objects.inv \
     html/genindex.html \
     html/search.html \
@@ -149,6 +151,7 @@ src_files = \
     ../src/json-structure.rst \
     ../src/query-servers.rst \
     ../src/replication.rst \
+    ../src/replicator.rst \
     ../src/conf.py
 
 src_files_html = \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eb364ff3/share/doc/src/index.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/index.rst b/share/doc/src/index.rst
index 44d2f12..014450c 100644
--- a/share/doc/src/index.rst
+++ b/share/doc/src/index.rst
@@ -31,6 +31,7 @@ Contents
     api-basics
     configuring
     replication
+    replicator
     ddocs
     query-servers
     changes

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eb364ff3/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index edc4c14..a5dc6d2 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -238,6 +238,8 @@ List of Active Tasks
 |     type                       | Operation Type                              |
 +--------------------------------+---------------------------------------------+
 
+.. _replication-settings:
+
 Replication Settings
 ====================
 
@@ -259,6 +261,18 @@ Replication Settings
 | proxy (optional)               | Address of a proxy server through which     |
 |                                | replication should occur                    |
 +--------------------------------+---------------------------------------------+
+| since_seq (optional)           | Sequence from which the replication should  |
+|                                | start                                       |
++--------------------------------+---------------------------------------------+
+| filter (optional)              | name of the filter function in the form of  |
+|                                | ddoc/myfilter                               |
++--------------------------------+---------------------------------------------+
+| query_params (optional)        | query parameter that are passed to the      |
+|                                | filter function; value should be a document |
+|                                | containing parameters as members            |
++--------------------------------+---------------------------------------------+
+
+.. _replication-status:
 
 Replication Status
 ==================

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eb364ff3/share/doc/src/replication.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/replication.rst b/share/doc/src/replication.rst
index 9245a08..9cbab50 100644
--- a/share/doc/src/replication.rst
+++ b/share/doc/src/replication.rst
@@ -12,372 +12,84 @@
 
 .. _replication:
 
-Replicator Database
-===================
+Replication
+===========
 
-A database where you ``PUT``/``POST`` documents to trigger replications
-and you ``DELETE`` to cancel ongoing replications. These documents have
-exactly the same content as the JSON objects we used to ``POST`` to
-``_replicate`` (fields ``source``, ``target``, ``create_target``,
-``continuous``, ``doc_ids``, ``filter``, ``query_params``.
+One of CouchDB's strengths is the ability to synchronize two copies of the same
+database. This enables users to distribute data across several nodes or
+datacenters, but also to move data more closely to clients.
 
-Replication documents can have a user defined ``_id``. Design documents
-(and ``_local`` documents) added to the replicator database are ignored.
+Replication involves a source and a destination database, which can be one the
+same or on different CouchDB instances. The aim of the replication is that at
+the end of the process, all active documents on the source database are also in
+the destination database and all documents that were deleted in the source
+databases are also deleted on the destination database (if they even existed).
 
-The default name of this database is ``_replicator``. The name can be
-changed in the ``local.ini`` configuration, section ``[replicator]``,
-parameter ``db``.
 
-Basics
-------
-
-Let's say you PUT the following document into ``_replicator``:
-
-.. code-block:: javascript
-
-    {
-        "_id": "my_rep",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar",
-        "create_target":  true
-    }
-
-In the couch log you'll see 2 entries like these:
-
-.. code-block:: text
-
-    [Thu, 17 Feb 2011 19:43:59 GMT] [info] [<0.291.0>] Document `my_rep` triggered replication `c0ebe9256695ff083347cbf95f93e280+create_target`
-    [Thu, 17 Feb 2011 19:44:37 GMT] [info] [<0.124.0>] Replication `c0ebe9256695ff083347cbf95f93e280+create_target` finished (triggered by document `my_rep`)
-
-As soon as the replication is triggered, the document will be updated by
-CouchDB with 3 new fields:
-
-.. code-block:: javascript
-
-    {
-        "_id": "my_rep",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar",
-        "create_target":  true,
-        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
-        "_replication_state":  "triggered",
-        "_replication_state_time":  1297974122
-    }
-
-Special fields set by the replicator start with the prefix
-``_replication_``.
-
--  ``_replication_id``
-
-   The ID internally assigned to the replication. This is also the ID
-   exposed by ``/_active_tasks``.
-
--  ``_replication_state``
-
-   The current state of the replication.
-
--  ``_replication_state_time``
-
-   A Unix timestamp (number of seconds since 1 Jan 1970) that tells us
-   when the current replication state (marked in ``_replication_state``)
-   was set.
-
-When the replication finishes, it will update the ``_replication_state``
-field (and ``_replication_state_time``) with the value ``completed``, so
-the document will look like:
-
-.. code-block:: javascript
-
-    {
-        "_id": "my_rep",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar",
-        "create_target":  true,
-        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
-        "_replication_state":  "completed",
-        "_replication_state_time":  1297974122
-    }
-
-When an error happens during replication, the ``_replication_state``
-field is set to ``error`` (and ``_replication_state`` gets updated of
-course).
-
-When you PUT/POST a document to the ``_replicator`` database, CouchDB
-will attempt to start the replication up to 10 times (configurable under
-``[replicator]``, parameter ``max_replication_retry_count``). If it
-fails on the first attempt, it waits 5 seconds before doing a second
-attempt. If the second attempt fails, it waits 10 seconds before doing a
-third attempt. If the third attempt fails, it waits 20 seconds before
-doing a fourth attempt (each attempt doubles the previous wait period).
-When an attempt fails, the Couch log will show you something like:
-
-.. code-block:: text
-
-    [error] [<0.149.0>] Error starting replication `67c1bb92010e7abe35d7d629635f18b6+create_target` (document `my_rep_2`): {db_not_found,<<"could not open http://myserver:5986/foo/">>
-
-.. note::
-   The ``_replication_state`` field is only set to ``error`` when all
-   the attempts were unsuccessful.
-
-There are only 3 possible values for the ``_replication_state`` field:
-``triggered``, ``completed`` and ``error``. Continuous replications
-never get their state set to ``completed``.
-
-Documents describing the same replication
------------------------------------------
-
-Lets suppose 2 documents are added to the ``_replicator`` database in
-the following order:
-
-.. code-block:: javascript
-
-    {
-        "_id": "doc_A",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar"
-    }
-
-and
-
-.. code-block:: javascript
-
-    {
-        "_id": "doc_B",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar"
-    }
-
-Both describe exactly the same replication (only their ``_ids`` differ).
-In this case document ``doc_A`` triggers the replication, getting
-updated by CouchDB with the fields ``_replication_state``,
-``_replication_state_time`` and ``_replication_id``, just like it was
-described before. Document ``doc_B`` however, is only updated with one
-field, the ``_replication_id`` so it will look like this:
-
-.. code-block:: javascript
-
-    {
-        "_id": "doc_B",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar",
-        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280"
-    }
-
-While document ``doc_A`` will look like this:
-
-.. code-block:: javascript
-
-    {
-        "_id": "doc_A",
-        "source":  "http://myserver.com:5984/foo",
-        "target":  "bar",
-        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
-        "_replication_state":  "triggered",
-        "_replication_state_time":  1297974122
-    }
-
-Note that both document get exactly the same value for the
-``_replication_id`` field. This way you can identify which documents
-refer to the same replication - you can for example define a view which
-maps replication IDs to document IDs.
-
-Canceling replications
+Triggering Replication
 ----------------------
 
-To cancel a replication simply ``DELETE`` the document which triggered
-the replication. The Couch log will show you an entry like the
-following:
-
-.. code-block:: text
-
-    [Thu, 17 Feb 2011 20:16:29 GMT] [info] [<0.125.0>] Stopped replication `c0ebe9256695ff083347cbf95f93e280+continuous+create_target` because replication document `doc_A` was deleted
-
-.. note::
-   You need to ``DELETE`` the document that triggered the replication.
-   ``DELETE``-ing another document that describes the same replication
-   but did not trigger it, will not cancel the replication.
-
-Server restart
---------------
-
-When CouchDB is restarted, it checks its ``_replicator`` database and
-restarts any replication that is described by a document that either has
-its ``_replication_state`` field set to ``triggered`` or it doesn't have
-yet the ``_replication_state`` field set.
-
-.. note::
-   Continuous replications always have a ``_replication_state`` field
-   with the value ``triggered``, therefore they're always restarted
-   when CouchDB is restarted.
-
-Changing the Replicator Database
---------------------------------
-
-Imagine your replicator database (default name is ``_replicator``) has the
-two following documents that represent pull replications from servers A
-and B:
-
-.. code-block:: javascript
-
-    {
-        "_id": "rep_from_A",
-        "source":  "http://aserver.com:5984/foo",
-        "target":  "foo_a",
-        "continuous":  true,
-        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
-        "_replication_state":  "triggered",
-        "_replication_state_time":  1297971311
-    }
-
-.. code-block:: javascript
-
-    {
-        "_id": "rep_from_B",
-        "source":  "http://bserver.com:5984/foo",
-        "target":  "foo_b",
-        "continuous":  true,
-        "_replication_id":  "231bb3cf9d48314eaa8d48a9170570d1",
-        "_replication_state":  "triggered",
-        "_replication_state_time":  1297974122
-    }
-
-Now without stopping and restarting CouchDB, you change the name of the
-replicator database to ``another_replicator_db``:
-
-.. code-block:: bash
-
-    $ curl -X PUT http://localhost:5984/_config/replicator/db -d '"another_replicator_db"'
-    "_replicator"
-
-As soon as this is done, both pull replications defined before, are
-stopped. This is explicitly mentioned in CouchDB's log:
-
-.. code-block:: text
-
-    [Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.104.0>] Stopping all ongoing replications because the replicator database was deleted or changed
-    [Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.127.0>] 127.0.0.1 - - PUT /_config/replicator/db 200
-
-Imagine now you add a replication document to the new replicator
-database named ``another_replicator_db``:
-
-.. code-block:: javascript
-
-    {
-        "_id": "rep_from_X",
-        "source":  "http://xserver.com:5984/foo",
-        "target":  "foo_x",
-        "continuous":  true
-    }
-
-From now own you have a single replication going on in your system: a
-pull replication pulling from server X. Now you change back the
-replicator database to the original one ``_replicator``:
-
-::
-
-    $ curl -X PUT http://localhost:5984/_config/replicator/db -d '"_replicator"'
-    "another_replicator_db"
-
-Immediately after this operation, the replication pulling from server X
-will be stopped and the replications defined in the ``_replicator``
-database (pulling from servers A and B) will be resumed.
-
-Changing again the replicator database to ``another_replicator_db`` will
-stop the pull replications pulling from servers A and B, and resume the
-pull replication pulling from server X.
-
-Replicating the replicator database
------------------------------------
-
-Imagine you have in server C a replicator database with the two
-following pull replication documents in it:
-
-.. code-block:: javascript
+Replication is controlled through documents in the :ref:`replicator`, where
+each document describes one replication process (see
+:ref:`replication-settings`).
 
-    {
-         "_id": "rep_from_A",
-         "source":  "http://aserver.com:5984/foo",
-         "target":  "foo_a",
-         "continuous":  true,
-         "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
-         "_replication_state":  "triggered",
-         "_replication_state_time":  1297971311
-    }
+A replication is triggered by storing a replication document in the replicator
+database. Its status can be inspected through the active tasks API (see
+:ref:`active-tasks` and :ref:`replication-status`). A replication can be
+stopped by deleting the document, or by updating it with its `cancel` property
+set to `true`.
 
-.. code-block:: javascript
 
-    {
-         "_id": "rep_from_B",
-         "source":  "http://bserver.com:5984/foo",
-         "target":  "foo_b",
-         "continuous":  true,
-         "_replication_id":  "231bb3cf9d48314eaa8d48a9170570d1",
-         "_replication_state":  "triggered",
-         "_replication_state_time":  1297974122
-    }
+Replication Procedure
+---------------------
 
-Now you would like to have the same pull replications going on in server
-D, that is, you would like to have server D pull replicating from
-servers A and B. You have two options:
+During replication, CouchDB will compare the source and the destination
+database to determine which documents differ between the source and the
+destination database. It does so by following the :ref:`changes` on the source
+and comparing the documents to the destination. Changes are submitted to the
+destination in batches where they can introduce conflicts. Documents that
+already exist on the destination in the same revision are not transferred. As
+the deletion of documents is represented by a new revision, a document deleted
+on the source will also be deleted on the target.
 
--  Explicitly add two documents to server's D replicator database
+A replication task will finish once it reaches the end of the changes feed. If
+its `continuous` property is set to true, it will wait for new changes to
+appear until the task is cancelled. Replication tasks also create checkpoint
+documents on the destination to ensure that a restarted task can continue from
+where it stopped, for example after it has crashed.
 
--  Replicate server's C replicator database into server's D replicator
-   database
+When a replication task is initiated on the sending node, it is called *push*
+replication, if it is initiated by the receiving node, it is called *pull*
+replication.
 
-Both alternatives accomplish exactly the same goal.
 
-Delegations
------------
+Master - Master replication
+---------------------------
 
-Replication documents can have a custom ``user_ctx`` property. This
-property defines the user context under which a replication runs. For
-the old way of triggering replications (POSTing to ``/_replicate/``),
-this property was not needed (it didn't exist in fact) - this is because
-at the moment of triggering the replication it has information about the
-authenticated user. With the replicator database, since it's a regular
-database, the information about the authenticated user is only present
-at the moment the replication document is written to the database - the
-replicator database implementation is like a ``_changes`` feed consumer
-(with ``?include_docs=true``) that reacts to what was written to the
-replicator database - in fact this feature could be implemented with an
-external script/program. This implementation detail implies that for non
-admin users, a ``user_ctx`` property, containing the user's name and a
-subset of his/her roles, must be defined in the replication document.
-This is ensured by the document update validation function present in
-the default design document of the replicator database. This validation
-function also ensure that a non admin user can set a user name property
-in the ``user_ctx`` property that doesn't match his/her own name (same
-principle applies for the roles).
+One replication task will only transfer changes in one direction. To achieve
+master-master replication it is possible to set up two replication tasks in
+different directions. When a change is replication from database A to B by the
+first task, the second will discover that the new change on B already exists in
+A and will wait for further changes.
 
-For admins, the ``user_ctx`` property is optional, and if it's missing
-it defaults to a user context with name null and an empty list of roles
-- this mean design documents will not be written to local targets. If
-writing design documents to local targets is desired, the a user context
-with the roles ``_admin`` must be set explicitly.
 
-Also, for admins the ``user_ctx`` property can be used to trigger a
-replication on behalf of another user. This is the user context that
-will be passed to local target database document validation functions.
+Controlling which Documents to Replicate
+----------------------------------------
 
-.. note::
-   The ``user_ctx`` property only has effect for local endpoints.
+There are two ways for controlling which documents are replicated, and which
+are skipped. *Local* documents are never replicated (see :ref:`api-local`).
 
-Example delegated replication document:
+Additionally, :ref:`filterfun` can be used in a replication documents (see
+:ref:`replication-settings`). The replication task will then evaluate
+the filter function for each document in the changes feed. The document will
+only be replicated if the filter returns `true`.
 
-.. code-block:: javascript
 
-    {
-         "_id": "my_rep",
-         "source":  "http://bserver.com:5984/foo",
-         "target":  "bar",
-         "continuous":  true,
-         "user_ctx": {
-              "name": "joe",
-              "roles": ["erlanger", "researcher"]
-         }
-    }
+Migrating Data to Clients
+-------------------------
 
-As stated before, for admins the ``user_ctx`` property is optional, while
-for regular (non admin) users it's mandatory. When the roles property of
-``user_ctx`` is missing, it defaults to the empty list ``[ ]``.
+Replication can be especially useful for bringing data closer to clients.
+`PouchDB <http://pouchdb.com/>`_ implements the replication algorithm of CouchDB
+in JavaScript, making it possible to make data from a CouchDB database
+available in an offline browser application, and synchronize changes back to
+CouchDB.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/eb364ff3/share/doc/src/replicator.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/replicator.rst b/share/doc/src/replicator.rst
new file mode 100644
index 0000000..1a40c65
--- /dev/null
+++ b/share/doc/src/replicator.rst
@@ -0,0 +1,383 @@
+.. 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.
+
+.. _replicator:
+
+Replicator Database
+===================
+
+A database where you ``PUT``/``POST`` documents to trigger replications
+and you ``DELETE`` to cancel ongoing replications. These documents have
+exactly the same content as the JSON objects we used to ``POST`` to
+``_replicate`` (fields ``source``, ``target``, ``create_target``,
+``continuous``, ``doc_ids``, ``filter``, ``query_params``.
+
+Replication documents can have a user defined ``_id``. Design documents
+(and ``_local`` documents) added to the replicator database are ignored.
+
+The default name of this database is ``_replicator``. The name can be
+changed in the ``local.ini`` configuration, section ``[replicator]``,
+parameter ``db``.
+
+Basics
+------
+
+Let's say you PUT the following document into ``_replicator``:
+
+.. code-block:: javascript
+
+    {
+        "_id": "my_rep",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar",
+        "create_target":  true
+    }
+
+In the couch log you'll see 2 entries like these:
+
+.. code-block:: text
+
+    [Thu, 17 Feb 2011 19:43:59 GMT] [info] [<0.291.0>] Document `my_rep` triggered replication `c0ebe9256695ff083347cbf95f93e280+create_target`
+    [Thu, 17 Feb 2011 19:44:37 GMT] [info] [<0.124.0>] Replication `c0ebe9256695ff083347cbf95f93e280+create_target` finished (triggered by document `my_rep`)
+
+As soon as the replication is triggered, the document will be updated by
+CouchDB with 3 new fields:
+
+.. code-block:: javascript
+
+    {
+        "_id": "my_rep",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar",
+        "create_target":  true,
+        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
+        "_replication_state":  "triggered",
+        "_replication_state_time":  1297974122
+    }
+
+Special fields set by the replicator start with the prefix
+``_replication_``.
+
+-  ``_replication_id``
+
+   The ID internally assigned to the replication. This is also the ID
+   exposed by ``/_active_tasks``.
+
+-  ``_replication_state``
+
+   The current state of the replication.
+
+-  ``_replication_state_time``
+
+   A Unix timestamp (number of seconds since 1 Jan 1970) that tells us
+   when the current replication state (marked in ``_replication_state``)
+   was set.
+
+When the replication finishes, it will update the ``_replication_state``
+field (and ``_replication_state_time``) with the value ``completed``, so
+the document will look like:
+
+.. code-block:: javascript
+
+    {
+        "_id": "my_rep",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar",
+        "create_target":  true,
+        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
+        "_replication_state":  "completed",
+        "_replication_state_time":  1297974122
+    }
+
+When an error happens during replication, the ``_replication_state``
+field is set to ``error`` (and ``_replication_state_time`` gets updated of
+course).
+
+When you PUT/POST a document to the ``_replicator`` database, CouchDB
+will attempt to start the replication up to 10 times (configurable under
+``[replicator]``, parameter ``max_replication_retry_count``). If it
+fails on the first attempt, it waits 5 seconds before doing a second
+attempt. If the second attempt fails, it waits 10 seconds before doing a
+third attempt. If the third attempt fails, it waits 20 seconds before
+doing a fourth attempt (each attempt doubles the previous wait period).
+When an attempt fails, the Couch log will show you something like:
+
+.. code-block:: text
+
+    [error] [<0.149.0>] Error starting replication `67c1bb92010e7abe35d7d629635f18b6+create_target` (document `my_rep_2`): {db_not_found,<<"could not open http://myserver:5986/foo/">>
+
+.. note::
+   The ``_replication_state`` field is only set to ``error`` when all
+   the attempts were unsuccessful.
+
+There are only 3 possible values for the ``_replication_state`` field:
+``triggered``, ``completed`` and ``error``. Continuous replications
+never get their state set to ``completed``.
+
+Documents describing the same replication
+-----------------------------------------
+
+Lets suppose 2 documents are added to the ``_replicator`` database in
+the following order:
+
+.. code-block:: javascript
+
+    {
+        "_id": "doc_A",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar"
+    }
+
+and
+
+.. code-block:: javascript
+
+    {
+        "_id": "doc_B",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar"
+    }
+
+Both describe exactly the same replication (only their ``_ids`` differ).
+In this case document ``doc_A`` triggers the replication, getting
+updated by CouchDB with the fields ``_replication_state``,
+``_replication_state_time`` and ``_replication_id``, just like it was
+described before. Document ``doc_B`` however, is only updated with one
+field, the ``_replication_id`` so it will look like this:
+
+.. code-block:: javascript
+
+    {
+        "_id": "doc_B",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar",
+        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280"
+    }
+
+While document ``doc_A`` will look like this:
+
+.. code-block:: javascript
+
+    {
+        "_id": "doc_A",
+        "source":  "http://myserver.com:5984/foo",
+        "target":  "bar",
+        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
+        "_replication_state":  "triggered",
+        "_replication_state_time":  1297974122
+    }
+
+Note that both document get exactly the same value for the
+``_replication_id`` field. This way you can identify which documents
+refer to the same replication - you can for example define a view which
+maps replication IDs to document IDs.
+
+Canceling replications
+----------------------
+
+To cancel a replication simply ``DELETE`` the document which triggered
+the replication. The Couch log will show you an entry like the
+following:
+
+.. code-block:: text
+
+    [Thu, 17 Feb 2011 20:16:29 GMT] [info] [<0.125.0>] Stopped replication `c0ebe9256695ff083347cbf95f93e280+continuous+create_target` because replication document `doc_A` was deleted
+
+.. note::
+   You need to ``DELETE`` the document that triggered the replication.
+   ``DELETE``-ing another document that describes the same replication
+   but did not trigger it, will not cancel the replication.
+
+Server restart
+--------------
+
+When CouchDB is restarted, it checks its ``_replicator`` database and
+restarts any replication that is described by a document that either has
+its ``_replication_state`` field set to ``triggered`` or it doesn't have
+yet the ``_replication_state`` field set.
+
+.. note::
+   Continuous replications always have a ``_replication_state`` field
+   with the value ``triggered``, therefore they're always restarted
+   when CouchDB is restarted.
+
+Changing the Replicator Database
+--------------------------------
+
+Imagine your replicator database (default name is ``_replicator``) has the
+two following documents that represent pull replications from servers A
+and B:
+
+.. code-block:: javascript
+
+    {
+        "_id": "rep_from_A",
+        "source":  "http://aserver.com:5984/foo",
+        "target":  "foo_a",
+        "continuous":  true,
+        "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
+        "_replication_state":  "triggered",
+        "_replication_state_time":  1297971311
+    }
+
+.. code-block:: javascript
+
+    {
+        "_id": "rep_from_B",
+        "source":  "http://bserver.com:5984/foo",
+        "target":  "foo_b",
+        "continuous":  true,
+        "_replication_id":  "231bb3cf9d48314eaa8d48a9170570d1",
+        "_replication_state":  "triggered",
+        "_replication_state_time":  1297974122
+    }
+
+Now without stopping and restarting CouchDB, you change the name of the
+replicator database to ``another_replicator_db``:
+
+.. code-block:: bash
+
+    $ curl -X PUT http://localhost:5984/_config/replicator/db -d '"another_replicator_db"'
+    "_replicator"
+
+As soon as this is done, both pull replications defined before, are
+stopped. This is explicitly mentioned in CouchDB's log:
+
+.. code-block:: text
+
+    [Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.104.0>] Stopping all ongoing replications because the replicator database was deleted or changed
+    [Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.127.0>] 127.0.0.1 - - PUT /_config/replicator/db 200
+
+Imagine now you add a replication document to the new replicator
+database named ``another_replicator_db``:
+
+.. code-block:: javascript
+
+    {
+        "_id": "rep_from_X",
+        "source":  "http://xserver.com:5984/foo",
+        "target":  "foo_x",
+        "continuous":  true
+    }
+
+From now own you have a single replication going on in your system: a
+pull replication pulling from server X. Now you change back the
+replicator database to the original one ``_replicator``:
+
+::
+
+    $ curl -X PUT http://localhost:5984/_config/replicator/db -d '"_replicator"'
+    "another_replicator_db"
+
+Immediately after this operation, the replication pulling from server X
+will be stopped and the replications defined in the ``_replicator``
+database (pulling from servers A and B) will be resumed.
+
+Changing again the replicator database to ``another_replicator_db`` will
+stop the pull replications pulling from servers A and B, and resume the
+pull replication pulling from server X.
+
+Replicating the replicator database
+-----------------------------------
+
+Imagine you have in server C a replicator database with the two
+following pull replication documents in it:
+
+.. code-block:: javascript
+
+    {
+         "_id": "rep_from_A",
+         "source":  "http://aserver.com:5984/foo",
+         "target":  "foo_a",
+         "continuous":  true,
+         "_replication_id":  "c0ebe9256695ff083347cbf95f93e280",
+         "_replication_state":  "triggered",
+         "_replication_state_time":  1297971311
+    }
+
+.. code-block:: javascript
+
+    {
+         "_id": "rep_from_B",
+         "source":  "http://bserver.com:5984/foo",
+         "target":  "foo_b",
+         "continuous":  true,
+         "_replication_id":  "231bb3cf9d48314eaa8d48a9170570d1",
+         "_replication_state":  "triggered",
+         "_replication_state_time":  1297974122
+    }
+
+Now you would like to have the same pull replications going on in server
+D, that is, you would like to have server D pull replicating from
+servers A and B. You have two options:
+
+-  Explicitly add two documents to server's D replicator database
+
+-  Replicate server's C replicator database into server's D replicator
+   database
+
+Both alternatives accomplish exactly the same goal.
+
+Delegations
+-----------
+
+Replication documents can have a custom ``user_ctx`` property. This
+property defines the user context under which a replication runs. For
+the old way of triggering replications (POSTing to ``/_replicate/``),
+this property was not needed (it didn't exist in fact) - this is because
+at the moment of triggering the replication it has information about the
+authenticated user. With the replicator database, since it's a regular
+database, the information about the authenticated user is only present
+at the moment the replication document is written to the database - the
+replicator database implementation is like a ``_changes`` feed consumer
+(with ``?include_docs=true``) that reacts to what was written to the
+replicator database - in fact this feature could be implemented with an
+external script/program. This implementation detail implies that for non
+admin users, a ``user_ctx`` property, containing the user's name and a
+subset of his/her roles, must be defined in the replication document.
+This is ensured by the document update validation function present in
+the default design document of the replicator database. This validation
+function also ensure that a non admin user can set a user name property
+in the ``user_ctx`` property that doesn't match his/her own name (same
+principle applies for the roles).
+
+For admins, the ``user_ctx`` property is optional, and if it's missing
+it defaults to a user context with name null and an empty list of roles
+- this mean design documents will not be written to local targets. If
+writing design documents to local targets is desired, the a user context
+with the roles ``_admin`` must be set explicitly.
+
+Also, for admins the ``user_ctx`` property can be used to trigger a
+replication on behalf of another user. This is the user context that
+will be passed to local target database document validation functions.
+
+.. note::
+   The ``user_ctx`` property only has effect for local endpoints.
+
+Example delegated replication document:
+
+.. code-block:: javascript
+
+    {
+         "_id": "my_rep",
+         "source":  "http://bserver.com:5984/foo",
+         "target":  "bar",
+         "continuous":  true,
+         "user_ctx": {
+              "name": "joe",
+              "roles": ["erlanger", "researcher"]
+         }
+    }
+
+As stated before, for admins the ``user_ctx`` property is optional, while
+for regular (non admin) users it's mandatory. When the roles property of
+``user_ctx`` is missing, it defaults to the empty list ``[ ]``.


[49/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Import couch_dbupdates from rcouch.

This creates a new top level API endpoint: `/_db_updates`
that returns a line of JSON for each database event along
with the database name.

A database event is one of `created`, `updated`, `deleted`.

The API endpoint supports a `?feed=` parameter with the
options: `longpoll`, `continuous` and `eventsource`.

A second parameter `timeout=` specifies when the server should
close the connection.

`longpoll` closes the connection after a single notification.
It is the default option.

`continuous` keeps a socket open until the specified `timeout`
or 60 seconds by default.

`heartbeat` decides whether to send a newline character on
`timeout` to avoid clients closing the connection prematurely.

`eventsource` works like continuous, but sends the data in
EventSource format. See http://dev.w3.org/html5/eventsource/

The parameters are modelled after the existing `/_changes` API
endpoint. Note that `/_db_updates` does not support resuming
of notifications via a sequence ID.

This is a port of the existing DbUpdateNotification interface
to the HTTP API.

Functional changes compared to rcouch:

 - make _db_updates an admin-only resource

Docs:

 - updated api/misc to include basic info on `/_db_updates`

License:

  Apache 2 license, updated LICENSE.

Notice:

  (c) 2012 Benoit Chesneau, updated NOTICE.

Tests:

 - only manual testing of the various API differences due to
   complications with asynchronous HTTP requests in the JS
   test suite and total annoyance of overly complicated
   ibrowse/httpc modules for writing etap tests.

Recommendation to ship this as EXPERIMENTAL until we have tests.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 700581865870e591872b9e68e3e80af128c1ba50
Parents: c40b25d
Author: Jan Lehnardt <ja...@apache.org>
Authored: Mon Mar 4 12:02:24 2013 +0100
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Mon Jul 22 12:00:26 2013 +0200

----------------------------------------------------------------------
 LICENSE                                         |  7 ++
 NOTICE                                          |  3 +
 configure.ac                                    |  1 +
 etc/couchdb/default.ini.tpl.in                  |  1 +
 license.skip                                    |  1 +
 share/doc/src/api/misc.rst                      | 62 ++++++++++++++++++
 src/Makefile.am                                 |  1 +
 src/couch_dbupdates/LICENSE                     | 22 +++++++
 src/couch_dbupdates/Makefile.am                 | 33 ++++++++++
 src/couch_dbupdates/NOTICE                      |  6 ++
 src/couch_dbupdates/README.md                   | 32 +++++++++
 src/couch_dbupdates/src/couch_dbupdates.app.src | 11 ++++
 src/couch_dbupdates/src/couch_dbupdates.erl     | 46 +++++++++++++
 .../src/couch_dbupdates_httpd.erl               | 69 ++++++++++++++++++++
 14 files changed, 295 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index d488036..31ed94d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -605,6 +605,7 @@ For the share/server/coffee-script.js file
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   OTHER DEALINGS IN THE SOFTWARE.
 
+<<<<<<< HEAD
 For src/fauxton/apps/modules/pouchdb
 
   Copyright (c) 2012 Dale Harvey et al
@@ -889,3 +890,9 @@ For src/fauxton/assets/js/plugins/codemirror-javascript.js
 	Please note that some subdirectories of the CodeMirror distribution
 	include their own LICENSE files, and are released under different
 	licences.
+
+For the src/couch_dbupdates component
+
+  2009-2012 (c) Benoît Chesneau <be...@e-engura.org>
+
+  Apache 2 License, see above.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 8379f97..0d1407e 100644
--- a/NOTICE
+++ b/NOTICE
@@ -86,6 +86,7 @@ This product also includes the following third-party components:
 
    Copyright 2012, Jeremy Ashkenas
 
+<<<<<<< HEAD
  * almond.js (http://github.com/jrburke/almond)
 
   Copyright 2011, The Dojo Foundation
@@ -142,4 +143,6 @@ This product also includes the following third-party components:
 
    Copyright 2006-2013 (c) M. Alsup
 
+ * couch_dbupdates
 
+   Copyright 2012, Benoît Chesneau <be...@refuge.io>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 92a1643..9b1b758 100644
--- a/configure.ac
+++ b/configure.ac
@@ -722,6 +722,7 @@ AC_CONFIG_FILES([share/Makefile])
 AC_CONFIG_FILES([share/doc/Makefile])
 AC_CONFIG_FILES([share/doc/build/Makefile])
 AC_CONFIG_FILES([src/Makefile])
+AC_CONFIG_FILES([src/couch_dbupdates/Makefile])
 AC_CONFIG_FILES([src/couch_index/Makefile])
 AC_CONFIG_FILES([src/couch_mrview/Makefile])
 AC_CONFIG_FILES([src/couch_replicator/Makefile])

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index 5eb7ebc..43b13a0 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -159,6 +159,7 @@ _stats = {couch_httpd_stats_handlers, handle_stats_req}
 _log = {couch_httpd_misc_handlers, handle_log_req}
 _session = {couch_httpd_auth, handle_session_req}
 _oauth = {couch_httpd_oauth, handle_oauth_req}
+_db_updates = {couch_dbupdates_httpd, handle_req}
 
 [httpd_db_handlers]
 _all_docs = {couch_mrview_http, handle_all_docs_req}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/license.skip
----------------------------------------------------------------------
diff --git a/license.skip b/license.skip
index db08c31..b398ff7 100644
--- a/license.skip
+++ b/license.skip
@@ -98,6 +98,7 @@
 ^src/couchdb/priv/couchspawnkillable
 ^src/couchdb/priv/stat_descriptions.cfg
 ^src/erlang-oauth/.*
+^src/couch_dbupdates
 ^src/ejson/.*
 ^src/etap/.*
 ^src/fauxton/app/app.js

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/share/doc/src/api/misc.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/api/misc.rst b/share/doc/src/api/misc.rst
index f9562ae..faac880 100644
--- a/share/doc/src/api/misc.rst
+++ b/share/doc/src/api/misc.rst
@@ -33,6 +33,8 @@ A list of the available methods and URL paths are provided below:
 +--------+-------------------------+-------------------------------------------+
 | GET    | /_all_dbs               |  Get a list of all the DBs                |
 +--------+-------------------------+-------------------------------------------+
+| GET    | /_db_updates            |  A feed of database events                |
++--------+-------------------------+-------------------------------------------+
 | GET    | /_log                   |  Return the server log file               |
 +--------+-------------------------+-------------------------------------------+
 | POST   | /_replicate             |  Set or cancel replication                |
@@ -153,6 +155,66 @@ The return is a JSON array:
        "locations"
     ]
 
+``GET /_db_updates``
+====================
+
+* **Method**: ``GET /_db_updates``
+* **Request**: None
+* **Admin Privileges Required**: yes
+* **Query ARguments**:
+
+  * **Argument**: feed
+
+    * **Descroption**: Format of the response feed
+    * **Optional**: yes
+    * **Type**: string
+    * **Default**: longpoll
+    * **Supported Values**:
+
+      * **longpoll**: Closes the connection after the first event.
+      * **continuous**: Send a line of JSON per event. Keeps the socket open until ``timeout``.
+      * **eventsource**: Like, ``continuous``, but sends the events in EventSource format. See http://dev.w3.org/html5/eventsource/ for details,
+
+  * **Argument**: timeout
+
+    * **Descroption**: Number of seconds until CouchDB closes the connection.
+    * **Optional**: yes
+    * **Type**: numeric
+    * **Default**: 60
+
+  * **Argument**: heartbeat
+
+    * **Descroption**: Whether CouchDB will send a newline character (``\n``) on ``timeout``.
+    * **Optional**: yes
+    * **Type**: boolean
+    * **Default**: true
+
+* **Return Codes**:
+
+  * **200**
+    Request completed successfully.
+
+Returns a list of all database events in the CouchDB instance.
+
+A database event is one of `created`, `updated`, `deleted`.
+
+For example:
+
+.. code-block:: http
+
+    GET http://couchdb:5984/_db_events?feed=continuous
+    Accept: application/json
+
+.. code-block:: javascript
+
+    {"dbname":"my-database", "type":"created"}
+    {"dbname":"my-database", "type":"updated"}
+    {"dbname":"another-database", "type":"created"}
+    {"dbname":"my-database", "type":"deleted"}
+    {"dbname":"another-database", "type":"updated"}
+
+
+
 ``GET /_log``
 =============
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index fbd514c..7b11e15 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@
 ## the License.
 
 SUBDIRS = \
+    couch_dbupdates \
     couch_index \
     couch_mrview \
     couch_replicator \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/LICENSE
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/LICENSE b/src/couch_dbupdates/LICENSE
new file mode 100644
index 0000000..a089916
--- /dev/null
+++ b/src/couch_dbupdates/LICENSE
@@ -0,0 +1,22 @@
+2009-2012 (c) Benoît Chesneau <be...@e-engura.org>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/Makefile.am
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/Makefile.am b/src/couch_dbupdates/Makefile.am
new file mode 100644
index 0000000..d131b9b
--- /dev/null
+++ b/src/couch_dbupdates/Makefile.am
@@ -0,0 +1,33 @@
+## 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.
+
+couch_dbupdateslibdir = $(localerlanglibdir)/couch_dbupdates-0.1
+couch_dbupdatesebindir = $(couch_dbupdateslibdir)/ebin
+
+couch_dbupdatesebin_DATA = $(compiled_files)
+
+EXTRA_DIST = $(source_files)
+CLEANFILES = $(compiled_files)
+
+source_files = \
+    src/couch_dbupdates.erl \
+    src/couch_dbupdates.app.src \
+    src/couch_dbupdates_httpd.erl
+
+compiled_files = \
+    ebin/couch_dbupdates.beam \
+    ebin/couch_dbupdates_httpd.beam
+
+ebin/%.beam: src/%.erl
+	@mkdir -p ebin/
+	$(ERLC) -I$(top_srcdir)/src/couchdb -o ebin/ $(ERLC_FLAGS) ${TEST} $<;
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/NOTICE
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/NOTICE b/src/couch_dbupdates/NOTICE
new file mode 100644
index 0000000..ee00a85
--- /dev/null
+++ b/src/couch_dbupdates/NOTICE
@@ -0,0 +1,6 @@
+couch_dbupdates
+---------------
+
+2012 (c) Benoît Chesneau <be...@refuge.io>
+
+couch_dbupdates is released under the Apache License 2.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/README.md
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/README.md b/src/couch_dbupdates/README.md
new file mode 100644
index 0000000..c683102
--- /dev/null
+++ b/src/couch_dbupdates/README.md
@@ -0,0 +1,32 @@
+# couch_dbupdates
+
+`couch_dbupdates` is a simple couchdb modules to receive databases
+events in couchdb node.
+
+It's actually **supported by all the [refuge](http://refuge.io) projects**:
+
+- [refuge](https://github.com/refuge/refuge)
+- [rcouch](https://github.com/refuge/rcouch)
+- [rcouch_template](https://github.com/refuge/rcouch_template)
+
+
+## HTTP API
+
+To get db events, do a GET to `/_db_updates` .
+
+You can pass an optional query parameters:
+
+* `feed` The feed can be `longpoll` (default) for longpolling, `eventsource`
+  for event stream or `continuous` for continuous feed.
+* `timeout`: timeout before the longpolling connection close or when the
+  heartbeat is emitted.
+* `heartbeat`: true, or false. an empty line is emittend when the
+  timeout occurs to maintain the connection active.
+
+
+## Example of usage
+
+    $ curl http://127.0.0.1:5984/_db_updates?feed=continuous
+    {"type":"created","db_name":"testdb"}
+    {"type":"updated","db_name":"testdb"}
+    {"type":"deleted","db_name":"testdb"}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/src/couch_dbupdates.app.src
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/src/couch_dbupdates.app.src b/src/couch_dbupdates/src/couch_dbupdates.app.src
new file mode 100644
index 0000000..c420283
--- /dev/null
+++ b/src/couch_dbupdates/src/couch_dbupdates.app.src
@@ -0,0 +1,11 @@
+{application, couch_dbupdates,
+ [
+  {description, ""},
+  {vsn, "@version@"},
+  {registered, []},
+  {applications, [
+                  kernel,
+                  stdlib
+                 ]},
+  {env, []}
+ ]}.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/src/couch_dbupdates.erl
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/src/couch_dbupdates.erl b/src/couch_dbupdates/src/couch_dbupdates.erl
new file mode 100644
index 0000000..e37362f
--- /dev/null
+++ b/src/couch_dbupdates/src/couch_dbupdates.erl
@@ -0,0 +1,46 @@
+-module(couch_dbupdates).
+
+-export([handle_dbupdates/3]).
+
+
+handle_dbupdates(Fun, Acc, Options) ->
+    NotifierPid = db_update_notifier(),
+    try
+        loop(Fun, Acc, Options)
+    after
+        couch_db_update_notifier:stop(NotifierPid)
+    end.
+
+
+loop(Fun, Acc, Options) ->
+    [{timeout, Timeout}, {heartbeat, Heartbeat}] = Options,
+    receive
+        {db_updated, Event} ->
+            case Fun(Event, Acc) of
+                {ok, Acc1} ->
+                    loop(Fun, Acc1, Options);
+                stop ->
+                    Fun(stop, Acc)
+
+            end
+    after Timeout ->
+        case Heartbeat of
+            true ->
+                case Fun(heartbeat, Acc) of
+                {ok, Acc1} ->
+                    loop(Fun, Acc1, Options);
+                stop ->
+                    Fun(stop, Acc)
+
+                end;
+            _ ->
+                Fun(stop, Acc)
+        end
+    end.
+
+db_update_notifier() ->
+    Self = self(),
+    {ok, Notifier} = couch_db_update_notifier:start_link(fun(Event) ->
+        Self ! {db_updated, Event}
+    end),
+    Notifier.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/70058186/src/couch_dbupdates/src/couch_dbupdates_httpd.erl
----------------------------------------------------------------------
diff --git a/src/couch_dbupdates/src/couch_dbupdates_httpd.erl b/src/couch_dbupdates/src/couch_dbupdates_httpd.erl
new file mode 100644
index 0000000..96058d3
--- /dev/null
+++ b/src/couch_dbupdates/src/couch_dbupdates_httpd.erl
@@ -0,0 +1,69 @@
+-module(couch_dbupdates_httpd).
+
+-export([handle_req/1]).
+
+-include_lib("couch_db.hrl").
+
+-record(state, {resp, feed}).
+
+handle_req(#httpd{method='GET'}=Req) ->
+    ok = couch_httpd:verify_is_server_admin(Req),
+    Qs = couch_httpd:qs(Req),
+    Feed = proplists:get_value("feed", Qs, "longpoll"),
+
+    Timeout = list_to_integer(
+                proplists:get_value("timeout", Qs, "60000")
+    ),
+
+    Heartbeat0 = proplists:get_value("heartbeat", Qs),
+    Heartbeat = case {Feed, Heartbeat0} of
+        {"longpoll", _} -> false;
+        {_, "false"} -> false;
+        _ -> true
+    end,
+
+    Options = [{timeout, Timeout}, {heartbeat, Heartbeat}],
+
+    {ok, Resp} = case Feed of
+        "eventsource" ->
+            Headers = [
+                {"Content-Type", "text/event-stream"},
+                {"Cache-Control", "no-cache"}
+            ],
+            couch_httpd:start_json_response(Req, 200, Headers);
+        _ ->
+            couch_httpd:start_json_response(Req, 200)
+    end,
+
+    State = #state{resp=Resp, feed=Feed},
+    couch_dbupdates:handle_dbupdates(fun handle_update/2,
+                                     State, Options).
+
+handle_req(Req, _Db) ->
+    couch_httpd:send_method_not_allowed(Req, "GET").
+
+handle_update(stop, #state{resp=Resp}) ->
+    couch_httpd:end_json_response(Resp);
+handle_update(heartbeat, #state{resp=Resp}=State) ->
+    {ok, Resp1} = couch_httpd:send_chunk(Resp, "\n"),
+    {ok, State#state{resp=Resp1}};
+handle_update(Event, #state{resp=Resp, feed="eventsource"}=State) ->
+    EventObj = event_obj(Event),
+    {ok, Resp1} = couch_httpd:send_chunk(Resp, ["data: ",
+                                                ?JSON_ENCODE(EventObj),
+                                                "\n\n"]),
+    {ok, State#state{resp=Resp1}};
+handle_update(Event, #state{resp=Resp, feed="continuous"}=State) ->
+    EventObj = event_obj(Event),
+    {ok, Resp1} = couch_httpd:send_chunk(Resp, [?JSON_ENCODE(EventObj) |
+                            "\n"]),
+    {ok, State#state{resp=Resp1}};
+handle_update(Event, #state{resp=Resp, feed="longpoll"}) ->
+    {Props} = event_obj(Event),
+    JsonObj = {[{<<"ok">>, true} | Props]},
+    couch_httpd:send_chunk(Resp, ?JSON_ENCODE(JsonObj)),
+    stop.
+
+event_obj({Type, DbName}) ->
+    {[{<<"type">>, couch_util:to_binary(Type)},
+      {<<"db_name">>, couch_util:to_binary(DbName)}]}.


[44/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Copy preliminary 1.4 changelog items to docs.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 89efb747c9ebc7a412ee5be91dbaa90a8849bcb7
Parents: 9b64526
Author: Dirkjan Ochtman <dj...@apache.org>
Authored: Thu Jul 18 14:27:04 2013 +0200
Committer: Dirkjan Ochtman <dj...@apache.org>
Committed: Thu Jul 18 14:27:04 2013 +0200

----------------------------------------------------------------------
 share/doc/src/changelog.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/89efb747/share/doc/src/changelog.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/changelog.rst b/share/doc/src/changelog.rst
index b933b9a..de61621 100644
--- a/share/doc/src/changelog.rst
+++ b/share/doc/src/changelog.rst
@@ -17,6 +17,25 @@ Release History
    :depth: 1
    :local:
 
+1.4.x Branch
+============
+
+.. contents::
+   :depth: 1
+   :local:
+
+Upgrade Notes
+-------------
+
+We now support Erlang/OTP R16; the minimum required version is R14B.
+
+Version 1.4.0
+-------------
+
+* Bumped Mochiweb dependency to 2.4.2.
+* Disabled link to the Futon test suite.
+* Split up replicator_db tests into multiple independent tests.
+
 1.3.x Branch
 ============
 


[29/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
move watch files to settings.json


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

Branch: refs/heads/1684-feature-db-updates
Commit: f4b27ceb4e2c496f74c0347e224520397b4659b5
Parents: 8d7ab8b
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Jun 27 16:23:28 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Jun 27 16:23:28 2013 +0200

----------------------------------------------------------------------
 src/fauxton/Gruntfile.js          | 2 +-
 src/fauxton/settings.json.default | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/f4b27ceb/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index b76ae24..35a2c67 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -206,7 +206,7 @@ module.exports = function(grunt) {
     },
 
     watch: {
-      files: './app/**/*',
+      files: helper.readSettingsFile().watch.files,
       tasks: ['debug', 'template']
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f4b27ceb/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 9716ceb..051e3fb 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -24,5 +24,9 @@
           "okay_if_missing": true
         }
       }
+    },
+
+    "watch": {
+      "files": ["./app/**/*"]
     }
 }


[04/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Distribute test_setup.js


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

Branch: refs/heads/1684-feature-db-updates
Commit: 86dd4eadf7b96ecb861e94ff4570248b2936a556
Parents: fed3302
Author: Noah Slater <ns...@apache.org>
Authored: Tue May 28 21:35:08 2013 +0100
Committer: Noah Slater <ns...@apache.org>
Committed: Tue May 28 21:35:36 2013 +0100

----------------------------------------------------------------------
 test/javascript/Makefile.am | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/86dd4ead/test/javascript/Makefile.am
----------------------------------------------------------------------
diff --git a/test/javascript/Makefile.am b/test/javascript/Makefile.am
index d7367e0..e7036ca 100644
--- a/test/javascript/Makefile.am
+++ b/test/javascript/Makefile.am
@@ -13,6 +13,7 @@
 EXTRA_DIST = \
 	cli_runner.js \
 	couch_http.js \
+	test_setup.js \
 	run.tpl
 
 noinst_SCRIPTS = run


[02/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Forward port 1.3.1 changes


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

Branch: refs/heads/1684-feature-db-updates
Commit: 06b9aa50abdb572a98e44cfff4b7e89bf01e2fbc
Parents: cd42fa0
Author: Noah Slater <ns...@apache.org>
Authored: Tue May 28 21:03:03 2013 +0100
Committer: Noah Slater <ns...@apache.org>
Committed: Tue May 28 21:03:03 2013 +0100

----------------------------------------------------------------------
 CHANGES                     | 27 ++++++++++++---------------
 NEWS                        | 16 +++++++---------
 share/doc/src/changelog.rst | 28 ++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/06b9aa50/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 08cb160..fd8187b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,29 +20,26 @@ Apache CouchDB CHANGES
 #  * Bump Mochiweb dependency to v2.4.2.
 #  * Minimum Erlang/OTP version is now R14B.
 
-# Version 1.3.1
-# -------------
-#
-# This version has not been released yet.
+Version 1.3.1
+-------------
 
-# Replicator:
+Replicator:
 
-#  * Tolerate missing source and target fields in _replicator docs
-  (COUCHDB-1788).
+ * Tolerate missing source and target fields in _replicator docs (COUCHDB-1788).
 
-# Log System:
+Log System:
 
-#  * Don't log about missing .compact files.
-#  * Fix bug in WARN level logging from 1.3.0 (COUCHDB-1794).
+ * Don't log about missing .compact files.
+ * Fix bug in WARN level logging from 1.3.0 (COUCHDB-1794).
 
-# View Server:
+View Server:
 
-#  * Fix the -S option to couchjs to increase memory limits (COUCHDB-1792).
+ * Fix the -S option to couchjs to increase memory limits (COUCHDB-1792).
 
-# Misc:
+Misc:
 
-#  * Improve documentation: better structure, improve language, less duplication.
-#  * Improvements to test suite and VPATH build system.
+ * Improve documentation: better structure, improve language, less duplication.
+ * Improvements to test suite and VPATH build system.
 
 Version 1.3.0
 -------------

http://git-wip-us.apache.org/repos/asf/couchdb/blob/06b9aa50/NEWS
----------------------------------------------------------------------
diff --git a/NEWS b/NEWS
index efa79aa..ee45eff 100644
--- a/NEWS
+++ b/NEWS
@@ -16,16 +16,14 @@ Each release section notes when backwards incompatible changes have been made.
 #  * Bump Mochiweb dependency to v2.4.2.
 #  * Minimum Erlang/OTP version is now R14B.
 
-# Version 1.3.1
-# -------------
-#
-# This version has not been released yet.
+Version 1.3.1
+-------------
 
-#  * Tolerate missing source and target fields in _replicator docs.
-#  * Don't log about missing .compact files.
-#  * Fix bug in WARN level logging from 1.3.0.
-#  * Improve documentation: better structure, improve language, less duplication.
-#  * Improvements to test suite.
+ * Tolerate missing source and target fields in _replicator docs.
+ * Don't log about missing .compact files.
+ * Fix bug in WARN level logging from 1.3.0.
+ * Improve documentation: better structure, improve language, less duplication.
+ * Improvements to test suite.
 
 Version 1.3.0
 -------------

http://git-wip-us.apache.org/repos/asf/couchdb/blob/06b9aa50/share/doc/src/changelog.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/changelog.rst b/share/doc/src/changelog.rst
index 2f2334d..b933b9a 100644
--- a/share/doc/src/changelog.rst
+++ b/share/doc/src/changelog.rst
@@ -43,6 +43,34 @@ CouchDB 1.0.x release.
    CouchDB 1.0.x you must back up your data files before performing the
    upgrade and compaction process.
 
+Version 1.3.1
+-------------
+
+Replicator
+^^^^^^^^^^
+
+* :issue:`1788`: Tolerate missing source and target fields in _replicator docs.
+  :commit:`869f42e2`
+
+Log System
+^^^^^^^^^^
+
+* Don't log about missing .compact files. :commit:`06f1a8dc`
+* :issue:`1794`: Fix bug in WARN level logging from 1.3.0.
+
+View Server
+^^^^^^^^^^^
+
+* :issue:`1792`: Fix the -S option to couchjs to increase memory limits.
+  :commit:`cfaa66cd`
+
+Miscellaneous
+^^^^^^^^^^^^^
+
+* Improve documentation: better structure, improve language, less duplication.
+* :issue:`1784`: Improvements to test suite and VPATH build system.
+  :commit:`01afaa4f`
+
 Version 1.3.0
 -------------
 


[12/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Show view request duration amd goto doc id

This is for issues #1812 and #1810.


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

Branch: refs/heads/1684-feature-db-updates
Commit: c984eadde8e93dd8d693d65b0575035a55d177f8
Parents: 9cace04
Author: Garren Smith <ga...@gmail.com>
Authored: Thu May 30 11:14:32 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jun 4 15:46:39 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js  | 45 +++++++++++++++++++-
 src/fauxton/app/modules/documents/routes.js     |  3 +-
 src/fauxton/app/modules/documents/views.js      | 26 ++++++++---
 .../app/templates/documents/all_docs_list.html  |  5 +++
 .../app/templates/documents/sidebar.html        | 18 ++++++--
 src/fauxton/assets/less/database.less           |  5 +++
 6 files changed, 91 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 7bfee3d..8fc384e 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -299,7 +299,9 @@ function(app, FauxtonAPI) {
     },
 
     parse: function(resp) {
-      that = this;
+      this.endTime = new Date().getTime();
+      this.requestDuration = (this.endTime - this.startTime);
+
       this.viewMeta = {
         total_rows: resp.total_rows,
         offest: resp.offest,
@@ -319,10 +321,50 @@ function(app, FauxtonAPI) {
       this.fetch();
     },
 
+    // We implement our own fetch to store the starttime so we that
+    // we can get the request duration
+    fetch: function () {
+      this.startTime = new Date().getTime();
+      return Backbone.Collection.prototype.fetch.call(this);
+    },
+
     allDocs: function(){
       return this.models;
+    },
+
+    // This is taken from futon.browse.js $.timeString
+    requestDurationInString: function () {
+      var ms, sec, min, h, timeString, milliseconds = this.requestDuration;
+
+      sec = Math.floor(milliseconds / 1000.0);
+      min = Math.floor(sec / 60.0);
+      sec = (sec % 60.0).toString();
+      if (sec.length < 2) {
+         sec = "0" + sec;
+      }
+
+      h = (Math.floor(min / 60.0)).toString();
+      if (h.length < 2) {
+        h = "0" + h;
+      }
+
+      min = (min % 60.0).toString();
+      if (min.length < 2) {
+        min = "0" + min;
+      }
+
+      timeString = h + ":" + min + ":" + sec;
+
+      ms = (milliseconds % 1000.0).toString();
+      while (ms.length < 3) {
+        ms = "0" + ms;
+      }
+      timeString += "." + ms;
+
+      return timeString;
     }
   });
+
   
   Documents.PouchIndexCollection = Backbone.Collection.extend({
     model: Documents.ViewRow,
@@ -355,7 +397,6 @@ function(app, FauxtonAPI) {
     },
 
     totalRows: function() {
-      console.log(this);
       return this.viewMeta.total_rows || "unknown";
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index e02ac93..5a44c0e 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -115,7 +115,8 @@ function(app, FauxtonAPI, Documents, Databases) {
       });
 
       this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
-        collection: this.data.designDocs
+        collection: this.data.designDocs,
+        database: this.data.database
       }));
 
       this.setView("#tabs", new Documents.Views.Tabs({

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index af85134..f8c7447 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -318,12 +318,19 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
         updateSeq = this.collection.updateSeq();
       }
 
-      return {
+      var info = {
         updateSeq: updateSeq,
         totalRows: totalRows,
         numModels: this.collection.models.length,
-        viewList: this.viewList
+        viewList: this.viewList,
+        requestDuration: null
       };
+
+      if (this.collection.requestDurationInString) {
+        info.requestDuration = this.collection.requestDurationInString();
+      }
+
+      return info;
     },
 
     /*
@@ -550,7 +557,9 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
     },
 
     establish: function () {
-      return this.ddocInfo.fetch();
+      if (this.ddocInfo) {
+        return this.ddocInfo.fetch();
+      }
     },
 
     updateDesignDoc: function () {
@@ -1003,10 +1012,12 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
   Views.Sidebar = FauxtonAPI.View.extend({
     template: "templates/documents/sidebar",
     events: {
-      "click a.new#index": "newIndex"
+      "click a.new#index": "newIndex",
+      "submit #jump-to-doc": "jumpToDoc"
     },
 
     initialize: function(options) {
+      this.database = options.database;
       if (options.ddocInfo) {
         this.ddocID = options.ddocInfo.id;
         this.currView = options.ddocInfo.currView;
@@ -1039,6 +1050,12 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
       app.router.navigate(url);
     },
 
+    jumpToDoc: function (event) {
+      event.preventDefault();
+      var docId = this.$('#jump-to-doc-id').val();
+      FauxtonAPI.navigate('/database/' + this.database.id +'/' + docId, {trigger: true});
+    },
+
     buildIndexList: function(collection, selector, design){
 
       _.each(_.keys(collection), function(key){
@@ -1123,7 +1140,6 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
       if (this.intervalId) { return ; }
 
       this.intervalId = setInterval(function () {
-        console.log('refreshing');
         model.fetch();
       }, this.refreshTime);
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_list.html b/src/fauxton/app/templates/documents/all_docs_list.html
index 9f4ffdd..c0a0d40 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -33,6 +33,11 @@ the License.
     <% 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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/app/templates/documents/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/sidebar.html b/src/fauxton/app/templates/documents/sidebar.html
index b573725..df75311 100644
--- a/src/fauxton/app/templates/documents/sidebar.html
+++ b/src/fauxton/app/templates/documents/sidebar.html
@@ -13,10 +13,22 @@ the License.
 -->
 
 <div id="sidenav">
-  <a class="btn btn-small new" id="doc" href="#<%= database.url('app') %>/new"><i class="icon-file"></i> New doc</a>
-  <div class="btn-group" id="new-index">
-    <a class="btn btn-small" href="#<%= database.url('app') %>/new_view">New view</a>
+  <div class="row-fluid">
+    <div class="span4">
+      <a class="btn btn-small new" id="doc" href="#<%= database.url('app') %>/new"><i class="icon-file"></i> New doc</a>
+      <div class="btn-group" id="new-index">
+        <a class="btn btn-small" href="#<%= database.url('app') %>/new_view">New view</a>
+      </div>
+    </div>
+    <div class="span6">
+      <form id="jump-to-doc" class="form-inline">
+        <label> Jump To: 
+          <input type="text" id="jump-to-doc-id" class="input-small" placeholder="Document Id"></input>
+        </label>
+      </form>
+    </div>
   </div>
+
   <hr>
   <ul class="nav nav-list">
     <li class="active"><a id="all-docs" href="#<%= database.url('index') %>?limit=100" class="toggle-view"><i class="icon-list"></i> All documents</a></li>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c984eadd/src/fauxton/assets/less/database.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/database.less b/src/fauxton/assets/less/database.less
index 74a990f..4ce41f8 100644
--- a/src/fauxton/assets/less/database.less
+++ b/src/fauxton/assets/less/database.less
@@ -161,3 +161,8 @@
 }
 
 .loading {display: none;}
+
+.view-request-duration {
+  padding-right: 10px;
+  float: right;
+}


[26/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Revert "fix perms on install instructions"

This reverts commit 9cf9b53d2cee9976a5b215af52672838abec0d6b.


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

Branch: refs/heads/1684-feature-db-updates
Commit: 5b7e4bd0a5dc19f1adafb555ed712e8892fad965
Parents: 9cf9b53
Author: Jan Lehnardt <ja...@apache.org>
Authored: Thu Jun 20 23:56:27 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Thu Jun 20 23:56:27 2013 +0200

----------------------------------------------------------------------
 INSTALL.Unix | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5b7e4bd0/INSTALL.Unix
----------------------------------------------------------------------
diff --git a/INSTALL.Unix b/INSTALL.Unix
index 76ba8eb..854fd13 100644
--- a/INSTALL.Unix
+++ b/INSTALL.Unix
@@ -230,10 +230,10 @@ Change the ownership of the CouchDB directories by running:
 
 Change the permission of the CouchDB directories by running:
 
-    chmod 0755 /usr/local/etc/couchdb
-    chmod 0755 /usr/local/var/lib/couchdb
-    chmod 0755 /usr/local/var/log/couchdb
-    chmod 0755 /usr/local/var/run/couchdb
+    chmod 0770 /usr/local/etc/couchdb
+    chmod 0770 /usr/local/var/lib/couchdb
+    chmod 0770 /usr/local/var/log/couchdb
+    chmod 0770 /usr/local/var/run/couchdb
 
 Running as a Daemon
 -------------------


[48/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
remove more build-system traces of NEWS & CHANGES


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

Branch: refs/heads/1684-feature-db-updates
Commit: c40b25dfc69c23e63441af579b7cb9972820038f
Parents: 77b44e0
Author: Jan Lehnardt <ja...@apache.org>
Authored: Thu Jul 18 15:00:28 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Thu Jul 18 15:00:28 2013 +0200

----------------------------------------------------------------------
 Makefile.am | 10 ----------
 1 file changed, 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c40b25df/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index 8703a30..debfdf4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,13 +17,11 @@ ACLOCAL_AMFLAGS = -I m4
 localdoc_DATA = \
     AUTHORS.gz \
     BUGS.gz \
-    CHANGES.gz \
     DEVELOPERS.gz \
     INSTALL.gz \
     INSTALL.Unix.gz \
     INSTALL.Windows.gz \
     LICENSE.gz \
-    NEWS.gz \
     NOTICE.gz \
     README.gz \
     THANKS.gz
@@ -33,13 +31,11 @@ DISTCLEANFILES = $(localdoc_DATA)
 EXTRA_DIST = \
     AUTHORS \
     BUGS \
-    CHANGES \
     DEVELOPERS \
     INSTALL \
     INSTALL.Unix \
     INSTALL.Windows \
     LICENSE \
-    NEWS \
     NOTICE \
     README.rst \
     THANKS \
@@ -54,9 +50,6 @@ AUTHORS.gz: AUTHORS
 BUGS.gz: BUGS
 	gzip -9 < $< > $@
 
-CHANGES.gz: CHANGES
-	gzip -9 < $< > $@
-
 DEVELOPERS.gz: DEVELOPERS
 	gzip -9 < $< > $@
 
@@ -72,9 +65,6 @@ INSTALL.Windows.gz: INSTALL.Windows
 LICENSE.gz: LICENSE
 	gzip -9 < $< > $@
 
-NEWS.gz: NEWS
-	gzip -9 < $< > $@
-
 NOTICE.gz: NOTICE
 	gzip -9 < $< > $@
 


[11/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton wrap codemirror errors in try catch.


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

Branch: refs/heads/1684-feature-db-updates
Commit: df23be9339140dd0631db2f9a42c31587e78b3f3
Parents: c984ead
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jun 4 15:13:32 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jun 4 15:46:39 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/views.js | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/df23be93/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index f8c7447..93f06f1 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -477,8 +477,11 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          //throwing errors at the moment
-          //that.runJSHint();
+          try {
+            that.runJSHint();
+          } catch (e) {
+            console.log('ERROR for jshint',e);
+          }
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveDoc(); },
@@ -950,7 +953,11 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          //that.runJSHint("mapEditor");
+          try {
+            that.runJSHint("mapEditor");
+          } catch (e) {
+            console.log('ERROR for jshint',e);
+          }
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveView(); },
@@ -963,7 +970,11 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
         matchBrackets: true,
         lineWrapping: true,
         onChange: function() {
-          //that.runJSHint("reduceEditor");
+          try {
+            that.runJSHint("reduceEditor");
+          } catch (e) {
+            console.log('ERROR for jshint',e);
+          }
         },
         extraKeys: {
           "Ctrl-S": function(instance) { that.saveView(); },


[36/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fauxton: remove route events from main.js


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

Branch: refs/heads/1684-feature-db-updates
Commit: c86d73f03a640b50efe46da79baeba482db12b08
Parents: 5f86eca
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jul 2 09:38:39 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jul 2 09:38:39 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/main.js | 33 ++++++++++++---------------------
 1 file changed, 12 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c86d73f0/src/fauxton/app/main.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js
index 203b295..2f8f8fa 100644
--- a/src/fauxton/app/main.js
+++ b/src/fauxton/app/main.js
@@ -1,9 +1,9 @@
 require([
-  // Application.
-  "app",
+        // Application.
+        "app",
 
-  // Main Router.
-  "router"
+        // Main Router.
+        "router"
 ],
 
 function(app, Router) {
@@ -23,25 +23,16 @@ function(app, Router) {
     // Get the absolute root.
     var root = location.protocol + "//" + location.host + app.root;
 
-    var routeEvent = $(this).attr("route-event");
-    if (routeEvent) {
+    // Ensure the root is part of the anchor href, meaning it's relative.
+    if (href.prop && href.prop.slice(0, root.length) === root) {
+      // Stop the default event to ensure the link will not cause a page
+      // refresh.
       evt.preventDefault();
-      // TODO:: change to false when route events are functional
-      Backbone.history.navigate(href.attr, true);
-      // Trigger  route events after update of history so that we can get params from url
-      app.router.triggerRouteEvent("route:"+routeEvent, href);
-    } else {
-      // Ensure the root is part of the anchor href, meaning it's relative.
-      if (href.prop && href.prop.slice(0, root.length) === root) {
-        // Stop the default event to ensure the link will not cause a page
-        // refresh.
-        evt.preventDefault();
 
-        // `Backbone.history.navigate` is sufficient for all Routers and will
-        // trigger the correct events. The Router's internal `navigate` method
-        // calls this anyways.  The fragment is sliced from the root.
-        Backbone.history.navigate(href.attr, true);
-      }
+      // `Backbone.history.navigate` is sufficient for all Routers and will
+      // trigger the correct events. The Router's internal `navigate` method
+      // calls this anyways.  The fragment is sliced from the root.
+      Backbone.history.navigate(href.attr, true);
     }
   });
 });


[13/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
fix 140-*.t, reflect mv README README.rst


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

Branch: refs/heads/1684-feature-db-updates
Commit: e78ce41f7c2a6f684b1cda998d5bb6e4d0385e23
Parents: df23be9
Author: Jan Lehnardt <ja...@apache.org>
Authored: Wed Jun 5 22:04:32 2013 +0200
Committer: Jan Lehnardt <ja...@apache.org>
Committed: Wed Jun 5 22:04:39 2013 +0200

----------------------------------------------------------------------
 test/etap/140-attachment-comp.t | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e78ce41f/test/etap/140-attachment-comp.t
----------------------------------------------------------------------
diff --git a/test/etap/140-attachment-comp.t b/test/etap/140-attachment-comp.t
index 130b09f..6f075ce 100755
--- a/test/etap/140-attachment-comp.t
+++ b/test/etap/140-attachment-comp.t
@@ -723,6 +723,6 @@ test_png_data() ->
 
 test_text_data() ->
     {ok, Data} = file:read_file(
-        test_util:source_file("README")
+        test_util:source_file("README.rst")
     ),
     Data.


[39/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Fix database info's instance_start_time field description


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

Branch: refs/heads/1684-feature-db-updates
Commit: 65e5074a3b3d23c03492f634c6c849096a14bf27
Parents: ef9ac46
Author: Alexander Shorin <kx...@apache.org>
Authored: Thu Jul 4 06:38:29 2013 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Thu Jul 4 06:38:29 2013 +0400

----------------------------------------------------------------------
 share/doc/src/api/database.rst   | 2 +-
 share/doc/src/json-structure.rst | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/65e5074a/share/doc/src/api/database.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/api/database.rst b/share/doc/src/api/database.rst
index 826adaa..ba2195c 100644
--- a/share/doc/src/api/database.rst
+++ b/share/doc/src/api/database.rst
@@ -166,7 +166,7 @@ The elements of the returned structure are shown in the table below:
 | doc_del_count                    | Number of deleted documents               |
 +----------------------------------+-------------------------------------------+
 | instance_start_time              | Timestamp of when the database was        |
-|                                  | created, expressed in milliseconds since  |
+|                                  | opened, expressed in microseconds since   |
 |                                  | the epoch.                                |
 +----------------------------------+-------------------------------------------+
 | purge_seq                        | The number of purge operations on the     |

http://git-wip-us.apache.org/repos/asf/couchdb/blob/65e5074a/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index a5dc6d2..c4089b9 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -136,8 +136,8 @@ CouchDB database information object
 |                                | disk. Views indexes are not included in the |
 |                                | calculation.                                |
 +--------------------------------+---------------------------------------------+
-| instance_start_time            | Timestamp of when the database was created, |
-|                                | expressed in milliseconds since the epoch.  |
+| instance_start_time            | Timestamp of when the database was opened,  |
+|                                | expressed in microseconds since the epoch.  |
 +--------------------------------+---------------------------------------------+
 | purge_seq                      | The number of purge operations on the       |
 |                                | database.                                   |


[43/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Improved development server

Fauton: Much faster and simpler build server. Only updates changed files, uses
requirejs to load necessary dependancies.

Fixes COUCHDB-1846


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

Branch: refs/heads/1684-feature-db-updates
Commit: 9b64526db9e22de0c94fd6065186336ad423f4c0
Parents: 03d1b7e
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Jun 27 16:17:59 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Jul 15 14:21:19 2013 +0200

----------------------------------------------------------------------
 src/fauxton/Gruntfile.js                        |   83 +-
 src/fauxton/app/api.js                          |    2 +-
 src/fauxton/app/app.js                          |    1 -
 src/fauxton/app/config.js                       |    3 +-
 src/fauxton/app/main.js                         |   13 +-
 src/fauxton/app/modules/documents/views.js      |    2 +-
 src/fauxton/assets/index.underscore             |    4 +-
 src/fauxton/assets/js/libs/require.js           | 1112 +++++++--------
 .../assets/less/bootstrap/tests/buttons.html    |  139 --
 .../assets/less/bootstrap/tests/css-tests.css   |  139 --
 .../assets/less/bootstrap/tests/css-tests.html  | 1296 ------------------
 .../less/bootstrap/tests/forms-responsive.html  |   71 -
 .../assets/less/bootstrap/tests/forms.html      |  179 ---
 .../less/bootstrap/tests/navbar-fixed-top.html  |  104 --
 .../less/bootstrap/tests/navbar-static-top.html |  107 --
 .../assets/less/bootstrap/tests/navbar.html     |  107 --
 src/fauxton/package.json                        |   16 +-
 src/fauxton/settings.json.default               |   23 +-
 src/fauxton/tasks/couchserver.js                |   73 +-
 src/fauxton/tasks/fauxton.js                    |    2 +-
 src/fauxton/tasks/helper.js                     |    6 +-
 21 files changed, 707 insertions(+), 2775 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 7c9d4ec..886272d 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -78,22 +78,33 @@ module.exports = function(grunt) {
         theAssets.img.push(imgPath + "/**");
       }
     });
-    grunt.log.write(theAssets.img[0]);
     return theAssets;
   }();
 
   var templateSettings = function(){
     var defaultSettings = {
-      "src": "assets/index.underscore",
-      "dest": "dist/debug/index.html",
-      "variables": {
-        "assets_root": "./",
-        "requirejs": "require.js",
-        "base": null
+     "development": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "/assets/js/libs/require.js",
+          "css": "./css/index.css",
+          "base": null
+        }
+      },
+      "release": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "./js/require.js",
+          "css": "./css/index.css",
+          "base": null
+        }
       }
     };
+
     var settings = helper.readSettingsFile();
-    return {template: settings.template || defaultSettings};
+    return settings.template || defaultSettings;
   }();
 
   grunt.initConfig({
@@ -154,7 +165,7 @@ module.exports = function(grunt) {
     // index.html.
     concat: {
       requirejs: {
-        src: ["assets/js/libs/almond.js", "dist/debug/templates.js", "dist/debug/require.js"],
+        src: [ "assets/js/libs/require.js", "dist/debug/templates.js", "dist/debug/require.js"],
         dest: "dist/debug/js/require.js"
       },
 
@@ -206,8 +217,17 @@ module.exports = function(grunt) {
     },
 
     watch: {
-      files: helper.watchFiles(["./app/**/*", "./assets/**/*"]),
-      tasks: ['debug', 'template']
+      js: { 
+        files: helper.watchFiles(['.js'], ["./app/**/*.js", '!./app/load_addons.js',"./assets/**/*.js"]),
+        tasks: ['watchRun'],
+      },
+      style: {
+        files: helper.watchFiles(['.less','.css'],["./app/**/*.css","./app/**/*.less","./assets/**/*.css", "./assets/**/*.less"]),
+        tasks: ['less', 'concat:index_css'],
+      },
+      options: {
+        nospawn: true,
+      }
     },
 
     requirejs: {
@@ -225,8 +245,8 @@ module.exports = function(grunt) {
 
           // Do not wrap everything in an IIFE.
           wrap: false,
-          optimize: "none"
-      }
+          optimize: "none",
+        }
       }
     },
 
@@ -294,6 +314,16 @@ module.exports = function(grunt) {
 
   });
 
+  // on watch events configure jshint:all to only run on changed file
+  grunt.event.on('watch', function(action, filepath) {
+    if (!!filepath.match(/.js$/)) {
+      grunt.config(['jshint', 'all'], filepath);
+    }
+    /*} else if (!!filepath.match(/.css$|.less$/)) {
+      grunt.task.run(['less', 'concat:index_css']);
+    }*/
+  });
+
   /*
    * Load Grunt plugins
    */
@@ -302,11 +332,23 @@ module.exports = function(grunt) {
   // Load the couchapp task
   grunt.loadNpmTasks('grunt-couchapp');
   // Load the copy task
-  grunt.loadNpmTasks('grunt-contrib');
+  grunt.loadNpmTasks('grunt-contrib-watch');
   // Load the exec task
   grunt.loadNpmTasks('grunt-exec');
   // Load Require.js task
-  grunt.loadNpmTasks('grunt-requirejs');
+  grunt.loadNpmTasks('grunt-contrib-requirejs');
+  // Load Copy task
+  grunt.loadNpmTasks('grunt-contrib-copy');
+  // Load Clean task
+  grunt.loadNpmTasks('grunt-contrib-clean');
+  // Load jshint task
+  grunt.loadNpmTasks('grunt-contrib-jshint');
+  // Load jst task
+  grunt.loadNpmTasks('grunt-contrib-jst');
+  // Load less task
+  grunt.loadNpmTasks('grunt-contrib-less');
+  // Load concat task
+  grunt.loadNpmTasks('grunt-contrib-concat');
   // Load UglifyJS task
   grunt.loadNpmTasks('grunt-contrib-uglify');
   // Load CSSMin task
@@ -326,7 +368,7 @@ module.exports = function(grunt) {
   // Fetch dependencies (from git or local dir), lint them and make load_addons
   grunt.registerTask('dependencies', ['get_deps', 'jshint', 'gen_load_addons:default']);
   // build templates, js and css
-  grunt.registerTask('build', ['jst', 'requirejs', 'concat:requirejs', 'less', 'concat:index_css', 'template']);
+  grunt.registerTask('build', ['less', 'concat:index_css', 'jst', 'requirejs', 'concat:requirejs', 'template:release']);
   // minify code and css, ready for release.
   grunt.registerTask('minify', ['uglify', 'cssmin:compress']);
 
@@ -334,9 +376,12 @@ module.exports = function(grunt) {
    * Build the app in either dev, debug, or release mode
    */
   // dev server
-  grunt.registerTask('dev', ['debug', 'couchserver']);
+  grunt.registerTask('dev', ['debugDev', 'couchserver']);
   // build a debug release
-  grunt.registerTask('debug', ['test', 'dependencies', 'build', 'copy:debug']);
+  grunt.registerTask('debug', ['test', 'dependencies', 'concat:requirejs','less', 'concat:index_css', 'template:development', 'copy:debug']);
+  grunt.registerTask('debugDev', ['test', 'dependencies', 'less', 'concat:index_css', 'template:development', 'copy:debug']);
+
+  grunt.registerTask('watchRun', ['dependencies']);
   // build a release
   grunt.registerTask('release', ['test' ,'dependencies', 'build', 'minify', 'copy:dist']);
 
@@ -348,7 +393,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', ['build', 'minify', 'copy:dist']);
+  grunt.registerTask('couchapp_setup', ['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/9b64526d/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index 4732528..0f3923e 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -78,7 +78,7 @@ function(app, Fauxton) {
     }
 
     return $.when(deferreds);
-  },
+  };
 
   FauxtonAPI.addRoute = function(route) {
     app.router.route(route.route, route.name, route.callback);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/app/app.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/app.js b/src/fauxton/app/app.js
index be0136d..df0894a 100644
--- a/src/fauxton/app/app.js
+++ b/src/fauxton/app/app.js
@@ -56,7 +56,6 @@ function($, _, Backbone, Helpers) {
       } else {
         // Put fetch into `async-mode`.
         done = this.async();
-
         // Seek out the template asynchronously.
         return $.ajax({ url: app.root + path }).then(function(contents) {
           done(JST[path] = _.template(contents));

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index c7ae1d6..d7d3b40 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -20,6 +20,8 @@ require.config({
     "nv.d3": "../assets/js/libs/nv.d3"
   },
 
+  baseUrl: '/',
+
   shim: {
     // Backbone library depends on lodash and jQuery.
     backbone: {
@@ -51,5 +53,4 @@ require.config({
 
     "plugins/jquery.form": ["jquery"]
   }
-
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/app/main.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js
index 2f8f8fa..c06b0c4 100644
--- a/src/fauxton/app/main.js
+++ b/src/fauxton/app/main.js
@@ -23,16 +23,7 @@ function(app, Router) {
     // Get the absolute root.
     var root = location.protocol + "//" + location.host + app.root;
 
-    // Ensure the root is part of the anchor href, meaning it's relative.
-    if (href.prop && href.prop.slice(0, root.length) === root) {
-      // Stop the default event to ensure the link will not cause a page
-      // refresh.
-      evt.preventDefault();
-
-      // `Backbone.history.navigate` is sufficient for all Routers and will
-      // trigger the correct events. The Router's internal `navigate` method
-      // calls this anyways.  The fragment is sliced from the root.
-      Backbone.history.navigate(href.attr, true);
-    }
+    evt.preventDefault();
+    Backbone.history.navigate(href.attr, true);
   });
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 59e3b7d..6c92cfa 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -764,7 +764,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
 
       var that = this,
           promise,
-          viewName = this.$('#index-name').val();
+          viewName = this.$('#index-name').val(),
           ddocName = this.$('#ddoc :selected').val(),
           ddoc = this.getCurrentDesignDoc();
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9b64526d/src/fauxton/assets/index.underscore
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/index.underscore b/src/fauxton/assets/index.underscore
index e29b4c4..7ccb930 100644
--- a/src/fauxton/assets/index.underscore
+++ b/src/fauxton/assets/index.underscore
@@ -24,7 +24,7 @@
   <title>Project Fauxton</title>
 
   <!-- Application styles. -->
-  <link rel="stylesheet" href="<%= assets_root %>css/index.css">
+  <link rel="stylesheet" href="<%= css %>">
   <style type="text/css">
     body {
     padding-top: 60px;
@@ -49,6 +49,6 @@
   </div>
 
   <!-- Application source. -->
-  <script data-main="/app/config" src="<%= assets_root %>js/<%= requirejs %>"></script>
+  <script data-main="/config" src="<%= requirejs %>"></script>
 </body>
 </html>


[09/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Add design doc metadata to view
Fixes issue #1816


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

Branch: refs/heads/1684-feature-db-updates
Commit: 9cace040dbf48b4b366e2118b9e2078d8d0ee1db
Parents: 90e4da6
Author: Garren Smith <ga...@gmail.com>
Authored: Wed May 29 16:39:24 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jun 4 15:46:38 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/logs/resources.js        |  8 ++--
 src/fauxton/app/modules/documents/resources.js  | 27 +++++++++++-
 src/fauxton/app/modules/documents/views.js      | 44 +++++++++++++++++++-
 .../app/templates/documents/ddoc_info.html      |  8 ++++
 .../app/templates/documents/view_editor.html    |  1 +
 5 files changed, 82 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cace040/src/fauxton/app/addons/logs/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/logs/resources.js b/src/fauxton/app/addons/logs/resources.js
index bf7f657..955b3ec 100644
--- a/src/fauxton/app/addons/logs/resources.js
+++ b/src/fauxton/app/addons/logs/resources.js
@@ -158,14 +158,14 @@ function (app, FauxtonAPI, Backbone) {
     },
 
     startRefreshInterval: function () {
-      var that = this;
+      var collection = this.collection;
 
       // Interval already set
-      if (that.intervalId) { return ; }
+      if (this.intervalId) { return ; }
 
       that.intervalId = setInterval(function () {
-        that.collection.fetch();
-      }, that.refreshTime);
+        collection.fetch();
+      }, this.refreshTime);
 
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cace040/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index e313378..7bfee3d 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -164,6 +164,31 @@ function(app, FauxtonAPI) {
     }
   });
 
+  Documents.DdocInfo = Backbone.Model.extend({
+    idAttribute: "_id",
+
+    initialize: function (_attrs, options) {
+      this.database = options.database;
+    },
+
+    url: function(context) {
+      if (context === "app") {
+        return this.database.url("app") + "/" + this.safeID() + '/_info';
+      } else {
+        return app.host + "/" + this.database.id + "/" + this.id + '/_info';
+      }
+    },
+
+    // Need this to work around backbone router thinking _design/foo
+    // is a separate route. Alternatively, maybe these should be
+    // treated separately. For instance, we could default into the
+    // json editor for docs, or into a ddoc specific page.
+    safeID: function() {
+      return this.id.replace('/', '%2F');
+    }
+
+  });
+
   Documents.ViewRow = Backbone.Model.extend({
     docType: function() {
       if (!this.id) return "reduction";
@@ -330,7 +355,6 @@ function(app, FauxtonAPI) {
     },
 
     totalRows: function() {
-      console.log('rows');
       console.log(this);
       return this.viewMeta.total_rows || "unknown";
     },
@@ -349,5 +373,6 @@ function(app, FauxtonAPI) {
   });
 
 
+
   return Documents;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cace040/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index f5cd882..af85134 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -545,9 +545,14 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
       } else {
         this.ddocID = options.ddocInfo.id;
         this.viewName = options.viewName;
+        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
       } 
     },
 
+    establish: function () {
+      return this.ddocInfo.fetch();
+    },
+
     updateDesignDoc: function () {
 
       if (this.$('#ddoc :selected').prop('id') === 'new-doc') {
@@ -915,6 +920,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
       } else {
         this.model = this.ddocs.get(this.ddocID).dDocModel();
         this.reduceFunStr = this.model.viewHasReduce(this.viewName);
+        this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));
       }
     },
 
@@ -1081,7 +1087,6 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
     },
 
     serialize: function () {
-      console.log('c', this.model.changes.toJSON());
       return {
         changes: this.model.changes.toJSON(),
         database: this.model
@@ -1091,8 +1096,45 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
     afterRender: function(){
       prettyPrint();
     }
+  });
+
+  Views.DdocInfo = FauxtonAPI.View.extend({
+    template: "templates/documents/ddoc_info",
+
+    initialize: function (options) {
+      this.refreshTime = options.refreshTime || 5000;
+      this.listenTo(this.model, 'change', this.render);
+    },
+
+    serialize: function () {
+      return {
+        view_index: this.model.get('view_index')
+      };
+    },
+
+    afterRender: function () {
+      this.startRefreshInterval();
+    },
 
+    startRefreshInterval: function () {
+      var model = this.model;
 
+      // Interval already set
+      if (this.intervalId) { return ; }
+
+      this.intervalId = setInterval(function () {
+        console.log('refreshing');
+        model.fetch();
+      }, this.refreshTime);
+    },
+    
+    stopRefreshInterval: function () {
+      clearInterval(this.intervalId);
+    },
+
+    cleanup: function () {
+      this.stopRefreshInterval();
+    }
   });
 
   Documents.Views = Views;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cace040/src/fauxton/app/templates/documents/ddoc_info.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/ddoc_info.html b/src/fauxton/app/templates/documents/ddoc_info.html
new file mode 100644
index 0000000..18bf4d8
--- /dev/null
+++ b/src/fauxton/app/templates/documents/ddoc_info.html
@@ -0,0 +1,8 @@
+<div class="well" >
+  <h2> Design Doc MetaData </h2>
+  <ul style="list-style-type: none;">
+  <% _.each(view_index, function (val, key) { %>
+    <li><strong> <%= key %></strong> : <%= val %>  </li>
+  <% }); %>
+  </ul>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/9cace040/src/fauxton/app/templates/documents/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/view_editor.html b/src/fauxton/app/templates/documents/view_editor.html
index a34ff0d..32f1d14 100644
--- a/src/fauxton/app/templates/documents/view_editor.html
+++ b/src/fauxton/app/templates/documents/view_editor.html
@@ -14,6 +14,7 @@ the License.
 <div class="row">
   <div class="all-docs-list errors-container"></div>
   <div id="edit-index-container">
+    <div id="ddoc-info"> </div>
 
     <div class="accordion" id="edit-index-accordion">
       <div class="accordion-group">


[32/50] [abbrv] git commit: updated refs/heads/1684-feature-db-updates to ea07223

Posted by ja...@apache.org.
Use Array#forEach instead of for .. in

Also improved the wording in a few places.


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

Branch: refs/heads/1684-feature-db-updates
Commit: e204f0d0dbe9ae6385bcc225218731105fd5ff5e
Parents: ba3adb1
Author: Michael Jackson <mj...@gmail.com>
Authored: Sat Jun 29 12:47:05 2013 -0700
Committer: Michael Jackson <mj...@gmail.com>
Committed: Sat Jun 29 12:47:05 2013 -0700

----------------------------------------------------------------------
 share/doc/src/ddocs.rst | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e204f0d0/share/doc/src/ddocs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/ddocs.rst b/share/doc/src/ddocs.rst
index 368f49e..ada5b0d 100644
--- a/share/doc/src/ddocs.rst
+++ b/share/doc/src/ddocs.rst
@@ -48,25 +48,23 @@ Map functions
 
    :param doc: Processed document object.
 
-Map functions should take a single argument as document object and optionally
-emits paired values also known as `key` and `value`. Since JavaScript
-doesn't support generators and ``yield`` statement it is emulated via :func:`emit`:
+Map functions accept a single document as the argument and (optionally) :func:`emit`
+key/value pairs that are stored in a view.
 
 .. code-block:: javascript
 
-    function(doc){
-      if (!doc.tags || !isArray(doc.tags) || !doc.type || doc.type != 'post'){
-        return;
-      }
-      for (var idx in doc.tags){
-        emit(doc.tags[idx].toLower(), 1);
+    function (doc) {
+      if (doc.type === 'post' && doc.tags && Array.isArray(doc.tags)) {
+        doc.tags.forEach(function (tag) {
+          emit(tag.toLowerCase(), 1);
+        });
       }
     }
 
-In this example the map function produces documents view by tag if they
-has `tags` attribute as array and `type` attribute with "post" value. Note that
-:func:`emit` function could be called  multiple times, so the same document
-will be available by several `keys`.
+In this example a key/value pair is emitted for each value in the `tags` array
+of a document with a `type` of "post". Note that :func:`emit` may be called many
+times for a single document, so the same document may be available by several
+different keys.
 
 Also keep in mind that each document is *sealed* to prevent situation when one
 map function changes document state and the other one received a modified
@@ -77,7 +75,7 @@ each document is processed by group of map functions from all views of
 related design document. This means that if you trigger index update for one
 view in ddoc, all others will get updated too.
 
-Since `1.1.0` release `map` function supports 
+Since `1.1.0` release `map` function supports
 :ref:`CommonJS <commonjs>` modules and access to :func:`require` function.
 
 .. _reducefun:
@@ -128,7 +126,7 @@ JavaScript below:
 
     // could be replaced by _count
     function(keys, values, rereduce){
-      if (rereduce){
+      if (rereduce) {
         return sum(values);
       } else {
         return values.length;
@@ -143,11 +141,13 @@ JavaScript below:
         '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;
+          var sumsqr = 0;
+
+          values.forEach(function (value) {
+            sumsqr += value * value;
+          });
+
+          return sumsqr;
         })(),
       }
     }
@@ -208,7 +208,7 @@ Basic example of show function could be:
 .. code-block:: javascript
 
     function(doc, req){
-      if (doc){
+      if (doc) {
         return "Hello from " + doc._id + "!";
       } else {
         return "Hello, world!";
@@ -712,7 +712,7 @@ permissions:
 
 .. note::
 
-   The ``return`` statement used only for function, it has no impact on 
+   The ``return`` statement used only for function, it has no impact on
    the validation process.
 
 .. seealso::