- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / examples / howto / sandbox / handlebars-1.0.0.beta.6.js
1 // Copyright (C) 2011 by Yehuda Katz
2 // Licensing details in LICENSE.handlebars
3
4 // lib/handlebars/base.js
5 var Handlebars = {};
6
7 Handlebars.VERSION = "1.0.beta.6";
8
9 Handlebars.helpers  = {};
10 Handlebars.partials = {};
11
12 Handlebars.registerHelper = function(name, fn, inverse) {
13   if(inverse) { fn.not = inverse; }
14   this.helpers[name] = fn;
15 };
16
17 Handlebars.registerPartial = function(name, str) {
18   this.partials[name] = str;
19 };
20
21 Handlebars.registerHelper('helperMissing', function(arg) {
22   if(arguments.length === 2) {
23     return undefined;
24   } else {
25     throw new Error("Could not find property '" + arg + "'");
26   }
27 });
28
29 var toString = Object.prototype.toString, functionType = "[object Function]";
30
31 Handlebars.registerHelper('blockHelperMissing', function(context, options) {
32   var inverse = options.inverse || function() {}, fn = options.fn;
33
34
35   var ret = "";
36   var type = toString.call(context);
37
38   if(type === functionType) { context = context.call(this); }
39
40   if(context === true) {
41     return fn(this);
42   } else if(context === false || context == null) {
43     return inverse(this);
44   } else if(type === "[object Array]") {
45     if(context.length > 0) {
46       for(var i=0, j=context.length; i<j; i++) {
47         ret = ret + fn(context[i]);
48       }
49     } else {
50       ret = inverse(this);
51     }
52     return ret;
53   } else {
54     return fn(context);
55   }
56 });
57
58 Handlebars.registerHelper('each', function(context, options) {
59   var fn = options.fn, inverse = options.inverse;
60   var ret = "";
61
62   if(context && context.length > 0) {
63     for(var i=0, j=context.length; i<j; i++) {
64       ret = ret + fn(context[i]);
65     }
66   } else {
67     ret = inverse(this);
68   }
69   return ret;
70 });
71
72 Handlebars.registerHelper('if', function(context, options) {
73   var type = toString.call(context);
74   if(type === functionType) { context = context.call(this); }
75
76   if(!context || Handlebars.Utils.isEmpty(context)) {
77     return options.inverse(this);
78   } else {
79     return options.fn(this);
80   }
81 });
82
83 Handlebars.registerHelper('unless', function(context, options) {
84   var fn = options.fn, inverse = options.inverse;
85   options.fn = inverse;
86   options.inverse = fn;
87
88   return Handlebars.helpers['if'].call(this, context, options);
89 });
90
91 Handlebars.registerHelper('with', function(context, options) {
92   return options.fn(context);
93 });
94
95 Handlebars.registerHelper('log', function(context) {
96   Handlebars.log(context);
97 });
98 ;
99 // lib/handlebars/compiler/parser.js
100 /* Jison generated parser */
101 var handlebars = (function(){
102
103 var parser = {trace: function trace() { },
104 yy: {},
105 symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
106 terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
107 productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
108 performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
109
110 var $0 = $$.length - 1;
111 switch (yystate) {
112 case 1: return $$[$0-1] 
113 break;
114 case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]) 
115 break;
116 case 3: this.$ = new yy.ProgramNode($$[$0]) 
117 break;
118 case 4: this.$ = new yy.ProgramNode([]) 
119 break;
120 case 5: this.$ = [$$[$0]] 
121 break;
122 case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1] 
123 break;
124 case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0]) 
125 break;
126 case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0]) 
127 break;
128 case 9: this.$ = $$[$0] 
129 break;
130 case 10: this.$ = $$[$0] 
131 break;
132 case 11: this.$ = new yy.ContentNode($$[$0]) 
133 break;
134 case 12: this.$ = new yy.CommentNode($$[$0]) 
135 break;
136 case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
137 break;
138 case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
139 break;
140 case 15: this.$ = $$[$0-1] 
141 break;
142 case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
143 break;
144 case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true) 
145 break;
146 case 18: this.$ = new yy.PartialNode($$[$0-1]) 
147 break;
148 case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]) 
149 break;
150 case 20: 
151 break;
152 case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]] 
153 break;
154 case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null] 
155 break;
156 case 23: this.$ = [[$$[$0-1]], $$[$0]] 
157 break;
158 case 24: this.$ = [[$$[$0]], null] 
159 break;
160 case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
161 break;
162 case 26: this.$ = [$$[$0]] 
163 break;
164 case 27: this.$ = $$[$0] 
165 break;
166 case 28: this.$ = new yy.StringNode($$[$0]) 
167 break;
168 case 29: this.$ = new yy.IntegerNode($$[$0]) 
169 break;
170 case 30: this.$ = new yy.BooleanNode($$[$0]) 
171 break;
172 case 31: this.$ = new yy.HashNode($$[$0]) 
173 break;
174 case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1] 
175 break;
176 case 33: this.$ = [$$[$0]] 
177 break;
178 case 34: this.$ = [$$[$0-2], $$[$0]] 
179 break;
180 case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])] 
181 break;
182 case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])] 
183 break;
184 case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])] 
185 break;
186 case 38: this.$ = new yy.IdNode($$[$0]) 
187 break;
188 case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; 
189 break;
190 case 40: this.$ = [$$[$0]] 
191 break;
192 }
193 },
194 table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
195 defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
196 parseError: function parseError(str, hash) {
197     throw new Error(str);
198 },
199 parse: function parse(input) {
200     var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
201     this.lexer.setInput(input);
202     this.lexer.yy = this.yy;
203     this.yy.lexer = this.lexer;
204     if (typeof this.lexer.yylloc == "undefined")
205         this.lexer.yylloc = {};
206     var yyloc = this.lexer.yylloc;
207     lstack.push(yyloc);
208     if (typeof this.yy.parseError === "function")
209         this.parseError = this.yy.parseError;
210     function popStack(n) {
211         stack.length = stack.length - 2 * n;
212         vstack.length = vstack.length - n;
213         lstack.length = lstack.length - n;
214     }
215     function lex() {
216         var token;
217         token = self.lexer.lex() || 1;
218         if (typeof token !== "number") {
219             token = self.symbols_[token] || token;
220         }
221         return token;
222     }
223     var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
224     while (true) {
225         state = stack[stack.length - 1];
226         if (this.defaultActions[state]) {
227             action = this.defaultActions[state];
228         } else {
229             if (symbol == null)
230                 symbol = lex();
231             action = table[state] && table[state][symbol];
232         }
233         if (typeof action === "undefined" || !action.length || !action[0]) {
234             if (!recovering) {
235                 expected = [];
236                 for (p in table[state])
237                     if (this.terminals_[p] && p > 2) {
238                         expected.push("'" + this.terminals_[p] + "'");
239                     }
240                 var errStr = "";
241                 if (this.lexer.showPosition) {
242                     errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
243                 } else {
244                     errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
245                 }
246                 this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
247             }
248         }
249         if (action[0] instanceof Array && action.length > 1) {
250             throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
251         }
252         switch (action[0]) {
253         case 1:
254             stack.push(symbol);
255             vstack.push(this.lexer.yytext);
256             lstack.push(this.lexer.yylloc);
257             stack.push(action[1]);
258             symbol = null;
259             if (!preErrorSymbol) {
260                 yyleng = this.lexer.yyleng;
261                 yytext = this.lexer.yytext;
262                 yylineno = this.lexer.yylineno;
263                 yyloc = this.lexer.yylloc;
264                 if (recovering > 0)
265                     recovering--;
266             } else {
267                 symbol = preErrorSymbol;
268                 preErrorSymbol = null;
269             }
270             break;
271         case 2:
272             len = this.productions_[action[1]][1];
273             yyval.$ = vstack[vstack.length - len];
274             yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
275             r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
276             if (typeof r !== "undefined") {
277                 return r;
278             }
279             if (len) {
280                 stack = stack.slice(0, -1 * len * 2);
281                 vstack = vstack.slice(0, -1 * len);
282                 lstack = lstack.slice(0, -1 * len);
283             }
284             stack.push(this.productions_[action[1]][0]);
285             vstack.push(yyval.$);
286             lstack.push(yyval._$);
287             newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
288             stack.push(newState);
289             break;
290         case 3:
291             return true;
292         }
293     }
294     return true;
295 }
296 };/* Jison generated lexer */
297 var lexer = (function(){
298
299 var lexer = ({EOF:1,
300 parseError:function parseError(str, hash) {
301         if (this.yy.parseError) {
302             this.yy.parseError(str, hash);
303         } else {
304             throw new Error(str);
305         }
306     },
307 setInput:function (input) {
308         this._input = input;
309         this._more = this._less = this.done = false;
310         this.yylineno = this.yyleng = 0;
311         this.yytext = this.matched = this.match = '';
312         this.conditionStack = ['INITIAL'];
313         this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
314         return this;
315     },
316 input:function () {
317         var ch = this._input[0];
318         this.yytext+=ch;
319         this.yyleng++;
320         this.match+=ch;
321         this.matched+=ch;
322         var lines = ch.match(/\n/);
323         if (lines) this.yylineno++;
324         this._input = this._input.slice(1);
325         return ch;
326     },
327 unput:function (ch) {
328         this._input = ch + this._input;
329         return this;
330     },
331 more:function () {
332         this._more = true;
333         return this;
334     },
335 pastInput:function () {
336         var past = this.matched.substr(0, this.matched.length - this.match.length);
337         return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
338     },
339 upcomingInput:function () {
340         var next = this.match;
341         if (next.length < 20) {
342             next += this._input.substr(0, 20-next.length);
343         }
344         return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
345     },
346 showPosition:function () {
347         var pre = this.pastInput();
348         var c = new Array(pre.length + 1).join("-");
349         return pre + this.upcomingInput() + "\n" + c+"^";
350     },
351 next:function () {
352         if (this.done) {
353             return this.EOF;
354         }
355         if (!this._input) this.done = true;
356
357         var token,
358             match,
359             col,
360             lines;
361         if (!this._more) {
362             this.yytext = '';
363             this.match = '';
364         }
365         var rules = this._currentRules();
366         for (var i=0;i < rules.length; i++) {
367             match = this._input.match(this.rules[rules[i]]);
368             if (match) {
369                 lines = match[0].match(/\n.*/g);
370                 if (lines) this.yylineno += lines.length;
371                 this.yylloc = {first_line: this.yylloc.last_line,
372                                last_line: this.yylineno+1,
373                                first_column: this.yylloc.last_column,
374                                last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
375                 this.yytext += match[0];
376                 this.match += match[0];
377                 this.matches = match;
378                 this.yyleng = this.yytext.length;
379                 this._more = false;
380                 this._input = this._input.slice(match[0].length);
381                 this.matched += match[0];
382                 token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
383                 if (token) return token;
384                 else return;
385             }
386         }
387         if (this._input === "") {
388             return this.EOF;
389         } else {
390             this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), 
391                     {text: "", token: null, line: this.yylineno});
392         }
393     },
394 lex:function lex() {
395         var r = this.next();
396         if (typeof r !== 'undefined') {
397             return r;
398         } else {
399             return this.lex();
400         }
401     },
402 begin:function begin(condition) {
403         this.conditionStack.push(condition);
404     },
405 popState:function popState() {
406         return this.conditionStack.pop();
407     },
408 _currentRules:function _currentRules() {
409         return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
410     },
411 topState:function () {
412         return this.conditionStack[this.conditionStack.length-2];
413     },
414 pushState:function begin(condition) {
415         this.begin(condition);
416     }});
417 lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
418
419 var YYSTATE=YY_START
420 switch($avoiding_name_collisions) {
421 case 0:
422                                    if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
423                                    if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
424                                    if(yy_.yytext) return 14;
425                                  
426 break;
427 case 1: return 14; 
428 break;
429 case 2: this.popState(); return 14; 
430 break;
431 case 3: return 24; 
432 break;
433 case 4: return 16; 
434 break;
435 case 5: return 20; 
436 break;
437 case 6: return 19; 
438 break;
439 case 7: return 19; 
440 break;
441 case 8: return 23; 
442 break;
443 case 9: return 23; 
444 break;
445 case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; 
446 break;
447 case 11: return 22; 
448 break;
449 case 12: return 34; 
450 break;
451 case 13: return 33; 
452 break;
453 case 14: return 33; 
454 break;
455 case 15: return 36; 
456 break;
457 case 16: /*ignore whitespace*/ 
458 break;
459 case 17: this.popState(); return 18; 
460 break;
461 case 18: this.popState(); return 18; 
462 break;
463 case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28; 
464 break;
465 case 20: return 30; 
466 break;
467 case 21: return 30; 
468 break;
469 case 22: return 29; 
470 break;
471 case 23: return 33; 
472 break;
473 case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33; 
474 break;
475 case 25: return 'INVALID'; 
476 break;
477 case 26: return 5; 
478 break;
479 }
480 };
481 lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];
482 lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,26],"inclusive":true}};return lexer;})()
483 parser.lexer = lexer;
484 return parser;
485 })();
486 if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
487 exports.parser = handlebars;
488 exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
489 exports.main = function commonjsMain(args) {
490     if (!args[1])
491         throw new Error('Usage: '+args[0]+' FILE');
492     if (typeof process !== 'undefined') {
493         var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
494     } else {
495         var cwd = require("file").path(require("file").cwd());
496         var source = cwd.join(args[1]).read({charset: "utf-8"});
497     }
498     return exports.parser.parse(source);
499 }
500 if (typeof module !== 'undefined' && require.main === module) {
501   exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
502 }
503 };
504 ;
505 // lib/handlebars/compiler/base.js
506 Handlebars.Parser = handlebars;
507
508 Handlebars.parse = function(string) {
509   Handlebars.Parser.yy = Handlebars.AST;
510   return Handlebars.Parser.parse(string);
511 };
512
513 Handlebars.print = function(ast) {
514   return new Handlebars.PrintVisitor().accept(ast);
515 };
516
517 Handlebars.logger = {
518   DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
519
520   // override in the host environment
521   log: function(level, str) {}
522 };
523
524 Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
525 ;
526 // lib/handlebars/compiler/ast.js
527 (function() {
528
529   Handlebars.AST = {};
530
531   Handlebars.AST.ProgramNode = function(statements, inverse) {
532     this.type = "program";
533     this.statements = statements;
534     if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
535   };
536
537   Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
538     this.type = "mustache";
539     this.id = params[0];
540     this.params = params.slice(1);
541     this.hash = hash;
542     this.escaped = !unescaped;
543   };
544
545   Handlebars.AST.PartialNode = function(id, context) {
546     this.type    = "partial";
547
548     // TODO: disallow complex IDs
549
550     this.id      = id;
551     this.context = context;
552   };
553
554   var verifyMatch = function(open, close) {
555     if(open.original !== close.original) {
556       throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
557     }
558   };
559
560   Handlebars.AST.BlockNode = function(mustache, program, close) {
561     verifyMatch(mustache.id, close);
562     this.type = "block";
563     this.mustache = mustache;
564     this.program  = program;
565   };
566
567   Handlebars.AST.InverseNode = function(mustache, program, close) {
568     verifyMatch(mustache.id, close);
569     this.type = "inverse";
570     this.mustache = mustache;
571     this.program  = program;
572   };
573
574   Handlebars.AST.ContentNode = function(string) {
575     this.type = "content";
576     this.string = string;
577   };
578
579   Handlebars.AST.HashNode = function(pairs) {
580     this.type = "hash";
581     this.pairs = pairs;
582   };
583
584   Handlebars.AST.IdNode = function(parts) {
585     this.type = "ID";
586     this.original = parts.join(".");
587
588     var dig = [], depth = 0;
589
590     for(var i=0,l=parts.length; i<l; i++) {
591       var part = parts[i];
592
593       if(part === "..") { depth++; }
594       else if(part === "." || part === "this") { this.isScoped = true; }
595       else { dig.push(part); }
596     }
597
598     this.parts    = dig;
599     this.string   = dig.join('.');
600     this.depth    = depth;
601     this.isSimple = (dig.length === 1) && (depth === 0);
602   };
603
604   Handlebars.AST.StringNode = function(string) {
605     this.type = "STRING";
606     this.string = string;
607   };
608
609   Handlebars.AST.IntegerNode = function(integer) {
610     this.type = "INTEGER";
611     this.integer = integer;
612   };
613
614   Handlebars.AST.BooleanNode = function(bool) {
615     this.type = "BOOLEAN";
616     this.bool = bool;
617   };
618
619   Handlebars.AST.CommentNode = function(comment) {
620     this.type = "comment";
621     this.comment = comment;
622   };
623
624 })();;
625 // lib/handlebars/utils.js
626 Handlebars.Exception = function(message) {
627   var tmp = Error.prototype.constructor.apply(this, arguments);
628
629   for (var p in tmp) {
630     if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
631   }
632
633   this.message = tmp.message;
634 };
635 Handlebars.Exception.prototype = new Error;
636
637 // Build out our basic SafeString type
638 Handlebars.SafeString = function(string) {
639   this.string = string;
640 };
641 Handlebars.SafeString.prototype.toString = function() {
642   return this.string.toString();
643 };
644
645 (function() {
646   var escape = {
647     "<": "&lt;",
648     ">": "&gt;",
649     '"': "&quot;",
650     "'": "&#x27;",
651     "`": "&#x60;"
652   };
653
654   var badChars = /&(?!\w+;)|[<>"'`]/g;
655   var possible = /[&<>"'`]/;
656
657   var escapeChar = function(chr) {
658     return escape[chr] || "&amp;";
659   };
660
661   Handlebars.Utils = {
662     escapeExpression: function(string) {
663       // don't escape SafeStrings, since they're already safe
664       if (string instanceof Handlebars.SafeString) {
665         return string.toString();
666       } else if (string == null || string === false) {
667         return "";
668       }
669
670       if(!possible.test(string)) { return string; }
671       return string.replace(badChars, escapeChar);
672     },
673
674     isEmpty: function(value) {
675       if (typeof value === "undefined") {
676         return true;
677       } else if (value === null) {
678         return true;
679       } else if (value === false) {
680         return true;
681       } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
682         return true;
683       } else {
684         return false;
685       }
686     }
687   };
688 })();;
689 // lib/handlebars/compiler/compiler.js
690 Handlebars.Compiler = function() {};
691 Handlebars.JavaScriptCompiler = function() {};
692
693 (function(Compiler, JavaScriptCompiler) {
694   Compiler.OPCODE_MAP = {
695     appendContent: 1,
696     getContext: 2,
697     lookupWithHelpers: 3,
698     lookup: 4,
699     append: 5,
700     invokeMustache: 6,
701     appendEscaped: 7,
702     pushString: 8,
703     truthyOrFallback: 9,
704     functionOrFallback: 10,
705     invokeProgram: 11,
706     invokePartial: 12,
707     push: 13,
708     assignToHash: 15,
709     pushStringParam: 16
710   };
711
712   Compiler.MULTI_PARAM_OPCODES = {
713     appendContent: 1,
714     getContext: 1,
715     lookupWithHelpers: 2,
716     lookup: 1,
717     invokeMustache: 3,
718     pushString: 1,
719     truthyOrFallback: 1,
720     functionOrFallback: 1,
721     invokeProgram: 3,
722     invokePartial: 1,
723     push: 1,
724     assignToHash: 1,
725     pushStringParam: 1
726   };
727
728   Compiler.DISASSEMBLE_MAP = {};
729
730   for(var prop in Compiler.OPCODE_MAP) {
731     var value = Compiler.OPCODE_MAP[prop];
732     Compiler.DISASSEMBLE_MAP[value] = prop;
733   }
734
735   Compiler.multiParamSize = function(code) {
736     return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
737   };
738
739   Compiler.prototype = {
740     compiler: Compiler,
741
742     disassemble: function() {
743       var opcodes = this.opcodes, opcode, nextCode;
744       var out = [], str, name, value;
745
746       for(var i=0, l=opcodes.length; i<l; i++) {
747         opcode = opcodes[i];
748
749         if(opcode === 'DECLARE') {
750           name = opcodes[++i];
751           value = opcodes[++i];
752           out.push("DECLARE " + name + " = " + value);
753         } else {
754           str = Compiler.DISASSEMBLE_MAP[opcode];
755
756           var extraParams = Compiler.multiParamSize(opcode);
757           var codes = [];
758
759           for(var j=0; j<extraParams; j++) {
760             nextCode = opcodes[++i];
761
762             if(typeof nextCode === "string") {
763               nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
764             }
765
766             codes.push(nextCode);
767           }
768
769           str = str + " " + codes.join(" ");
770
771           out.push(str);
772         }
773       }
774
775       return out.join("\n");
776     },
777
778     guid: 0,
779
780     compile: function(program, options) {
781       this.children = [];
782       this.depths = {list: []};
783       this.options = options;
784
785       // These changes will propagate to the other compiler components
786       var knownHelpers = this.options.knownHelpers;
787       this.options.knownHelpers = {
788         'helperMissing': true,
789         'blockHelperMissing': true,
790         'each': true,
791         'if': true,
792         'unless': true,
793         'with': true,
794         'log': true
795       };
796       if (knownHelpers) {
797         for (var name in knownHelpers) {
798           this.options.knownHelpers[name] = knownHelpers[name];
799         }
800       }
801
802       return this.program(program);
803     },
804
805     accept: function(node) {
806       return this[node.type](node);
807     },
808
809     program: function(program) {
810       var statements = program.statements, statement;
811       this.opcodes = [];
812
813       for(var i=0, l=statements.length; i<l; i++) {
814         statement = statements[i];
815         this[statement.type](statement);
816       }
817       this.isSimple = l === 1;
818
819       this.depths.list = this.depths.list.sort(function(a, b) {
820         return a - b;
821       });
822
823       return this;
824     },
825
826     compileProgram: function(program) {
827       var result = new this.compiler().compile(program, this.options);
828       var guid = this.guid++;
829
830       this.usePartial = this.usePartial || result.usePartial;
831
832       this.children[guid] = result;
833
834       for(var i=0, l=result.depths.list.length; i<l; i++) {
835         depth = result.depths.list[i];
836
837         if(depth < 2) { continue; }
838         else { this.addDepth(depth - 1); }
839       }
840
841       return guid;
842     },
843
844     block: function(block) {
845       var mustache = block.mustache;
846       var depth, child, inverse, inverseGuid;
847
848       var params = this.setupStackForMustache(mustache);
849
850       var programGuid = this.compileProgram(block.program);
851
852       if(block.program.inverse) {
853         inverseGuid = this.compileProgram(block.program.inverse);
854         this.declare('inverse', inverseGuid);
855       }
856
857       this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
858       this.declare('inverse', null);
859       this.opcode('append');
860     },
861
862     inverse: function(block) {
863       var params = this.setupStackForMustache(block.mustache);
864
865       var programGuid = this.compileProgram(block.program);
866
867       this.declare('inverse', programGuid);
868
869       this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
870       this.declare('inverse', null);
871       this.opcode('append');
872     },
873
874     hash: function(hash) {
875       var pairs = hash.pairs, pair, val;
876
877       this.opcode('push', '{}');
878
879       for(var i=0, l=pairs.length; i<l; i++) {
880         pair = pairs[i];
881         val  = pair[1];
882
883         this.accept(val);
884         this.opcode('assignToHash', pair[0]);
885       }
886     },
887
888     partial: function(partial) {
889       var id = partial.id;
890       this.usePartial = true;
891
892       if(partial.context) {
893         this.ID(partial.context);
894       } else {
895         this.opcode('push', 'depth0');
896       }
897
898       this.opcode('invokePartial', id.original);
899       this.opcode('append');
900     },
901
902     content: function(content) {
903       this.opcode('appendContent', content.string);
904     },
905
906     mustache: function(mustache) {
907       var params = this.setupStackForMustache(mustache);
908
909       this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);
910
911       if(mustache.escaped && !this.options.noEscape) {
912         this.opcode('appendEscaped');
913       } else {
914         this.opcode('append');
915       }
916     },
917
918     ID: function(id) {
919       this.addDepth(id.depth);
920
921       this.opcode('getContext', id.depth);
922
923       this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
924
925       for(var i=1, l=id.parts.length; i<l; i++) {
926         this.opcode('lookup', id.parts[i]);
927       }
928     },
929
930     STRING: function(string) {
931       this.opcode('pushString', string.string);
932     },
933
934     INTEGER: function(integer) {
935       this.opcode('push', integer.integer);
936     },
937
938     BOOLEAN: function(bool) {
939       this.opcode('push', bool.bool);
940     },
941
942     comment: function() {},
943
944     // HELPERS
945     pushParams: function(params) {
946       var i = params.length, param;
947
948       while(i--) {
949         param = params[i];
950
951         if(this.options.stringParams) {
952           if(param.depth) {
953             this.addDepth(param.depth);
954           }
955
956           this.opcode('getContext', param.depth || 0);
957           this.opcode('pushStringParam', param.string);
958         } else {
959           this[param.type](param);
960         }
961       }
962     },
963
964     opcode: function(name, val1, val2, val3) {
965       this.opcodes.push(Compiler.OPCODE_MAP[name]);
966       if(val1 !== undefined) { this.opcodes.push(val1); }
967       if(val2 !== undefined) { this.opcodes.push(val2); }
968       if(val3 !== undefined) { this.opcodes.push(val3); }
969     },
970
971     declare: function(name, value) {
972       this.opcodes.push('DECLARE');
973       this.opcodes.push(name);
974       this.opcodes.push(value);
975     },
976
977     addDepth: function(depth) {
978       if(depth === 0) { return; }
979
980       if(!this.depths[depth]) {
981         this.depths[depth] = true;
982         this.depths.list.push(depth);
983       }
984     },
985
986     setupStackForMustache: function(mustache) {
987       var params = mustache.params;
988
989       this.pushParams(params);
990
991       if(mustache.hash) {
992         this.hash(mustache.hash);
993       }
994
995       this.ID(mustache.id);
996
997       return params;
998     }
999   };
1000
1001   JavaScriptCompiler.prototype = {
1002     // PUBLIC API: You can override these methods in a subclass to provide
1003     // alternative compiled forms for name lookup and buffering semantics
1004     nameLookup: function(parent, name, type) {
1005       if (/^[0-9]+$/.test(name)) {
1006         return parent + "[" + name + "]";
1007       } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1008         return parent + "." + name;
1009       }
1010       else {
1011         return parent + "['" + name + "']";
1012       }
1013     },
1014
1015     appendToBuffer: function(string) {
1016       if (this.environment.isSimple) {
1017         return "return " + string + ";";
1018       } else {
1019         return "buffer += " + string + ";";
1020       }
1021     },
1022
1023     initializeBuffer: function() {
1024       return this.quotedString("");
1025     },
1026
1027     namespace: "Handlebars",
1028     // END PUBLIC API
1029
1030     compile: function(environment, options, context, asObject) {
1031       this.environment = environment;
1032       this.options = options || {};
1033
1034       this.name = this.environment.name;
1035       this.isChild = !!context;
1036       this.context = context || {
1037         programs: [],
1038         aliases: { self: 'this' },
1039         registers: {list: []}
1040       };
1041
1042       this.preamble();
1043
1044       this.stackSlot = 0;
1045       this.stackVars = [];
1046
1047       this.compileChildren(environment, options);
1048
1049       var opcodes = environment.opcodes, opcode;
1050
1051       this.i = 0;
1052
1053       for(l=opcodes.length; this.i<l; this.i++) {
1054         opcode = this.nextOpcode(0);
1055
1056         if(opcode[0] === 'DECLARE') {
1057           this.i = this.i + 2;
1058           this[opcode[1]] = opcode[2];
1059         } else {
1060           this.i = this.i + opcode[1].length;
1061           this[opcode[0]].apply(this, opcode[1]);
1062         }
1063       }
1064
1065       return this.createFunctionContext(asObject);
1066     },
1067
1068     nextOpcode: function(n) {
1069       var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
1070       var extraParams, codes;
1071
1072       if(opcode === 'DECLARE') {
1073         name = opcodes[this.i + 1];
1074         val  = opcodes[this.i + 2];
1075         return ['DECLARE', name, val];
1076       } else {
1077         name = Compiler.DISASSEMBLE_MAP[opcode];
1078
1079         extraParams = Compiler.multiParamSize(opcode);
1080         codes = [];
1081
1082         for(var j=0; j<extraParams; j++) {
1083           codes.push(opcodes[this.i + j + 1 + n]);
1084         }
1085
1086         return [name, codes];
1087       }
1088     },
1089
1090     eat: function(opcode) {
1091       this.i = this.i + opcode.length;
1092     },
1093
1094     preamble: function() {
1095       var out = [];
1096
1097       // this register will disambiguate helper lookup from finding a function in
1098       // a context. This is necessary for mustache compatibility, which requires
1099       // that context functions in blocks are evaluated by blockHelperMissing, and
1100       // then proceed as if the resulting value was provided to blockHelperMissing.
1101       this.useRegister('foundHelper');
1102
1103       if (!this.isChild) {
1104         var namespace = this.namespace;
1105         var copies = "helpers = helpers || " + namespace + ".helpers;";
1106         if(this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
1107         out.push(copies);
1108       } else {
1109         out.push('');
1110       }
1111
1112       if (!this.environment.isSimple) {
1113         out.push(", buffer = " + this.initializeBuffer());
1114       } else {
1115         out.push("");
1116       }
1117
1118       // track the last context pushed into place to allow skipping the
1119       // getContext opcode when it would be a noop
1120       this.lastContext = 0;
1121       this.source = out;
1122     },
1123
1124     createFunctionContext: function(asObject) {
1125       var locals = this.stackVars;
1126       if (!this.isChild) {
1127         locals = locals.concat(this.context.registers.list);
1128       }
1129
1130       if(locals.length > 0) {
1131         this.source[1] = this.source[1] + ", " + locals.join(", ");
1132       }
1133
1134       // Generate minimizer alias mappings
1135       if (!this.isChild) {
1136         var aliases = []
1137         for (var alias in this.context.aliases) {
1138           this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1139         }
1140       }
1141
1142       if (this.source[1]) {
1143         this.source[1] = "var " + this.source[1].substring(2) + ";";
1144       }
1145
1146       // Merge children
1147       if (!this.isChild) {
1148         this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1149       }
1150
1151       if (!this.environment.isSimple) {
1152         this.source.push("return buffer;");
1153       }
1154
1155       var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1156
1157       for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1158         params.push("depth" + this.environment.depths.list[i]);
1159       }
1160
1161       if (asObject) {
1162         params.push(this.source.join("\n  "));
1163
1164         return Function.apply(this, params);
1165       } else {
1166         var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + this.source.join("\n  ") + '}';
1167         Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
1168         return functionSource;
1169       }
1170     },
1171
1172     appendContent: function(content) {
1173       this.source.push(this.appendToBuffer(this.quotedString(content)));
1174     },
1175
1176     append: function() {
1177       var local = this.popStack();
1178       this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1179       if (this.environment.isSimple) {
1180         this.source.push("else { " + this.appendToBuffer("''") + " }");
1181       }
1182     },
1183
1184     appendEscaped: function() {
1185       var opcode = this.nextOpcode(1), extra = "";
1186       this.context.aliases.escapeExpression = 'this.escapeExpression';
1187
1188       if(opcode[0] === 'appendContent') {
1189         extra = " + " + this.quotedString(opcode[1][0]);
1190         this.eat(opcode);
1191       }
1192
1193       this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
1194     },
1195
1196     getContext: function(depth) {
1197       if(this.lastContext !== depth) {
1198         this.lastContext = depth;
1199       }
1200     },
1201
1202     lookupWithHelpers: function(name, isScoped) {
1203       if(name) {
1204         var topStack = this.nextStack();
1205
1206         this.usingKnownHelper = false;
1207
1208         var toPush;
1209         if (!isScoped && this.options.knownHelpers[name]) {
1210           toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
1211           this.usingKnownHelper = true;
1212         } else if (isScoped || this.options.knownHelpersOnly) {
1213           toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
1214         } else {
1215           this.register('foundHelper', this.nameLookup('helpers', name, 'helper'));
1216           toPush = topStack + " = foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context');
1217         }
1218
1219         toPush += ';';
1220         this.source.push(toPush);
1221       } else {
1222         this.pushStack('depth' + this.lastContext);
1223       }
1224     },
1225
1226     lookup: function(name) {
1227       var topStack = this.topStack();
1228       this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
1229         topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
1230     },
1231
1232     pushStringParam: function(string) {
1233       this.pushStack('depth' + this.lastContext);
1234       this.pushString(string);
1235     },
1236
1237     pushString: function(string) {
1238       this.pushStack(this.quotedString(string));
1239     },
1240
1241     push: function(name) {
1242       this.pushStack(name);
1243     },
1244
1245     invokeMustache: function(paramSize, original, hasHash) {
1246       this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
1247         if (!this.usingKnownHelper) {
1248           this.context.aliases.helperMissing = 'helpers.helperMissing';
1249           this.context.aliases.undef = 'void 0';
1250           this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
1251           if (nextStack !== id) {
1252             this.source.push("else { " + nextStack + " = " + id + "; }");
1253           }
1254         }
1255       });
1256     },
1257
1258     invokeProgram: function(guid, paramSize, hasHash) {
1259       var inverse = this.programExpression(this.inverse);
1260       var mainProgram = this.programExpression(guid);
1261
1262       this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
1263         if (!this.usingKnownHelper) {
1264           this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1265           this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
1266         }
1267       });
1268     },
1269
1270     populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
1271       var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
1272       var id = this.popStack(), nextStack;
1273       var params = [], param, stringParam, stringOptions;
1274
1275       if (needsRegister) {
1276         this.register('tmp1', program);
1277         stringOptions = 'tmp1';
1278       } else {
1279         stringOptions = '{ hash: {} }';
1280       }
1281
1282       if (needsRegister) {
1283         var hash = (hasHash ? this.popStack() : '{}');
1284         this.source.push('tmp1.hash = ' + hash + ';');
1285       }
1286
1287       if(this.options.stringParams) {
1288         this.source.push('tmp1.contexts = [];');
1289       }
1290
1291       for(var i=0; i<paramSize; i++) {
1292         param = this.popStack();
1293         params.push(param);
1294
1295         if(this.options.stringParams) {
1296           this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
1297         }
1298       }
1299
1300       if(inverse) {
1301         this.source.push('tmp1.fn = tmp1;');
1302         this.source.push('tmp1.inverse = ' + inverse + ';');
1303       }
1304
1305       if(this.options.data) {
1306         this.source.push('tmp1.data = data;');
1307       }
1308
1309       params.push(stringOptions);
1310
1311       this.populateCall(params, id, helperId || id, fn, program !== '{}');
1312     },
1313
1314     populateCall: function(params, id, helperId, fn, program) {
1315       var paramString = ["depth0"].concat(params).join(", ");
1316       var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
1317
1318       var nextStack = this.nextStack();
1319
1320       if (this.usingKnownHelper) {
1321         this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
1322       } else {
1323         this.context.aliases.functionType = '"function"';
1324         var condition = program ? "foundHelper && " : ""
1325         this.source.push("if(" + condition + "typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
1326       }
1327       fn.call(this, nextStack, helperMissingString, id);
1328       this.usingKnownHelper = false;
1329     },
1330
1331     invokePartial: function(context) {
1332       params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];
1333
1334       if (this.options.data) {
1335         params.push("data");
1336       }
1337
1338       this.pushStack("self.invokePartial(" + params.join(", ") + ");");
1339     },
1340
1341     assignToHash: function(key) {
1342       var value = this.popStack();
1343       var hash = this.topStack();
1344
1345       this.source.push(hash + "['" + key + "'] = " + value + ";");
1346     },
1347
1348     // HELPERS
1349
1350     compiler: JavaScriptCompiler,
1351
1352     compileChildren: function(environment, options) {
1353       var children = environment.children, child, compiler;
1354
1355       for(var i=0, l=children.length; i<l; i++) {
1356         child = children[i];
1357         compiler = new this.compiler();
1358
1359         this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
1360         var index = this.context.programs.length;
1361         child.index = index;
1362         child.name = 'program' + index;
1363         this.context.programs[index] = compiler.compile(child, options, this.context);
1364       }
1365     },
1366
1367     programExpression: function(guid) {
1368       if(guid == null) { return "self.noop"; }
1369
1370       var child = this.environment.children[guid],
1371           depths = child.depths.list;
1372       var programParams = [child.index, child.name, "data"];
1373
1374       for(var i=0, l = depths.length; i<l; i++) {
1375         depth = depths[i];
1376
1377         if(depth === 1) { programParams.push("depth0"); }
1378         else { programParams.push("depth" + (depth - 1)); }
1379       }
1380
1381       if(depths.length === 0) {
1382         return "self.program(" + programParams.join(", ") + ")";
1383       } else {
1384         programParams.shift();
1385         return "self.programWithDepth(" + programParams.join(", ") + ")";
1386       }
1387     },
1388
1389     register: function(name, val) {
1390       this.useRegister(name);
1391       this.source.push(name + " = " + val + ";");
1392     },
1393
1394     useRegister: function(name) {
1395       if(!this.context.registers[name]) {
1396         this.context.registers[name] = true;
1397         this.context.registers.list.push(name);
1398       }
1399     },
1400
1401     pushStack: function(item) {
1402       this.source.push(this.nextStack() + " = " + item + ";");
1403       return "stack" + this.stackSlot;
1404     },
1405
1406     nextStack: function() {
1407       this.stackSlot++;
1408       if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1409       return "stack" + this.stackSlot;
1410     },
1411
1412     popStack: function() {
1413       return "stack" + this.stackSlot--;
1414     },
1415
1416     topStack: function() {
1417       return "stack" + this.stackSlot;
1418     },
1419
1420     quotedString: function(str) {
1421       return '"' + str
1422         .replace(/\\/g, '\\\\')
1423         .replace(/"/g, '\\"')
1424         .replace(/\n/g, '\\n')
1425         .replace(/\r/g, '\\r') + '"';
1426     }
1427   };
1428
1429   var reservedWords = (
1430     "break else new var" +
1431     " case finally return void" +
1432     " catch for switch while" +
1433     " continue function this with" +
1434     " default if throw" +
1435     " delete in try" +
1436     " do instanceof typeof" +
1437     " abstract enum int short" +
1438     " boolean export interface static" +
1439     " byte extends long super" +
1440     " char final native synchronized" +
1441     " class float package throws" +
1442     " const goto private transient" +
1443     " debugger implements protected volatile" +
1444     " double import public let yield"
1445   ).split(" ");
1446
1447   var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
1448
1449   for(var i=0, l=reservedWords.length; i<l; i++) {
1450     compilerWords[reservedWords[i]] = true;
1451   }
1452
1453   JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
1454     if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
1455       return true;
1456     }
1457     return false;
1458   }
1459
1460 })(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
1461
1462 Handlebars.precompile = function(string, options) {
1463   options = options || {};
1464
1465   var ast = Handlebars.parse(string);
1466   var environment = new Handlebars.Compiler().compile(ast, options);
1467   return new Handlebars.JavaScriptCompiler().compile(environment, options);
1468 };
1469
1470 Handlebars.compile = function(string, options) {
1471   options = options || {};
1472
1473   var compiled;
1474   function compile() {
1475     var ast = Handlebars.parse(string);
1476     var environment = new Handlebars.Compiler().compile(ast, options);
1477     var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
1478     return Handlebars.template(templateSpec);
1479   }
1480
1481   // Template is only compiled on first use and cached after that point.
1482   return function(context, options) {
1483     if (!compiled) {
1484       compiled = compile();
1485     }
1486     return compiled.call(this, context, options);
1487   };
1488 };
1489 ;
1490 // lib/handlebars/runtime.js
1491 Handlebars.VM = {
1492   template: function(templateSpec) {
1493     // Just add water
1494     var container = {
1495       escapeExpression: Handlebars.Utils.escapeExpression,
1496       invokePartial: Handlebars.VM.invokePartial,
1497       programs: [],
1498       program: function(i, fn, data) {
1499         var programWrapper = this.programs[i];
1500         if(data) {
1501           return Handlebars.VM.program(fn, data);
1502         } else if(programWrapper) {
1503           return programWrapper;
1504         } else {
1505           programWrapper = this.programs[i] = Handlebars.VM.program(fn);
1506           return programWrapper;
1507         }
1508       },
1509       programWithDepth: Handlebars.VM.programWithDepth,
1510       noop: Handlebars.VM.noop
1511     };
1512
1513     return function(context, options) {
1514       options = options || {};
1515       return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
1516     };
1517   },
1518
1519   programWithDepth: function(fn, data, $depth) {
1520     var args = Array.prototype.slice.call(arguments, 2);
1521
1522     return function(context, options) {
1523       options = options || {};
1524
1525       return fn.apply(this, [context, options.data || data].concat(args));
1526     };
1527   },
1528   program: function(fn, data) {
1529     return function(context, options) {
1530       options = options || {};
1531
1532       return fn(context, options.data || data);
1533     };
1534   },
1535   noop: function() { return ""; },
1536   invokePartial: function(partial, name, context, helpers, partials, data) {
1537     options = { helpers: helpers, partials: partials, data: data };
1538
1539     if(partial === undefined) {
1540       throw new Handlebars.Exception("The partial " + name + " could not be found");
1541     } else if(partial instanceof Function) {
1542       return partial(context, options);
1543     } else if (!Handlebars.compile) {
1544       throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
1545     } else {
1546       partials[name] = Handlebars.compile(partial);
1547       return partials[name](context, options);
1548     }
1549   }
1550 };
1551
1552 Handlebars.template = Handlebars.VM.template;
1553 ;