Last active
December 16, 2015 21:59
-
-
Save elliotf/5503389 to your computer and use it in GitHub Desktop.
compiled js template benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// version 0.4.3 | |
var Haml; | |
(function () { | |
var matchers, self_close_tags, embedder, forceXML, escaperName, escapeHtmlByDefault; | |
function html_escape(text) { | |
return (text + ""). | |
replace(/&/g, "&"). | |
replace(/</g, "<"). | |
replace(/>/g, ">"). | |
replace(/\"/g, """); | |
} | |
function render_attribs(attribs) { | |
var key, value, result = []; | |
for (key in attribs) { | |
if (key !== '_content' && attribs.hasOwnProperty(key)) { | |
switch (attribs[key]) { | |
case 'undefined': | |
case 'false': | |
case 'null': | |
case '""': | |
break; | |
default: | |
try { | |
value = JSON.parse("[" + attribs[key] +"]")[0]; | |
if (value === true) { | |
value = key; | |
} else if (typeof value === 'string' && embedder.test(value)) { | |
value = '" +\n' + parse_interpol(html_escape(value)) + ' +\n"'; | |
} else { | |
value = html_escape(value); | |
} | |
result.push(" " + key + '=\\"' + value + '\\"'); | |
} catch (e) { | |
result.push(" " + key + '=\\"" + '+escaperName+'(' + attribs[key] + ') + "\\"'); | |
} | |
} | |
} | |
} | |
return result.join(""); | |
} | |
// Parse the attribute block using a state machine | |
function parse_attribs(line) { | |
var attributes = {}, | |
l = line.length, | |
i, c, | |
count = 1, | |
quote = false, | |
skip = false, | |
open, close, joiner, seperator, | |
pair = { | |
start: 1, | |
middle: null, | |
end: null | |
}; | |
if (!(l > 0 && (line.charAt(0) === '{' || line.charAt(0) === '('))) { | |
return { | |
_content: line[0] === ' ' ? line.substr(1, l) : line | |
}; | |
} | |
open = line.charAt(0); | |
close = (open === '{') ? '}' : ')'; | |
joiner = (open === '{') ? ':' : '='; | |
seperator = (open === '{') ? ',' : ' '; | |
function process_pair() { | |
if (typeof pair.start === 'number' && | |
typeof pair.middle === 'number' && | |
typeof pair.end === 'number') { | |
var key = line.substr(pair.start, pair.middle - pair.start).trim(), | |
value = line.substr(pair.middle + 1, pair.end - pair.middle - 1).trim(); | |
attributes[key] = value; | |
} | |
pair = { | |
start: null, | |
middle: null, | |
end: null | |
}; | |
} | |
for (i = 1; count > 0; i += 1) { | |
// If we reach the end of the line, then there is a problem | |
if (i > l) { | |
throw "Malformed attribute block"; | |
} | |
c = line.charAt(i); | |
if (skip) { | |
skip = false; | |
} else { | |
if (quote) { | |
if (c === '\\') { | |
skip = true; | |
} | |
if (c === quote) { | |
quote = false; | |
} | |
} else { | |
if (c === '"' || c === "'") { | |
quote = c; | |
} | |
if (count === 1) { | |
if (c === joiner) { | |
pair.middle = i; | |
} | |
if (c === seperator || c === close) { | |
pair.end = i; | |
process_pair(); | |
if (c === seperator) { | |
pair.start = i + 1; | |
} | |
} | |
} | |
if (c === open || c === "(") { | |
count += 1; | |
} | |
if (c === close || (count > 1 && c === ")")) { | |
count -= 1; | |
} | |
} | |
} | |
} | |
attributes._content = line.substr(i, line.length); | |
return attributes; | |
} | |
// Split interpolated strings into an array of literals and code fragments. | |
function parse_interpol(value) { | |
var items = [], | |
pos = 0, | |
next = 0, | |
match; | |
while (true) { | |
// Match up to embedded string | |
next = value.substr(pos).search(embedder); | |
if (next < 0) { | |
if (pos < value.length) { | |
items.push(JSON.stringify(value.substr(pos))); | |
} | |
break; | |
} | |
items.push(JSON.stringify(value.substr(pos, next))); | |
pos += next; | |
// Match embedded string | |
match = value.substr(pos).match(embedder); | |
next = match[0].length; | |
if (next < 0) { break; } | |
if(match[1] === "#"){ | |
items.push(escaperName+"("+(match[2] || match[3])+")"); | |
}else{ | |
//unsafe!!! | |
items.push(match[2] || match[3]); | |
} | |
pos += next; | |
} | |
return items.filter(function (part) { return part && part.length > 0}).join(" +\n"); | |
} | |
// Used to find embedded code in interpolated strings. | |
embedder = /([#!])\{([^}]*)\}/; | |
self_close_tags = ["meta", "img", "link", "br", "hr", "input", "area", "base"]; | |
// All matchers' regexps should capture leading whitespace in first capture | |
// and trailing content in last capture | |
matchers = [ | |
// html tags | |
{ | |
name: "html tags", | |
regexp: /^(\s*)((?:[.#%][a-z_\-][a-z0-9_:\-]*)+)(.*)$/i, | |
process: function () { | |
var line_beginning, tag, classes, ids, attribs, content, whitespaceSpecifier, whitespace={}, output; | |
line_beginning = this.matches[2]; | |
classes = line_beginning.match(/\.([a-z_\-][a-z0-9_\-]*)/gi); | |
ids = line_beginning.match(/\#([a-z_\-][a-z0-9_\-]*)/gi); | |
tag = line_beginning.match(/\%([a-z_\-][a-z0-9_:\-]*)/gi); | |
// Default to <div> tag | |
tag = tag ? tag[0].substr(1, tag[0].length) : 'div'; | |
attribs = this.matches[3]; | |
if (attribs) { | |
attribs = parse_attribs(attribs); | |
if (attribs._content) { | |
var leader0 = attribs._content.charAt(0), | |
leader1 = attribs._content.charAt(1), | |
leaderLength = 0; | |
if(leader0 == "<"){ | |
leaderLength++; | |
whitespace.inside = true; | |
if(leader1 == ">"){ | |
leaderLength++; | |
whitespace.around = true; | |
} | |
}else if(leader0 == ">"){ | |
leaderLength++; | |
whitespace.around = true; | |
if(leader1 == "<"){ | |
leaderLength++; | |
whitespace.inside = true; | |
} | |
} | |
attribs._content = attribs._content.substr(leaderLength); | |
//once we've identified the tag and its attributes, the rest is content. | |
// this is currently trimmed for neatness. | |
this.contents.unshift(attribs._content.trim()); | |
delete(attribs._content); | |
} | |
} else { | |
attribs = {}; | |
} | |
if (classes) { | |
classes = classes.map(function (klass) { | |
return klass.substr(1, klass.length); | |
}).join(' '); | |
if (attribs['class']) { | |
try { | |
attribs['class'] = JSON.stringify(classes + " " + JSON.parse(attribs['class'])); | |
} catch (e) { | |
attribs['class'] = JSON.stringify(classes + " ") + " + " + attribs['class']; | |
} | |
} else { | |
attribs['class'] = JSON.stringify(classes); | |
} | |
} | |
if (ids) { | |
ids = ids.map(function (id) { | |
return id.substr(1, id.length); | |
}).join(' '); | |
if (attribs.id) { | |
attribs.id = JSON.stringify(ids + " ") + attribs.id; | |
} else { | |
attribs.id = JSON.stringify(ids); | |
} | |
} | |
attribs = render_attribs(attribs); | |
content = this.render_contents(); | |
if (content === '""') { | |
content = ''; | |
} | |
if(whitespace.inside){ | |
if(content.length==0){ | |
content='" "' | |
}else{ | |
try{ //remove quotes if they are there | |
content = '" '+JSON.parse(content)+' "'; | |
}catch(e){ | |
content = '" "+\n'+content+'+\n" "'; | |
} | |
} | |
} | |
if (forceXML ? content.length > 0 : self_close_tags.indexOf(tag) == -1) { | |
output = '"<' + tag + attribs + '>"' + | |
(content.length > 0 ? ' + \n' + content : "") + | |
' + \n"</' + tag + '>"'; | |
} else { | |
output = '"<' + tag + attribs + ' />"'; | |
} | |
if(whitespace.around){ | |
//output now contains '"<b>hello</b>"' | |
//we need to crack it open to insert whitespace. | |
output = '" '+output.substr(1, output.length - 2)+' "'; | |
} | |
return output; | |
} | |
}, | |
// each loops | |
{ | |
name: "each loop", | |
regexp: /^(\s*)(?::for|:each)\s+(?:([a-z_][a-z_\-]*),\s*)?([a-z_][a-z_\-]*)\s+in\s+(.*)(\s*)$/i, | |
process: function () { | |
var ivar = this.matches[2] || '__key__', // index | |
vvar = this.matches[3], // value | |
avar = this.matches[4], // array | |
rvar = '__result__'; // results | |
if (this.matches[5]) { | |
this.contents.unshift(this.matches[5]); | |
} | |
return '(function () { ' + | |
'var ' + rvar + ' = [], ' + ivar + ', ' + vvar + '; ' + | |
'for (' + ivar + ' in ' + avar + ') { ' + | |
'if (' + avar + '.hasOwnProperty(' + ivar + ')) { ' + | |
vvar + ' = ' + avar + '[' + ivar + ']; ' + | |
rvar + '.push(\n' + (this.render_contents() || "''") + '\n); ' + | |
'} } return ' + rvar + '.join(""); }).call(this)'; | |
} | |
}, | |
// if statements | |
{ | |
name: "if", | |
regexp: /^(\s*):if\s+(.*)\s*$/i, | |
process: function () { | |
var condition = this.matches[2]; | |
this.pushIfCondition([condition]); | |
return '(function () { ' + | |
'if (' + condition + ') { ' + | |
'return (\n' + (this.render_contents() || '') + '\n);' + | |
'} else { return ""; } }).call(this)'; | |
} | |
}, | |
// else if statements | |
{ | |
name: "else if", | |
regexp: /^(\s*):else if\s+(.*)\s*$/i, | |
process: function () { | |
var condition = this.matches[2], | |
conditionsArray = this.getIfConditions()[this.getIfConditions().length - 1], | |
ifArray = [], | |
ifStatement; | |
for (var i=0, l=conditionsArray.length; i<l; i++) { | |
ifArray.push('! (' + conditionsArray[i]+')'); | |
} | |
conditionsArray.push(condition); | |
ifArray.push(condition); | |
ifStatement = 'if (' + ifArray.join(' && ') + ') { '; | |
return '(function () { ' + | |
ifStatement + | |
'return (\n' + (this.render_contents() || '') + '\n);' + | |
'} else { return ""; } }).call(this)'; | |
} | |
}, | |
// else statements | |
{ | |
name: "else", | |
regexp: /^(\s*):else\s*$/i, | |
process: function () { | |
var conditionsArray = this.popIfCondition(), | |
ifArray = [], | |
ifStatement; | |
for (var i=0, l=conditionsArray.length; i<l; i++) { | |
ifArray.push('! (' + conditionsArray[i]+')'); | |
} | |
ifStatement = 'if (' + ifArray.join(' && ') + ') { '; | |
return '(function () { ' + | |
ifStatement + | |
'return (\n' + (this.render_contents() || '') + '\n);' + | |
'} else { return ""; } }).call(this)'; | |
} | |
}, | |
// silent-comments | |
{ | |
name: "silent-comments", | |
regexp: /^(\s*)-#\s*(.*)\s*$/i, | |
process: function () { | |
return '""'; | |
} | |
}, | |
//html-comments | |
{ | |
name: "silent-comments", | |
regexp: /^(\s*)\/\s*(.*)\s*$/i, | |
process: function () { | |
this.contents.unshift(this.matches[2]); | |
return '"<!--'+this.contents.join('\\n').replace(/\"/g, '\\"')+'-->"'; | |
} | |
}, | |
// raw js | |
{ | |
name: "rawjs", | |
regexp: /^(\s*)-\s*(.*)\s*$/i, | |
process: function () { | |
this.contents.unshift(this.matches[2]); | |
return '"";' + this.contents.join("\n")+"; _$output = _$output "; | |
} | |
}, | |
// raw js | |
{ | |
name: "pre", | |
regexp: /^(\s*):pre(\s+(.*)|$)/i, | |
process: function () { | |
this.contents.unshift(this.matches[2]); | |
return '"<pre>"+\n' + JSON.stringify(this.contents.join("\n"))+'+\n"</pre>"'; | |
} | |
}, | |
// declarations | |
{ | |
name: "doctype", | |
regexp: /^()!!!(?:\s*(.*))\s*$/, | |
process: function () { | |
var line = ''; | |
switch ((this.matches[2] || '').toLowerCase()) { | |
case '': | |
// XHTML 1.0 Transitional | |
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'; | |
break; | |
case 'strict': | |
case '1.0': | |
// XHTML 1.0 Strict | |
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; | |
break; | |
case 'frameset': | |
// XHTML 1.0 Frameset | |
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'; | |
break; | |
case '5': | |
// XHTML 5 | |
line = '<!DOCTYPE html>'; | |
break; | |
case '1.1': | |
// XHTML 1.1 | |
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'; | |
break; | |
case 'basic': | |
// XHTML Basic 1.1 | |
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'; | |
break; | |
case 'mobile': | |
// XHTML Mobile 1.2 | |
line = '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'; | |
break; | |
case 'xml': | |
// XML | |
line = "<?xml version='1.0' encoding='utf-8' ?>"; | |
break; | |
case 'xml iso-8859-1': | |
// XML iso-8859-1 | |
line = "<?xml version='1.0' encoding='iso-8859-1' ?>"; | |
break; | |
} | |
return JSON.stringify(line + "\n"); | |
} | |
}, | |
// Embedded markdown. Needs to be added to exports externally. | |
{ | |
name: "markdown", | |
regexp: /^(\s*):markdown\s*$/i, | |
process: function () { | |
return parse_interpol(exports.Markdown.encode(this.contents.join("\n"))); | |
} | |
}, | |
// script blocks | |
{ | |
name: "script", | |
regexp: /^(\s*):(?:java)?script\s*$/, | |
process: function () { | |
return parse_interpol('\n<script type="text/javascript">\n' + | |
'//<![CDATA[\n' + | |
this.contents.join("\n") + | |
"\n//]]>\n</script>\n"); | |
} | |
}, | |
// css blocks | |
{ | |
name: "css", | |
regexp: /^(\s*):css\s*$/, | |
process: function () { | |
return JSON.stringify('<style type="text/css">\n' + | |
this.contents.join("\n") + | |
"\n</style>"); | |
} | |
} | |
]; | |
function compile(lines) { | |
var block = false, | |
output = [], | |
ifConditions = []; | |
// If lines is a string, turn it into an array | |
if (typeof lines === 'string') { | |
lines = lines.trim().replace(/\n\r|\r/g, '\n').split('\n'); | |
} | |
lines.forEach(function(line) { | |
var match, found = false; | |
// Collect all text as raw until outdent | |
if (block) { | |
match = block.check_indent.exec(line); | |
if (match) { | |
block.contents.push(match[1] || ""); | |
return; | |
} else { | |
output.push(block.process()); | |
block = false; | |
} | |
} | |
matchers.forEach(function (matcher) { | |
if (!found) { | |
match = matcher.regexp.exec(line); | |
if (match) { | |
block = { | |
contents: [], | |
indent_level: (match[1]), | |
matches: match, | |
check_indent: new RegExp("^(?:\\s*|" + match[1] + " (.*))$"), | |
process: matcher.process, | |
getIfConditions: function() { | |
return ifConditions; | |
}, | |
pushIfCondition: function(condition) { | |
ifConditions.push(condition); | |
}, | |
popIfCondition: function() { | |
return ifConditions.pop(); | |
}, | |
render_contents: function () { | |
return compile(this.contents); | |
} | |
}; | |
found = true; | |
} | |
} | |
}); | |
// Match plain text | |
if (!found) { | |
output.push(function () { | |
// Escaped plain text | |
if (line[0] === '\\') { | |
return parse_interpol(line.substr(1, line.length)); | |
} | |
function escapedLine(){ | |
try { | |
return escaperName+'('+JSON.stringify(JSON.parse(line)) +')'; | |
} catch (e2) { | |
return escaperName+'(' + line + ')'; | |
} | |
} | |
function unescapedLine(){ | |
try { | |
return parse_interpol(JSON.parse(line)); | |
} catch (e) { | |
return line; | |
} | |
} | |
// always escaped | |
if((line.substr(0, 2) === "&=")) { | |
line = line.substr(2, line.length).trim(); | |
return escapedLine(); | |
} | |
//never escaped | |
if((line.substr(0, 2) === "!=")) { | |
line = line.substr(2, line.length).trim(); | |
return unescapedLine(); | |
} | |
// sometimes escaped | |
if ( (line[0] === '=')) { | |
line = line.substr(1, line.length).trim(); | |
if(escapeHtmlByDefault){ | |
return escapedLine(); | |
}else{ | |
return unescapedLine(); | |
} | |
} | |
// Plain text | |
return parse_interpol(line); | |
}()); | |
} | |
}); | |
if (block) { | |
output.push(block.process()); | |
} | |
var txt = output.filter(function (part) { return part && part.length > 0}).join(" +\n"); | |
if(txt.length == 0){ | |
txt = '""'; | |
} | |
return txt; | |
}; | |
function optimize(js) { | |
var new_js = [], buffer = [], part, end; | |
function flush() { | |
if (buffer.length > 0) { | |
new_js.push(JSON.stringify(buffer.join("")) + end); | |
buffer = []; | |
} | |
} | |
js.replace(/\n\r|\r/g, '\n').split('\n').forEach(function (line) { | |
part = line.match(/^(\".*\")(\s*\+\s*)?$/); | |
if (!part) { | |
flush(); | |
new_js.push(line); | |
return; | |
} | |
end = part[2] || ""; | |
part = part[1]; | |
try { | |
buffer.push(JSON.parse(part)); | |
} catch (e) { | |
flush(); | |
new_js.push(line); | |
} | |
}); | |
flush(); | |
return new_js.join("\n"); | |
}; | |
function render(text, options) { | |
options = options || {}; | |
text = text || ""; | |
var js = compile(text, options); | |
if (options.optimize) { | |
js = Haml.optimize(js); | |
} | |
return execute(js, options.context || Haml, options.locals); | |
}; | |
function execute(js, self, locals) { | |
return (function () { | |
with(locals || {}) { | |
try { | |
var _$output; | |
eval("_$output =" + js ); | |
return _$output; //set in eval | |
} catch (e) { | |
return "\n<pre class='error'>" + html_escape(e.stack) + "</pre>\n"; | |
} | |
} | |
}).call(self); | |
}; | |
Haml = function Haml(haml, config) { | |
if(typeof(config) != "object"){ | |
forceXML = config; | |
config = {}; | |
} | |
var escaper; | |
if(config.customEscape){ | |
escaper = ""; | |
escaperName = config.customEscape; | |
}else{ | |
escaper = html_escape.toString() + "\n"; | |
escaperName = "html_escape"; | |
} | |
escapeHtmlByDefault = (config.escapeHtmlByDefault || config.escapeHTML || config.escape_html); | |
var js = optimize(compile(haml)); | |
var str = "with(locals || {}) {\n" + | |
" try {\n" + | |
" var _$output=" + js + ";\n return _$output;" + | |
" } catch (e) {\n" + | |
" return \"\\n<pre class='error'>\" + "+escaperName+"(e.stack) + \"</pre>\\n\";\n" + | |
" }\n" + | |
"}" | |
try{ | |
var f = new Function("locals", escaper + str ); | |
return f; | |
}catch(e){ | |
if ( typeof(console) !== 'undefined' ) { console.error(str); } | |
throw e; | |
} | |
} | |
Haml.compile = compile; | |
Haml.optimize = optimize; | |
Haml.render = render; | |
Haml.execute = execute; | |
Haml.html_escape = html_escape; | |
}()); | |
// Hook into module system | |
if (typeof module !== 'undefined') { | |
module.exports = Haml; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// version 0.30.0 | |
var jade=function(){function require(p){var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}return require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p.charAt(0))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i<segs.length;i++){var seg=segs[i];".."==seg?path.pop():"."!=seg&&path.push(seg)}return require(path.join("/"))}},require.register("compiler.js",function(module,exports,require){function isConstant(val){if(/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val))return!0;if(!isNaN(Number(val)))return!0;var matches;return(matches=/^ *\[(.*)\] *$/.exec(val))?matches[1].split(",").every(isConstant):!1}var nodes=require("./nodes"),filters=require("./filters"),doctypes=require("./doctypes"),selfClosing=require("./self-closing"),runtime=require("./runtime"),utils=require("./utils"),parseJSExpression=require("character-parser").parseMax;Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/,"")});var Compiler=module.exports=function Compiler(node,options){this.options=options=options||{},this.node=node,this.hasCompiledDoctype=!1,this.hasCompiledTag=!1,this.pp=options.pretty||!1,this.debug=!1!==options.compileDebug,this.indents=0,this.parentIndents=0,options.doctype&&this.setDoctype(options.doctype)};Compiler.prototype={compile:function(){return this.buf=[],this.pp&&this.buf.push("jade.indent = [];"),this.lastBufferedIdx=-1,this.visit(this.node),this.buf.join("\n")},setDoctype:function(name){name=name&&name.toLowerCase()||"default",this.doctype=doctypes[name]||"<!DOCTYPE "+name+">",this.terse=this.doctype.toLowerCase()=="<!doctype html>",this.xml=0==this.doctype.indexOf("<?xml")},buffer:function(str,interpolate){var self=this;if(interpolate){var match=/(\\)?([#!]){((?:.|\n)*)$/.exec(str);if(match){this.buffer(str.substr(0,match.index),!1);if(match[1]){this.buffer(match[2]+"{",!1),this.buffer(match[3],!0);return}try{var rest=match[3],range=parseJSExpression(rest),code=("!"==match[2]?"":"jade.escape")+"((jade.interp = "+range.src+") == null ? '' : jade.interp)"}catch(ex){throw ex}this.bufferExpression(code),this.buffer(rest.substr(range.end+1),!0);return}}str=JSON.stringify(str),str=str.substr(1,str.length-2),this.lastBufferedIdx==this.buf.length?(this.lastBufferedType==="code"&&(this.lastBuffered+=' + "'),this.lastBufferedType="text",this.lastBuffered+=str,this.buf[this.lastBufferedIdx-1]="buf.push("+this.bufferStartChar+this.lastBuffered+'");'):(this.buf.push('buf.push("'+str+'");'),this.lastBufferedType="text",this.bufferStartChar='"',this.lastBuffered=str,this.lastBufferedIdx=this.buf.length)},bufferExpression:function(src){this.lastBufferedIdx==this.buf.length?(this.lastBufferedType==="text"&&(this.lastBuffered+='"'),this.lastBufferedType="code",this.lastBuffered+=" + ("+src+")",this.buf[this.lastBufferedIdx-1]="buf.push("+this.bufferStartChar+this.lastBuffered+");"):(this.buf.push("buf.push("+src+");"),this.lastBufferedType="code",this.bufferStartChar="",this.lastBuffered="("+src+")",this.lastBufferedIdx=this.buf.length)},prettyIndent:function(offset,newline){offset=offset||0,newline=newline?"\n":"",this.buffer(newline+Array(this.indents+offset).join(" ")),this.parentIndents&&this.buf.push("buf.push.apply(buf, jade.indent);")},visit:function(node){var debug=this.debug;debug&&this.buf.push("jade.debug.unshift({ lineno: "+node.line+", filename: "+(node.filename?JSON.stringify(node.filename):"jade.debug[0].filename")+" });"),!1===node.debug&&this.debug&&(this.buf.pop(),this.buf.pop()),this.visitNode(node),debug&&this.buf.push("jade.debug.shift();")},visitNode:function(node){var name=node.constructor.name||node.constructor.toString().match(/function ([^(\s]+)()/)[1];return this["visit"+name](node)},visitCase:function(node){var _=this.withinCase;this.withinCase=!0,this.buf.push("switch ("+node.expr+"){"),this.visit(node.block),this.buf.push("}"),this.withinCase=_},visitWhen:function(node){"default"==node.expr?this.buf.push("default:"):this.buf.push("case "+node.expr+":"),this.visit(node.block),this.buf.push(" break;")},visitLiteral:function(node){this.buffer(node.str)},visitBlock:function(block){var len=block.nodes.length,escape=this.escape,pp=this.pp;if(this.parentIndents&&block.mode){pp&&this.buf.push("jade.indent.push('"+Array(this.indents+1).join(" ")+"');"),this.buf.push("block && block();"),pp&&this.buf.push("jade.indent.pop();");return}pp&&len>1&&!escape&&block.nodes[0].isText&&block.nodes[1].isText&&this.prettyIndent(1,!0);for(var i=0;i<len;++i)pp&&i>0&&!escape&&block.nodes[i].isText&&block.nodes[i-1].isText&&this.prettyIndent(1,!1),this.visit(block.nodes[i]),block.nodes[i+1]&&block.nodes[i].isText&&block.nodes[i+1].isText&&this.buffer("\n")},visitDoctype:function(doctype){doctype&&(doctype.val||!this.doctype)&&this.setDoctype(doctype.val||"default"),this.doctype&&this.buffer(this.doctype),this.hasCompiledDoctype=!0},visitMixin:function(mixin){var name=mixin.name.replace(/-/g,"_")+"_mixin",args=mixin.args||"",block=mixin.block,attrs=mixin.attrs,pp=this.pp;if(mixin.call){pp&&this.buf.push("jade.indent.push('"+Array(this.indents+1).join(" ")+"');");if(block||attrs.length){this.buf.push(name+".call({");if(block){this.buf.push("block: function(){"),this.parentIndents++;var _indents=this.indents;this.indents=0,this.visit(mixin.block),this.indents=_indents,this.parentIndents--,attrs.length?this.buf.push("},"):this.buf.push("}")}if(attrs.length){var val=this.attrs(attrs);val.inherits?this.buf.push("attributes: jade.merge({"+val.buf+"}, attributes), escaped: jade.merge("+val.escaped+", escaped, true)"):this.buf.push("attributes: {"+val.buf+"}, escaped: "+val.escaped)}args?this.buf.push("}, "+args+");"):this.buf.push("});")}else this.buf.push(name+"("+args+");");pp&&this.buf.push("jade.indent.pop();")}else this.buf.push("var "+name+" = function("+args+"){"),this.buf.push("var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};"),this.parentIndents++,this.visit(block),this.parentIndents--,this.buf.push("};")},visitTag:function(tag){function bufferName(){tag.buffer?self.bufferExpression(name):self.buffer(name)}this.indents++;var name=tag.name,pp=this.pp,self=this;this.hasCompiledTag||(!this.hasCompiledDoctype&&"html"==name&&this.visitDoctype(),this.hasCompiledTag=!0),pp&&!tag.isInline()&&this.prettyIndent(0,!0),(~selfClosing.indexOf(name)||tag.selfClosing)&&!this.xml?(this.buffer("<"),bufferName(),this.visitAttributes(tag.attrs),this.terse?this.buffer(">"):this.buffer("/>")):(tag.attrs.length?(this.buffer("<"),bufferName(),tag.attrs.length&&this.visitAttributes(tag.attrs),this.buffer(">")):(this.buffer("<"),bufferName(),this.buffer(">")),tag.code&&this.visitCode(tag.code),this.escape="pre"==tag.name,this.visit(tag.block),pp&&!tag.isInline()&&"pre"!=tag.name&&!tag.canInline()&&this.prettyIndent(0,!0),this.buffer("</"),bufferName(),this.buffer(">")),this.indents--},visitFilter:function(filter){var text=filter.block.nodes.map(function(node){return node.val}).join("\n");filter.attrs=filter.attrs||{},filter.attrs.filename=this.options.filename,this.buffer(filters(filter.name,text,filter.attrs),!0)},visitText:function(text){this.buffer(text.val,!0)},visitComment:function(comment){if(!comment.buffer)return;this.pp&&this.prettyIndent(1,!0),this.buffer("<!--"+comment.val+"-->")},visitBlockComment:function(comment){if(!comment.buffer)return;0==comment.val.trim().indexOf("if")?(this.buffer("<!--["+comment.val.trim()+"]>"),this.visit(comment.block),this.buffer("<![endif]-->")):(this.buffer("<!--"+comment.val),this.visit(comment.block),this.buffer("-->"))},visitCode:function(code){if(code.buffer){var val=code.val.trimLeft();val="null == (jade.interp = "+val+') ? "" : jade.interp',code.escape&&(val="jade.escape("+val+")"),this.bufferExpression(val)}else this.buf.push(code.val);code.block&&(code.buffer||this.buf.push("{"),this.visit(code.block),code.buffer||this.buf.push("}"))},visitEach:function(each){this.buf.push("// iterate "+each.obj+"\n"+";(function(){\n"+" var $$obj = "+each.obj+";\n"+" if ('number' == typeof $$obj.length) {\n"),each.alternative&&this.buf.push(" if ($$obj.length) {"),this.buf.push(" for (var "+each.key+" = 0, $$l = $$obj.length; "+each.key+" < $$l; "+each.key+"++) {\n"+" var "+each.val+" = $$obj["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n"),each.alternative&&(this.buf.push(" } else {"),this.visit(each.alternative),this.buf.push(" }")),this.buf.push(" } else {\n var $$l = 0;\n for (var "+each.key+" in $$obj) {\n"+" $$l++;"+" if ($$obj.hasOwnProperty("+each.key+")){"+" var "+each.val+" = $$obj["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n"),this.buf.push(" }\n"),each.alternative&&(this.buf.push(" if ($$l === 0) {"),this.visit(each.alternative),this.buf.push(" }")),this.buf.push(" }\n}).call(this);\n")},visitAttributes:function(attrs){var val=this.attrs(attrs);val.inherits?this.bufferExpression("jade.attrs(jade.merge({ "+val.buf+" }, attributes), jade.merge("+val.escaped+", escaped, true))"):val.constant?(eval("var buf={"+val.buf+"};"),this.buffer(runtime.attrs(buf,JSON.parse(val.escaped)))):this.bufferExpression("jade.attrs({ "+val.buf+" }, "+val.escaped+")")},attrs:function(attrs){var buf=[],classes=[],escaped={},constant=attrs.every(function(attr){return isConstant(attr.val)}),inherits=!1;return this.terse&&buf.push("terse: true"),attrs.forEach(function(attr){if(attr.name=="attributes")return inherits=!0;escaped[attr.name]=attr.escaped;if(attr.name=="class")classes.push("("+attr.val+")");else{var pair="'"+attr.name+"':("+attr.val+")";buf.push(pair)}}),classes.length&&(classes=classes.join(" + ' ' + "),buf.push('"class": '+classes)),{buf:buf.join(", "),escaped:JSON.stringify(escaped),inherits:inherits,constant:constant}}}}),require.register("doctypes.js",function(module,exports,require){module.exports={5:"<!DOCTYPE html>","default":"<!DOCTYPE html>",xml:'<?xml version="1.0" encoding="utf-8" ?>',transitional:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',strict:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',frameset:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',1.1:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',basic:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',mobile:'<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'}}),require.register("filters.js",function(module,exports,require){function filter(name,str,options){if(typeof filter[name]=="function")var res=filter[name](str,options);else{if(!transformers[name])throw new Error('unknown filter ":'+name+'"');var res=transformers[name].renderSync(str,options);transformers[name].outputFormat==="js"?res='<script type="text/javascript">\n'+res+"</script>":transformers[name].outputFormat==="css"?res='<style type="text/css">'+res+"</style>":transformers[name].outputFormat==="xml"&&(res=res.replace(/'/g,"'"))}return res}var transformers=require("transformers");module.exports=filter,filter.exists=function(name,str,options){return typeof filter[name]=="function"||transformers[name]}}),require.register("inline-tags.js",function(module,exports,require){module.exports=["a","abbr","acronym","b","br","code","em","font","i","img","ins","kbd","map","samp","small","span","strong","sub","sup"]}),require.register("jade.js",function(module,exports,require){function parse(str,options){try{var parser=new Parser(str,options.filename,options),compiler=new(options.compiler||Compiler)(parser.parse(),options),js=compiler.compile();return options.debug&&console.error("\nCompiled Function:\n\n[90m%s[0m",js.replace(/^/gm," ")),"var buf = [];\n"+(options.self?"var self = locals || {};\n"+js:"with (locals || {}) {\n"+js+"\n}\n")+'return buf.join("");'}catch(err){parser=parser.context(),runtime.rethrow(err,parser.filename,parser.lexer.lineno)}}function stripBOM(str){return 65279==str.charCodeAt(0)?str.substring(1):str}var Parser=require("./parser"),Lexer=require("./lexer"),Compiler=require("./compiler"),runtime=require("./runtime");exports.version="0.30.0",exports.selfClosing=require("./self-closing"),exports.doctypes=require("./doctypes"),exports.filters=require("./filters"),exports.utils=require("./utils"),exports.Compiler=Compiler,exports.Parser=Parser,exports.Lexer=Lexer,exports.nodes=require("./nodes"),exports.runtime=runtime,exports.cache={},exports.compile=function(str,options){var options=options||{},filename=options.filename?JSON.stringify(options.filename):"undefined",fn;return str=stripBOM(String(str)),options.compileDebug!==!1?fn=["jade.debug = [{ lineno: 1, filename: "+filename+" }];","try {",parse(str,options),"} catch (err) {"," jade.rethrow(err, jade.debug[0].filename, jade.debug[0].lineno);","}"].join("\n"):fn=parse(str,options),options.client?new Function("locals",fn):(fn=new Function("locals, jade",fn),function(locals){return fn(locals,Object.create(runtime))})},exports.render=function(str,options,fn){"function"==typeof options&&(fn=options,options={});if(options.cache&&!options.filename)return fn(new Error('the "filename" option is required for caching'));try{var path=options.filename,tmpl=options.cache?exports.cache[path]||(exports.cache[path]=exports.compile(str,options)):exports.compile(str,options);fn(null,tmpl(options))}catch(err){fn(err)}},exports.renderFile=function(path,options,fn){var key=path+":string";"function"==typeof options&&(fn=options,options={});try{options.filename=path;var str=options.cache?exports.cache[key]||(exports.cache[key]=fs.readFileSync(path,"utf8")):fs.readFileSync(path,"utf8");exports.render(str,options,fn)}catch(err){fn(err)}},exports.__express=exports.renderFile}),require.register("lexer.js",function(module,exports,require){var utils=require("./utils"),parseJSExpression=require("character-parser").parseMax,Lexer=module.exports=function Lexer(str,options){options=options||{},this.input=str.replace(/\r\n|\r/g,"\n"),this.colons=options.colons,this.deferredTokens=[],this.lastIndents=0,this.lineno=1,this.stash=[],this.indentStack=[],this.indentRe=null,this.pipeless=!1};Lexer.prototype={tok:function(type,val){return{type:type,line:this.lineno,val:val}},consume:function(len){this.input=this.input.substr(len)},scan:function(regexp,type){var captures;if(captures=regexp.exec(this.input))return this.consume(captures[0].length),this.tok(type,captures[1])},defer:function(tok){this.deferredTokens.push(tok)},lookahead:function(n){var fetch=n-this.stash.length;while(fetch-->0)this.stash.push(this.next());return this.stash[--n]},bracketExpression:function(skip){skip=skip||0;var start=this.input[skip];if(start!="("&&start!="{"&&start!="[")throw new Error("unrecognized start character");var end={"(":")","{":"}","[":"]"}[start],range=parseJSExpression(this.input,{start:skip+1});if(this.input[range.end]!==end)throw new Error("start character "+start+" does not match end character "+this.input[range.end]);return range},stashed:function(){return this.stash.length&&this.stash.shift()},deferred:function(){return this.deferredTokens.length&&this.deferredTokens.shift()},eos:function(){if(this.input.length)return;return this.indentStack.length?(this.indentStack.shift(),this.tok("outdent")):this.tok("eos")},blank:function(){var captures;if(captures=/^\n *\n/.exec(this.input))return this.consume(captures[0].length-1),++this.lineno,this.pipeless?this.tok("text",""):this.next()},comment:function(){var captures;if(captures=/^ *\/\/(-)?([^\n]*)/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("comment",captures[2]);return tok.buffer="-"!=captures[1],tok}},interpolation:function(){if(/^#\{/.test(this.input)){var match;try{match=this.bracketExpression(1)}catch(ex){return}return this.consume(match.end+1),this.tok("interpolation",match.src)}},tag:function(){var captures;if(captures=/^(\w[-:\w]*)(\/?)/.exec(this.input)){this.consume(captures[0].length);var tok,name=captures[1];if(":"==name[name.length-1]){name=name.slice(0,-1),tok=this.tok("tag",name),this.defer(this.tok(":"));while(" "==this.input[0])this.input=this.input.substr(1)}else tok=this.tok("tag",name);return tok.selfClosing=!!captures[2],tok}},filter:function(){return this.scan(/^:(\w+)/,"filter")},doctype:function(){return this.scan(/^(?:!!!|doctype) *([^\n]+)?/,"doctype")},id:function(){return this.scan(/^#([\w-]+)/,"id")},className:function(){return this.scan(/^\.([\w-]+)/,"class")},text:function(){return this.scan(/^(?:\| ?| ?)?([^\n]+)/,"text")},"extends":function(){return this.scan(/^extends? +([^\n]+)/,"extends")},prepend:function(){var captures;if(captures=/^prepend +([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var mode="prepend",name=captures[1],tok=this.tok("block",name);return tok.mode=mode,tok}},append:function(){var captures;if(captures=/^append +([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var mode="append",name=captures[1],tok=this.tok("block",name);return tok.mode=mode,tok}},block:function(){var captures;if(captures=/^block\b *(?:(prepend|append) +)?([^\n]*)/.exec(this.input)){this.consume(captures[0].length);var mode=captures[1]||"replace",name=captures[2],tok=this.tok("block",name);return tok.mode=mode,tok}},yield:function(){return this.scan(/^yield */,"yield")},include:function(){return this.scan(/^include +([^\n]+)/,"include")},"case":function(){return this.scan(/^case +([^\n]+)/,"case")},when:function(){return this.scan(/^when +([^:\n]+)/,"when")},"default":function(){return this.scan(/^default */,"default")},assignment:function(){var captures;if(captures=/^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)){this.consume(captures[0].length);var name=captures[1],val=captures[2];return this.tok("code","var "+name+" = ("+val+");")}},call:function(){var captures;if(captures=/^\+([-\w]+)/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("call",captures[1]);if(captures=/^ *\(/.exec(this.input))try{var range=this.bracketExpression(captures[0].length-1);/^ *[-\w]+ *=/.test(range.src)||(this.consume(range.end+1),tok.args=range.src)}catch(ex){}return tok}},mixin:function(){var captures;if(captures=/^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("mixin",captures[1]);return tok.args=captures[2],tok}},conditional:function(){var captures;if(captures=/^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)){this.consume(captures[0].length);var type=captures[1],js=captures[2];switch(type){case"if":js="if ("+js+")";break;case"unless":js="if (!("+js+"))";break;case"else if":js="else if ("+js+")";break;case"else":js="else"}return this.tok("code",js)}},"while":function(){var captures;if(captures=/^while +([^\n]+)/.exec(this.input))return this.consume(captures[0].length),this.tok("code","while ("+captures[1]+")")},each:function(){var captures;if(captures=/^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("each",captures[1]);return tok.key=captures[2]||"$index",tok.code=captures[3],tok}},code:function(){var captures;if(captures=/^(!?=|-)[ \t]*([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var flags=captures[1];captures[1]=captures[2];var tok=this.tok("code",captures[1]);return tok.escape=flags.charAt(0)==="=",tok.buffer=flags.charAt(0)==="="||flags.charAt(1)==="=",tok}},attrs:function(){if("("==this.input.charAt(0)){var index=this.bracketExpression().end,str=this.input.substr(1,index-1),tok=this.tok("attrs"),len=str.length,colons=this.colons,states=["key"],escapedAttr,key="",val="",quote,c,p;function state(){return states[states.length-1]}function interpolate(attr){return attr.replace(/(\\)?#\{(.+)/g,function(_,escape,expr){if(escape)return _;try{var range=parseJSExpression(expr);return expr[range.end]!=="}"?_.substr(0,2)+interpolate(_.substr(2)):quote+" + ("+range.src+") + "+quote+interpolate(expr.substr(range.end+1))}catch(ex){return _.substr(0,2)+interpolate(_.substr(2))}})}this.consume(index+1),tok.attrs={},tok.escaped={};function parse(c){var real=c;colons&&":"==c&&(c="=");switch(c){case",":case"\n":switch(state()){case"expr":case"array":case"string":case"object":val+=c;break;default:states.push("key"),val=val.trim(),key=key.trim();if(""==key)return;key=key.replace(/^['"]|['"]$/g,"").replace("!",""),tok.escaped[key]=escapedAttr,tok.attrs[key]=""==val?!0:interpolate(val),key=val=""}break;case"=":switch(state()){case"key char":key+=real;break;case"val":case"expr":case"array":case"string":case"object":val+=real;break;default:escapedAttr="!"!=p,states.push("val")}break;case"(":("val"==state()||"expr"==state())&&states.push("expr"),val+=c;break;case")":("expr"==state()||"val"==state())&&states.pop(),val+=c;break;case"{":"val"==state()&&states.push("object"),val+=c;break;case"}":"object"==state()&&states.pop(),val+=c;break;case"[":"val"==state()&&states.push("array"),val+=c;break;case"]":"array"==state()&&states.pop(),val+=c;break;case'"':case"'":switch(state()){case"key":states.push("key char");break;case"key char":states.pop();break;case"string":c==quote&&states.pop(),val+=c;break;default:states.push("string"),val+=c,quote=c}break;case"":break;default:switch(state()){case"key":case"key char":key+=c;break;default:val+=c}}p=c}for(var i=0;i<len;++i)parse(str.charAt(i));return parse(","),"/"==this.input.charAt(0)&&(this.consume(1),tok.selfClosing=!0),tok}},indent:function(){var captures,re;this.indentRe?captures=this.indentRe.exec(this.input):(re=/^\n(\t*) */,captures=re.exec(this.input),captures&&!captures[1].length&&(re=/^\n( *)/,captures=re.exec(this.input)),captures&&captures[1].length&&(this.indentRe=re));if(captures){var tok,indents=captures[1].length;++this.lineno,this.consume(indents+1);if(" "==this.input[0]||" "==this.input[0])throw new Error("Invalid indentation, you can use tabs or spaces but not both");if("\n"==this.input[0])return this.tok("newline");if(this.indentStack.length&&indents<this.indentStack[0]){while(this.indentStack.length&&this.indentStack[0]>indents)this.stash.push(this.tok("outdent")),this.indentStack.shift();tok=this.stash.pop()}else indents&&indents!=this.indentStack[0]?(this.indentStack.unshift(indents),tok=this.tok("indent",indents)):tok=this.tok("newline");return tok}},pipelessText:function(){if(this.pipeless){if("\n"==this.input[0])return;var i=this.input.indexOf("\n");-1==i&&(i=this.input.length);var str=this.input.substr(0,i);return this.consume(str.length),this.tok("text",str)}},colon:function(){return this.scan(/^: */,":")},advance:function(){return this.stashed()||this.next()},next:function(){return this.deferred()||this.blank()||this.eos()||this.pipelessText()||this.yield()||this.doctype()||this.interpolation()||this["case"]()||this.when()||this["default"]()||this["extends"]()||this.append()||this.prepend()||this.block()||this.include()||this.mixin()||this.call()||this.conditional()||this.each()||this["while"]()||this.assignment()||this.tag()||this.filter()||this.code()||this.id()||this.className()||this.attrs()||this.indent()||this.comment()||this.colon()||this.text()}}}),require.register("nodes/attrs.js",function(module,exports,require){var Node=require("./node"),Block=require("./block"),Attrs=module.exports=function Attrs(){this.attrs=[]};Attrs.prototype=new Node,Attrs.prototype.constructor=Attrs,Attrs.prototype.setAttribute=function(name,val,escaped){return this.attrs.push({name:name,val:val,escaped:escaped}),this},Attrs.prototype.removeAttribute=function(name){for(var i=0,len=this.attrs.length;i<len;++i)this.attrs[i]&&this.attrs[i].name==name&&delete this.attrs[i]},Attrs.prototype.getAttribute=function(name){for(var i=0,len=this.attrs.length;i<len;++i)if(this.attrs[i]&&this.attrs[i].name==name)return this.attrs[i].val}}),require.register("nodes/block-comment.js",function(module,exports,require){var Node=require("./node"),BlockComment=module.exports=function BlockComment(val,block,buffer){this.block=block,this.val=val,this.buffer=buffer};BlockComment.prototype=new Node,BlockComment.prototype.constructor=BlockComment}),require.register("nodes/block.js",function(module,exports,require){var Node=require("./node"),Block=module.exports=function Block(node){this.nodes=[],node&&this.push(node)};Block.prototype=new Node,Block.prototype.constructor=Block,Block.prototype.isBlock=!0,Block.prototype.replace=function(other){other.nodes=this.nodes},Block.prototype.push=function(node){return this.nodes.push(node)},Block.prototype.isEmpty=function(){return 0==this.nodes.length},Block.prototype.unshift=function(node){return this.nodes.unshift(node)},Block.prototype.includeBlock=function(){var ret=this,node;for(var i=0,len=this.nodes.length;i<len;++i){node=this.nodes[i];if(node.yield)return node;if(node.textOnly)continue;node.includeBlock?ret=node.includeBlock():node.block&&!node.block.isEmpty()&&(ret=node.block.includeBlock());if(ret.yield)return ret}return ret},Block.prototype.clone=function(){var clone=new Block;for(var i=0,len=this.nodes.length;i<len;++i)clone.push(this.nodes[i].clone());return clone}}),require.register("nodes/case.js",function(module,exports,require){var Node=require("./node"),Case=exports=module.exports=function Case(expr,block){this.expr=expr,this.block=block};Case.prototype=new Node,Case.prototype.constructor=Case;var When=exports.When=function When(expr,block){this.expr=expr,this.block=block,this.debug=!1};When.prototype=new Node,When.prototype.constructor=When}),require.register("nodes/code.js",function(module,exports,require){var Node=require("./node"),Code=module.exports=function Code(val,buffer,escape){this.val=val,this.buffer=buffer,this.escape=escape,val.match(/^ *else/)&&(this.debug=!1)};Code.prototype=new Node,Code.prototype.constructor=Code}),require.register("nodes/comment.js",function(module,exports,require){var Node=require("./node"),Comment=module.exports=function Comment(val,buffer){this.val=val,this.buffer=buffer};Comment.prototype=new Node,Comment.prototype.constructor=Comment}),require.register("nodes/doctype.js",function(module,exports,require){var Node=require("./node"),Doctype=module.exports=function Doctype(val){this.val=val};Doctype.prototype=new Node,Doctype.prototype.constructor=Doctype}),require.register("nodes/each.js",function(module,exports,require){var Node=require("./node"),Each=module.exports=function Each(obj,val,key,block){this.obj=obj,this.val=val,this.key=key,this.block=block};Each.prototype=new Node,Each.prototype.constructor=Each}),require.register("nodes/filter.js",function(module,exports,require){var Node=require("./node"),Block=require("./block"),Filter=module.exports=function Filter(name,block,attrs){this.name=name,this.block=block,this.attrs=attrs};Filter.prototype=new Node,Filter.prototype.constructor=Filter}),require.register("nodes/index.js",function(module,exports,require){exports.Node=require("./node"),exports.Tag=require("./tag"),exports.Code=require("./code"),exports.Each=require("./each"),exports.Case=require("./case"),exports.Text=require("./text"),exports.Block=require("./block"),exports.Mixin=require("./mixin"),exports.Filter=require("./filter"),exports.Comment=require("./comment"),exports.Literal=require("./literal"),exports.BlockComment=require("./block-comment"),exports.Doctype=require("./doctype")}),require.register("nodes/literal.js",function(module,exports,require){var Node=require("./node"),Literal=module.exports=function Literal(str){this.str=str};Literal.prototype=new Node,Literal.prototype.constructor=Literal}),require.register("nodes/mixin.js",function(module,exports,require){var Attrs=require("./attrs"),Mixin=module.exports=function Mixin(name,args,block,call){this.name=name,this.args=args,this.block=block,this.attrs=[],this.call=call};Mixin.prototype=new Attrs,Mixin.prototype.constructor=Mixin}),require.register("nodes/node.js",function(module,exports,require){var Node=module.exports=function Node(){};Node.prototype.clone=function(){return this}}),require.register("nodes/tag.js",function(module,exports,require){var Attrs=require("./attrs"),Block=require("./block"),inlineTags=require("../inline-tags"),Tag=module.exports=function Tag(name,block){this.name=name,this.attrs=[],this.block=block||new Block};Tag.prototype=new Attrs,Tag.prototype.constructor=Tag,Tag.prototype.clone=function(){var clone=new Tag(this.name,this.block.clone());return clone.line=this.line,clone.attrs=this.attrs,clone.textOnly=this.textOnly,clone},Tag.prototype.isInline=function(){return~inlineTags.indexOf(this.name)},Tag.prototype.canInline=function(){function isInline(node){return node.isBlock?node.nodes.every(isInline):node.isText||node.isInline&&node.isInline()}var nodes=this.block.nodes;if(!nodes.length)return!0;if(1==nodes.length)return isInline(nodes[0]);if(this.block.nodes.every(isInline)){for(var i=1,len=nodes.length;i<len;++i)if(nodes[i-1].isText&&nodes[i].isText)return!1;return!0}return!1}}),require.register("nodes/text.js",function(module,exports,require){var Node=require("./node"),Text=module.exports=function Text(line){this.val="","string"==typeof line&&(this.val=line)};Text.prototype=new Node,Text.prototype.constructor=Text,Text.prototype.isText=!0}),require.register("parser.js",function(module,exports,require){var Lexer=require("./lexer"),nodes=require("./nodes"),utils=require("./utils"),filters=require("./filters"),path=require("path"),extname=path.extname,Parser=exports=module.exports=function Parser(str,filename,options){this.input=str,this.lexer=new Lexer(str,options),this.filename=filename,this.blocks=[],this.mixins={},this.options=options,this.contexts=[this]},textOnly=exports.textOnly=["script","style"];Parser.prototype={context:function(parser){if(!parser)return this.contexts.pop();this.contexts.push(parser)},advance:function(){return this.lexer.advance()},skip:function(n){while(n--)this.advance()},peek:function(){return this.lookahead(1)},line:function(){return this.lexer.lineno},lookahead:function(n){return this.lexer.lookahead(n)},parse:function(){var block=new nodes.Block,parser;block.line=this.line();while("eos"!=this.peek().type)"newline"==this.peek().type?this.advance():block.push(this.parseExpr());if(parser=this.extending){this.context(parser);var ast=parser.parse();this.context();for(var name in this.mixins)ast.unshift(this.mixins[name]);return ast}return this.handleBlocks(),block},handleBlocks:function(){this.blocks.reverse();var blocksHash={};for(var i in this.blocks)if(!{}.hasOwnProperty.call(blocksHash,[this.blocks[i].name]))blocksHash[this.blocks[i].name]=this.blocks[i];else{switch(this.blocks[i].mode){case"append":blocksHash[this.blocks[i].name].nodes=blocksHash[this.blocks[i].name].nodes.concat(this.blocks[i].nodes);break;case"prepend":blocksHash[this.blocks[i].name].nodes=this.blocks[i].nodes.concat(blocksHash[this.blocks[i].name].nodes);break;default:blocksHash[this.blocks[i].name].nodes=this.blocks[i].nodes}this.blocks[i]=blocksHash[this.blocks[i].name]}},expect:function(type){if(this.peek().type===type)return this.advance();throw new Error('expected "'+type+'", but got "'+this.peek().type+'"')},accept:function(type){if(this.peek().type===type)return this.advance()},parseExpr:function(){switch(this.peek().type){case"tag":return this.parseTag();case"mixin":return this.parseMixin();case"block":return this.parseBlock();case"case":return this.parseCase();case"when":return this.parseWhen();case"default":return this.parseDefault();case"extends":return this.parseExtends();case"include":return this.parseInclude();case"doctype":return this.parseDoctype();case"filter":return this.parseFilter();case"comment":return this.parseComment();case"text":return this.parseText();case"each":return this.parseEach();case"code":return this.parseCode();case"call":return this.parseCall();case"interpolation":return this.parseInterpolation();case"yield":this.advance();var block=new nodes.Block;return block.yield=!0,block;case"id":case"class":var tok=this.advance();return this | |
.lexer.defer(this.lexer.tok("tag","div")),this.lexer.defer(tok),this.parseExpr();default:throw new Error('unexpected token "'+this.peek().type+'"')}},parseText:function(){var tok=this.expect("text"),node=new nodes.Text(tok.val);return node.line=this.line(),node},parseBlockExpansion:function(){return":"==this.peek().type?(this.advance(),new nodes.Block(this.parseExpr())):this.block()},parseCase:function(){var val=this.expect("case").val,node=new nodes.Case(val);return node.line=this.line(),node.block=this.block(),node},parseWhen:function(){var val=this.expect("when").val;return new nodes.Case.When(val,this.parseBlockExpansion())},parseDefault:function(){return this.expect("default"),new nodes.Case.When("default",this.parseBlockExpansion())},parseCode:function(){var tok=this.expect("code"),node=new nodes.Code(tok.val,tok.buffer,tok.escape),block,i=1;node.line=this.line();while(this.lookahead(i)&&"newline"==this.lookahead(i).type)++i;return block="indent"==this.lookahead(i).type,block&&(this.skip(i-1),node.block=this.block()),node},parseComment:function(){var tok=this.expect("comment"),node;return"indent"==this.peek().type?node=new nodes.BlockComment(tok.val,this.block(),tok.buffer):node=new nodes.Comment(tok.val,tok.buffer),node.line=this.line(),node},parseDoctype:function(){var tok=this.expect("doctype"),node=new nodes.Doctype(tok.val);return node.line=this.line(),node},parseFilter:function(){var tok=this.expect("filter"),attrs=this.accept("attrs"),block;this.lexer.pipeless=!0,block=this.parseTextBlock(),this.lexer.pipeless=!1;var node=new nodes.Filter(tok.val,block,attrs&&attrs.attrs);return node.line=this.line(),node},parseEach:function(){var tok=this.expect("each"),node=new nodes.Each(tok.code,tok.val,tok.key);return node.line=this.line(),node.block=this.block(),this.peek().type=="code"&&this.peek().val=="else"&&(this.advance(),node.alternative=this.block()),node},resolvePath:function(path,purpose){var p=require("path"),dirname=p.dirname,basename=p.basename,join=p.join;if(path[0]!=="/"&&!this.filename)throw new Error('the "filename" option is required to use "'+purpose+'" with "relative" paths');if(path[0]==="/"&&!this.options.basedir)throw new Error('the "basedir" option is required to use "'+purpose+'" with "absolute" paths');return path=join(path[0]==="/"?this.options.basedir:dirname(this.filename),path),basename(path).indexOf(".")===-1&&(path+=".jade"),path},parseExtends:function(){var fs=require("fs"),path=this.resolvePath(this.expect("extends").val.trim(),"extends");".jade"!=path.substr(-5)&&(path+=".jade");var str=fs.readFileSync(path,"utf8"),parser=new Parser(str,path,this.options);return parser.blocks=this.blocks.reverse(),parser.contexts=this.contexts,this.extending=parser,new nodes.Literal("")},parseBlock:function(){var block=this.expect("block"),mode=block.mode,name=block.val.trim();return block="indent"==this.peek().type?this.block():new nodes.Block(new nodes.Literal("")),block.mode=mode,block.name=name,this.blocks.push(block),block},parseInclude:function(){var fs=require("fs"),path=this.resolvePath(this.expect("include").val.trim(),"include");if(".jade"!=path.substr(-5)){var str=fs.readFileSync(path,"utf8").replace(/\r/g,""),ext=extname(path).slice(1);return filters.exists(ext)&&(str=filters(ext,str,{filename:path})),new nodes.Literal(str)}var str=fs.readFileSync(path,"utf8"),parser=new Parser(str,path,this.options);parser.blocks=utils.merge([],this.blocks),parser.mixins=this.mixins,this.context(parser);var ast=parser.parse();return this.context(),ast.filename=path,"indent"==this.peek().type&&ast.includeBlock().push(this.block()),ast},parseCall:function(){var tok=this.expect("call"),name=tok.val,args=tok.args,mixin=new nodes.Mixin(name,args,new nodes.Block,!0);return this.tag(mixin),mixin.block.isEmpty()&&(mixin.block=null),mixin},parseMixin:function(){var tok=this.expect("mixin"),name=tok.val,args=tok.args,mixin;return"indent"==this.peek().type?(mixin=new nodes.Mixin(name,args,this.block(),!1),this.mixins[name]=mixin,mixin):new nodes.Mixin(name,args,null,!0)},parseTextBlock:function(){var block=new nodes.Block;block.line=this.line();var spaces=this.expect("indent").val;null==this._spaces&&(this._spaces=spaces);var indent=Array(spaces-this._spaces+1).join(" ");while("outdent"!=this.peek().type)switch(this.peek().type){case"newline":this.advance();break;case"indent":this.parseTextBlock().nodes.forEach(function(node){block.push(node)});break;default:var text=new nodes.Text(indent+this.advance().val);text.line=this.line(),block.push(text)}return spaces==this._spaces&&(this._spaces=null),this.expect("outdent"),block},block:function(){var block=new nodes.Block;block.line=this.line(),this.expect("indent");while("outdent"!=this.peek().type)"newline"==this.peek().type?this.advance():block.push(this.parseExpr());return this.expect("outdent"),block},parseInterpolation:function(){var tok=this.advance(),tag=new nodes.Tag(tok.val);return tag.buffer=!0,this.tag(tag)},parseTag:function(){var i=2;"attrs"==this.lookahead(i).type&&++i;var tok=this.advance(),tag=new nodes.Tag(tok.val);return tag.selfClosing=tok.selfClosing,this.tag(tag)},tag:function(tag){var dot;tag.line=this.line();e:for(;;)switch(this.peek().type){case"id":case"class":var tok=this.advance();tag.setAttribute(tok.type,"'"+tok.val+"'");continue;case"attrs":var tok=this.advance(),obj=tok.attrs,escaped=tok.escaped,names=Object.keys(obj);tok.selfClosing&&(tag.selfClosing=!0);for(var i=0,len=names.length;i<len;++i){var name=names[i],val=obj[name];tag.setAttribute(name,val,escaped[name])}continue;default:break e}"."==this.peek().val&&(dot=tag.textOnly=!0,this.advance());switch(this.peek().type){case"text":tag.block.push(this.parseText());break;case"code":tag.code=this.parseCode();break;case":":this.advance(),tag.block=new nodes.Block,tag.block.push(this.parseExpr())}while("newline"==this.peek().type)this.advance();tag.textOnly=tag.textOnly||~textOnly.indexOf(tag.name);if("script"==tag.name){var type=tag.getAttribute("type");!dot&&type&&"text/javascript"!=type.replace(/^['"]|['"]$/g,"")&&(tag.textOnly=!1)}if("indent"==this.peek().type)if(tag.textOnly)this.lexer.pipeless=!0,tag.block=this.parseTextBlock(),this.lexer.pipeless=!1;else{var block=this.block();if(tag.block)for(var i=0,len=block.nodes.length;i<len;++i)tag.block.push(block.nodes[i]);else tag.block=block}return tag}}}),require.register("runtime.js",function(module,exports,require){function nulls(val){return val!=null}Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.merge=function merge(a,b){var ac=a["class"],bc=b["class"];if(ac||bc)ac=ac||[],bc=bc||[],Array.isArray(ac)||(ac=[ac]),Array.isArray(bc)||(bc=[bc]),ac=ac.filter(nulls),bc=bc.filter(nulls),a["class"]=ac.concat(bc).join(" ");for(var key in b)key!="class"&&(a[key]=b[key]);return a},exports.attrs=function attrs(obj,escaped){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i<len;++i){var key=keys[i],val=obj[key];"boolean"==typeof val||null==val?val&&(terse?buf.push(key):buf.push(key+'="'+key+'"')):0==key.indexOf("data")&&"string"!=typeof val?buf.push(key+"='"+JSON.stringify(val)+"'"):"class"==key&&Array.isArray(val)?buf.push(key+'="'+exports.escape(val.join(" "))+'"'):escaped&&escaped[key]?buf.push(key+'="'+exports.escape(val)+'"'):buf.push(key+'="'+val+'"')}}return buf.join(" ")},exports.escape=function escape(html){return String(html).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},exports.rethrow=function rethrow(err,filename,lineno){if(!filename)throw err;if(typeof window!="undefined")throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err}}),require.register("self-closing.js",function(module,exports,require){module.exports=["meta","img","link","input","source","area","base","col","br","hr"]}),require.register("utils.js",function(module,exports,require){exports.merge=function(a,b){for(var key in b)a[key]=b[key];return a}}),require("jade")}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment