incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fabio Batalha Cunha dos Santos <fabio.bata...@scielo.org>
Subject Re: Mustache Sections
Date Fri, 17 Dec 2010 19:42:20 GMT
Hello guys!

I'm trying to use templates to format my views results, but I'm having the
same problem.

I tried with the {{%IMPLICIT-ITERATOR}} but it still not working.

This is my "list" code.

function(head, req) {

    start({
        "headers": {
            "Content-Type": "text/html"
        }
    });

   var mustache = require("lib/mustache");
   var view = {name: "Joe's shopping card",items: ["bananas", "apples"]};
   var template = "{{%IMPLICIT-ITERATOR}}{{name}}: <ul>
{{#items}}<li>{{.}}</li>{{/items}} </ul>";

   return mustache.to_html(template,view);

}


And this is what I get, when trying this code:

{"error":"invalid_require_path","reason":"Object has no property
\"lib\". {\"_id\":\"_design/couchdb\",\"_rev\":\"29-432e1407500022dfce5f9ef9fbc91253\",\"vendor\":{\"couchapp\":{\"evently\":{\"profile\":{\"profileReady\":{\"after\":\"function(e,
p) {\\u000a  $$(this).profile = p;\\u000a};\",\"data\":\"function(e,
p) {\\u000a  return p\\u000a}\",\"mustache\":\"<div
class=\\\"avatar\\\">\\u000a  {{#gravatar_url}}<img
src=\\\"{{gravatar_url}}\\\"/>{{/gravatar_url}}\\u000a  <div
class=\\\"name\\\">\\u000a    {{nickname}}\\u000a
</div>\\u000a</div>\\u000a<p>Hello {{nickname}}!</p>\\u000a<div
style=\\\"clear:left;\\\"></div>\"},\"noProfile\":{\"data\":\"function(e,
userCtx) {\\u000a  return
userCtx;\\u000a}\",\"mustache\":\"<form>\\u000a  <p>Hello {{name}},
Please setup your user profile.</p>\\u000a  <label
for=\\\"nickname\\\">Nickname \\u000a    <input type=\\\"text\\\"
name=\\\"nickname\\\" value=\\\"\\\"></label>\\u000a  <label
for=\\\"email\\\">Email (<em>for <a
href=\\\"http://gravatar.com\\\">Gravatar</a></em>)\\u000a    <input
type=\\\"text\\\" name=\\\"email\\\" value=\\\"\\\"></label>\\u000a
<label for=\\\"url\\\">URL \\u000a    <input type=\\\"text\\\"
name=\\\"url\\\" value=\\\"\\\"></label>\\u000a  <input
type=\\\"submit\\\" value=\\\"Go &rarr;\\\">\\u000a  <input
type=\\\"hidden\\\" name=\\\"userCtxName\\\" value=\\\"{{name}}\\\"
id=\\\"userCtxName\\\">\\u000a</form>\",\"selectors\":{\"form\":{\"submit\":\"function()
{\\u000a  var md5 =
$$(this).app.require(\\\"vendor/couchapp/lib/md5\\\");\\u000a  \\u000a
 // TODO this can be cleaned up with docForm?\\u000a  // it still
needs the workflow to edit an existing profile\\u000a  var name =
$(\\\"input[name=userCtxName]\\\",this).val();\\u000a  var newProfile
= {\\u000a    rand : Math.random().toString(), \\u000a    nickname :
$(\\\"input[name=nickname]\\\",this).val(),\\u000a    email :
$(\\\"input[name=email]\\\",this).val(),\\u000a    url :
$(\\\"input[name=url]\\\",this).val()\\u000a  }, widget =
$(this);\\u000a\\u000a  // setup gravatar_url\\u000a  if (md5)
{\\u000a    newProfile.gravatar_url =
'http://www.gravatar.com/avatar/'+md5.hex(newProfile.email ||
newProfile.rand)+'.jpg?s=40&d=identicon';    \\u000a  }\\u000a\\u000a
// store the user profile on the user account document\\u000a
$.couch.userDb(function(db) {\\u000a    var userDocId =
\\\"org.couchdb.user:\\\"+name;\\u000a    db.openDoc(userDocId,
{\\u000a      success : function(userDoc) {\\u000a
userDoc[\\\"couch.app.profile\\\"] = newProfile;\\u000a
db.saveDoc(userDoc, {\\u000a          success : function() {\\u000a
        newProfile.name = userDoc.name;\\u000a
$$(widget).profile = newProfile;\\u000a
widget.trigger(\\\"profileReady\\\", [newProfile]);\\u000a
}\\u000a        });\\u000a      }\\u000a    });\\u000a  });\\u000a
return false;\\u000a}\"}}},\"loggedIn\":\"function(e, r) {\\u000a  var
userCtx = r.userCtx;\\u000a  var widget = $(this);\\u000a  // load the
profile from the user doc\\u000a  var db =
$.couch.db(r.info.authentication_db);\\u000a  var userDocId =
\\\"org.couchdb.user:\\\"+userCtx.name;\\u000a  db.openDoc(userDocId,
{\\u000a    success : function(userDoc) {\\u000a      var profile =
userDoc[\\\"couch.app.profile\\\"];\\u000a      if (profile) {\\u000a
      // we copy the name to the profile so it can be used
later\\u000a        // without publishing the entire userdoc (roles,
pass, etc)\\u000a        profile.name = userDoc.name;\\u000a
$$(widget).profile = profile;\\u000a
widget.trigger(\\\"profileReady\\\", [profile]);\\u000a      } else
{\\u000a        widget.trigger(\\\"noProfile\\\", [userCtx]);\\u000a
   }\\u000a    }\\u000a
});\\u000a}\",\"loggedOut\":{\"after\":\"function() {\\u000a
$$(this).profile = null;\\u000a};\",\"mustache\":\"<p>Please log in to
see your profile.</p>\"}},\"README\":\"## Starting the Document this
code challenge\\u000a\\u000aI need help on this code. I only have so
many hours in the day. Please be liberal about patching and hacking
(and sharing code!) so we can all benefit. \\u000a\\u000aDocs patches
are deeply appreciated. For now you can just stick Markdown files in
the Docs directory.\\u000a\\u000a# Evently\\u000a\\u000aThese are some
vendor Evently widgets that are running on the CouchApp
system.\\u000a\\u000a## Account\\u000a  This is how you signup, login
and logout without worry about the code.\\u000a  Todo, we could have
this work against remote APIs like that Facebook stuff or
whatever.\\u000a\\u000a\\u000a## Profile\\u000a  Use this to load the
local users profile for the logged in user. Useful if you're going to
be posting new messages. Most applications end up customizing
`profile.profileReady` to render the primary data-entry form. This
gets you benefits like refreshing on login / logout, etc,
automatically.\\u000a\\u000a\\u000a## Docs\\u000a  This needs to be
moved to it's own app.\\u000a  I have this vision of a docs app
designed for offline editing, that involves each Markdown paragraph
being it's own document, with automatic use of Bespin for code
samples. Any help on this would be thanked
much.\",\"account\":{\"loggedIn\":{\"after\":\"function(e, r) {\\u000a
 $$(this).userCtx = r.userCtx;\\u000a  $$(this).info =
r.info;\\u000a};\",\"data\":\"function(e, r) {\\u000a  return {\\u000a
   name : r.userCtx.name,\\u000a    uri_name :
encodeURIComponent(r.userCtx.name),\\u000a    auth_db :
encodeURIComponent(r.info.authentication_db)\\u000a
};\\u000a}\",\"mustache\":\"<span>Welcome \\u000a<a
target=\\\"_new\\\"
href=\\\"/_utils/document.html?{{auth_db}}/org.couchdb.user%3A{{uri_name}}\\\">{{name}}</a>!
\\u000a<a href=\\\"#logout\\\">Logout?</a>\\u000a</span>\",\"selectors\":{\"a[href=#logout]\":{\"click\":[\"doLogout\"]}}},\"signupForm\":{\"after\":\"function()
{\\u000a  $(\\\"input[name=name]\\\",
this).focus();\\u000a}\",\"mustache\":\"<form>\\u000a  <label
for=\\\"name\\\">Name</label> <input type=\\\"text\\\"
name=\\\"name\\\" value=\\\"\\\" autocapitalize=\\\"off\\\"
autocorrect=\\\"off\\\">\\u000a  <label
for=\\\"password\\\">Password</label> <input type=\\\"password\\\"
name=\\\"password\\\" value=\\\"\\\">\\u000a  <input
type=\\\"submit\\\" value=\\\"Signup\\\">\\u000a  <a
href=\\\"#login\\\">or
Login</a>\\u000a</form>\",\"selectors\":{\"a[href=#login]\":{\"click\":[\"loginForm\"]},\"form\":{\"submit\":\"function(e)
{\\u000a  var name = $('input[name=name]', this).val(),\\u000a    pass
= $('input[name=password]', this).val();              \\u000a
$(this).trigger('doSignup', [name, pass]);\\u000a  return
false;\\u000a}\"}}},\"_init\":\"function() {\\u000a  var elem =
$(this);\\u000a  $$(this).userCtx = null;\\u000a
$.couch.session({\\u000a    success : function(r) {\\u000a      var
userCtx = r.userCtx;\\u000a      if (userCtx.name) {\\u000a
elem.trigger(\\\"loggedIn\\\", [r]);\\u000a      } else if
(userCtx.roles.indexOf(\\\"_admin\\\") != -1) {\\u000a
elem.trigger(\\\"adminParty\\\");\\u000a      } else {\\u000a
elem.trigger(\\\"loggedOut\\\");\\u000a      };\\u000a    }\\u000a
});\\u000a}\",\"doLogout\":\"function() {\\u000a  var elem =
$(this);\\u000a  $.couch.logout({\\u000a    success : function()
{\\u000a      elem.trigger(\\\"_init\\\");\\u000a    }\\u000a
});\\u000a}\",\"doSignup\":\"function(e, name, pass) {\\u000a  var
elem = $(this);\\u000a  $.couch.signup({\\u000a    name : name\\u000a
}, pass, {\\u000a    success : function() {\\u000a
elem.trigger(\\\"doLogin\\\", [name, pass]);\\u000a    }\\u000a
});\\u000a}\",\"adminParty\":{\"mustache\":\"<p><strong>Admin party,
everyone is admin!</strong> Fix this in <a
href=\\\"/_utils/index.html\\\">Futon</a> before
proceeding.</p>\"},\"loggedOut\":{\"mustache\":\"<a
href=\\\"#signup\\\">Signup</a> or <a
href=\\\"#login\\\">Login</a>\",\"selectors\":{\"a[href=#login]\":{\"click\":[\"loginForm\"]},\"a[href=#signup]\":{\"click\":[\"signupForm\"]}}},\"loginForm\":{\"after\":\"function()
{\\u000a  $(\\\"input[name=name]\\\",
this).focus();\\u000a}\",\"mustache\":\"<form>\\u000a  <label
for=\\\"name\\\">Name</label> <input type=\\\"text\\\"
name=\\\"name\\\" value=\\\"\\\" autocapitalize=\\\"off\\\"
autocorrect=\\\"off\\\">\\u000a  <label
for=\\\"password\\\">Password</label> <input type=\\\"password\\\"
name=\\\"password\\\" value=\\\"\\\">\\u000a  <input
type=\\\"submit\\\" value=\\\"Login\\\">\\u000a  <a
href=\\\"#signup\\\">or
Signup</a>\\u000a</form>\",\"selectors\":{\"form\":{\"submit\":\"function(e)
{\\u000a  var name = $('input[name=name]', this).val(),\\u000a    pass
= $('input[name=password]', this).val();              \\u000a
$(this).trigger('doLogin', [name, pass]);\\u000a  return
false;\\u000a}\"},\"a[href=#signup]\":{\"click\":[\"signupForm\"]}}},\"doLogin\":\"function(e,
name, pass) {\\u000a  var elem = $(this);\\u000a
$.couch.login({\\u000a    name : name,\\u000a    password :
pass,\\u000a    success : function(r) {\\u000a
elem.trigger(\\\"_init\\\")\\u000a    }\\u000a  });
\\u000a}\"}},\"lib\":{\"redirect\":\"exports.permanent =
function(redirect) {\\u000a  return {\\u000a    code : 301,\\u000a
headers : {\\u000a      \\\"Location\\\" : redirect\\u000a    }\\u000a
 };\\u000a};\",\"code\":\"exports.ddoc = function(ddoc) {\\u000a  //
only return the parts of the app that we use\\u000a  var i, j, path,
key, obj, ref, out = {},\\u000a    resources = ddoc.couchapp &&
ddoc.couchapp.load && ddoc.couchapp.load.app || [];\\u000a  for (i=0;
i < resources.length; i++) {\\u000a    path =
resources[i].split('/');\\u000a    obj = ddoc;\\u000a    ref =
out;\\u000a    for (j=0; j < path.length; j++) {\\u000a      key =
path[j];\\u000a      ref[key] = ref[key] || {};\\u000a      if (j <
path.length - 1) {\\u000a        obj = obj[key];\\u000a        ref =
ref[key];\\u000a      }\\u000a    };\\u000a    ref[key] =
obj[key];\\u000a  };\\u000a  return
out;\\u000a};\",\"utils\":\"exports.prettyDate =
function(time){\\u000a  \\u000a\\u0009var date = new
Date(time.replace(/-/g,\\\"/\\\").replace(\\\"T\\\", \\\"
\\\").replace(\\\"Z\\\", \\\"
+0000\\\").replace(/(\\\\d*\\\\:\\\\d*:\\\\d*)\\\\.\\\\d*/g,\\\"$1\\\")),\\u000a\\u0009\\u0009diff
= (((new Date()).getTime() - date.getTime()) /
1000),\\u000a\\u0009\\u0009day_diff = Math.floor(diff /
86400);\\u000a\\u000a  if (isNaN(day_diff)) return
time;\\u000a\\u000a\\u0009return day_diff < 1 &&
(\\u000a\\u0009\\u0009\\u0009diff < 60 && \\\"just now\\\"
||\\u000a\\u0009\\u0009\\u0009diff < 120 && \\\"1 minute ago\\\"
||\\u000a\\u0009\\u0009\\u0009diff < 3600 && Math.floor( diff / 60 ) +
\\\" minutes ago\\\" ||\\u000a\\u0009\\u0009\\u0009diff < 7200 &&
\\\"1 hour ago\\\" ||\\u000a\\u0009\\u0009\\u0009diff < 86400 &&
Math.floor( diff / 3600 ) + \\\" hours ago\\\")
||\\u000a\\u0009\\u0009day_diff == 1 && \\\"yesterday\\\"
||\\u000a\\u0009\\u0009day_diff < 21 && day_diff + \\\" days ago\\\"
||\\u000a\\u0009\\u0009day_diff < 45 && Math.ceil( day_diff / 7 ) +
\\\" weeks ago\\\" ||\\u000a    time;\\u000a    // day_diff < 730 &&
Math.ceil( day_diff / 31 ) + \\\" months ago\\\" ||\\u000a    //
Math.ceil( day_diff / 365 ) + \\\" years
ago\\\";\\u000a};\",\"cache\":\"exports.get = function(db, docid,
setFun, getFun) {\\u000a  db.openDoc(docid, {\\u000a    success :
function(doc) {\\u000a      getFun(doc.cache);\\u000a    },\\u000a
error : function() {\\u000a      setFun(function(cache) {\\u000a
 db.saveDoc({\\u000a          _id : docid,\\u000a          cache :
cache\\u000a        });\\u000a        getFun(cache);\\u000a
});\\u000a    }\\u000a  });\\u000a};\\u000a\\u000aexports.clear =
function(db, docid) {\\u000a  db.openDoc(docid, {\\u000a    success :
function(doc) {\\u000a      db.removeDoc(doc);\\u000a    },\\u000a
error : function() {}\\u000a  });\\u000a};\",\"list\":\"// Helpers for
writing server-side _list functions in CouchDB\\u000aexports.withRows
= function(fun) {\\u000a var f = function() {\\u000a    var row =
getRow();\\u000a    return row && fun(row);\\u000a  };\\u000a
f.iterator = true;\\u000a  return f;\\u000a}\\u000a\\u000aexports.send
= function(chunk) {\\u000a  send(chunk +
\\\"\\\\n\\\")\\u000a}\",\"markdown\":\"//\\u000a// showdown.js -- A
javascript port of Markdown.\\u000a//\\u000a// Copyright (c) 2007 John
Fraser.\\u000a//\\u000a// Original Markdown Copyright (c) 2004-2005
John Gruber\\u000a//
<http://daringfireball.net/projects/markdown/>\\u000a//\\u000a//
Redistributable under a BSD-style open source license.\\u000a// See
license.txt for more information.\\u000a//\\u000a// The full source
distribution is at:\\u000a//\\u000a//\\u0009\\u0009\\u0009\\u0009A A
L\\u000a//\\u0009\\u0009\\u0009\\u0009T C
A\\u000a//\\u0009\\u0009\\u0009\\u0009T K B\\u000a//\\u000a//
<http://www.attacklab.net/>\\u000a//\\u000a\\u000a//\\u000a// Wherever
possible, Showdown is a straight, line-by-line port\\u000a// of the
Perl version of Markdown.\\u000a//\\u000a// This is not a normal
parser design; it's basically just a\\u000a// series of string
substitutions.  It's hard to read and\\u000a// maintain this way,  but
keeping Showdown close to the original\\u000a// design makes it easier
to port new features.\\u000a//\\u000a// More importantly, Showdown
behaves like markdown.pl in most\\u000a// edge cases.  So web
applications can do client-side preview\\u000a// in Javascript, and
then build identical HTML on the server.\\u000a//\\u000a// This port
needs the new RegExp functionality of ECMA 262,\\u000a// 3rd Edition
(i.e. Javascript 1.5).  Most modern web browsers\\u000a// should do
fine.  Even with the new regular expression features,\\u000a// We do a
lot of work to emulate Perl's regex functionality.\\u000a// The tricky
changes in this file mostly have the \\\"attacklab:\\\"\\u000a//
label.  Major or self-explanatory changes don't.\\u000a//\\u000a//
Smart diff tools like Araxis Merge will be able to match up\\u000a//
this file with markdown.pl in a useful way.  A little
tweaking\\u000a// helps: in a copy of markdown.pl, replace \\\"#\\\"
with \\\"//\\\" and\\u000a// replace \\\"$text\\\" with \\\"text\\\".
Be sure to ignore whitespace\\u000a// and line
endings.\\u000a//\\u000a\\u000a\\u000a//\\u000a// Showdown
usage:\\u000a//\\u000a//   var text = \\\"Markdown
*rocks*.\\\";\\u000a//\\u000a//   var markdown =
require(\\\"markdown\\\");\\u000a//   var html =
markdown.encode(text);\\u000a//\\u000a//
print(html);\\u000a//\\u000a// Note: move the sample code to the
bottom of this\\u000a// file before uncommenting
it.\\u000a//\\u000a\\u000a\\u000a//\\u000a//
Globals:\\u000a//\\u000a\\u000a// Global hashes, used by various
utility routines\\u000avar g_urls;\\u000avar g_titles;\\u000avar
g_html_blocks;\\u000a\\u000a// Used to track when we're inside an
ordered or unordered list\\u000a// (see _ProcessListItems() for
details):\\u000avar g_list_level =
0;\\u000a\\u000a\\u000aexports.makeHtml = function(text)
{\\u000a//\\u000a// Main function. The order in which other subs are
called here is\\u000a// essential. Link and image substitutions need
to happen before\\u000a// _EscapeSpecialCharsWithinTagAttributes(), so
that any *'s or _'s in the <a>\\u000a// and <img> tags get
encoded.\\u000a//\\u000a\\u000a\\u0009// Clear the global hashes. If
we don't clear these, you get conflicts\\u000a\\u0009// from other
articles when generating a page which contains more
than\\u000a\\u0009// one article (e.g. an index page that shows the N
most recent\\u000a\\u0009// articles):\\u000a\\u0009g_urls = new
Array();\\u000a\\u0009g_titles = new
Array();\\u000a\\u0009g_html_blocks = new
Array();\\u000a\\u000a\\u0009// attacklab: Replace ~ with
~T\\u000a\\u0009// This lets us use tilde as an escape char to avoid
md5 hashes\\u000a\\u0009// The choice of character is arbitray;
anything that isn't\\u000a    // magic in Markdown will
work.\\u000a\\u0009text =
text.replace(/~/g,\\\"~T\\\");\\u000a\\u000a\\u0009// attacklab:
Replace $ with ~D\\u000a\\u0009// RegExp interprets $ as a special
character\\u000a\\u0009// when it's in a replacement
string\\u000a\\u0009text =
text.replace(/\\\\$/g,\\\"~D\\\");\\u000a\\u000a\\u0009// Standardize
line endings\\u000a\\u0009text =
text.replace(/\\\\r\\\\n/g,\\\"\\\\n\\\"); // DOS to
Unix\\u000a\\u0009text = text.replace(/\\\\r/g,\\\"\\\\n\\\"); // Mac
to Unix\\u000a\\u000a\\u0009// Make sure text begins and ends with a
couple of newlines:\\u000a\\u0009text = \\\"\\\\n\\\\n\\\" + text +
\\\"\\\\n\\\\n\\\";\\u000a\\u000a\\u0009// Convert all tabs to
spaces.\\u000a\\u0009text = _Detab(text);\\u000a\\u000a\\u0009// Strip
any lines consisting only of spaces and tabs.\\u000a\\u0009// This
makes subsequent regexen easier to write, because we
can\\u000a\\u0009// match consecutive blank lines with /\\\\n+/
instead of something\\u000a\\u0009// contorted like /[ \\\\t]*\\\\n+/
.\\u000a\\u0009text = text.replace(/^[
\\\\t]+$/mg,\\\"\\\");\\u000a\\u000a\\u0009// Turn block-level HTML
blocks into hash entries\\u000a\\u0009text =
_HashHTMLBlocks(text);\\u000a\\u000a\\u0009// Strip link definitions,
store in hashes.\\u000a\\u0009text =
_StripLinkDefinitions(text);\\u000a\\u000a\\u0009text =
_RunBlockGamut(text);\\u000a\\u000a\\u0009text =
_UnescapeSpecialChars(text);\\u000a\\u000a\\u0009// attacklab: Restore
dollar signs\\u000a\\u0009text =
text.replace(/~D/g,\\\"$$\\\");\\u000a\\u000a\\u0009// attacklab:
Restore tildes\\u000a\\u0009text =
text.replace(/~T/g,\\\"~\\\");\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _StripLinkDefinitions =
function(text) {\\u000a//\\u000a// Strips link definitions from text,
stores the URLs and titles in\\u000a// hash
references.\\u000a//\\u000a\\u000a\\u0009// Link defs are in the form:
^[id]: url \\\"optional
title\\\"\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009var text =
text.replace(/\\u000a\\u0009\\u0009\\u0009\\u0009^[
]{0,3}\\\\[(.+)\\\\]:  // id = $1  attacklab: g_tab_width -
1\\u000a\\u0009\\u0009\\u0009\\u0009  [
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009
\\\\n?\\u0009\\u0009\\u0009\\u0009// maybe *one*
newline\\u000a\\u0009\\u0009\\u0009\\u0009  [
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009<?(\\\\S+?)>?\\u0009\\u0009\\u0009//
url = $2\\u000a\\u0009\\u0009\\u0009\\u0009  [
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009
\\\\n?\\u0009\\u0009\\u0009\\u0009// maybe one
newline\\u000a\\u0009\\u0009\\u0009\\u0009  [
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\u0009
 (\\\\n*)\\u0009\\u0009\\u0009\\u0009// any lines skipped = $3
attacklab: lookbehind removed\\u000a\\u0009\\u0009\\u0009\\u0009
[\\\"(]\\u000a\\u0009\\u0009\\u0009\\u0009
(.+?)\\u0009\\u0009\\u0009\\u0009// title =
$4\\u000a\\u0009\\u0009\\u0009\\u0009
[\\\")]\\u000a\\u0009\\u0009\\u0009\\u0009  [
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009)?\\u0009\\u0009\\u0009\\u0009\\u0009//
title is optional\\u000a\\u0009\\u0009\\u0009\\u0009(?:\\\\n+|$)\\u000a\\u0009\\u0009\\u0009
 /gm,\\u000a\\u0009\\u0009\\u0009
function(){...});\\u000a\\u0009*/\\u000a\\u0009var text =
text.replace(/^[ ]{0,3}\\\\[(.+)\\\\]:[ \\\\t]*\\\\n?[
\\\\t]*<?(\\\\S+?)>?[ \\\\t]*\\\\n?[
\\\\t]*(?:(\\\\n*)[\\\"(](.+?)[\\\")][
\\\\t]*)?(?:\\\\n+|\\\\Z)/gm,\\u000a\\u0009\\u0009function
(wholeMatch,m1,m2,m3,m4) {\\u000a\\u0009\\u0009\\u0009m1 =
m1.toLowerCase();\\u000a\\u0009\\u0009\\u0009g_urls[m1] =
_EncodeAmpsAndAngles(m2);  // Link IDs are
case-insensitive\\u000a\\u0009\\u0009\\u0009if (m3)
{\\u000a\\u0009\\u0009\\u0009\\u0009// Oops, found blank lines, so
it's not a title.\\u000a\\u0009\\u0009\\u0009\\u0009// Put back the
parenthetical statement we
stole.\\u000a\\u0009\\u0009\\u0009\\u0009return
m3+m4;\\u000a\\u0009\\u0009\\u0009} else if (m4)
{\\u000a\\u0009\\u0009\\u0009\\u0009g_titles[m1] =
m4.replace(/\\\"/g,\\\"&quot;\\\");\\u000a\\u0009\\u0009\\u0009}\\u000a\\u0009\\u0009\\u0009\\u000a\\u0009\\u0009\\u0009//
Completely remove the definition from the
text\\u000a\\u0009\\u0009\\u0009return
\\\"\\\";\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _HashHTMLBlocks = function(text)
{\\u000a\\u0009// attacklab: Double up blank lines to reduce
lookaround\\u000a\\u0009text =
text.replace(/\\\\n/g,\\\"\\\\n\\\\n\\\");\\u000a\\u000a\\u0009//
Hashify HTML blocks:\\u000a\\u0009// We only want to do this for
block-level HTML tags, such as headers,\\u000a\\u0009// lists, and
tables. That's because we still want to wrap <p>s
around\\u000a\\u0009// \\\"paragraphs\\\" that are wrapped in
non-block-level tags, such as anchors,\\u000a\\u0009// phrase
emphasis, and spans. The list of tags we're looking for
is\\u000a\\u0009// hard-coded:\\u000a\\u0009var block_tags_a =
\\\"p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del\\\"\\u000a\\u0009var
block_tags_b = \\\"p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math\\\"\\u000a\\u000a\\u0009//
First, look for nested blocks, e.g.:\\u000a\\u0009//
<div>\\u000a\\u0009//     <div>\\u000a\\u0009//     tags for inner
block must be indented.\\u000a\\u0009//     </div>\\u000a\\u0009//
</div>\\u000a\\u0009//\\u000a\\u0009// The outermost tags must start
at the left margin for this to match, and\\u000a\\u0009// the inner
nested divs must be indented.\\u000a\\u0009// We need to do this
before the next, more liberal match, because the next\\u000a\\u0009//
match will start at the first `<div>` and stop at the first
`</div>`.\\u000a\\u000a\\u0009// attacklab: This regex can be
expensive when it fails.\\u000a\\u0009/*\\u000a\\u0009\\u0009var text
= text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
save in $1\\u000a\\u0009\\u0009\\u0009^\\u0009\\u0009\\u0009\\u0009\\u0009//
start of line  (with
/m)\\u000a\\u0009\\u0009\\u0009<($block_tags_a)\\u0009// start tag =
$2\\u000a\\u0009\\u0009\\u0009\\\\b\\u0009\\u0009\\u0009\\u0009\\u0009//
word break\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
attacklab: hack around khtml/pcre
bug...\\u000a\\u0009\\u0009\\u0009[^\\\\r]*?\\\\n\\u0009\\u0009\\u0009//
any number of lines, minimally
matching\\u000a\\u0009\\u0009\\u0009</\\\\2>\\u0009\\u0009\\u0009\\u0009//
the matching end tag\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u0009\\u0009\\u0009\\u0009// trailing
spaces/tabs\\u000a\\u0009\\u0009\\u0009(?=\\\\n+)\\u0009\\u0009\\u0009\\u0009//
followed by a newline\\u000a\\u0009\\u0009)\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
attacklab: there are sentinel newlines at end of
document\\u000a\\u0009\\u0009/gm,function(){...}};\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\\\\b[^\\\\r]*?\\\\n<\\\\/\\\\2>[
\\\\t]*(?=\\\\n+))/gm,hashElement);\\u000a\\u000a\\u0009//\\u000a\\u0009//
Now match more liberally, simply from `\\\\n<tag>` to
`</tag>\\\\n`\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009var
text = text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
save in $1\\u000a\\u0009\\u0009\\u0009^\\u0009\\u0009\\u0009\\u0009\\u0009//
start of line  (with
/m)\\u000a\\u0009\\u0009\\u0009<($block_tags_b)\\u0009// start tag =
$2\\u000a\\u0009\\u0009\\u0009\\\\b\\u0009\\u0009\\u0009\\u0009\\u0009//
word break\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
attacklab: hack around khtml/pcre
bug...\\u000a\\u0009\\u0009\\u0009[^\\\\r]*?\\u0009\\u0009\\u0009\\u0009//
any number of lines, minimally
matching\\u000a\\u0009\\u0009\\u0009.*</\\\\2>\\u0009\\u0009\\u0009\\u0009//
the matching end tag\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u0009\\u0009\\u0009\\u0009// trailing
spaces/tabs\\u000a\\u0009\\u0009\\u0009(?=\\\\n+)\\u0009\\u0009\\u0009\\u0009//
followed by a newline\\u000a\\u0009\\u0009)\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
attacklab: there are sentinel newlines at end of
document\\u000a\\u0009\\u0009/gm,function(){...}};\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\\\\b[^\\\\r]*?.*<\\\\/\\\\2>[
\\\\t]*(?=\\\\n+)\\\\n)/gm,hashElement);\\u000a\\u000a\\u0009//
Special case just for <hr />. It was easier to make a special case
than\\u000a\\u0009// to make the other regex more complicated.
\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
save in $1\\u000a\\u0009\\u0009\\u0009\\\\n\\\\n\\u0009\\u0009\\u0009\\u0009//
Starting after a blank line\\u000a\\u0009\\u0009\\u0009[
]{0,3}\\u000a\\u0009\\u0009\\u0009(<(hr)\\u0009\\u0009\\u0009\\u0009//
start tag = $2\\u000a\\u0009\\u0009\\u0009\\\\b\\u0009\\u0009\\u0009\\u0009\\u0009//
word break\\u000a\\u0009\\u0009\\u0009([^<>])*?\\u0009\\u0009\\u0009//
\\u000a\\u0009\\u0009\\u0009\\\\/?>)\\u0009\\u0009\\u0009\\u0009// the
matching end tag\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(?=\\\\n{2,})\\u0009\\u0009\\u0009//
followed by a blank
line\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/g,hashElement);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(\\\\n[ ]{0,3}(<(hr)\\\\b([^<>])*?\\\\/?>)[
\\\\t]*(?=\\\\n{2,}))/g,hashElement);\\u000a\\u000a\\u0009// Special
case for standalone HTML
comments:\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
save in $1\\u000a\\u0009\\u0009\\u0009\\\\n\\\\n\\u0009\\u0009\\u0009\\u0009//
Starting after a blank line\\u000a\\u0009\\u0009\\u0009[
]{0,3}\\u0009\\u0009\\u0009// attacklab: g_tab_width -
1\\u000a\\u0009\\u0009\\u0009<!\\u000a\\u0009\\u0009\\u0009(--[^\\\\r]*?--\\\\s*)+\\u000a\\u0009\\u0009\\u0009>\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(?=\\\\n{2,})\\u0009\\u0009\\u0009//
followed by a blank
line\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/g,hashElement);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(\\\\n\\\\n[ ]{0,3}<!(--[^\\\\r]*?--\\\\s*)+>[
\\\\t]*(?=\\\\n{2,}))/g,hashElement);\\u000a\\u000a\\u0009// PHP and
ASP-style processor instructions (<?...?> and
<%...%>)\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\\\n\\\\n\\u0009\\u0009\\u0009\\u0009//
Starting after a blank
line\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
save in $1\\u000a\\u0009\\u0009\\u0009[ ]{0,3}\\u0009\\u0009\\u0009//
attacklab: g_tab_width -
1\\u000a\\u0009\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\u0009<([?%])\\u0009\\u0009\\u0009//
$2\\u000a\\u0009\\u0009\\u0009\\u0009[^\\\\r]*?\\u000a\\u0009\\u0009\\u0009\\u0009\\\\2>\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(?=\\\\n{2,})\\u0009\\u0009\\u0009//
followed by a blank
line\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/g,hashElement);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(?:\\\\n\\\\n)([ ]{0,3}(?:<([?%])[^\\\\r]*?\\\\2>)[
\\\\t]*(?=\\\\n{2,}))/g,hashElement);\\u000a\\u000a\\u0009//
attacklab: Undo double lines (see comment at top of this
function)\\u000a\\u0009text =
text.replace(/\\\\n\\\\n/g,\\\"\\\\n\\\");\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar hashElement = function(wholeMatch,m1)
{\\u000a\\u0009var blockText = m1;\\u000a\\u000a\\u0009// Undo double
lines\\u000a\\u0009blockText =
blockText.replace(/\\\\n\\\\n/g,\\\"\\\\n\\\");\\u000a\\u0009blockText
= blockText.replace(/^\\\\n/,\\\"\\\");\\u000a\\u0009\\u000a\\u0009//
strip trailing blank lines\\u000a\\u0009blockText =
blockText.replace(/\\\\n+$/g,\\\"\\\");\\u000a\\u0009\\u000a\\u0009//
Replace the element text with a marker (\\\"~KxK\\\" where x is its
key)\\u000a\\u0009blockText = \\\"\\\\n\\\\n~K\\\" +
(g_html_blocks.push(blockText)-1) +
\\\"K\\\\n\\\\n\\\";\\u000a\\u0009\\u000a\\u0009return
blockText;\\u000a};\\u000a\\u000avar _RunBlockGamut = function(text)
{\\u000a//\\u000a// These are all the transformations that form
block-level\\u000a// tags like paragraphs, headers, and list
items.\\u000a//\\u000a\\u0009text =
_DoHeaders(text);\\u000a\\u000a\\u0009// Do Horizontal
Rules:\\u000a\\u0009var key = hashBlock(\\\"<hr
/>\\\");\\u000a\\u0009text = text.replace(/^[ ]{0,2}([ ]?\\\\*[
]?){3,}[ \\\\t]*$/gm,key);\\u000a\\u0009text = text.replace(/^[
]{0,2}([ ]?\\\\-[ ]?){3,}[ \\\\t]*$/gm,key);\\u000a\\u0009text =
text.replace(/^[ ]{0,2}([ ]?\\\\_[ ]?){3,}[
\\\\t]*$/gm,key);\\u000a\\u000a\\u0009text =
_DoLists(text);\\u000a\\u0009text =
_DoCodeBlocks(text);\\u000a\\u0009text =
_DoBlockQuotes(text);\\u000a\\u000a\\u0009// We already ran
_HashHTMLBlocks() before, in Markdown(), but that\\u000a\\u0009// was
to escape raw HTML in the original Markdown source. This
time,\\u000a\\u0009// we're escaping the markup we've just created, so
that we don't wrap\\u000a\\u0009// <p> tags around block-level
tags.\\u000a\\u0009text = _HashHTMLBlocks(text);\\u000a\\u0009text =
_FormParagraphs(text);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _RunSpanGamut = function(text)
{\\u000a//\\u000a// These are all the transformations that occur
*within* block-level\\u000a// tags like paragraphs, headers, and list
items.\\u000a//\\u000a\\u000a\\u0009text =
_DoCodeSpans(text);\\u000a\\u0009text =
_EscapeSpecialCharsWithinTagAttributes(text);\\u000a\\u0009text =
_EncodeBackslashEscapes(text);\\u000a\\u000a\\u0009// Process anchor
and image tags. Images must come first,\\u000a\\u0009// because
![foo][f] looks like an anchor.\\u000a\\u0009text =
_DoImages(text);\\u000a\\u0009text =
_DoAnchors(text);\\u000a\\u000a\\u0009// Make links out of things like
`<http://example.com/>`\\u000a\\u0009// Must come after _DoAnchors(),
because you can use < and >\\u000a\\u0009// delimiters in inline links
like [this](<url>).\\u000a\\u0009text =
_DoAutoLinks(text);\\u000a\\u0009text =
_EncodeAmpsAndAngles(text);\\u000a\\u0009text =
_DoItalicsAndBold(text);\\u000a\\u000a\\u0009// Do hard
breaks:\\u000a\\u0009text = text.replace(/  +\\\\n/g,\\\" <br
/>\\\\n\\\");\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar _EscapeSpecialCharsWithinTagAttributes
= function(text) {\\u000a//\\u000a// Within tags -- meaning between <
and > -- encode [\\\\ ` * _] so they\\u000a// don't conflict with
their use in Markdown for code, italics and
strong.\\u000a//\\u000a\\u000a\\u0009// Build a regex to find HTML
tags and comments.  See Friedl's \\u000a\\u0009// \\\"Mastering
Regular Expressions\\\", 2nd Ed., pp. 200-201.\\u000a\\u0009var regex
= /(<[a-z\\\\/!$](\\\"[^\\\"]*\\\"|'[^']*'|[^'\\\">])*>|<!(--.*?--\\\\s*)+>)/gi;\\u000a\\u000a\\u0009text
= text.replace(regex, function(wholeMatch) {\\u000a\\u0009\\u0009var
tag = wholeMatch.replace(/(.)<\\\\/?code>(?=.)/g,\\\"$1`\\\");\\u000a\\u0009\\u0009tag
= escapeCharacters(tag,\\\"\\\\\\\\`*_\\\");\\u000a\\u0009\\u0009return
tag;\\u000a\\u0009});\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar _DoAnchors = function(text)
{\\u000a//\\u000a// Turn Markdown link shortcuts into XHTML <a>
tags.\\u000a//\\u000a\\u0009//\\u000a\\u0009// First, handle
reference-style links: [link text]
[id]\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009\\\\[\\u000a\\u0009\\u0009\\u0009(\\u000a\\u0009\\u0009\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009\\\\[[^\\\\]]*\\\\]\\u0009\\u0009//
allow brackets nested one
level\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009|\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009[^\\\\[]\\u0009\\u0009\\u0009//
or anything else\\u000a\\u0009\\u0009\\u0009\\u0009)*\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u000a\\u0009\\u0009\\u0009[
]?\\u0009\\u0009\\u0009\\u0009\\u0009// one optional
space\\u000a\\u0009\\u0009\\u0009(?:\\\\n[
]*)?\\u0009\\u0009\\u0009\\u0009// one optional newline followed by
spaces\\u000a\\u000a\\u0009\\u0009\\u0009\\\\[\\u000a\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009\\u0009\\u0009//
id = $3\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u0009\\u0009)()()()()\\u0009\\u0009\\u0009\\u0009\\u0009//
pad remaining backreferences\\u000a\\u0009\\u0009/g,_DoAnchors_callback);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(\\\\[((?:\\\\[[^\\\\]]*\\\\]|[^\\\\[\\\\]])*)\\\\][
]?(?:\\\\n[ ]*)?\\\\[(.*?)\\\\])()()()()/g,writeAnchorTag);\\u000a\\u000a\\u0009//\\u000a\\u0009//
Next, inline-style links: [link text](url \\\"optional
title\\\")\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text
= text.replace(/\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009\\u0009\\\\[\\u000a\\u0009\\u0009\\u0009\\u0009(\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\\\[[^\\\\]]*\\\\]\\u0009//
allow brackets nested one
level\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009|\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009[^\\\\[\\\\]]\\u0009\\u0009\\u0009//
or anything else\\u000a\\u0009\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u0009\\u0009\\u0009\\\\(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
literal paren\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009()\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
no id, so leave $3
empty\\u000a\\u0009\\u0009\\u0009<?(.*?)>?\\u0009\\u0009\\u0009\\u0009//
href = $4\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$5\\u000a\\u0009\\u0009\\u0009\\u0009(['\\\"])\\u0009\\u0009\\u0009\\u0009//
quote char = $6\\u000a\\u0009\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009\\u0009//
Title = $7\\u000a\\u0009\\u0009\\u0009\\u0009\\\\6\\u0009\\u0009\\u0009\\u0009\\u0009//
matching quote\\u000a\\u0009\\u0009\\u0009\\u0009[
\\\\t]*\\u0009\\u0009\\u0009\\u0009// ignore any spaces/tabs between
closing quote and
)\\u000a\\u0009\\u0009\\u0009)?\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
title is optional\\u000a\\u0009\\u0009\\u0009\\\\)\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/g,writeAnchorTag);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(\\\\[((?:\\\\[[^\\\\]]*\\\\]|[^\\\\[\\\\]])*)\\\\]\\\\([
\\\\t]*()<?(.*?)>?[ \\\\t]*((['\\\"])(.*?)\\\\6[
\\\\t]*)?\\\\))/g,writeAnchorTag);\\u000a\\u000a\\u0009//\\u000a\\u0009//
Last, handle reference-style shortcuts: [link text]\\u000a\\u0009//
These must come last in case you've also got [link
test][1]\\u000a\\u0009// or [link
test](/foo)\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text
= text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009
\\u0009\\u0009\\u0009\\u0009\\u0009// wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009\\\\[\\u000a\\u0009\\u0009\\u0009([^\\\\[\\\\]]+)\\u0009\\u0009\\u0009\\u0009//
link text = $2; can't contain '[' or
']'\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u0009\\u0009)()()()()()\\u0009\\u0009\\u0009\\u0009\\u0009//
pad rest of backreferences\\u000a\\u0009\\u0009/g,
writeAnchorTag);\\u000a\\u0009*/\\u000a\\u0009text =
text.replace(/(\\\\[([^\\\\[\\\\]]+)\\\\])()()()()()/g,
writeAnchorTag);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar writeAnchorTag =
function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {\\u000a\\u0009if (m7 ==
undefined) m7 = \\\"\\\";\\u000a\\u0009var whole_match =
m1;\\u000a\\u0009var link_text   = m2;\\u000a\\u0009var link_id\\u0009
= m3.toLowerCase();\\u000a\\u0009var url\\u0009\\u0009=
m4;\\u000a\\u0009var title\\u0009= m7;\\u000a\\u0009\\u000a\\u0009if
(url == \\\"\\\") {\\u000a\\u0009\\u0009if (link_id == \\\"\\\")
{\\u000a\\u0009\\u0009\\u0009// lower-case and turn embedded newlines
into spaces\\u000a\\u0009\\u0009\\u0009link_id =
link_text.toLowerCase().replace(/ ?\\\\n/g,\\\"
\\\");\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009url =
\\\"#\\\"+link_id;\\u000a\\u0009\\u0009\\u000a\\u0009\\u0009if
(g_urls[link_id] != undefined) {\\u000a\\u0009\\u0009\\u0009url =
g_urls[link_id];\\u000a\\u0009\\u0009\\u0009if (g_titles[link_id] !=
undefined) {\\u000a\\u0009\\u0009\\u0009\\u0009title =
g_titles[link_id];\\u000a\\u0009\\u0009\\u0009}\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009else
{\\u000a\\u0009\\u0009\\u0009if
(whole_match.search(/\\\\(\\\\s*\\\\)$/m)>-1)
{\\u000a\\u0009\\u0009\\u0009\\u0009// Special case for explicit empty
url\\u000a\\u0009\\u0009\\u0009\\u0009url =
\\\"\\\";\\u000a\\u0009\\u0009\\u0009} else
{\\u000a\\u0009\\u0009\\u0009\\u0009return
whole_match;\\u000a\\u0009\\u0009\\u0009}\\u000a\\u0009\\u0009}\\u000a\\u0009}\\u0009\\u000a\\u0009\\u000a\\u0009url
= escapeCharacters(url,\\\"*_\\\");\\u000a\\u0009var result = \\\"<a
href=\\\\\\\"\\\" + url +
\\\"\\\\\\\"\\\";\\u000a\\u0009\\u000a\\u0009if (title != \\\"\\\")
{\\u000a\\u0009\\u0009title =
title.replace(/\\\"/g,\\\"&quot;\\\");\\u000a\\u0009\\u0009title =
escapeCharacters(title,\\\"*_\\\");\\u000a\\u0009\\u0009result +=
\\\" title=\\\\\\\"\\\" + title +
\\\"\\\\\\\"\\\";\\u000a\\u0009}\\u000a\\u0009\\u000a\\u0009result +=
\\\">\\\" + link_text +
\\\"</a>\\\";\\u000a\\u0009\\u000a\\u0009return
result;\\u000a}\\u000a\\u000a\\u000avar _DoImages = function(text)
{\\u000a//\\u000a// Turn Markdown image shortcuts into <img>
tags.\\u000a//\\u000a\\u000a\\u0009//\\u000a\\u0009// First, handle
reference-style labeled images: ![alt
text][id]\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text
= text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009!\\\\[\\u000a\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009\\u0009//
alt text = $2\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u000a\\u0009\\u0009\\u0009[
]?\\u0009\\u0009\\u0009\\u0009// one optional
space\\u000a\\u0009\\u0009\\u0009(?:\\\\n[ ]*)?\\u0009\\u0009\\u0009//
one optional newline followed by
spaces\\u000a\\u000a\\u0009\\u0009\\u0009\\\\[\\u000a\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009\\u0009//
id = $3\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u0009\\u0009)()()()()\\u0009\\u0009\\u0009\\u0009//
pad rest of backreferences\\u000a\\u0009\\u0009/g,writeImageTag);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(!\\\\[(.*?)\\\\][ ]?(?:\\\\n[
]*)?\\\\[(.*?)\\\\])()()()()/g,writeImageTag);\\u000a\\u000a\\u0009//\\u000a\\u0009//
Next, handle inline images:  ![alt text](url \\\"optional
title\\\")\\u000a\\u0009// Don't forget: encode * and
_\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009!\\\\[\\u000a\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009\\u0009//
alt text = $2\\u000a\\u0009\\u0009\\u0009\\\\]\\u000a\\u0009\\u0009\\u0009\\\\s?\\u0009\\u0009\\u0009\\u0009\\u0009//
One optional whitespace
character\\u000a\\u0009\\u0009\\u0009\\\\(\\u0009\\u0009\\u0009\\u0009\\u0009//
literal paren\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009()\\u0009\\u0009\\u0009\\u0009\\u0009//
no id, so leave $3
empty\\u000a\\u0009\\u0009\\u0009<?(\\\\S+?)>?\\u0009\\u0009\\u0009//
src url = $4\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009//
$5\\u000a\\u0009\\u0009\\u0009\\u0009(['\\\"])\\u0009\\u0009\\u0009//
quote char = $6\\u000a\\u0009\\u0009\\u0009\\u0009(.*?)\\u0009\\u0009\\u0009//
title = $7\\u000a\\u0009\\u0009\\u0009\\u0009\\\\6\\u0009\\u0009\\u0009\\u0009//
matching quote\\u000a\\u0009\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009)?\\u0009\\u0009\\u0009\\u0009\\u0009//
title is optional\\u000a\\u0009\\u0009\\\\)\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/g,writeImageTag);\\u000a\\u0009*/\\u000a\\u0009text
= text.replace(/(!\\\\[(.*?)\\\\]\\\\s?\\\\([ \\\\t]*()<?(\\\\S+?)>?[
\\\\t]*((['\\\"])(.*?)\\\\6[
\\\\t]*)?\\\\))/g,writeImageTag);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar writeImageTag =
function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {\\u000a\\u0009var
whole_match = m1;\\u000a\\u0009var alt_text   = m2;\\u000a\\u0009var
link_id\\u0009 = m3.toLowerCase();\\u000a\\u0009var url\\u0009\\u0009=
m4;\\u000a\\u0009var title\\u0009= m7;\\u000a\\u000a\\u0009if (!title)
title = \\\"\\\";\\u000a\\u0009\\u000a\\u0009if (url == \\\"\\\")
{\\u000a\\u0009\\u0009if (link_id == \\\"\\\")
{\\u000a\\u0009\\u0009\\u0009// lower-case and turn embedded newlines
into spaces\\u000a\\u0009\\u0009\\u0009link_id =
alt_text.toLowerCase().replace(/ ?\\\\n/g,\\\"
\\\");\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009url =
\\\"#\\\"+link_id;\\u000a\\u0009\\u0009\\u000a\\u0009\\u0009if
(g_urls[link_id] != undefined) {\\u000a\\u0009\\u0009\\u0009url =
g_urls[link_id];\\u000a\\u0009\\u0009\\u0009if (g_titles[link_id] !=
undefined) {\\u000a\\u0009\\u0009\\u0009\\u0009title =
g_titles[link_id];\\u000a\\u0009\\u0009\\u0009}\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009else
{\\u000a\\u0009\\u0009\\u0009return
whole_match;\\u000a\\u0009\\u0009}\\u000a\\u0009}\\u0009\\u000a\\u0009\\u000a\\u0009alt_text
= alt_text.replace(/\\\"/g,\\\"&quot;\\\");\\u000a\\u0009url =
escapeCharacters(url,\\\"*_\\\");\\u000a\\u0009var result = \\\"<img
src=\\\\\\\"\\\" + url + \\\"\\\\\\\" alt=\\\\\\\"\\\" + alt_text +
\\\"\\\\\\\"\\\";\\u000a\\u000a\\u0009// attacklab: Markdown.pl adds
empty title attributes to images.\\u000a\\u0009// Replicate this
bug.\\u000a\\u000a\\u0009//if (title != \\\"\\\")
{\\u000a\\u0009\\u0009title =
title.replace(/\\\"/g,\\\"&quot;\\\");\\u000a\\u0009\\u0009title =
escapeCharacters(title,\\\"*_\\\");\\u000a\\u0009\\u0009result +=
\\\" title=\\\\\\\"\\\" + title +
\\\"\\\\\\\"\\\";\\u000a\\u0009//}\\u000a\\u0009\\u000a\\u0009result
+= \\\" />\\\";\\u000a\\u0009\\u000a\\u0009return
result;\\u000a}\\u000a\\u000a\\u000avar _DoHeaders = function(text)
{\\u000a\\u000a\\u0009// Setext-style
headers:\\u000a\\u0009//\\u0009Header
1\\u000a\\u0009//\\u0009========\\u000a\\u0009//
\\u000a\\u0009//\\u0009Header
2\\u000a\\u0009//\\u0009--------\\u000a\\u0009//\\u000a\\u0009text =
text.replace(/^(.+)[ \\\\t]*\\\\n=+[
\\\\t]*\\\\n+/gm,\\u000a\\u0009\\u0009function(wholeMatch,m1){return
hashBlock(\\\"<h1>\\\" + _RunSpanGamut(m1) +
\\\"</h1>\\\");});\\u000a\\u000a\\u0009text = text.replace(/^(.+)[
\\\\t]*\\\\n-+[
\\\\t]*\\\\n+/gm,\\u000a\\u0009\\u0009function(matchFound,m1){return
hashBlock(\\\"<h2>\\\" + _RunSpanGamut(m1) +
\\\"</h2>\\\");});\\u000a\\u000a\\u0009// atx-style
headers:\\u000a\\u0009//  # Header 1\\u000a\\u0009//  ## Header
2\\u000a\\u0009//  ## Header 2 with closing hashes ##\\u000a\\u0009//
...\\u000a\\u0009//  ###### Header
6\\u000a\\u0009//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009\\u0009^(\\\\#{1,6})\\u0009\\u0009\\u0009\\u0009//
$1 = string of #'s\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009(.+?)\\u0009\\u0009\\u0009\\u0009\\u0009//
$2 = Header text\\u000a\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\\\#*\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
optional closing #'s (not
counted)\\u000a\\u0009\\u0009\\u0009\\\\n+\\u000a\\u0009\\u0009/gm,
function() {...});\\u000a\\u0009*/\\u000a\\u000a\\u0009text =
text.replace(/^(\\\\#{1,6})[ \\\\t]*(.+?)[
\\\\t]*\\\\#*\\\\n+/gm,\\u000a\\u0009\\u0009function(wholeMatch,m1,m2)
{\\u000a\\u0009\\u0009\\u0009var h_level =
m1.length;\\u000a\\u0009\\u0009\\u0009return hashBlock(\\\"<h\\\" +
h_level + \\\">\\\" + _RunSpanGamut(m2) + \\\"</h\\\" + h_level +
\\\">\\\");\\u000a\\u0009\\u0009});\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a// This declaration keeps Dojo compressor
from outputting garbage:\\u000avar _ProcessListItems;\\u000a\\u000avar
_DoLists = function(text) {\\u000a//\\u000a// Form HTML ordered
(numbered) and unordered (bulleted)
lists.\\u000a//\\u000a\\u000a\\u0009// attacklab: add sentinel to hack
around khtml/safari bug:\\u000a\\u0009//
http://bugs.webkit.org/show_bug.cgi?id=11231\\u000a\\u0009text +=
\\\"~0\\\";\\u000a\\u000a\\u0009// Re-usable pattern to match any
entirel ul or ol list:\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009var
whole_list = /\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$1 = whole list\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$2\\u000a\\u0009\\u0009\\u0009\\u0009[
]{0,3}\\u0009\\u0009\\u0009\\u0009\\u0009// attacklab: g_tab_width -
1\\u000a\\u0009\\u0009\\u0009\\u0009([*+-]|\\\\d+[.])\\u0009\\u0009\\u0009\\u0009//
$3 = first list item marker\\u000a\\u0009\\u0009\\u0009\\u0009[
\\\\t]+\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009[^\\\\r]+?\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$4\\u000a\\u0009\\u0009\\u0009\\u0009~0\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
sentinel for workaround; should be
$\\u000a\\u0009\\u0009\\u0009|\\u000a\\u0009\\u0009\\u0009\\u0009\\\\n{2,}\\u000a\\u0009\\u0009\\u0009\\u0009(?=\\\\S)\\u000a\\u0009\\u0009\\u0009\\u0009(?!\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
Negative lookahead for another list item
marker\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009[
\\\\t]*\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009(?:[*+-]|\\\\d+[.])[
\\\\t]+\\u000a\\u0009\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009)/g\\u000a\\u0009*/\\u000a\\u0009var
whole_list = /^(([ ]{0,3}([*+-]|\\\\d+[.])[
\\\\t]+)[^\\\\r]+?(~0|\\\\n{2,}(?=\\\\S)(?![
\\\\t]*(?:[*+-]|\\\\d+[.])[ \\\\t]+)))/gm;\\u000a\\u000a\\u0009if
(g_list_level) {\\u000a\\u0009\\u0009text =
text.replace(whole_list,function(wholeMatch,m1,m2)
{\\u000a\\u0009\\u0009\\u0009var list =
m1;\\u000a\\u0009\\u0009\\u0009var list_type =
(m2.search(/[*+-]/g)>-1) ? \\\"ul\\\" :
\\\"ol\\\";\\u000a\\u000a\\u0009\\u0009\\u0009// Turn double returns
into triple returns, so that we can make
a\\u000a\\u0009\\u0009\\u0009// paragraph for the last item in a list,
if necessary:\\u000a\\u0009\\u0009\\u0009list =
list.replace(/\\\\n{2,}/g,\\\"\\\\n\\\\n\\\\n\\\");;\\u000a\\u0009\\u0009\\u0009var
result = _ProcessListItems(list);\\u000a\\u0009\\u000a\\u0009\\u0009\\u0009//
Trim any trailing whitespace, to put the closing
`</$list_type>`\\u000a\\u0009\\u0009\\u0009// up on the preceding
line, to get it past the current stupid\\u000a\\u0009\\u0009\\u0009//
HTML block parser. This is a hack to work around the
terrible\\u000a\\u0009\\u0009\\u0009// hack that is the HTML block
parser.\\u000a\\u0009\\u0009\\u0009result =
result.replace(/\\\\s+$/,\\\"\\\");\\u000a\\u0009\\u0009\\u0009result
= \\\"<\\\"+list_type+\\\">\\\" + result +
\\\"</\\\"+list_type+\\\">\\\\n\\\";\\u000a\\u0009\\u0009\\u0009return
result;\\u000a\\u0009\\u0009});\\u000a\\u0009} else
{\\u000a\\u0009\\u0009whole_list = /(\\\\n\\\\n|^\\\\n?)(([
]{0,3}([*+-]|\\\\d+[.])[ \\\\t]+)[^\\\\r]+?(~0|\\\\n{2,}(?=\\\\S)(?![
\\\\t]*(?:[*+-]|\\\\d+[.])[ \\\\t]+)))/g;\\u000a\\u0009\\u0009text =
text.replace(whole_list,function(wholeMatch,m1,m2,m3)
{\\u000a\\u0009\\u0009\\u0009var runup =
m1;\\u000a\\u0009\\u0009\\u0009var list =
m2;\\u000a\\u000a\\u0009\\u0009\\u0009var list_type =
(m3.search(/[*+-]/g)>-1) ? \\\"ul\\\" :
\\\"ol\\\";\\u000a\\u0009\\u0009\\u0009// Turn double returns into
triple returns, so that we can make a\\u000a\\u0009\\u0009\\u0009//
paragraph for the last item in a list, if
necessary:\\u000a\\u0009\\u0009\\u0009var list =
list.replace(/\\\\n{2,}/g,\\\"\\\\n\\\\n\\\\n\\\");;\\u000a\\u0009\\u0009\\u0009var
result = _ProcessListItems(list);\\u000a\\u0009\\u0009\\u0009result =
runup + \\\"<\\\"+list_type+\\\">\\\\n\\\" + result +
\\\"</\\\"+list_type+\\\">\\\\n\\\";\\u0009\\u000a\\u0009\\u0009\\u0009return
result;\\u000a\\u0009\\u0009});\\u000a\\u0009}\\u000a\\u000a\\u0009//
attacklab: strip sentinel\\u000a\\u0009text =
text.replace(/~0/,\\\"\\\");\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a_ProcessListItems = function(list_str)
{\\u000a//\\u000a//  Process the contents of a single ordered or
unordered list, splitting it\\u000a//  into individual list
items.\\u000a//\\u000a\\u0009// The $g_list_level global keeps track
of when we're inside a list.\\u000a\\u0009// Each time we enter a
list, we increment it; when we leave a list,\\u000a\\u0009// we
decrement. If it's zero, we're not in a list
anymore.\\u000a\\u0009//\\u000a\\u0009// We do this because when we're
not inside a list, we want to treat\\u000a\\u0009// something like
this:\\u000a\\u0009//\\u000a\\u0009//    I recommend upgrading to
version\\u000a\\u0009//    8. Oops, now this line is
treated\\u000a\\u0009//    as a
sub-list.\\u000a\\u0009//\\u000a\\u0009// As a single paragraph,
despite the fact that the second line starts\\u000a\\u0009// with a
digit-period-space sequence.\\u000a\\u0009//\\u000a\\u0009// Whereas
when we're inside a list (or sub-list), that line will
be\\u000a\\u0009// treated as the start of a sub-list. What a kludge,
huh? This is\\u000a\\u0009// an aspect of Markdown's syntax that's
hard to parse perfectly\\u000a\\u0009// without resorting to
mind-reading. Perhaps the solution is to\\u000a\\u0009// change the
syntax rules such that sub-lists must start with a\\u000a\\u0009//
starting cardinal number; e.g. \\\"1.\\\" or
\\\"a.\\\".\\u000a\\u000a\\u0009g_list_level++;\\u000a\\u000a\\u0009//
trim trailing blank lines:\\u000a\\u0009list_str =
list_str.replace(/\\\\n{2,}$/,\\\"\\\\n\\\");\\u000a\\u000a\\u0009//
attacklab: add sentinel to emulate \\\\z\\u000a\\u0009list_str +=
\\\"~0\\\";\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009list_str =
list_str.replace(/\\u000a\\u0009\\u0009\\u0009(\\\\n)?\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
leading line = $1\\u000a\\u0009\\u0009\\u0009(^[
\\\\t]*)\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009// leading
whitespace = $2\\u000a\\u0009\\u0009\\u0009([*+-]|\\\\d+[.]) [
\\\\t]+\\u0009\\u0009\\u0009// list marker =
$3\\u000a\\u0009\\u0009\\u0009([^\\\\r]+?\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
list item text   =
$4\\u000a\\u0009\\u0009\\u0009(\\\\n{1,2}))\\u000a\\u0009\\u0009\\u0009(?=
\\\\n* (~0 | \\\\2 ([*+-]|\\\\d+[.]) [
\\\\t]+))\\u000a\\u0009\\u0009/gm,
function(){...});\\u000a\\u0009*/\\u000a\\u0009list_str =
list_str.replace(/(\\\\n)?(^[ \\\\t]*)([*+-]|\\\\d+[.])[
\\\\t]+([^\\\\r]+?(\\\\n{1,2}))(?=\\\\n*(~0|\\\\2([*+-]|\\\\d+[.])[
\\\\t]+))/gm,\\u000a\\u0009\\u0009function(wholeMatch,m1,m2,m3,m4){\\u000a\\u0009\\u0009\\u0009var
item = m4;\\u000a\\u0009\\u0009\\u0009var leading_line =
m1;\\u000a\\u0009\\u0009\\u0009var leading_space =
m2;\\u000a\\u000a\\u0009\\u0009\\u0009if (leading_line ||
(item.search(/\\\\n{2,}/)>-1))
{\\u000a\\u0009\\u0009\\u0009\\u0009item =
_RunBlockGamut(_Outdent(item));\\u000a\\u0009\\u0009\\u0009}\\u000a\\u0009\\u0009\\u0009else
{\\u000a\\u0009\\u0009\\u0009\\u0009// Recursion for
sub-lists:\\u000a\\u0009\\u0009\\u0009\\u0009item =
_DoLists(_Outdent(item));\\u000a\\u0009\\u0009\\u0009\\u0009item =
item.replace(/\\\\n$/,\\\"\\\"); //
chomp(item)\\u000a\\u0009\\u0009\\u0009\\u0009item =
_RunSpanGamut(item);\\u000a\\u0009\\u0009\\u0009}\\u000a\\u000a\\u0009\\u0009\\u0009return
 \\\"<li>\\\" + item +
\\\"</li>\\\\n\\\";\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u000a\\u0009//
attacklab: strip sentinel\\u000a\\u0009list_str =
list_str.replace(/~0/g,\\\"\\\");\\u000a\\u000a\\u0009g_list_level--;\\u000a\\u0009return
list_str;\\u000a}\\u000a\\u000a\\u000avar _DoCodeBlocks =
function(text) {\\u000a//\\u000a//  Process Markdown `<pre><code>`
blocks.\\u000a//  \\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(text,\\u000a\\u0009\\u0009\\u0009/(?:\\\\n\\\\n|^)\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$1 = the code block -- one or more lines, starting with a
space/tab\\u000a\\u0009\\u0009\\u0009\\u0009(?:\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009(?:[
]{4}|\\\\t)\\u0009\\u0009\\u0009// Lines must start with a tab or a
tab-width of spaces - attacklab:
g_tab_width\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009.*\\\\n+\\u000a\\u0009\\u0009\\u0009\\u0009)+\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009(\\\\n*[
]{0,3}[^ \\\\t\\\\n]|(?=~0))\\u0009// attacklab:
g_tab_width\\u000a\\u0009\\u0009/g,function(){...});\\u000a\\u0009*/\\u000a\\u000a\\u0009//
attacklab: sentinel workarounds for lack of \\\\A and \\\\Z,
safari\\\\khtml bug\\u000a\\u0009text +=
\\\"~0\\\";\\u000a\\u0009\\u000a\\u0009text =
text.replace(/(?:\\\\n\\\\n|^)((?:(?:[ ]{4}|\\\\t).*\\\\n+)+)(\\\\n*[
]{0,3}[^ \\\\t\\\\n]|(?=~0))/g,\\u000a\\u0009\\u0009function(wholeMatch,m1,m2)
{\\u000a\\u0009\\u0009\\u0009var codeblock =
m1;\\u000a\\u0009\\u0009\\u0009var nextChar =
m2;\\u000a\\u0009\\u0009\\u000a\\u0009\\u0009\\u0009codeblock =
_EncodeCode( _Outdent(codeblock));\\u000a\\u0009\\u0009\\u0009codeblock
= _Detab(codeblock);\\u000a\\u0009\\u0009\\u0009codeblock =
codeblock.replace(/^\\\\n+/g,\\\"\\\"); // trim leading
newlines\\u000a\\u0009\\u0009\\u0009codeblock =
codeblock.replace(/\\\\n+$/g,\\\"\\\"); // trim trailing
whitespace\\u000a\\u000a\\u0009\\u0009\\u0009codeblock =
\\\"<pre><code>\\\" + codeblock +
\\\"\\\\n</code></pre>\\\";\\u000a\\u000a\\u0009\\u0009\\u0009return
hashBlock(codeblock) +
nextChar;\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u000a\\u0009//
attacklab: strip sentinel\\u000a\\u0009text =
text.replace(/~0/,\\\"\\\");\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar hashBlock = function(text)
{\\u000a\\u0009text =
text.replace(/(^\\\\n+|\\\\n+$)/g,\\\"\\\");\\u000a\\u0009return
\\\"\\\\n\\\\n~K\\\" + (g_html_blocks.push(text)-1) +
\\\"K\\\\n\\\\n\\\";\\u000a}\\u000a\\u000a\\u000avar _DoCodeSpans =
function(text) {\\u000a//\\u000a//   *  Backtick quotes are used for
<code></code> spans.\\u000a// \\u000a//   *  You can use multiple
backticks as the delimiters if you want to\\u000a//\\u0009 include
literal backticks in the code span. So, this input:\\u000a//\\u0009
\\u000a//\\u0009\\u0009 Just type ``foo `bar` baz`` at the
prompt.\\u000a//\\u0009 \\u000a//\\u0009   Will translate
to:\\u000a//\\u0009 \\u000a//\\u0009\\u0009 <p>Just type <code>foo
`bar` baz</code> at the prompt.</p>\\u000a//\\u0009
\\u000a//\\u0009There's no arbitrary limit to the number of backticks
you\\u000a//\\u0009can use as delimters. If you need three consecutive
backticks\\u000a//\\u0009in your code, use four for delimiters,
etc.\\u000a//\\u000a//  *  You can use spaces to get literal backticks
at the edges:\\u000a//\\u0009 \\u000a//\\u0009\\u0009 ... type ``
`bar` `` ...\\u000a//\\u0009 \\u000a//\\u0009   Turns
to:\\u000a//\\u0009 \\u000a//\\u0009\\u0009 ... type
<code>`bar`</code>
...\\u000a//\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009\\u0009(^|[^\\\\\\\\])\\u0009\\u0009\\u0009\\u0009\\u0009//
Character before opening ` can't be a
backslash\\u000a\\u0009\\u0009\\u0009(`+)\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$2 = Opening run of
`\\u000a\\u0009\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
$3 = The code block\\u000a\\u0009\\u0009\\u0009\\u0009[^\\\\r]*?\\u000a\\u0009\\u0009\\u0009\\u0009[^`]\\u0009\\u0009\\u0009\\u0009\\u0009//
attacklab: work around lack of
lookbehind\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009\\\\2\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
Matching closer\\u000a\\u0009\\u0009\\u0009(?!`)\\u000a\\u0009\\u0009/gm,
function(){...});\\u000a\\u0009*/\\u000a\\u000a\\u0009text =
text.replace(/(^|[^\\\\\\\\])(`+)([^\\\\r]*?[^`])\\\\2(?!`)/gm,\\u000a\\u0009\\u0009function(wholeMatch,m1,m2,m3,m4)
{\\u000a\\u0009\\u0009\\u0009var c = m3;\\u000a\\u0009\\u0009\\u0009c
= c.replace(/^([ \\\\t]*)/g,\\\"\\\");\\u0009// leading
whitespace\\u000a\\u0009\\u0009\\u0009c = c.replace(/[
\\\\t]*$/g,\\\"\\\");\\u0009// trailing
whitespace\\u000a\\u0009\\u0009\\u0009c =
_EncodeCode(c);\\u000a\\u0009\\u0009\\u0009return
m1+\\\"<code>\\\"+c+\\\"</code>\\\";\\u000a\\u0009\\u0009});\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _EncodeCode = function(text)
{\\u000a//\\u000a// Encode/escape certain characters inside Markdown
code runs.\\u000a// The point is that in code, these characters are
literals,\\u000a// and lose their special Markdown
meanings.\\u000a//\\u000a\\u0009// Encode all ampersands; HTML
entities are not\\u000a\\u0009// entities within a Markdown code
span.\\u000a\\u0009text =
text.replace(/&/g,\\\"&amp;\\\");\\u000a\\u000a\\u0009// Do the angle
bracket song and dance:\\u000a\\u0009text =
text.replace(/</g,\\\"&lt;\\\");\\u000a\\u0009text =
text.replace(/>/g,\\\"&gt;\\\");\\u000a\\u000a\\u0009// Now, escape
characters that are magic in Markdown:\\u000a\\u0009text =
escapeCharacters(text,\\\"\\\\*_{}[]\\\\\\\\\\\",false);\\u000a\\u000a//
jj the line above breaks this:\\u000a//---\\u000a\\u000a//*
Item\\u000a\\u000a//   1. Subitem\\u000a\\u000a//            special
char: *\\u000a//---\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _DoItalicsAndBold =
function(text) {\\u000a\\u000a\\u0009// <strong> must go
first:\\u000a\\u0009text =
text.replace(/(\\\\*\\\\*|__)(?=\\\\S)([^\\\\r]*?\\\\S[*_]*)\\\\1/g,\\u000a\\u0009\\u0009\\\"<strong>$2</strong>\\\");\\u000a\\u000a\\u0009text
= text.replace(/(\\\\*|_)(?=\\\\S)([^\\\\r]*?\\\\S)\\\\1/g,\\u000a\\u0009\\u0009\\\"<em>$2</em>\\\");\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _DoBlockQuotes = function(text)
{\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text =
text.replace(/\\u000a\\u0009\\u0009(\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
Wrap whole match in
$1\\u000a\\u0009\\u0009\\u0009(\\u000a\\u0009\\u0009\\u0009\\u0009^[
\\\\t]*>[ \\\\t]?\\u0009\\u0009\\u0009// '>' at the start of a
line\\u000a\\u0009\\u0009\\u0009\\u0009.+\\\\n\\u0009\\u0009\\u0009\\u0009\\u0009//
rest of the first
line\\u000a\\u0009\\u0009\\u0009\\u0009(.+\\\\n)*\\u0009\\u0009\\u0009\\u0009\\u0009//
subsequent consecutive
lines\\u000a\\u0009\\u0009\\u0009\\u0009\\\\n*\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009//
blanks\\u000a\\u0009\\u0009\\u0009)+\\u000a\\u0009\\u0009)\\u000a\\u0009\\u0009/gm,
function(){...});\\u000a\\u0009*/\\u000a\\u000a\\u0009text =
text.replace(/((^[ \\\\t]*>[
\\\\t]?.+\\\\n(.+\\\\n)*\\\\n*)+)/gm,\\u000a\\u0009\\u0009function(wholeMatch,m1)
{\\u000a\\u0009\\u0009\\u0009var bq =
m1;\\u000a\\u000a\\u0009\\u0009\\u0009// attacklab: hack around
Konqueror 3.5.4 bug:\\u000a\\u0009\\u0009\\u0009//
\\\"----------bug\\\".replace(/^-/g,\\\"\\\") ==
\\\"bug\\\"\\u000a\\u000a\\u0009\\u0009\\u0009bq = bq.replace(/^[
\\\\t]*>[ \\\\t]?/gm,\\\"~0\\\");\\u0009// trim one level of
quoting\\u000a\\u000a\\u0009\\u0009\\u0009// attacklab: clean up
hack\\u000a\\u0009\\u0009\\u0009bq =
bq.replace(/~0/g,\\\"\\\");\\u000a\\u000a\\u0009\\u0009\\u0009bq =
bq.replace(/^[ \\\\t]+$/gm,\\\"\\\");\\u0009\\u0009// trim
whitespace-only lines\\u000a\\u0009\\u0009\\u0009bq =
_RunBlockGamut(bq);\\u0009\\u0009\\u0009\\u0009//
recurse\\u000a\\u0009\\u0009\\u0009\\u000a\\u0009\\u0009\\u0009bq =
bq.replace(/(^|\\\\n)/g,\\\"$1  \\\");\\u000a\\u0009\\u0009\\u0009//
These leading spaces screw with <pre> content, so we need to fix
that:\\u000a\\u0009\\u0009\\u0009bq =
bq.replace(\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009/(\\\\s*<pre>[^\\\\r]+?<\\\\/pre>)/gm,\\u000a\\u0009\\u0009\\u0009\\u0009function(wholeMatch,m1)
{\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009var pre =
m1;\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009// attacklab: hack around
Konqueror 3.5.4 bug:\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009pre =
pre.replace(/^
/mg,\\\"~0\\\");\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009pre =
pre.replace(/~0/g,\\\"\\\");\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009return
pre;\\u000a\\u0009\\u0009\\u0009\\u0009});\\u000a\\u0009\\u0009\\u0009\\u000a\\u0009\\u0009\\u0009return
hashBlock(\\\"<blockquote>\\\\n\\\" + bq +
\\\"\\\\n</blockquote>\\\");\\u000a\\u0009\\u0009});\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _FormParagraphs = function(text)
{\\u000a//\\u000a//  Params:\\u000a//    $text - string to process
with html <p> tags\\u000a//\\u000a\\u000a\\u0009// Strip leading and
trailing lines:\\u000a\\u0009text =
text.replace(/^\\\\n+/g,\\\"\\\");\\u000a\\u0009text =
text.replace(/\\\\n+$/g,\\\"\\\");\\u000a\\u000a\\u0009var grafs =
text.split(/\\\\n{2,}/g);\\u000a\\u0009var grafsOut = new
Array();\\u000a\\u000a\\u0009//\\u000a\\u0009// Wrap <p>
tags.\\u000a\\u0009//\\u000a\\u0009var end =
grafs.length;\\u000a\\u0009for (var i=0; i<end; i++)
{\\u000a\\u0009\\u0009var str =
grafs[i];\\u000a\\u000a\\u0009\\u0009// if this is an HTML marker,
copy it\\u000a\\u0009\\u0009if (str.search(/~K(\\\\d+)K/g) >= 0)
{\\u000a\\u0009\\u0009\\u0009grafsOut.push(str);\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009else
if (str.search(/\\\\S/) >= 0) {\\u000a\\u0009\\u0009\\u0009str =
_RunSpanGamut(str);\\u000a\\u0009\\u0009\\u0009str = str.replace(/^([
\\\\t]*)/g,\\\"<p>\\\");\\u000a\\u0009\\u0009\\u0009str +=
\\\"</p>\\\"\\u000a\\u0009\\u0009\\u0009grafsOut.push(str);\\u000a\\u0009\\u0009}\\u000a\\u000a\\u0009}\\u000a\\u000a\\u0009//\\u000a\\u0009//
Unhashify HTML blocks\\u000a\\u0009//\\u000a\\u0009end =
grafsOut.length;\\u000a\\u0009for (var i=0; i<end; i++)
{\\u000a\\u0009\\u0009// if this is a marker for an html
block...\\u000a\\u0009\\u0009while (grafsOut[i].search(/~K(\\\\d+)K/)
>= 0) {\\u000a\\u0009\\u0009\\u0009var blockText =
g_html_blocks[RegExp.$1];\\u000a\\u0009\\u0009\\u0009blockText =
blockText.replace(/\\\\$/g,\\\"$$$$\\\"); // Escape any dollar
signs\\u000a\\u0009\\u0009\\u0009grafsOut[i] =
grafsOut[i].replace(/~K\\\\d+K/,blockText);\\u000a\\u0009\\u0009}\\u000a\\u0009}\\u000a\\u000a\\u0009return
grafsOut.join(\\\"\\\\n\\\\n\\\");\\u000a}\\u000a\\u000a\\u000avar
_EncodeAmpsAndAngles = function(text) {\\u000a// Smart processing for
ampersands and angle brackets that need to be
encoded.\\u000a\\u0009\\u000a\\u0009// Ampersand-encoding based
entirely on Nat Irons's Amputator MT plugin:\\u000a\\u0009//
http://bumppo.net/projects/amputator/\\u000a\\u0009text =
text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\\\\w+);)/g,\\\"&amp;\\\");\\u000a\\u0009\\u000a\\u0009//
Encode naked <'s\\u000a\\u0009text =
text.replace(/<(?![a-z\\\\/?\\\\$!])/gi,\\\"&lt;\\\");\\u000a\\u0009\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _EncodeBackslashEscapes =
function(text) {\\u000a//\\u000a//   Parameter:  String.\\u000a//
Returns:\\u0009The string, with after processing the following
backslash\\u000a//\\u0009\\u0009\\u0009   escape
sequences.\\u000a//\\u000a\\u000a\\u0009// attacklab: The polite way
to do this is with the new\\u000a\\u0009// escapeCharacters()
function:\\u000a\\u0009//\\u000a\\u0009// \\u0009text =
escapeCharacters(text,\\\"\\\\\\\\\\\",true);\\u000a\\u0009//
\\u0009text = escapeCharacters(text,\\\"`*_{}[]()>#+-.!\\\",true);\\u000a\\u0009//\\u000a\\u0009//
...but we're sidestepping its use of the (slow) RegExp
constructor\\u000a\\u0009// as an optimization for Firefox.  This
function gets called a LOT.\\u000a\\u000a\\u0009text =
text.replace(/\\\\\\\\(\\\\\\\\)/g,escapeCharacters_callback);\\u000a\\u0009text
= text.replace(/\\\\\\\\([`*_{}\\\\[\\\\]()>#+-.!])/g,escapeCharacters_callback);\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _DoAutoLinks = function(text)
{\\u000a\\u000a\\u0009text =
text.replace(/<((https?|ftp|dict):[^'\\\">\\\\s]+)>/gi,\\\"<a
href=\\\\\\\"$1\\\\\\\">$1</a>\\\");\\u000a\\u000a\\u0009// Email
addresses: <address@domain.foo>\\u000a\\u000a\\u0009/*\\u000a\\u0009\\u0009text
= text.replace(/\\u000a\\u0009\\u0009\\u0009<\\u000a\\u0009\\u0009\\u0009(?:mailto:)?\\u000a\\u0009\\u0009\\u0009(\\u000a\\u0009\\u0009\\u0009\\u0009[-.\\\\w]+\\u000a\\u0009\\u0009\\u0009\\u0009\\\\@\\u000a\\u0009\\u0009\\u0009\\u0009[-a-z0-9]+(\\\\.[-a-z0-9]+)*\\\\.[a-z]+\\u000a\\u0009\\u0009\\u0009)\\u000a\\u0009\\u0009\\u0009>\\u000a\\u0009\\u0009/gi,
_DoAutoLinks_callback());\\u000a\\u0009*/\\u000a\\u0009text =
text.replace(/<(?:mailto:)?([-.\\\\w]+\\\\@[-a-z0-9]+(\\\\.[-a-z0-9]+)*\\\\.[a-z]+)>/gi,\\u000a\\u0009\\u0009function(wholeMatch,m1)
{\\u000a\\u0009\\u0009\\u0009return _EncodeEmailAddress(
_UnescapeSpecialChars(m1)
);\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _EncodeEmailAddress =
function(addr) {\\u000a//\\u000a//  Input: an email address, e.g.
\\\"foo@example.com\\\"\\u000a//\\u000a//  Output: the email address
as a mailto link, with each character\\u000a//\\u0009of the address
encoded as either a decimal or hex entity, in\\u000a//\\u0009the hopes
of foiling most address harvesting spam bots.
E.g.:\\u000a//\\u000a//\\u0009<a
href=\\\"&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;\\u000a//\\u0009
  x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;\\\">&#102;&#111;&#111;\\u000a//\\u0009
  &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>\\u000a//\\u000a//
 Based on a filter by Matthew Wickline, posted to the
BBEdit-Talk\\u000a//  mailing list:
<http://tinyurl.com/yu7ue>\\u000a//\\u000a\\u000a\\u0009// attacklab:
why can't javascript speak hex?\\u000a\\u0009function char2hex(ch)
{\\u000a\\u0009\\u0009var hexDigits =
'0123456789ABCDEF';\\u000a\\u0009\\u0009var dec =
ch.charCodeAt(0);\\u000a\\u0009\\u0009return(hexDigits.charAt(dec>>4)
+ hexDigits.charAt(dec&15));\\u000a\\u0009}\\u000a\\u000a\\u0009var
encode = [\\u000a\\u0009\\u0009function(ch){return
\\\"&#\\\"+ch.charCodeAt(0)+\\\";\\\";},\\u000a\\u0009\\u0009function(ch){return
\\\"&#x\\\"+char2hex(ch)+\\\";\\\";},\\u000a\\u0009\\u0009function(ch){return
ch;}\\u000a\\u0009];\\u000a\\u000a\\u0009addr = \\\"mailto:\\\" +
addr;\\u000a\\u000a\\u0009addr = addr.replace(/./g, function(ch)
{\\u000a\\u0009\\u0009if (ch == \\\"@\\\") {\\u000a\\u0009\\u0009
\\u0009// this *must* be encoded. I
insist.\\u000a\\u0009\\u0009\\u0009ch =
encode[Math.floor(Math.random()*2)](ch);\\u000a\\u0009\\u0009} else if
(ch !=\\\":\\\") {\\u000a\\u0009\\u0009\\u0009// leave ':' alone (to
spot mailto: later)\\u000a\\u0009\\u0009\\u0009var r =
Math.random();\\u000a\\u0009\\u0009\\u0009// roughly 10% raw, 45% hex,
45% dec\\u000a\\u0009\\u0009\\u0009ch =
(\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009r > .9
?\\u0009encode[2](ch)   :\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009r >
.45 ?\\u0009encode[1](ch)
:\\u000a\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009\\u0009encode[0](ch)\\u000a\\u0009\\u0009\\u0009\\u0009);\\u000a\\u0009\\u0009}\\u000a\\u0009\\u0009return
ch;\\u000a\\u0009});\\u000a\\u000a\\u0009addr = \\\"<a
href=\\\\\\\"\\\" + addr + \\\"\\\\\\\">\\\" + addr +
\\\"</a>\\\";\\u000a\\u0009addr =
addr.replace(/\\\">.+:/g,\\\"\\\\\\\">\\\"); // strip the mailto: from
the visible part\\u000a\\u000a\\u0009return
addr;\\u000a}\\u000a\\u000a\\u000avar _UnescapeSpecialChars =
function(text) {\\u000a//\\u000a// Swap back in all the special
characters we've hidden.\\u000a//\\u000a\\u0009text =
text.replace(/~E(\\\\d+)E/g,\\u000a\\u0009\\u0009function(wholeMatch,m1)
{\\u000a\\u0009\\u0009\\u0009var charCodeToReplace =
parseInt(m1);\\u000a\\u0009\\u0009\\u0009return
String.fromCharCode(charCodeToReplace);\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar _Outdent = function(text)
{\\u000a//\\u000a// Remove one level of line-leading tabs or
spaces\\u000a//\\u000a\\u000a\\u0009// attacklab: hack around
Konqueror 3.5.4 bug:\\u000a\\u0009//
\\\"----------bug\\\".replace(/^-/g,\\\"\\\") ==
\\\"bug\\\"\\u000a\\u000a\\u0009text = text.replace(/^(\\\\t|[
]{1,4})/gm,\\\"~0\\\"); // attacklab:
g_tab_width\\u000a\\u000a\\u0009// attacklab: clean up
hack\\u000a\\u0009text =
text.replace(/~0/g,\\\"\\\")\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000avar _Detab = function(text) {\\u000a//
attacklab: Detab's completely rewritten for speed.\\u000a// In perl we
could fix it by anchoring the regexp with \\\\G.\\u000a// In
javascript we're less fortunate.\\u000a\\u000a\\u0009// expand first
n-1 tabs\\u000a\\u0009text = text.replace(/\\\\t(?=\\\\t)/g,\\\"
\\\"); // attacklab: g_tab_width\\u000a\\u000a\\u0009// replace the
nth with two sentinels\\u000a\\u0009text =
text.replace(/\\\\t/g,\\\"~A~B\\\");\\u000a\\u000a\\u0009// use the
sentinel to anchor our regex so it doesn't explode\\u000a\\u0009text =
text.replace(/~B(.+?)~A/g,\\u000a\\u0009\\u0009function(wholeMatch,m1,m2)
{\\u000a\\u0009\\u0009\\u0009var leadingText =
m1;\\u000a\\u0009\\u0009\\u0009var numSpaces = 4 - leadingText.length
% 4;  // attacklab: g_tab_width\\u000a\\u000a\\u0009\\u0009\\u0009//
there *must* be a better way to do
this:\\u000a\\u0009\\u0009\\u0009for (var i=0; i<numSpaces; i++)
leadingText+=\\\" \\\";\\u000a\\u000a\\u0009\\u0009\\u0009return
leadingText;\\u000a\\u0009\\u0009}\\u000a\\u0009);\\u000a\\u000a\\u0009//
clean up sentinels\\u000a\\u0009text = text.replace(/~A/g,\\\"
\\\");  // attacklab: g_tab_width\\u000a\\u0009text =
text.replace(/~B/g,\\\"\\\");\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000a//\\u000a//  attacklab: Utility
functions\\u000a//\\u000a\\u000a\\u000avar escapeCharacters =
function(text, charsToEscape, afterBackslash) {\\u000a\\u0009// First
we have to escape the escape characters so that\\u000a\\u0009// we can
build a character class out of them\\u000a\\u0009var regexString =
\\\"([\\\" + charsToEscape.replace(/([\\\\[\\\\]\\\\\\\\])/g,\\\"\\\\\\\\$1\\\")
+ \\\"])\\\";\\u000a\\u000a\\u0009if (afterBackslash)
{\\u000a\\u0009\\u0009regexString = \\\"\\\\\\\\\\\\\\\\\\\" +
regexString;\\u000a\\u0009}\\u000a\\u000a\\u0009var regex = new
RegExp(regexString,\\\"g\\\");\\u000a\\u0009text =
text.replace(regex,escapeCharacters_callback);\\u000a\\u000a\\u0009return
text;\\u000a}\\u000a\\u000a\\u000avar escapeCharacters_callback =
function(wholeMatch,m1) {\\u000a\\u0009var charCodeToEscape =
m1.charCodeAt(0);\\u000a\\u0009return
\\\"~E\\\"+charCodeToEscape+\\\"E\\\";\\u000a}\\u000a\\u000aexports.encode
= exports.markdown = function (src) {\\u000a   return
exports.makeHtml(src);\\u000a};\\u000a\\u000aexports.main = function
(system) {\\u000a    var command = system.args.shift();\\u000a    if
(!system.args.length) {\\u000a
system.stdout.write(exports.markdown(system.stdin.read())).flush();\\u000a
   } else {\\u000a        var arg;\\u000a        while (arg =
system.args.shift()) {\\u000a            var out =
system.fs.basename(arg, '.md') + '.html';\\u000a
print(out);\\u000a            system.fs.write(out,
exports.markdown(system.fs.read(arg)));\\u000a        }\\u000a
}\\u000a};\",\"atom\":\"// atom feed generator\\u000a// requries E4X
support.\\u000a\\u000afunction f(n) {    // Format integers to have at
least two digits.\\u000a    return n < 10 ? '0' + n :
n;\\u000a}\\u000a\\u000afunction rfc3339(date) {\\u000a  return
date.getUTCFullYear()   + '-' +\\u000a    f(date.getUTCMonth() + 1) +
'-' +\\u000a    f(date.getUTCDate())      + 'T' +\\u000a
f(date.getUTCHours())     + ':' +\\u000a    f(date.getUTCMinutes())
+ ':' +\\u000a    f(date.getUTCSeconds())   +
'Z';\\u000a};\\u000a\\u000aexports.header = function(data) {\\u000a
var f = <feed xmlns=\\\"http://www.w3.org/2005/Atom\\\"/>;\\u000a
f.title = data.title;\\u000a  f.id = data.feed_id;\\u000a
f.link.@href = data.feed_link;\\u000a  f.link.@rel =
\\\"self\\\";\\u000a  f.generator = \\\"CouchApp on
CouchDB\\\";\\u000a  f.updated = rfc3339(data.updated);\\u000a  return
f.toXMLString().replace(/\\\\<\\\\/feed\\\\>/,'');\\u000a};\\u000a\\u000aexports.entry
= function(data) {\\u000a  var entry = <entry/>;\\u000a  entry.id =
data.entry_id;\\u000a  entry.title = data.title;\\u000a  entry.content
= data.content;\\u000a  entry.content.@type = (data.content_type ||
'html');\\u000a  entry.updated = rfc3339(data.updated);\\u000a
entry.author = <author><name>{data.author}</name></author>;\\u000a
entry.link.@href = data.alternate;\\u000a  entry.link.@rel =
\\\"alternate\\\";\\u000a  return entry;\\u000a}\",\"linkup\":\"//
this code makes http://example.com into a link, \\u000a// and also
handles @name and #hashtag\\u000a\\u000a// todo add
[[wiki_links]]\\u000a\\u000avar mustache =
require(\\\"vendor/couchapp/lib/mustache\\\");\\u000aexports.encode =
function(body, person_prefix, tag_prefix) {\\u000a  body =
mustache.escape(body);\\u000a  person_prefix = person_prefix ||
\\\"http://twitter.com/\\\";\\u000a  tag_prefix = tag_prefix ||
\\\"http://delicious.com/tag/\\\";\\u000a  return
body.replace(/((ftp|http|https):\\\\/\\\\/(\\\\w+:{0,1}\\\\w*@)?(\\\\S+)(:[0-9]+)?(\\\\/|\\\\/([\\\\w#!:.?+=&%@!\\\\-\\\\/]))?)/gi,function(a)
{\\u000a    return '<a target=\\\"_blank\\\"
href=\\\"'+a+'\\\">'+a+'</a>';\\u000a
}).replace(/\\\\@([\\\\w\\\\-]+)/g,function(user,name) {\\u000a
return '<a href=\\\"'+person_prefix+encodeURIComponent(name)+'\\\">'+user+'</a>';\\u000a
 }).replace(/\\\\#([\\\\w\\\\-\\\\.]+)/g,function(word,tag) {\\u000a
 return '<a href=\\\"'+tag_prefix+encodeURIComponent(tag)+'\\\">'+word+'</a>';\\u000a
 });\\u000a};\",\"path\":\"// from couch.js\\u000afunction
encodeOptions(options) {\\u000a  var buf = [];\\u000a  if
(typeof(options) == \\\"object\\\" && options !== null) {\\u000a
for (var name in options) {\\u000a      if
(!options.hasOwnProperty(name)) {continue;}\\u000a      var value =
options[name];\\u000a      if (name == \\\"key\\\" || name ==
\\\"startkey\\\" || name == \\\"endkey\\\") {\\u000a        value =
JSON.stringify(value);\\u000a      }\\u000a
buf.push(encodeURIComponent(name) + \\\"=\\\" +
encodeURIComponent(value));\\u000a    }\\u000a  }\\u000a  if
(!buf.length) {\\u000a    return \\\"\\\";\\u000a  }\\u000a  return
\\\"?\\\" + buf.join(\\\"&\\\");\\u000a}\\u000a\\u000afunction
concatArgs(array, args) {\\u000a  for (var i=0; i < args.length; i++)
{\\u000a    array.push(args[i]);\\u000a  };\\u000a  return
array;\\u000a};\\u000a\\u000afunction makePath(array) {\\u000a  var
options, path;\\u000a  \\u000a  if (typeof array[array.length - 1] !=
\\\"string\\\") {\\u000a    // it's a params hash\\u000a    options =
array.pop();\\u000a  }\\u000a  path = array.map(function(item) {return
encodeURIComponent(item)}).join('/');\\u000a  if (options) {\\u000a
return path + encodeOptions(options);\\u000a  } else {\\u000a
return path;    \\u000a  }\\u000a};\\u000a\\u000aexports.init =
function(req) {\\u000a  return {\\u000a    asset : function() {\\u000a
     var p = req.path, parts = ['', p[0], p[1] , p[2]];\\u000a
return makePath(concatArgs(parts, arguments));\\u000a    },\\u000a
show : function() {\\u000a      var p = req.path, parts = ['', p[0],
p[1] , p[2], '_show'];\\u000a      return makePath(concatArgs(parts,
arguments));\\u000a    },\\u000a    list : function() {\\u000a
var p = req.path, parts = ['', p[0], p[1] , p[2], '_list'];\\u000a
 return makePath(concatArgs(parts, arguments));\\u000a    },\\u000a
update : function() {\\u000a      var p = req.path, parts = ['', p[0],
p[1] , p[2], '_update'];\\u000a      return makePath(concatArgs(parts,
arguments));\\u000a    },\\u000a    limit : function(limit) {\\u000a
   var query = req.query;\\u000a      var l = query.limit;\\u000a
query.limit = limit;\\u000a      var view = req.path[req.path.length -
1];\\u000a      var list = req.path[req.path.length - 2];\\u000a
var link = this.list(list, view, query);\\u000a      query.limit =
l;\\u000a      return link;\\u000a    },\\u000a    older :
function(key) {\\u000a      if (!typeof key == \\\"undefined\\\")
return null;\\u000a      var query = req.query;\\u000a
query.startkey = key;\\u000a      query.skip=1;\\u000a      var view =
req.path[req.path.length - 1];\\u000a      var list =
req.path[req.path.length - 2];\\u000a      return this.list(list,
view, query);\\u000a    },\\u000a    absolute : function(path)
{\\u000a      return 'http://' + req.headers.Host + path;\\u000a
}\\u000a  }\\u000a};\",\"md5\":\"/*\\u000a * A JavaScript
implementation of the RSA Data Security, Inc. MD5 Message\\u000a *
Digest Algorithm, as defined in RFC 1321.\\u000a * Version 2.1
Copyright (C) Paul Johnston 1999 - 2002.\\u000a * Other contributors:
Greg Holt, Andrew Kepert, Ydnar, Lostinet\\u000a * Distributed under
the BSD License\\u000a * See http://pajhome.org.uk/crypt/md5 for more
info.\\u000a */\\u000a\\u000a/*\\u000a * Configurable variables. You
may need to tweak these to be compatible with\\u000a * the
server-side, but the defaults work in most cases.\\u000a */\\u000avar
hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase
 */\\u000avar b64pad  = \\\"\\\"; /* base-64 pad character. \\\"=\\\"
for strict RFC compliance   */\\u000avar chrsz   = 8;  /* bits per
input character. 8 - ASCII; 16 - Unicode
*/\\u000a\\u000a/*\\u000a * These are the functions you'll usually
want to call\\u000a * They take string arguments and return either hex
or base-64 encoded strings\\u000a */\\u000afunction hex_md5(s){ return
binl2hex(core_md5(str2binl(s), s.length * chrsz));}\\u000afunction
b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length *
chrsz));}\\u000afunction str_md5(s){ return
binl2str(core_md5(str2binl(s), s.length * chrsz));}\\u000afunction
hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data));
}\\u000afunction b64_hmac_md5(key, data) { return
binl2b64(core_hmac_md5(key, data)); }\\u000afunction str_hmac_md5(key,
data) { return binl2str(core_hmac_md5(key, data));
}\\u000a\\u000a/*\\u000a * Perform a simple self-test to see if the VM
is working\\u000a */\\u000afunction md5_vm_test()\\u000a{\\u000a
return hex_md5(\\\"abc\\\") ==
\\\"900150983cd24fb0d6963f7d28e17f72\\\";\\u000a}\\u000a\\u000a/*\\u000a
* Calculate the MD5 of an array of little-endian words, and a bit
length\\u000a keep\\u000a */\\u000afunction core_md5(x,
len)\\u000a{\\u000a  /* append padding */\\u000a  x[len >> 5] |= 0x80
<< ((len) % 32);\\u000a  x[(((len + 64) >>> 9) << 4) + 14] =
len;\\u000a\\u000a  var a =  1732584193;\\u000a  var b =
-271733879;\\u000a  var c = -1732584194;\\u000a  var d =
271733878;\\u000a\\u000a  for(var i = 0; i < x.length; i += 16)\\u000a
 {\\u000a    var olda = a;\\u000a    var oldb = b;\\u000a    var oldc
= c;\\u000a    var oldd = d;\\u000a\\u000a    a = md5_ff(a, b, c, d,
x[i+ 0], 7 , -680876936);\\u000a    d = md5_ff(d, a, b, c, x[i+ 1],
12, -389564586);\\u000a    c = md5_ff(c, d, a, b, x[i+ 2], 17,
606105819);\\u000a    b = md5_ff(b, c, d, a, x[i+ 3], 22,
-1044525330);\\u000a    a = md5_ff(a, b, c, d, x[i+ 4], 7 ,
-176418897);\\u000a    d = md5_ff(d, a, b, c, x[i+ 5], 12,
1200080426);\\u000a    c = md5_ff(c, d, a, b, x[i+ 6], 17,
-1473231341);\\u000a    b = md5_ff(b, c, d, a, x[i+ 7], 22,
-45705983);\\u000a    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,
1770035416);\\u000a    d = md5_ff(d, a, b, c, x[i+ 9], 12,
-1958414417);\\u000a    c = md5_ff(c, d, a, b, x[i+10], 17,
-42063);\\u000a    b = md5_ff(b, c, d, a, x[i+11], 22,
-1990404162);\\u000a    a = md5_ff(a, b, c, d, x[i+12], 7 ,
1804603682);\\u000a    d = md5_ff(d, a, b, c, x[i+13], 12,
-40341101);\\u000a    c = md5_ff(c, d, a, b, x[i+14], 17,
-1502002290);\\u000a    b = md5_ff(b, c, d, a, x[i+15], 22,
1236535329);\\u000a\\u000a    a = md5_gg(a, b, c, d, x[i+ 1], 5 ,
-165796510);\\u000a    d = md5_gg(d, a, b, c, x[i+ 6], 9 ,
-1069501632);\\u000a    c = md5_gg(c, d, a, b, x[i+11], 14,
643717713);\\u000a    b = md5_gg(b, c, d, a, x[i+ 0], 20,
-373897302);\\u000a    a = md5_gg(a, b, c, d, x[i+ 5], 5 ,
-701558691);\\u000a    d = md5_gg(d, a, b, c, x[i+10], 9 ,
38016083);\\u000a    c = md5_gg(c, d, a, b, x[i+15], 14,
-660478335);\\u000a    b = md5_gg(b, c, d, a, x[i+ 4], 20,
-405537848);\\u000a    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,
568446438);\\u000a    d = md5_gg(d, a, b, c, x[i+14], 9 ,
-1019803690);\\u000a    c = md5_gg(c, d, a, b, x[i+ 3], 14,
-187363961);\\u000a    b = md5_gg(b, c, d, a, x[i+ 8], 20,
1163531501);\\u000a    a = md5_gg(a, b, c, d, x[i+13], 5 ,
-1444681467);\\u000a    d = md5_gg(d, a, b, c, x[i+ 2], 9 ,
-51403784);\\u000a    c = md5_gg(c, d, a, b, x[i+ 7], 14,
1735328473);\\u000a    b = md5_gg(b, c, d, a, x[i+12], 20,
-1926607734);\\u000a\\u000a    a = md5_hh(a, b, c, d, x[i+ 5], 4 ,
-378558);\\u000a    d = md5_hh(d, a, b, c, x[i+ 8], 11,
-2022574463);\\u000a    c = md5_hh(c, d, a, b, x[i+11], 16,
1839030562);\\u000a    b = md5_hh(b, c, d, a, x[i+14], 23,
-35309556);\\u000a    a = md5_hh(a, b, c, d, x[i+ 1], 4 ,
-1530992060);\\u000a    d = md5_hh(d, a, b, c, x[i+ 4], 11,
1272893353);\\u000a    c = md5_hh(c, d, a, b, x[i+ 7], 16,
-155497632);\\u000a    b = md5_hh(b, c, d, a, x[i+10], 23,
-1094730640);\\u000a    a = md5_hh(a, b, c, d, x[i+13], 4 ,
681279174);\\u000a    d = md5_hh(d, a, b, c, x[i+ 0], 11,
-358537222);\\u000a    c = md5_hh(c, d, a, b, x[i+ 3], 16,
-722521979);\\u000a    b = md5_hh(b, c, d, a, x[i+ 6], 23,
76029189);\\u000a    a = md5_hh(a, b, c, d, x[i+ 9], 4 ,
-640364487);\\u000a    d = md5_hh(d, a, b, c, x[i+12], 11,
-421815835);\\u000a    c = md5_hh(c, d, a, b, x[i+15], 16,
530742520);\\u000a    b = md5_hh(b, c, d, a, x[i+ 2], 23,
-995338651);\\u000a\\u000a    a = md5_ii(a, b, c, d, x[i+ 0], 6 ,
-198630844);\\u000a    d = md5_ii(d, a, b, c, x[i+ 7], 10,
1126891415);\\u000a    c = md5_ii(c, d, a, b, x[i+14], 15,
-1416354905);\\u000a    b = md5_ii(b, c, d, a, x[i+ 5], 21,
-57434055);\\u000a    a = md5_ii(a, b, c, d, x[i+12], 6 ,
1700485571);\\u000a    d = md5_ii(d, a, b, c, x[i+ 3], 10,
-1894986606);\\u000a    c = md5_ii(c, d, a, b, x[i+10], 15,
-1051523);\\u000a    b = md5_ii(b, c, d, a, x[i+ 1], 21,
-2054922799);\\u000a    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,
1873313359);\\u000a    d = md5_ii(d, a, b, c, x[i+15], 10,
-30611744);\\u000a    c = md5_ii(c, d, a, b, x[i+ 6], 15,
-1560198380);\\u000a    b = md5_ii(b, c, d, a, x[i+13], 21,
1309151649);\\u000a    a = md5_ii(a, b, c, d, x[i+ 4], 6 ,
-145523070);\\u000a    d = md5_ii(d, a, b, c, x[i+11], 10,
-1120210379);\\u000a    c = md5_ii(c, d, a, b, x[i+ 2], 15,
718787259);\\u000a    b = md5_ii(b, c, d, a, x[i+ 9], 21,
-343485551);\\u000a\\u000a    a = safe_add(a, olda);\\u000a    b =
safe_add(b, oldb);\\u000a    c = safe_add(c, oldc);\\u000a    d =
safe_add(d, oldd);\\u000a  }\\u000a  return Array(a, b, c,
d);\\u000a\\u000a}\\u000a\\u000a/*\\u000a * These functions implement
the four basic operations the algorithm uses.\\u000a */\\u000afunction
md5_cmn(q, a, b, x, s, t)\\u000a{\\u000a  return
safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)),
s),b);\\u000a}\\u000afunction md5_ff(a, b, c, d, x, s,
t)\\u000a{\\u000a  return md5_cmn((b & c) | ((~b) & d), a, b, x, s,
t);\\u000a}\\u000afunction md5_gg(a, b, c, d, x, s, t)\\u000a{\\u000a
return md5_cmn((b & d) | (c & (~d)), a, b, x, s,
t);\\u000a}\\u000afunction md5_hh(a, b, c, d, x, s, t)\\u000a{\\u000a
return md5_cmn(b ^ c ^ d, a, b, x, s, t);\\u000a}\\u000afunction
md5_ii(a, b, c, d, x, s, t)\\u000a{\\u000a  return md5_cmn(c ^ (b |
(~d)), a, b, x, s, t);\\u000a}\\u000a\\u000a/*\\u000a * Calculate the
HMAC-MD5, of a key and some data\\u000a */\\u000afunction
core_hmac_md5(key, data)\\u000a{\\u000a  var bkey =
str2binl(key);\\u000a  if(bkey.length > 16) bkey = core_md5(bkey,
key.length * chrsz);\\u000a\\u000a  var ipad = Array(16), opad =
Array(16);\\u000a  for(var i = 0; i < 16; i++)\\u000a  {\\u000a
ipad[i] = bkey[i] ^ 0x36363636;\\u000a    opad[i] = bkey[i] ^
0x5C5C5C5C;\\u000a  }\\u000a\\u000a  var hash =
core_md5(ipad.concat(str2binl(data)), 512 + data.length *
chrsz);\\u000a  return core_md5(opad.concat(hash), 512 +
128);\\u000a}\\u000a\\u000a/*\\u000a * Add integers, wrapping at 2^32.
This uses 16-bit operations internally\\u000a * to work around bugs in
some JS interpreters.\\u000a */\\u000afunction safe_add(x,
y)\\u000a{\\u000a  var lsw = (x & 0xFFFF) + (y & 0xFFFF);\\u000a  var
msw = (x >> 16) + (y >> 16) + (lsw >> 16);\\u000a  return (msw << 16)
| (lsw & 0xFFFF);\\u000a}\\u000a\\u000a/*\\u000a * Bitwise rotate a
32-bit number to the left.\\u000a */\\u000afunction bit_rol(num,
cnt)\\u000a{\\u000a  return (num << cnt) | (num >>> (32 -
cnt));\\u000a}\\u000a\\u000a/*\\u000a * Convert a string to an array
of little-endian words\\u000a * If chrsz is ASCII, characters >255
have their hi-byte silently ignored.\\u000a keep\\u000a
*/\\u000afunction str2binl(str)\\u000a{\\u000a  var bin =
Array();\\u000a  var mask = (1 << chrsz) - 1;\\u000a  for(var i = 0; i
< str.length * chrsz; i += chrsz)\\u000a    bin[i>>5] |=
(str.charCodeAt(i / chrsz) & mask) << (i%32);\\u000a  return
bin;\\u000a}\\u000a\\u000a/*\\u000a * Convert an array of
little-endian words to a string\\u000a */\\u000afunction
binl2str(bin)\\u000a{\\u000a  var str = \\\"\\\";\\u000a  var mask =
(1 << chrsz) - 1;\\u000a  for(var i = 0; i < bin.length * 32; i +=
chrsz)\\u000a    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) &
mask);\\u000a  return str;\\u000a}\\u000a\\u000a/*\\u000a * Convert an
array of little-endian words to a hex string.\\u000a keep\\u000a
*/\\u000afunction binl2hex(binarray)\\u000a{\\u000a  var hex_tab =
hexcase ? \\\"0123456789ABCDEF\\\" : \\\"0123456789abcdef\\\";\\u000a
var str = \\\"\\\";\\u000a  for(var i = 0; i < binarray.length * 4;
i++)\\u000a  {\\u000a    str += hex_tab.charAt((binarray[i>>2] >>
((i%4)*8+4)) & 0xF) +\\u000a           hex_tab.charAt((binarray[i>>2]
>> ((i%4)*8  )) & 0xF);\\u000a  }\\u000a  return
str;\\u000a}\\u000a\\u000a/*\\u000a * Convert an array of
little-endian words to a base-64 string\\u000a */\\u000afunction
binl2b64(binarray)\\u000a{\\u000a  var tab =
\\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\u000a
 var str = \\\"\\\";\\u000a  for(var i = 0; i < binarray.length * 4; i
+= 3)\\u000a  {\\u000a    var triplet = (((binarray[i   >> 2] >> 8 * (
i   %4)) & 0xFF) << 16)\\u000a                | (((binarray[i+1 >> 2]
>> 8 * ((i+1)%4)) & 0xFF) << 8 )\\u000a                |
((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);\\u000a    for(var j =
0; j < 4; j++)\\u000a    {\\u000a      if(i * 8 + j * 6 >
binarray.length * 32) str += b64pad;\\u000a      else str +=
tab.charAt((triplet >> 6*(3-j)) & 0x3F);\\u000a    }\\u000a  }\\u000a
return str;\\u000a}\\u000a\\u000aexports.hex =
hex_md5;\",\"validate\":\"// a library for validations\\u000a// over
time we expect to extract more helpers and move them
here.\\u000aexports.init = function(newDoc, oldDoc, userCtx, secObj)
{\\u000a  var v = {};\\u000a  \\u000a  v.forbidden = function(message)
{    \\u000a    throw({forbidden : message});\\u000a  };\\u000a\\u000a
 v.unauthorized = function(message) {\\u000a    throw({unauthorized :
message});\\u000a  };\\u000a\\u000a  v.assert = function(should,
message) {\\u000a    if (!should) v.forbidden(message);\\u000a
}\\u000a  \\u000a  v.isAdmin = function() {\\u000a    return
userCtx.roles.indexOf('_admin') != -1\\u000a  };\\u000a  \\u000a
v.isRole = function(role) {\\u000a    return
userCtx.roles.indexOf(role) != -1\\u000a  };\\u000a\\u000a  v.require
= function() {\\u000a    for (var i=0; i < arguments.length; i++)
{\\u000a      var field = arguments[i];\\u000a      message = \\\"The
'\\\"+field+\\\"' field is required.\\\";\\u000a      if (typeof
newDoc[field] == \\\"undefined\\\") v.forbidden(message);\\u000a
};\\u000a  };\\u000a\\u000a  v.unchanged = function(field) {\\u000a
if (oldDoc && oldDoc[field] != newDoc[field]) \\u000a
v.forbidden(\\\"You may not change the '\\\"+field+\\\"'
field.\\\");\\u000a  };\\u000a\\u000a  v.matches = function(field,
regex, message) {\\u000a    if (!newDoc[field].match(regex)) {\\u000a
    message = message || \\\"Format of '\\\"+field+\\\"' field is
invalid.\\\";\\u000a      v.forbidden(message);    \\u000a    }\\u000a
 };\\u000a\\u000a  // this ensures that the date will be UTC,
parseable, and collate correctly\\u000a  v.dateFormat =
function(field) {\\u000a    message = \\\"Sorry, '\\\"+field+\\\"' is
not a valid date format. Try: 2010-02-24T17:00:03.432Z\\\";\\u000a
v.matches(field,
/\\\\d{4}\\\\-\\\\d{2}\\\\-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d*)?Z/,
message);\\u000a  }\\u000a  \\u000a  return
v;\\u000a};\",\"mustache\":\"/*\\u000a * CommonJS-compatible
mustache.js module\\u000a *\\u000a * See
http://github.com/janl/mustache.js for more info.\\u000a
*/\\u000a\\u000a/*\\u000a  mustache.js \u2014 Logic-less templates in
JavaScript\\u000a\\u000a  See http://mustache.github.com/ for more
info.\\u000a*/\\u000a\\u000avar Mustache = function() {\\u000a  var
Renderer = function() {};\\u000a\\u000a  Renderer.prototype = {\\u000a
   otag: \\\"{{\\\",\\u000a    ctag: \\\"}}\\\",\\u000a    pragmas:
{},\\u000a    buffer: [],\\u000a    pragmas_implemented: {\\u000a
\\\"IMPLICIT-ITERATOR\\\": true\\u000a    },\\u000a    context:
{},\\u000a\\u000a    render: function(template, context, partials,
in_recursion) {\\u000a      // reset buffer & set context\\u000a
if(!in_recursion) {\\u000a        this.context = context;\\u000a
 this.buffer = []; // TODO: make this non-lazy\\u000a
}\\u000a\\u000a      // fail fast\\u000a
if(!this.includes(\\\"\\\", template)) {\\u000a
if(in_recursion) {\\u000a          return template;\\u000a        }
else {\\u000a          this.send(template);\\u000a
return;\\u000a        }\\u000a      }\\u000a\\u000a      template =
this.render_pragmas(template);\\u000a      var html =
this.render_section(template, context, partials);\\u000a
if(in_recursion) {\\u000a        return this.render_tags(html,
context, partials, in_recursion);\\u000a      }\\u000a\\u000a
this.render_tags(html, context, partials, in_recursion);\\u000a
},\\u000a\\u000a    /*\\u000a      Sends parsed lines\\u000a
*/\\u000a    send: function(line) {\\u000a      if(line != \\\"\\\")
{\\u000a        this.buffer.push(line);\\u000a      }\\u000a
},\\u000a\\u000a    /*\\u000a      Looks for %PRAGMAS\\u000a
*/\\u000a    render_pragmas: function(template) {\\u000a      // no
pragmas\\u000a      if(!this.includes(\\\"%\\\", template)) {\\u000a
     return template;\\u000a      }\\u000a\\u000a      var that =
this;\\u000a      var regex = new RegExp(this.otag +
\\\"%([\\\\\\\\w-]+) ?([\\\\\\\\w]+=[\\\\\\\\w]+)?\\\" +\\u000a
    this.ctag);\\u000a      return template.replace(regex,
function(match, pragma, options) {\\u000a
if(!that.pragmas_implemented[pragma]) {\\u000a
throw({message: \\u000a            \\\"This implementation of mustache
doesn't understand the '\\\" +\\u000a            pragma + \\\"'
pragma\\\"});\\u000a        }\\u000a        that.pragmas[pragma] =
{};\\u000a        if(options) {\\u000a          var opts =
options.split(\\\"=\\\");\\u000a
that.pragmas[pragma][opts[0]] = opts[1];\\u000a        }\\u000a
return \\\"\\\";\\u000a        // ignore unknown pragmas
silently\\u000a      });\\u000a    },\\u000a\\u000a    /*\\u000a
Tries to find a partial in the curent scope and render it\\u000a
*/\\u000a    render_partial: function(name, context, partials)
{\\u000a      name = this.trim(name);\\u000a      if(!partials ||
partials[name] === undefined) {\\u000a        throw({message:
\\\"unknown_partial '\\\" + name + \\\"'\\\"});\\u000a      }\\u000a
   if(typeof(context[name]) != \\\"object\\\") {\\u000a        return
this.render(partials[name], context, partials, true);\\u000a
}\\u000a      return this.render(partials[name], context[name],
partials, true);\\u000a    },\\u000a\\u000a    /*\\u000a      Renders
inverted (^) and normal (#) sections\\u000a    */\\u000a
render_section: function(template, context, partials) {\\u000a
if(!this.includes(\\\"#\\\", template) && !this.includes(\\\"^\\\",
template)) {\\u000a        return template;\\u000a
}\\u000a\\u000a      var that = this;\\u000a      // CSW - Added
\\\"+?\\\" so it finds the tighest bound, not the widest\\u000a
var regex = new RegExp(this.otag +
\\\"(\\\\\\\\^|\\\\\\\\#)\\\\\\\\s*(.+)\\\\\\\\s*\\\" + this.ctag
+\\u000a              \\\"\\\\n*([\\\\\\\\s\\\\\\\\S]+?)\\\" +
this.otag + \\\"\\\\\\\\/\\\\\\\\s*\\\\\\\\2\\\\\\\\s*\\\" + this.ctag
+\\u000a              \\\"\\\\\\\\s*\\\", \\\"mg\\\");\\u000a\\u000a
   // for each {{#foo}}{{/foo}} section do...\\u000a      return
template.replace(regex, function(match, type, name, content) {\\u000a
      var value = that.find(name, context);\\u000a        if(type ==
\\\"^\\\") { // inverted section\\u000a          if(!value ||
that.is_array(value) && value.length === 0) {\\u000a            //
false or empty list, render it\\u000a            return
that.render(content, context, partials, true);\\u000a          } else
{\\u000a            return \\\"\\\";\\u000a          }\\u000a        }
else if(type == \\\"#\\\") { // normal section\\u000a
if(that.is_array(value)) { // Enumerable, Let's loop!\\u000a
 return that.map(value, function(row) {\\u000a              return
that.render(content, that.create_context(row),\\u000a
partials, true);\\u000a            }).join(\\\"\\\");\\u000a
} else if(that.is_object(value)) { // Object, Use it as
subcontext!\\u000a            return that.render(content,
that.create_context(value),\\u000a              partials,
true);\\u000a          } else if(typeof value === \\\"function\\\")
{\\u000a            // higher order section\\u000a            return
value.call(context, content, function(text) {\\u000a
return that.render(text, context, partials, true);\\u000a
});\\u000a          } else if(value) { // boolean section\\u000a
     return that.render(content, context, partials, true);\\u000a
    } else {\\u000a            return \\\"\\\";\\u000a
}\\u000a        }\\u000a      });\\u000a    },\\u000a\\u000a
/*\\u000a      Replace {{foo}} and friends with values from our
view\\u000a    */\\u000a    render_tags: function(template, context,
partials, in_recursion) {\\u000a      // tit for tat\\u000a      var
that = this;\\u000a\\u000a      var new_regex = function() {\\u000a
    return new RegExp(that.otag +
\\\"(=|!|>|\\\\\\\\{|%)?([^\\\\\\\\/#\\\\\\\\^]+?)\\\\\\\\1?\\\"
+\\u000a          that.ctag + \\\"+\\\", \\\"g\\\");\\u000a
};\\u000a\\u000a      var regex = new_regex();\\u000a      var
tag_replace_callback = function(match, operator, name) {\\u000a
switch(operator) {\\u000a        case \\\"!\\\": // ignore
comments\\u000a          return \\\"\\\";\\u000a        case
\\\"=\\\": // set new delimiters, rebuild the replace regexp\\u000a
      that.set_delimiters(name);\\u000a          regex =
new_regex();\\u000a          return \\\"\\\";\\u000a        case
\\\">\\\": // render partial\\u000a          return
that.render_partial(name, context, partials);\\u000a        case
\\\"{\\\": // the triple mustache is unescaped\\u000a          return
that.find(name, context);\\u000a        default: // escape the
value\\u000a          return that.escape(that.find(name,
context));\\u000a        }\\u000a      };\\u000a      var lines =
template.split(\\\"\\\\n\\\");\\u000a      for(var i = 0; i <
lines.length; i++) {\\u000a        lines[i] = lines[i].replace(regex,
tag_replace_callback, this);\\u000a        if(!in_recursion) {\\u000a
        this.send(lines[i]);\\u000a        }\\u000a
}\\u000a\\u000a      if(in_recursion) {\\u000a        return
lines.join(\\\"\\\\n\\\");\\u000a      }\\u000a    },\\u000a\\u000a
set_delimiters: function(delimiters) {\\u000a      var dels =
delimiters.split(\\\" \\\");\\u000a      this.otag =
this.escape_regex(dels[0]);\\u000a      this.ctag =
this.escape_regex(dels[1]);\\u000a    },\\u000a\\u000a
escape_regex: function(text) {\\u000a      // thank you Simon
Willison\\u000a      if(!arguments.callee.sRE) {\\u000a        var
specials = [\\u000a          '/', '.', '*', '+', '?', '|',\\u000a
    '(', ')', '[', ']', '{', '}', '\\\\\\\\'\\u000a        ];\\u000a
     arguments.callee.sRE = new RegExp(\\u000a          '(\\\\\\\\' +
specials.join('|\\\\\\\\') + ')', 'g'\\u000a        );\\u000a
}\\u000a      return text.replace(arguments.callee.sRE,
'\\\\\\\\$1');\\u000a    },\\u000a\\u000a    /*\\u000a      find
`name` in current `context`. That is find me a value\\u000a      from
the view object\\u000a    */\\u000a    find: function(name, context)
{\\u000a      name = this.trim(name);\\u000a\\u000a      // Checks
whether a value is thruthy or false or 0\\u000a      function
is_kinda_truthy(bool) {\\u000a        return bool === false || bool
=== 0 || bool;\\u000a      }\\u000a\\u000a      var value;\\u000a
if(is_kinda_truthy(context[name])) {\\u000a        value =
context[name];\\u000a      } else
if(is_kinda_truthy(this.context[name])) {\\u000a        value =
this.context[name];\\u000a      }\\u000a\\u000a      if(typeof value
=== \\\"function\\\") {\\u000a        return
value.apply(context);\\u000a      }\\u000a      if(value !==
undefined) {\\u000a        return value;\\u000a      }\\u000a      //
silently ignore unkown variables\\u000a      return \\\"\\\";\\u000a
 },\\u000a\\u000a    // Utility methods\\u000a\\u000a    /* includes
tag */\\u000a    includes: function(needle, haystack) {\\u000a
return haystack.indexOf(this.otag + needle) != -1;\\u000a
},\\u000a\\u000a    /*\\u000a      Does away with nasty
characters\\u000a    */\\u000a    escape: function(s) {\\u000a      s
= String(s === null ? \\\"\\\" : s);\\u000a      return
s.replace(/&(?!\\\\w+;)|[\\\"<>\\\\\\\\]/g, function(s) {\\u000a
 switch(s) {\\u000a        case \\\"&\\\": return
\\\"&amp;\\\";\\u000a        case \\\"\\\\\\\\\\\": return
\\\"\\\\\\\\\\\\\\\\\\\";\\u000a        case '\\\"': return
'\\\\\\\"';\\u000a        case \\\"<\\\": return \\\"&lt;\\\";\\u000a
      case \\\">\\\": return \\\"&gt;\\\";\\u000a        default:
return s;\\u000a        }\\u000a      });\\u000a    },\\u000a\\u000a
 // by @langalex, support for arrays of strings\\u000a
create_context: function(_context) {\\u000a
if(this.is_object(_context)) {\\u000a        return _context;\\u000a
   } else {\\u000a        var iterator = \\\".\\\";\\u000a
if(this.pragmas[\\\"IMPLICIT-ITERATOR\\\"]) {\\u000a          iterator
= this.pragmas[\\\"IMPLICIT-ITERATOR\\\"].iterator;\\u000a
}\\u000a        var ctx = {};\\u000a        ctx[iterator] =
_context;\\u000a        return ctx;\\u000a      }\\u000a
},\\u000a\\u000a    is_object: function(a) {\\u000a      return a &&
typeof a == \\\"object\\\";\\u000a    },\\u000a\\u000a    is_array:
function(a) {\\u000a      return Object.prototype.toString.call(a) ===
'[object Array]';\\u000a    },\\u000a\\u000a    /*\\u000a      Gets
rid of leading and trailing whitespace\\u000a    */\\u000a    trim:
function(s) {\\u000a      return s.replace(/^\\\\s*|\\\\s*$/g,
\\\"\\\");\\u000a    },\\u000a\\u000a    /*\\u000a      Why, why, why?
Because IE. Cry, cry cry.\\u000a    */\\u000a    map: function(array,
fn) {\\u000a      if (typeof array.map == \\\"function\\\") {\\u000a
     return array.map(fn);\\u000a      } else {\\u000a        var r =
[];\\u000a        var l = array.length;\\u000a        for(var i = 0; i
< l; i++) {\\u000a          r.push(fn(array[i]));\\u000a
}\\u000a        return r;\\u000a      }\\u000a    }\\u000a
};\\u000a\\u000a  return({\\u000a    name: \\\"mustache.js\\\",\\u000a
   version: \\\"0.3.1-dev\\\",\\u000a\\u000a    /*\\u000a      Turns a
template and view into HTML\\u000a    */\\u000a    to_html:
function(template, view, partials, send_fun) {\\u000a      var
renderer = new Renderer();\\u000a      if(send_fun) {\\u000a
renderer.send = send_fun;\\u000a      }\\u000a
renderer.render(template, view, partials);\\u000a      if(!send_fun)
{\\u000a        return renderer.buffer.join(\\\"\\\\n\\\");\\u000a
 }\\u000a    },\\u000a    escape : function(text) {\\u000a      return
new Renderer().escape(text);\\u000a    }\\u000a
});\\u000a}();\\u000a\\u000aexports.name =
Mustache.name;\\u000aexports.version =
Mustache.version;\\u000a\\u000aexports.to_html =
Mustache.to_html;\\u000aexports.escape =
Mustache.escape;\",\"docform\":\"// Licensed under the Apache License,
Version 2.0 (the \\\"License\\\"); you may not\\u000a// use this file
except in compliance with the License.  You may obtain a copy\\u000a//
of the License at\\u000a//\\u000a//
http://www.apache.org/licenses/LICENSE-2.0\\u000a//\\u000a// Unless
required by applicable law or agreed to in writing, software\\u000a//
distributed under the License is distributed on an \\\"AS IS\\\"
BASIS, WITHOUT\\u000a// WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied.  See the\\u000a// License for the specific
language governing permissions and limitations under\\u000a// the
License.\\u000a\\u000a// turn the form into deep json\\u000a// field
names like 'author-email' get turned into json like\\u000a//
{\\\"author\\\":{\\\"email\\\":\\\"quentin@example.com\\\"}}\\u000a//
acts on doc by reference, so you can safely pass non-form fields
through\\u000a\\u000afunction docForm(formSelector, opts) {\\u000a
var localFormDoc = {};\\u000a  opts = opts || {};\\u000a  opts.fields
= opts.fields || [];\\u000a\\u000a  // turn the form into deep
json\\u000a  // field names like 'author-email' get turned into json
like\\u000a  //
{\\\"author\\\":{\\\"email\\\":\\\"quentin@example.com\\\"}}\\u000a
function formToDeepJSON(form, fields, doc) {\\u000a    form =
$(form);\\u000a    fields.forEach(function(field) {\\u000a      var
element = form.find(\\\"[name=\\\"+field+\\\"]\\\"),\\u000a
parts = field.split('-'),\\u000a          frontObj = doc, frontName =
parts.shift();\\u000a\\u000a      if (element.attr('type') ===
'checkbox') {\\u000a          var val =
element.attr('checked');\\u000a      } else {\\u000a          var val
= element.val();\\u000a          if (!val) {\\u000a            if
(frontObj[field]) {\\u000a                delete
frontObj[field];\\u000a            }\\u000a            return;\\u000a
        }\\u000a      }\\u000a      \\u000a      while (parts.length >
0) {\\u000a        frontObj[frontName] = frontObj[frontName] ||
{};\\u000a        frontObj = frontObj[frontName];\\u000a
frontName = parts.shift();\\u000a      }\\u000a
frontObj[frontName] = val;\\u000a    });\\u000a  }\\u000a  \\u000a  //
Apply the behavior\\u000a  $(formSelector).submit(function(e) {\\u000a
   e.preventDefault();\\u000a    if (opts.validate && opts.validate()
== false) { return false;}\\u000a    // formToDeepJSON acts on
localFormDoc by reference\\u000a    formToDeepJSON(this, opts.fields,
localFormDoc);\\u000a    if (opts.beforeSave)
{opts.beforeSave(localFormDoc);}\\u000a    db.saveDoc(localFormDoc,
{\\u000a      success : function(resp) {\\u000a        if
(opts.success) {opts.success(resp, localFormDoc);}\\u000a
}\\u000a    });\\u000a    \\u000a    return false;\\u000a
});\\u000a\\u000a  // populate form from an existing doc\\u000a
function docToForm(doc) {\\u000a    var form = $(formSelector);\\u000a
   // fills in forms\\u000a    opts.fields.forEach(function(field)
{\\u000a      var parts = field.split('-');\\u000a      var run =
true, frontObj = doc, frontName = parts.shift();\\u000a      while
(frontObj && parts.length > 0) {                \\u000a
frontObj = frontObj[frontName];\\u000a        frontName =
parts.shift();\\u000a      }\\u000a      if (frontObj &&
frontObj[frontName]) {\\u000a        var element =
form.find(\\\"[name=\\\"+field+\\\"]\\\");\\u000a        if
(element.attr('type') === 'checkbox') {\\u000a
element.attr('checked', frontObj[frontName]);\\u000a        } else
{\\u000a          element.val(frontObj[frontName]);\\u000a
}\\u000a      }\\u000a    });\\u000a  }\\u000a  \\u000a  if (opts.id)
{\\u000a    db.openDoc(opts.id, {\\u000a      attachPrevRev :
opts.attachPrevRev,\\u000a      error: function() {\\u000a        if
(opts.error) {opts.error.apply(opts, arguments);}\\u000a
},\\u000a      success: function(doc) {\\u000a        if (opts.load ||
opts.onLoad) {(opts.load || opts.onLoad)(doc);}\\u000a
localFormDoc = doc;\\u000a        docToForm(doc);\\u000a
}});\\u000a  } else if (opts.template) {\\u000a    if (opts.load ||
opts.onLoad) {(opts.load || opts.onLoad)(opts.template);}\\u000a
localFormDoc = opts.template;\\u000a
docToForm(localFormDoc);\\u000a  }\\u000a  var instance = {\\u000a
deleteDoc : function(opts) {\\u000a      opts = opts || {};\\u000a
 if (confirm(\\\"Really delete this document?\\\")) {
\\u000a        db.removeDoc(localFormDoc, opts);\\u000a      }\\u000a
  },\\u000a    localDoc : function() {\\u000a
formToDeepJSON(formSelector, opts.fields, localFormDoc);\\u000a
return localFormDoc;\\u000a    }\\u000a  };\\u000a  return
instance;\\u000a}\"},\"metadata\":{\"name\":\"couchapp\",\"fetch_uri\":\"git://github.com/couchapp/couchapp.git\",\"description\":\"official
couchapp vendor\"}}},\"language\":\"javascript\",\"views\":{\"title_issn\":{\"map\":\"function(doc)
{\\u000a  if (doc.v706[0][\\\"_\\\"] == 't'){\\u000a     subjects =
new Array();\\u000a\\u000a     for (i in doc.v440){\\u000a
subjects.push(doc.v440[i][\\\"_\\\"]);\\u000a     }\\u000a\\u000a
emit(doc.v400[0][\\\"_\\\"],
{\\\"collection\\\":doc.v980[\\\"0\\\"][\\\"_\\\"],
\\\"issn\\\":doc.v400[0][\\\"_\\\"], \\\"title\\\":
doc.v100[0][\\\"_\\\"], \\\"subject\\\": subjects, \\\"publisher\\\":
doc.v480[0], \\\"insert_date\\\":doc.v942[0][\\\"_\\\"]});\\u000a
}\\u000a}\"},\"article_pr\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 'h' && doc.v41[0][\\\"_\\\"] ==\\\"pr\\\"
){\\u000a     emit([doc.v980[\\\"0\\\"][\\\"_\\\"],doc.v65[0][\\\"_\\\"]],{\\\"collection\\\":doc.v980[0][\\\"_\\\"],
\\\"pid\\\":doc.v880[0][\\\"_\\\"], \\\"article_title\\\":doc.v12,
\\\"author\\\":doc.v10, \\\"affiliation\\\":doc.v70,
\\\"abstract\\\":doc.v83});\\u000a
}\\u000a}\"},\"recent-items\":{\"map\":\"function(doc) {\\u000a  if
(doc.created_at) {\\u000a    emit(doc.created_at, doc);\\u000a
}\\u000a};\"},\"title\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 't'){\\u000a     subjects = new
Array();\\u000a\\u000a     for (i in doc.v440){\\u000a
subjects.push(doc.v440[i][\\\"_\\\"]);\\u000a     }\\u000a     \\u000a
    emit(doc.v100[0][\\\"_\\\"],
{\\\"collection\\\":doc.v980[\\\"0\\\"][\\\"_\\\"], \\\"issn\\\":
doc.v400[0][\\\"_\\\"], \\\"title\\\":doc.v100[0][\\\"_\\\"],
\\\"subject\\\": subjects, \\\"publisher\\\": doc.v480[0][\\\"_\\\"],
\\\"insert_date\\\":doc.v942[0][\\\"_\\\"]});\\u000a
}\\u000a}\"},\"article_pid\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 'h'){\\u000a
emit(doc.v880[0][\\\"_\\\"],doc.v880[0][\\\"c\\\"],doc.v12[0][\\\"_\\\"]);\\u000a
 }\\u000a}\"},\"article_date\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 'h'){\\u000a
emit([doc.v980[\\\"0\\\"][\\\"_\\\"],doc.v65[0][\\\"_\\\"]],{\\\"collection\\\":doc.v980[0][\\\"_\\\"],
\\\"pid\\\":doc.v880[0][\\\"_\\\"], \\\"article_title\\\":doc.v12,
\\\"author\\\":doc.v10, \\\"affiliation\\\":doc.v70,
\\\"abstract\\\":doc.v83});\\u000a
}\\u000a}\"},\"article\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 'h'){\\u000a
emit(doc.v880[0][\\\"_\\\"],doc);\\u000a
}\\u000a}\"},\"title_date\":{\"map\":\"function(doc) {\\u000a  if
(doc.v706[0][\\\"_\\\"] == 't'){\\u000a     subjects = new
Array();\\u000a\\u000a     for (i in doc.v440){\\u000a
subjects.push(doc.v440[i][\\\"_\\\"]);\\u000a     }\\u000a\\u000a
emit([doc.v980[\\\"0\\\"][\\\"_\\\"], doc.v942[0][\\\"_\\\"]],
{\\\"collection\\\":doc.v980[\\\"0\\\"][\\\"_\\\"],
\\\"issn\\\":doc.v400[0][\\\"_\\\"], \\\"title\\\":
doc.v100[0][\\\"_\\\"], \\\"subject\\\": subjects, \\\"publisher\\\":
doc.v480[0], \\\"insert_date\\\":doc.v942[0][\\\"_\\\"]});\\u000a
}\\u000a}\"}},\"lists\":{\"article_feed\":\"function(head, req)
{\\u000a  var row;\\u000a  var result = null;\\u000a  start({\\u000a
 \\\"headers\\\": {\\u000a      \\\"Content-Type\\\":
\\\"text/html\\\"\\u000a     }\\u000a  });\\u000a
send('<ul>');\\u000a  while(row = getRow()) {\\u000a    send('<li>' +
row.value.article_title[0][\\\"_\\\"] + '</li>');\\u000a  }\\u000a
send('</ul>');\\u000a}\\u000a\\u000a\\u000a/*\\u000afunction(head,
req) {\\u000a  var row;\\u000a  var result = null;\\u000a
start({\\u000a    \\\"headers\\\": {\\u000a      \\\"Content-Type\\\":
\\\"text/html\\\"\\u000a     }\\u000a  });\\u000a\\u000a  result =
'<ul>';\\u000a  while(row = getRow()) {\\u000a    result = result +
'<li>' + row.value.article_title[0][\\\"_\\\"] + '</li>';\\u000a
}\\u000a  result = result + '</ul>';\\u000a\\u000a
send(result);\\u000a}\\u000a*/\"},\"evently\":{\"profile\":{\"profileReady\":{\"mustache\":\"<p>Most
applications will customize this template
(<tt>ddoc.evently.profile.profileReady.mustache</tt>) for user
input.</p>\\u000a\\u000a<div class=\\\"avatar\\\">\\u000a
{{#gravatar_url}}<img
src=\\\"{{gravatar_url}}\\\"/>{{/gravatar_url}}\\u000a  <div
class=\\\"name\\\">\\u000a    {{name}}\\u000a
</div>\\u000a</div>\\u000a\\u000a<form>\\u000a  <label>New message
from {{nickname}}: <input type=\\\"text\\\" name=\\\"message\\\"
size=60 value=\\\"\\\"></label>\\u000a</form>\\u000a\\u000a<div
style=\\\"clear:left;\\\"></div>\",\"selectors\":{\"form\":{\"submit\":\"function()
{\\u000a  var form = $(this);\\u000a  var fdoc =
form.serializeObject();\\u000a  fdoc.created_at = new Date();\\u000a
fdoc.profile = $$(\\\"#profile\\\").profile;\\u000a
$$(this).app.db.saveDoc(fdoc, {\\u000a    success : function()
{\\u000a      form[0].reset();\\u000a    }\\u000a  });\\u000a  return
false;\\u000a};\"}}}},\"items\":{\"_changes\":{\"query\":{\"limit\":50,\"descending\":\"true\",\"view\":\"recent-items\"},\"data\":\"function(data)
{\\u000a  // $.log(data)\\u000a  var p;\\u000a  return {\\u000a
items : data.rows.map(function(r) {\\u000a      p = (r.value &&
r.value.profile) || {};\\u000a      p.message = r.value &&
r.value.message;\\u000a      return p;\\u000a    })\\u000a
}\\u000a};\",\"mustache\":\"<p>Customize this format here:
<tt>ddoc.evently.items._changes.mustache</tt></p>\\u000a<h3>Recent
Messages</h3>\\u000a<ul>\\u000a  {{#items}}\\u000a    <li>\\u000a
<div class=\\\"avatar\\\">\\u000a        {{#gravatar_url}}<img
src=\\\"{{gravatar_url}}\\\"
alt=\\\"{{name}}\\\"/>{{/gravatar_url}}\\u000a        <div
class=\\\"name\\\">\\u000a          {{nickname}}\\u000a
</div>\\u000a      </div>\\u000a      <p>{{message}}</p>\\u000a
<div style=\\\"clear:left;\\\"></div>\\u000a    </li>\\u000a
{{/items}}\\u000a</ul>\\u000a<p><em>Protip:</em> If you setup
continuous replication between this database and a remote one, this
list will reflect remote changes in near real-time.</p>\\u000a<p>This
would be a good place to add
pagination.</p>\"}}},\"updates\":{},\"README\":\"## Generated by
CouchApp\\u000a\\u000aCouchApps are web applications which can be
served directly from [CouchDB](http://couchdb.apache.org). This gives
them the nice property of replicating just like any other data stored
in CouchDB. They are also simple to write as they can use the built-in
jQuery libraries and plugins that ship with
CouchDB.\\u000a\\u000a[More info about CouchApps
here.](http://couchapp.org)\\u000a\\u000a## Deploying this
app\\u000a\\u000aAssuming you just cloned this app from git, and you
have changed into the app directory in your terminal, you want to push
it to your CouchDB with the CouchApp command line tool, like
this:\\u000a\\u000a    couchapp push .
http://name:password@hostname:5984/mydatabase\\u000a\\u000aIf you
don't have a password on your CouchDB (admin party) you can do it like
this (but it's a bad, idea, set a password):\\u000a\\u000a    couchapp
push . http://hostname:5984/mydatabase\\u000a\\u000aIf you get sick of
typing the URL, you should setup a `.couchapprc` file in the root of
your directory. Remember not to check this into version control as it
will have passwords in it.\\u000a\\u000aThe `.couchapprc` file should
have contents like this:\\u000a\\u000a    {\\u000a      \\\"env\\\" :
{\\u000a        \\\"public\\\" : {\\u000a          \\\"db\\\" :
\\\"http://name:pass@mycouch.couchone.com/mydatabase\\\"\\u000a
},\\u000a        \\\"default\\\" : {\\u000a          \\\"db\\\" :
\\\"http://name:pass@localhost:5984/mydatabase\\\"\\u000a
}\\u000a      }\\u000a    }\\u000a\\u000aNow that you have the
`.couchapprc` file set up, you can push your app to the CouchDB as
simply as:\\u000a\\u000a    couchapp push\\u000a\\u000aThis pushes to
the `default` as specified. To push to the `public` you'd
run:\\u000a\\u000a    couchapp push public\\u000a\\u000aOf course you
can continue to add more deployment targets as you see fit, and give
them whatever names you
like.\",\"shows\":{\"article_feed\":\"function(doc, req) {\\u000a
return '<h1>' + doc.v12[0][\\\"_\\\"] +
'</h1>';\\u000a}\"},\"couchapp\":{\"manifest\":[\"couchapp.json\",\"evently/\",\"evently/items/\",\"evently/items/_changes/\",\"evently/items/_changes/data.js\",\"evently/items/_changes/mustache.html\",\"evently/items/_changes/query.json\",\"evently/profile/\",\"evently/profile/profileReady/\",\"evently/profile/profileReady/mustache.html\",\"evently/profile/profileReady/selectors/\",\"evently/profile/profileReady/selectors/form/\",\"evently/profile/profileReady/selectors/form/submit.js\",\"language\",\"lists/\",\"lists/article_feed.js\",\"lists/mousttest.js\",\"README.md\",\"shows/\",\"shows/article_feed.js\",\"updates/\",\"vendor/\",\"vendor/couchapp/\",\"vendor/couchapp/evently/\",\"vendor/couchapp/evently/account/\",\"vendor/couchapp/evently/account/adminParty/\",\"vendor/couchapp/evently/account/adminParty/mustache.html\",\"vendor/couchapp/evently/account/doLogin.js\",\"vendor/couchapp/evently/account/doLogout.js\",\"vendor/couchapp/evently/account/doSignup.js\",\"vendor/couchapp/evently/account/loggedIn/\",\"vendor/couchapp/evently/account/loggedIn/after.js\",\"vendor/couchapp/evently/account/loggedIn/data.js\",\"vendor/couchapp/evently/account/loggedIn/mustache.html\",\"vendor/couchapp/evently/account/loggedIn/selectors.json\",\"vendor/couchapp/evently/account/loggedOut/\",\"vendor/couchapp/evently/account/loggedOut/mustache.html\",\"vendor/couchapp/evently/account/loggedOut/selectors.json\",\"vendor/couchapp/evently/account/loginForm/\",\"vendor/couchapp/evently/account/loginForm/after.js\",\"vendor/couchapp/evently/account/loginForm/mustache.html\",\"vendor/couchapp/evently/account/loginForm/selectors/\",\"vendor/couchapp/evently/account/loginForm/selectors/a[href=#signup].json\",\"vendor/couchapp/evently/account/loginForm/selectors/form/\",\"vendor/couchapp/evently/account/loginForm/selectors/form/submit.js\",\"vendor/couchapp/evently/account/signupForm/\",\"vendor/couchapp/evently/account/signupForm/after.js\",\"vendor/couchapp/evently/account/signupForm/mustache.html\",\"vendor/couchapp/evently/account/signupForm/selectors/\",\"vendor/couchapp/evently/account/signupForm/selectors/a[href=#login].json\",\"vendor/couchapp/evently/account/signupForm/selectors/form/\",\"vendor/couchapp/evently/account/signupForm/selectors/form/submit.js\",\"vendor/couchapp/evently/account/_init.js\",\"vendor/couchapp/evently/profile/\",\"vendor/couchapp/evently/profile/loggedIn.js\",\"vendor/couchapp/evently/profile/loggedOut/\",\"vendor/couchapp/evently/profile/loggedOut/after.js\",\"vendor/couchapp/evently/profile/loggedOut/mustache.html\",\"vendor/couchapp/evently/profile/noProfile/\",\"vendor/couchapp/evently/profile/noProfile/data.js\",\"vendor/couchapp/evently/profile/noProfile/mustache.html\",\"vendor/couchapp/evently/profile/noProfile/selectors/\",\"vendor/couchapp/evently/profile/noProfile/selectors/form/\",\"vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js\",\"vendor/couchapp/evently/profile/profileReady/\",\"vendor/couchapp/evently/profile/profileReady/after.js\",\"vendor/couchapp/evently/profile/profileReady/data.js\",\"vendor/couchapp/evently/profile/profileReady/mustache.html\",\"vendor/couchapp/evently/README.md\",\"vendor/couchapp/lib/\",\"vendor/couchapp/lib/atom.js\",\"vendor/couchapp/lib/cache.js\",\"vendor/couchapp/lib/code.js\",\"vendor/couchapp/lib/docform.js\",\"vendor/couchapp/lib/linkup.js\",\"vendor/couchapp/lib/list.js\",\"vendor/couchapp/lib/markdown.js\",\"vendor/couchapp/lib/md5.js\",\"vendor/couchapp/lib/mustache.js\",\"vendor/couchapp/lib/path.js\",\"vendor/couchapp/lib/redirect.js\",\"vendor/couchapp/lib/utils.js\",\"vendor/couchapp/lib/validate.js\",\"vendor/couchapp/metadata.json\",\"views/\",\"views/article/\",\"views/article/map.js\",\"views/article_date/\",\"views/article_date/map.js\",\"views/article_pid/\",\"views/article_pid/map.js\",\"views/article_pr/\",\"views/article_pr/map.js\",\"views/recent-items/\",\"views/recent-items/map.js\",\"views/title/\",\"views/title/map.js\",\"views/title_date/\",\"views/title_date/map.js\",\"views/title_issn/\",\"views/title_issn/map.js\"],\"signatures\":{\"index.html\":\"3d2443a683d7209013502919c895af81\",\"vendor/couchapp/jquery.pathbinder.js\":\"65ecfa230f539d62f36938aaebed4ac1\",\"vendor/couchapp/loader.js\":\"5c771689c7faebedd7be76f2e1638c6f\",\"vendor/couchapp/jquery.mustache.js\":\"0bfbc929b6d5500aacfa860c783550d8\",\"vendor/couchapp/jquery.couch.app.js\":\"d395b6e8c9781a78230050b90dd87936\",\"vendor/couchapp/jquery.evently.js\":\"fa350155fc1ec03a6a2b4bffee808869\",\"style/main.css\":\"9ebbd747b41569f1a99f7f6847bf79b8\",\"vendor/couchapp/jquery.couch.app.util.js\":\"9fc84685dfa7b35237239916ae406583\"},\"name\":\"Name
of your CouchApp\",\"objects\":{},\"description\":\"CouchApp\"},\"_attachments\":{\"index.html\":{\"content_type\":\"text/html\",\"revpos\":1,\"length\":854,\"stub\":true},\"vendor/couchapp/jquery.pathbinder.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":4879,\"stub\":true},\"vendor/couchapp/loader.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":457,\"stub\":true},\"vendor/couchapp/jquery.mustache.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":9466,\"stub\":true},\"vendor/couchapp/jquery.couch.app.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":7258,\"stub\":true},\"vendor/couchapp/jquery.evently.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":11733,\"stub\":true},\"style/main.css\":{\"content_type\":\"text/css\",\"revpos\":1,\"length\":886,\"stub\":true},\"vendor/couchapp/jquery.couch.app.util.js\":{\"content_type\":\"application/javascript\",\"revpos\":1,\"length\":3051,\"stub\":true}}}"}




*Fabio Batalha C. Santos*
Colegiado SciELO
www.scielo.org
FAPESP - CNPq - BIREME - FapUNIFESP



On Thu, Dec 9, 2010 at 1:59 AM, Jeff Charette <iomatix@yahoo.com> wrote:

> After digging around like crazy I found out the issue was with not having
> {{%IMPLICIT-ITERATOR}} in the template.
>
> More details here:
>
> http://stackoverflow.com/questions/4394595/mustache-section-in-couchdb-issues
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message