PageSourceSearch

https://www.hubmed.org/vendor/handlebars.js

js hubmed.org collected 2026-10-02 03:23:00 UTC 72,618 bytes, 2,278 lines download raw bytes

1/*
2
3Copyright (C) 2011 by Yehuda Katz
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*/
24
25// lib/handlebars/browser-prefix.js
26var Handlebars = {};
27
28(function(Handlebars, undefined) {
29;
30// lib/handlebars/base.js
31
32Handlebars.VERSION = "1.0.0";
33Handlebars.COMPILER_REVISION = 4;
34
35Handlebars.REVISION_CHANGES = {
36  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
37  2: '== 1.0.0-rc.3',
38  3: '== 1.0.0-rc.4',
39  4: '>= 1.0.0'
40};
41
42Handlebars.helpers  = {};
43Handlebars.partials = {};
44
45var toString = Object.prototype.toString,
46    functionType = '[object Function]',
47    objectType = '[object Object]';
48
49Handlebars.registerHelper = function(name, fn, inverse) {
50  if (toString.call(name) === objectType) {
51    if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
52    Handlebars.Utils.extend(this.helpers, name);
53  } else {
54    if (inverse) { fn.not = inverse; }
55    this.helpers[name] = fn;
56  }
57};
58
59Handlebars.registerPartial = function(name, str) {
60  if (toString.call(name) === objectType) {
61    Handlebars.Utils.extend(this.partials,  name);
62  } else {
63    this.partials[name] = str;
64  }
65};
66
67Handlebars.registerHelper('helperMissing', function(arg) {
68  if(arguments.length === 2) {
69    return undefined;
70  } else {
71    throw new Error("Missing helper: '" + arg + "'");
72  }
73});
74
75Handlebars.registerHelper('blockHelperMissing', function(context, options) {
76  var inverse = options.inverse || function() {}, fn = options.fn;
77
78  var type = toString.call(context);
79
80  if(type === functionType) { context = context.call(this); }
81
82  if(context === true) {
83    return fn(this);
84  } else if(context === false || context == null) {
85    return inverse(this);
86  } else if(type === "[object Array]") {
87    if(context.length > 0) {
88      return Handlebars.helpers.each(context, options);
89    } else {
90      return inverse(this);
91    }
92  } else {
93    return fn(context);
94  }
95});
96
97Handlebars.K = function() {};
98
99Handlebars.createFrame = Object.create || function(object) {
100  Handlebars.K.prototype = object;
101  var obj = new Handlebars.K();
102  Handlebars.K.prototype = null;
103  return obj;
104};
105
106Handlebars.logger = {
107  DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
108
109  methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
110
111  // can be overridden in the host environment
112  log: function(level, obj) {
113    if (Handlebars.logger.level <= level) {
114      var method = Handlebars.logger.methodMap[level];
115      if (typeof console !== 'undefined' && console[method]) {
116        console[method].call(console, obj);
117      }
118    }
119  }
120};
121
122Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
123
124Handlebars.registerHelper('each', function(context, options) {
125  var fn = options.fn, inverse = options.inverse;
126  var i = 0, ret = "", data;
127
128  var type = toString.call(context);
129  if(type === functionType) { context = context.call(this); }
130
131  if (options.data) {
132    data = Handlebars.createFrame(options.data);
133  }
134
135  if(context && typeof context === 'object') {
136    if(context instanceof Array){
137      for(var j = context.length; i<j; i++) {
138        if (data) { data.index = i; }
139        ret = ret + fn(context[i], { data: data });
140      }
141    } else {
142      for(var key in context) {
143        if(context.hasOwnProperty(key)) {
144          if(data) { data.key = key; }
145          ret = ret + fn(context[key], {data: data});
146          i++;
147        }
148      }
149    }
150  }
151
152  if(i === 0){
153    ret = inverse(this);
154  }
155
156  return ret;
157});
158
159Handlebars.registerHelper('if', function(conditional, options) {
160  var type = toString.call(conditional);
161  if(type === functionType) { conditional = conditional.call(this); }
162
163  if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
164    return options.inverse(this);
165  } else {
166    return options.fn(this);
167  }
168});
169
170Handlebars.registerHelper('unless', function(conditional, options) {
171  return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
172});
173
174Handlebars.registerHelper('with', function(context, options) {
175  var type = toString.call(context);
176  if(type === functionType) { context = context.call(this); }
177
178  if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
179});
180
181Handlebars.registerHelper('log', function(context, options) {
182  var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
183  Handlebars.log(level, context);
184});
185;
186// lib/handlebars/compiler/parser.js
187/* Jison generated parser */
188var handlebars = (function(){
189var parser = {trace: function trace() { },
190yy: {},
191symbols_: {"error":2,"root":3,"program":4,"EOF":5,"simpleInverse":6,"statements":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,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"params":27,"hash":28,"dataName":29,"param":30,"STRING":31,"INTEGER":32,"BOOLEAN":33,"hashSegments":34,"hashSegment":35,"ID":36,"EQUALS":37,"DATA":38,"pathSegments":39,"SEP":40,"$accept":0,"$end":1},
192terminals_: {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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",31:"STRING",32:"INTEGER",33:"BOOLEAN",36:"ID",37:"EQUALS",38:"DATA",40:"SEP"},
193productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,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],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[27,2],[27,1],[30,1],[30,1],[30,1],[30,1],[30,1],[28,1],[34,2],[34,1],[35,3],[35,3],[35,3],[35,3],[35,3],[26,1],[26,1],[26,1],[29,2],[21,1],[39,3],[39,1]],
194performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
195
196var $0 = $$.length - 1;
197switch (yystate) {
198case 1: return $$[$0-1];
199break;
200case 2: this.$ = new yy.ProgramNode([], $$[$0]);
201break;
202case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
203break;
204case 4: this.$ = new yy.ProgramNode($$[$0-1], []);
205break;
206case 5: this.$ = new yy.ProgramNode($$[$0]);
207break;
208case 6: this.$ = new yy.ProgramNode([], []);
209break;
210case 7: this.$ = new yy.ProgramNode([]);
211break;
212case 8: this.$ = [$$[$0]];
213break;
214case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
215break;
216case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
217break;
218case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
219break;
220case 12: this.$ = $$[$0];
221break;
222case 13: this.$ = $$[$0];
223break;
224case 14: this.$ = new yy.ContentNode($$[$0]);
225break;
226case 15: this.$ = new yy.CommentNode($$[$0]);
227break;
228case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
229break;
230case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
231break;
232case 18: this.$ = $$[$0-1];
233break;
234case 19:
235    // Parsing out the '&' escape token at this level saves ~500 bytes after min due to the removal of one parser node.
236    this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2][2] === '&');
237
238break;
239case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
240break;
241case 21: this.$ = new yy.PartialNode($$[$0-1]);
242break;
243case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
244break;
245case 23:
246break;
247case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
248break;
249case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null];
250break;
251case 26: this.$ = [[$$[$0-1]], $$[$0]];
252break;
253case 27: this.$ = [[$$[$0]], null];
254break;
255case 28: this.$ = [[$$[$0]], null];
256break;
257case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
258break;
259case 30: this.$ = [$$[$0]];
260break;
261case 31: this.$ = $$[$0];
262break;
263case 32: this.$ = new yy.StringNode($$[$0]);
264break;
265case 33: this.$ = new yy.IntegerNode($$[$0]);
266break;
267case 34: this.$ = new yy.BooleanNode($$[$0]);
268break;
269case 35: this.$ = $$[$0];
270break;
271case 36: this.$ = new yy.HashNode($$[$0]);
272break;
273case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
274break;
275case 38: this.$ = [$$[$0]];
276break;
277case 39: this.$ = [$$[$0-2], $$[$0]];
278break;
279case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
280break;
281case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
282break;
283case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
284break;
285case 43: this.$ = [$$[$0-2], $$[$0]];
286break;
287case 44: this.$ = new yy.PartialNameNode($$[$0]);
288break;
289case 45: this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0]));
290break;
291case 46: this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0]));
292break;
293case 47: this.$ = new yy.DataNode($$[$0]);
294break;
295case 48: this.$ = new yy.IdNode($$[$0]);
296break;
297case 49: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
298break;
299case 50: this.$ = [{part: $$[$0]}];
300break;
301}
302},
303table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],25:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22
vendor: 6,963 bytes, lines 303-362
303:[1,14],23:[1,15],25:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],25:[1,16]},{17:23,18:[1,22],21:24,29:25,36:[1,28],38:[1,27],39:26},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],25:[2,8]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],25:[1,16]},{4:30,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],25:[1,16]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{17:31,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:32,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:33,21:24,29:25,36:[1,28],38:[1,27],39:26},{21:35,26:34,31:[1,36],32:[1,37],36:[1,28],39:26},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],25:[1,16]},{17:23,21:24,29:25,36:[1,28],38:[1,27],39:26},{5:[2,4],7:38,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],25:[1,16]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{5:[2,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{18:[1,39]},{18:[2,27],21:44,24:[2,27],27:40,28:41,29:48,30:42,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,28],24:[2,28]},{18:[2,48],24:[2,48],31:[2,48],32:[2,48],33:[2,48],36:[2,48],38:[2,48],40:[1,51]},{21:52,36:[1,28],39:26},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],38:[2,50],40:[2,50]},{10:53,20:[1,54]},{10:55,20:[1,54]},{18:[1,56]},{18:[1,57]},{24:[1,58]},{18:[1,59],21:60,36:[1,28],39:26},{18:[2,44],36:[2,44]},{18:[2,45],36:[2,45]},{18:[2,46],36:[2,46]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],25:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{18:[2,25],21:44,24:[2,25],28:61,29:48,30:62,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,26],24:[2,26]},{18:[2,30],24:[2,30],31:[2,30],32:[2,30],33:[2,30],36:[2,30],38:[2,30]},{18:[2,36],24:[2,36],35:63,36:[1,64]},{18:[2,31],24:[2,31],31:[2,31],32:[2,31],33:[2,31],36:[2,31],38:[2,31]},{18:[2,32],24:[2,32],31:[2,32],32:[2,32],33:[2,32],36:[2,32],38:[2,32]},{18:[2,33],24:[2,33],31:[2,33],32:[2,33],33:[2,33],36:[2,33],38:[2,33]},{18:[2,34],24:[2,34],31:[2,34],32:[2,34],33:[2,34],36:[2,34],38:[2,34]},{18:[2,35],24:[2,35],31:[2,35],32:[2,35],33:[2,35],36:[2,35],38:[2,35]},{18:[2,38],24:[2,38],36:[2,38]},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],37:[1,65],38:[2,50],40:[2,50]},{36:[1,66]},{18:[2,47],24:[2,47],31:[2,47],32:[2,47],33:[2,47],36:[2,47],38:[2,47]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{21:67,36:[1,28],39:26},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,68]},{18:[2,24],24:[2,24]},{18:[2,29],24:[2,29],31:[2,29],32:[2,29],33:[2,29],36:[2,29],38:[2,29]},{18:[2,37],24:[2,37],36:[2,37]},{37:[1,65]},{21:69,29:73,31:[1,70],32:[1,71],33:[1,72],36:[1,28],38:[1,27],39:26},{18:[2,49],24:[2,49],31:[2,49],32:[2,49],33:[2,49],36:[2,49],38:[2,49],40:[2,49]},{18:[1,74]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{18:[2,39],24:[2,39],36:[2,39]},{18:[2,40],24:[2,40],36:[2,40]},{18:[2,41],24:[2,41],36:[2,41]},{18:[2,42],24:[2,42],36:[2,42]},{18:[2,43],24:[2,43],36:[2,43]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]}],
304defaultActions: {17:[2,1]},
305parseError: function parseError(str, hash) {
306    throw new Error(str);
307},
308parse: function parse(input) {
309    var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
310    this.lexer.setInput(input);
311    this.lexer.yy = this.yy;
312    this.yy.lexer = this.lexer;
313    this.yy.parser = this;
314    if (typeof this.lexer.yylloc == "undefined")
315        this.lexer.yylloc = {};
316    var yyloc = this.lexer.yylloc;
317    lstack.push(yyloc);
318    var ranges = this.lexer.options && this.lexer.options.ranges;
319    if (typeof this.yy.parseError === "function")
320        this.parseError = this.yy.parseError;
321    function popStack(n) {
322        stack.length = stack.length - 2 * n;
323        vstack.length = vstack.length - n;
324        lstack.length = lstack.length - n;
325    }
326    function lex() {
327        var token;
328        token = self.lexer.lex() || 1;
329        if (typeof token !== "number") {
330            token = self.symbols_[token] || token;
331        }
332        return token;
333    }
334    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
335    while (true) {
336        state = stack[stack.length - 1];
337        if (this.defaultActions[state]) {
338            action = this.defaultActions[state];
339        } else {
340            if (symbol === null || typeof symbol == "undefined") {
341                symbol = lex();
342            }
343            action = table[state] && table[state][symbol];
344        }
345        if (typeof action === "undefined" || !action.length || !action[0]) {
346            var errStr = "";
347            if (!recovering) {
348                expected = [];
349                for (p in table[state])
350                    if (this.terminals_[p] && p > 2) {
351                        expected.push("'" + this.terminals_[p] + "'");
352                    }
353                if (this.lexer.showPosition) {
354                    errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
355                } else {
356                    errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
357                }
358                this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
359            }
360        }
361        if (action[0] instanceof Array && action.length > 1) {
362            throw new Error("Parse Error: multiple actions possible at state: " + state 
vendor: 6,510 bytes, lines 362-542
362+ ", token: " + symbol);
363        }
364        switch (action[0]) {
365        case 1:
366            stack.push(symbol);
367            vstack.push(this.lexer.yytext);
368            lstack.push(this.lexer.yylloc);
369            stack.push(action[1]);
370            symbol = null;
371            if (!preErrorSymbol) {
372                yyleng = this.lexer.yyleng;
373                yytext = this.lexer.yytext;
374                yylineno = this.lexer.yylineno;
375                yyloc = this.lexer.yylloc;
376                if (recovering > 0)
377                    recovering--;
378            } else {
379                symbol = preErrorSymbol;
380                preErrorSymbol = null;
381            }
382            break;
383        case 2:
384            len = this.productions_[action[1]][1];
385            yyval.$ = vstack[vstack.length - len];
386            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};
387            if (ranges) {
388                yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
389            }
390            r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
391            if (typeof r !== "undefined") {
392                return r;
393            }
394            if (len) {
395                stack = stack.slice(0, -1 * len * 2);
396                vstack = vstack.slice(0, -1 * len);
397                lstack = lstack.slice(0, -1 * len);
398            }
399            stack.push(this.productions_[action[1]][0]);
400            vstack.push(yyval.$);
401            lstack.push(yyval._$);
402            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
403            stack.push(newState);
404            break;
405        case 3:
406            return true;
407        }
408    }
409    return true;
410}
411};
412/* Jison generated lexer */
413var lexer = (function(){
414var lexer = ({EOF:1,
415parseError:function parseError(str, hash) {
416        if (this.yy.parser) {
417            this.yy.parser.parseError(str, hash);
418        } else {
419            throw new Error(str);
420        }
421    },
422setInput:function (input) {
423        this._input = input;
424        this._more = this._less = this.done = false;
425        this.yylineno = this.yyleng = 0;
426        this.yytext = this.matched = this.match = '';
427        this.conditionStack = ['INITIAL'];
428        this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
429        if (this.options.ranges) this.yylloc.range = [0,0];
430        this.offset = 0;
431        return this;
432    },
433input:function () {
434        var ch = this._input[0];
435        this.yytext += ch;
436        this.yyleng++;
437        this.offset++;
438        this.match += ch;
439        this.matched += ch;
440        var lines = ch.match(/(?:\r\n?|\n).*/g);
441        if (lines) {
442            this.yylineno++;
443            this.yylloc.last_line++;
444        } else {
445            this.yylloc.last_column++;
446        }
447        if (this.options.ranges) this.yylloc.range[1]++;
448
449        this._input = this._input.slice(1);
450        return ch;
451    },
452unput:function (ch) {
453        var len = ch.length;
454        var lines = ch.split(/(?:\r\n?|\n)/g);
455
456        this._input = ch + this._input;
457        this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
458        //this.yyleng -= len;
459        this.offset -= len;
460        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
461        this.match = this.match.substr(0, this.match.length-1);
462        this.matched = this.matched.substr(0, this.matched.length-1);
463
464        if (lines.length-1) this.yylineno -= lines.length-1;
465        var r = this.yylloc.range;
466
467        this.yylloc = {first_line: this.yylloc.first_line,
468          last_line: this.yylineno+1,
469          first_column: this.yylloc.first_column,
470          last_column: lines ?
471              (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
472              this.yylloc.first_column - len
473          };
474
475        if (this.options.ranges) {
476            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
477        }
478        return this;
479    },
480more:function () {
481        this._more = true;
482        return this;
483    },
484less:function (n) {
485        this.unput(this.match.slice(n));
486    },
487pastInput:function () {
488        var past = this.matched.substr(0, this.matched.length - this.match.length);
489        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
490    },
491upcomingInput:function () {
492        var next = this.match;
493        if (next.length < 20) {
494            next += this._input.substr(0, 20-next.length);
495        }
496        return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
497    },
498showPosition:function () {
499        var pre = this.pastInput();
500        var c = new Array(pre.length + 1).join("-");
501        return pre + this.upcomingInput() + "\n" + c+"^";
502    },
503next:function () {
504        if (this.done) {
505            return this.EOF;
506        }
507        if (!this._input) this.done = true;
508
509        var token,
510            match,
511            tempMatch,
512            index,
513            col,
514            lines;
515        if (!this._more) {
516            this.yytext = '';
517            this.match = '';
518        }
519        var rules = this._currentRules();
520        for (var i=0;i < rules.length; i++) {
521            tempMatch = this._input.match(this.rules[rules[i]]);
522            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
523                match = tempMatch;
524                index = i;
525                if (!this.options.flex) break;
526            }
527        }
528        if (match) {
529            lines = match[0].match(/(?:\r\n?|\n).*/g);
530            if (lines) this.yylineno += lines.length;
531            this.yylloc = {first_line: this.yylloc.last_line,
532                           last_line: this.yylineno+1,
533                           first_column: this.yylloc.last_column,
534                           last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
535            this.yytext += match[0];
536            this.match += match[0];
537            this.matches = match;
538            this.yyleng = this.yytext.length;
539            if (this.options.ranges) {
540                this.yylloc.range = [this.offset, this.offset += this.yyleng];
541            }
542            this._more = false;
543            this._input = this._input.slice(match[0].length);
544            this.matched += match[0];
545            token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
546            if (this.done && this._input) this.done = false;
547            if (token) return token;
548            else return;
549        }
550        if (this._input === "") {
551            return this.EOF;
552        } else {
553            return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
554                    {text: "", token: null, line: this.yylineno});
555        }
556    },
557lex:function lex() {
558        var r = this.next();
559        if (typeof r !== 'undefined') {
560            return r;
561        } else {
562            return this.lex();
563        }
564    },
565begin:function begin(condition) {
566        this.conditionStack.push(condition);
567    },
568popState:function popState() {
569        return this.conditionStack.pop();
570    },
571_currentRules:function _currentRules() {
572        return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
573    },
574topState:function () {
575        return this.conditionStack[this.conditionStack.length-2];
576    },
577pushState:function begin(condition) {
578        this.begin(condition);
579    }});
580lexer.options = {};
581lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
582
583var YYSTATE=YY_START
584switch($avoiding_name_collisions) {
585case 0: yy_.yytext = "\\"; return 14;
586break;
587case 1:
588                                   if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
589                                   if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
590                                   if(yy_.yytext) return 14;
591
592break;
593case 2: return 14;
594break;
595case 3:
596                                   if(yy_.yytext.slice(-1) !== "\\") this.popState();
597                                   if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
598                                   return 14;
599
600break;
601case 4: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15;
602break;
603case 5: return 25;
604break;
605case 6: return 16;
606break;
607case 7: return 20;
608break;
609case 8: return 19;
610break;
611case 9: return 19;
612break;
613case 10: return 23;
614break;
615case 11: return 22;
616break;
617case 12: this.popState(); this.begin('com');
618break;
619case 13: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
620break;
621case 14: return 22;
622break;
623case 15: return 37;
624break;
625case 16: return 36;
626break;
627case 17: return 36;
628break;
629case 18: return 40;
630break;
631case 19: /*ignore whitespace*/
632break;
633case 20: this.popState(); return 24;
634break;
635case 21: this.popState(); return 18;
636break;
637case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 31;
638break;
639case 23: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 31;
640break;
641case 24: return 38;
642break;
643case 25: return 33;
644break;
645case 26: return 33;
646break;
647case 27: return 32;
648break;
649case 28: return 36;
650break;
651case 29: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 36;
652break;
653case 30: return 'INVALID';
654break;
655case 31: return 5;
656break;
657}
658};
659lexer.rules = [/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}\/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
660lexer.conditions = {"mu":{"rules":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31],"inclusive":false},"emu":{"rules":[3],"inclusive":false},"com":{"rules":[4],"inclusive":false},"INITIAL":{"rules":[0,1,2,31],"inclusive":true}};
661return lexer;})()
662parser.lexer = lexer;
663function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
664return new Parser;
665})();;
666// lib/handlebars/compiler/base.js
667
668Handlebars.Parser = handlebars;
669
670Handlebars.parse = function(input) {
671
672  // Just return if an already-compile AST was passed in.
673  if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
674
675  Handlebars.Parser.yy = Handlebars.AST;
676  return Handlebars.Parser.parse(input);
677};
678;
679// lib/handlebars/compiler/ast.js
680Handlebars.AST = {};
681
682Handlebars.AST.ProgramNode = function(statements, inverse) {
683  this.type = "program";
684  this.statements = statements;
685  if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
686};
687
688Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
689  this.type = "mustache";
690  this.escaped = !unescaped;
691  this.hash = hash;
692
693  var id = this.id = rawParams[0];
694  var params = this.params = rawParams.slice(1);
695
696  // a mustache is an eligible helper if:
697  // * its id is simple (a single part, not `this` or `..`)
698  var eligibleHelper = this.eligibleHelper = id.isSimple;
699
700  // a mustache is definitely a helper if:
701  // * it is an eligible helper, and
702  // * it has at least one parameter or hash segment
703  this.isHelper = eligibleHelper && (params.length || hash);
704
705  // if a mustache is an eligible helper but not a definite
706  // helper, it is ambiguous, and will be resolved in a later
707  // pass or at runtime.
708};
709
710Handlebars.AST.PartialNode = function(partialName, context) {
711  this.type         = "partial";
712  this.partialName  = partialName;
713  this.context      = context;
714};
715
716Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
717  var verifyMatch = function(open, close) {
718    if(open.original !== close.original) {
719      throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
720    }
721  };
722
723  verifyMatch(mustache.id, close);
724  this.type = "block";
725  this.mustache = mustache;
726  this.program  = program;
727  this.inverse  = inverse;
728
729  if (this.inverse && !this.program) {
730    this.isInverse = true;
731  }
732};
733
734Handlebars.AST.ContentNode = function(string) {
735  this.type = "content";
736  this.string = string;
737};
738
739Handlebars.AST.HashNode = function(pairs) {
740  this.type = "hash";
741  this.pairs = pairs;
742};
743
744Handlebars.AST.IdNode = function(parts) {
745  this.type = "ID";
746
747  var original = "",
748      dig = [],
749      depth = 0;
750
751  for(var i=0,l=parts.length; i<l; i++) {
752    var part = parts[i].part;
753    original += (parts[i].separator || '') + part;
754
755    if (part === ".." || part === "." || part === "this") {
756      if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + original); }
757      else if (part === "..") { depth++; }
758      else { this.isScoped = true; }
759    }
760    else { dig.push(part); }
761  }
762
763  this.original = original;
764  this.parts    = dig;
765  this.string   = dig.join('.');
766  this.depth    = depth;
767
768  // an ID is simple if it only has one part, and that part is not
769  // `..` or `this`.
770  this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
771
772  this.stringModeValue = this.string;
773};
774
775Handlebars.AST.PartialNameNode = function(name) {
776  this.type = "PARTIAL_NAME";
777  this.name = name.original;
778};
779
780Handlebars.AST.DataNode = function(id) {
781  this.type = "DATA";
782  this.id = id;
783};
784
785Handlebars.AST.StringNode = function(string) {
786  this.type = "STRING";
787  this.original =
788    this.string =
789    this.stringModeValue = string;
790};
791
792Handlebars.AST.IntegerNode = function(integer) {
793  this.type = "INTEGER";
794  this.original =
795    this.integer = integer;
796  this.stringModeValue = Number(integer);
797};
798
799Handlebars.AST.BooleanNode = function(bool) {
800  this.type = "BOOLEAN";
801  this.bool = bool;
802  this.stringModeValue = bool === "true";
803};
804
805Handlebars.AST.CommentNode = function(comment) {
806  this.type = "comment";
807  this.comment = comment;
808};
809;
810// lib/handlebars/utils.js
811
812var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
813
814Handlebars.Exception = function(message) {
815  var tmp = Error.prototype.constructor.apply(this, arguments);
816
817  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
818  for (var idx = 0; idx < errorProps.length; idx++) {
819    this[errorProps[idx]] = tmp[errorProps[idx]];
820  }
821};
822Handlebars.Exception.prototype = new Error();
823
824// Build out our basic SafeString type
825Handlebars.SafeString = function(string) {
826  this.string = string;
827};
828Handlebars.SafeString.prototype.toString = function() {
829  return this.string.toString();
830};
831
832var escape = {
833  "&": "&amp;",
834  "<": "&lt;",
835  ">": "&gt;",
836  '"': "&quot;",
837  "'": "&#x27;",
838  "`": "&#x60;"
839};
840
841var badChars = /[&<>"'`]/g;
842var possible = /[&<>"'`]/;
843
844var escapeChar = function(chr) {
845  return escape[chr] || "&amp;";
846};
847
848Handlebars.Utils = {
849  extend: function(obj, value) {
850    for(var key in value) {
851      if(value.hasOwnProperty(key)) {
852        obj[key] = value[key];
853      }
854    }
855  },
856
857  escapeExpression: function(string) {
858    // don't escape SafeStrings, since they're already safe
859    if (string instanceof Handlebars.SafeString) {
860      return string.toString();
861    } else if (string == null || string === false) {
862      return "";
863    }
864
865    // Force a string conversion as this will be done by the append regardless and
866    // the regex test will do this transparently behind the scenes, causing issues if
867    // an object's to string has escaped characters in it.
868    string = string.toString();
869
870    if(!possible.test(string)) { return string; }
871    return string.replace(badChars, escapeChar);
872  },
873
874  isEmpty: function(value) {
875    if (!value && value !== 0) {
876      return true;
877    } else if(toString.call(value) === "[object Array]" && value.length === 0) {
878      return true;
879    } else {
880      return false;
881    }
882  }
883};
884;
885// lib/handlebars/compiler/compiler.js
886
887/*jshint eqnull:true*/
888var Compiler = Handlebars.Compiler = function() {};
889var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {};
890
891// the foundHelper register will disambiguate helper lookup from finding a
892// function in a context. This is necessary for mustache compatibility, which
893// requires that context functions in blocks are evaluated by blockHelperMissing,
894// and then proceed as if the resulting value was provided to blockHelperMissing.
895
896Compiler.prototype = {
897  compiler: Compiler,
898
899  disassemble: function() {
900    var opcodes = this.opcodes, opcode, out = [], params, param;
901
902    for (var i=0, l=opcodes.length; i<l; i++) {
903      opcode = opcodes[i];
904
905      if (opcode.opcode === 'DECLARE') {
906        out.push("DECLARE " + opcode.name + "=" + opcode.value);
907      } else {
908        params = [];
909        for (var j=0; j<opcode.args.length; j++) {
910          param = opcode.args[j];
911          if (typeof param === "string") {
912            param = "\"" + param.replace("\n", "\\n") + "\"";
913          }
914          params.push(param);
915        }
916        out.push(opcode.opcode + " " + params.join(" "));
917      }
918    }
919
920    return out.join("\n");
921  },
922  equals: function(other) {
923    var len = this.opcodes.length;
924    if (other.opcodes.length !== len) {
925      return false;
926    }
927
928    for (var i = 0; i < len; i++) {
929      var opcode = this.opcodes[i],
930          otherOpcode = other.opcodes[i];
931      if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
932        return false;
933      }
934      for (var j = 0; j < opcode.args.length; j++) {
935        if (opcode.args[j] !== otherOpcode.args[j]) {
936          return false;
937        }
938      }
939    }
940
941    len = this.children.length;
942    if (other.children.length !== len) {
943      return false;
944    }
945    for (i = 0; i < len; i++) {
946      if (!this.children[i].equals(other.children[i])) {
947        return false;
948      }
949    }
950
951    return true;
952  },
953
954  guid: 0,
955
956  compile: function(program, options) {
957    this.children = [];
958    this.depths = {list: []};
959    this.options = options;
960
961    // These changes will propagate to the other compiler components
962    var knownHelpers = this.options.knownHelpers;
963    this.options.knownHelpers = {
964      'helperMissing': true,
965      'blockHelperMissing': true,
966      'each': true,
967      'if': true,
968      'unless': true,
969      'with': true,
970      'log': true
971    };
972    if (knownHelpers) {
973      for (var name in knownHelpers) {
974        this.options.knownHelpers[name] = knownHelpers[name];
975      }
976    }
977
978    return this.program(program);
979  },
980
981  accept: function(node) {
982    return this[node.type](node);
983  },
984
985  program: function(program) {
986    var statements = program.statements, statement;
987    this.opcodes = [];
988
989    for(var i=0, l=statements.length; i<l; i++) {
990      statement = statements[i];
991      this[statement.type](statement);
992    }
993    this.isSimple = l === 1;
994
995    this.depths.list = this.depths.list.sort(function(a, b) {
996      return a - b;
997    });
998
999    return this;
1000  },
1001
1002  compileProgram: function(program) {
1003    var result = new this.compiler().compile(program, this.options);
1004    var guid = this.guid++, depth;
1005
1006    this.usePartial = this.usePartial || result.usePartial;
1007
1008    this.children[guid] = result;
1009
1010    for(var i=0, l=result.depths.list.length; i<l; i++) {
1011      depth = result.depths.list[i];
1012
1013      if(depth < 2) { continue; }
1014      else { this.addDepth(depth - 1); }
1015    }
1016
1017    return guid;
1018  },
1019
1020  block: function(block) {
1021    var mustache = block.mustache,
1022        program = block.program,
1023        inverse = block.inverse;
1024
1025    if (program) {
1026      program = this.compileProgram(program);
1027    }
1028
1029    if (inverse) {
1030      inverse = this.compileProgram(inverse);
1031    }
1032
1033    var type = this.classifyMustache(mustache);
1034
1035    if (type === "helper") {
1036      this.helperMustache(mustache, program, inverse);
1037    } else if (type === "simple") {
1038      this.simpleMustache(mustache);
1039
1040      // now that the simple mustache is resolved, we need to
1041      // evaluate it by executing `blockHelperMissing`
1042      this.opcode('pushProgram', program);
1043      this.opcode('pushProgram', inverse);
1044      this.opcode('emptyHash');
1045      this.opcode('blockValue');
1046    } else {
1047      this.ambiguousMustache(mustache, program, inverse);
1048
1049      // now that the simple mustache is resolved, we need to
1050      // evaluate it by executing `blockHelperMissing`
1051      this.opcode('pushProgram', program);
1052      this.opcode('pushProgram', inverse);
1053      this.opcode('emptyHash');
1054      this.opcode('ambiguousBlockValue');
1055    }
1056
1057    this.opcode('append');
1058  },
1059
1060  hash: function(hash) {
1061    var pairs = hash.pairs, pair, val;
1062
1063    this.opcode('pushHash');
1064
1065    for(var i=0, l=pairs.length; i<l; i++) {
1066      pair = pairs[i];
1067      val  = pair[1];
1068
1069      if (this.options.stringParams) {
1070        if(val.depth) {
1071          this.addDepth(val.depth);
1072        }
1073        this.opcode('getContext', val.depth || 0);
1074        this.opcode('pushStringParam', val.stringModeValue, val.type);
1075      } else {
1076        this.accept(val);
1077      }
1078
1079      this.opcode('assignToHash', pair[0]);
1080    }
1081    this.opcode('popHash');
1082  },
1083
1084  partial: function(partial) {
1085    var partialName = partial.partialName;
1086    this.usePartial = true;
1087
1088    if(partial.context) {
1089      this.ID(partial.context);
1090    } else {
1091      this.opcode('push', 'depth0');
1092    }
1093
1094    this.opcode('invokePartial', partialName.name);
1095    this.opcode('append');
1096  },
1097
1098  content: function(content) {
1099    this.opcode('appendContent', content.string);
1100  },
1101
1102  mustache: function(mustache) {
1103    var options = this.options;
1104    var type = this.classifyMustache(mustache);
1105
1106    if (type === "simple") {
1107      this.simpleMustache(mustache);
1108    } else if (type === "helper") {
1109      this.helperMustache(mustache);
1110    } else {
1111      this.ambiguousMustache(mustache);
1112    }
1113
1114    if(mustache.escaped && !options.noEscape) {
1115      this.opcode('appendEscaped');
1116    } else {
1117      this.opcode('append');
1118    }
1119  },
1120
1121  ambiguousMustache: function(mustache, program, inverse) {
1122    var id = mustache.id,
1123        name = id.parts[0],
1124        isBlock = program != null || inverse != null;
1125
1126    this.opcode('getContext', id.depth);
1127
1128    this.opcode('pushProgram', program);
1129    this.opcode('pushProgram', inverse);
1130
1131    this.opcode('invokeAmbiguous', name, isBlock);
1132  },
1133
1134  simpleMustache: function(mustache) {
1135    var id = mustache.id;
1136
1137    if (id.type === 'DATA') {
1138      this.DATA(id);
1139    } else if (id.parts.length) {
1140      this.ID(id);
1141    } else {
1142      // Simplified ID for `this`
1143      this.addDepth(id.depth);
1144      this.opcode('getContext', id.depth);
1145      this.opcode('pushContext');
1146    }
1147
1148    this.opcode('resolvePossibleLambda');
1149  },
1150
1151  helperMustache: function(mustache, program, inverse) {
1152    var params = this.setupFullMustacheParams(mustache, program, inverse),
1153        name = mustache.id.parts[0];
1154
1155    if (this.options.knownHelpers[name]) {
1156      this.opcode('invokeKnownHelper', params.length, name);
1157    } else if (this.options.knownHelpersOnly) {
1158      throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
1159    } else {
1160      this.opcode('invokeHelper', params.length, name);
1161    }
1162  },
1163
1164  ID: function(id) {
1165    this.addDepth(id.depth);
1166    this.opcode('getContext', id.depth);
1167
1168    var name = id.parts[0];
1169    if (!name) {
1170      this.opcode('pushContext');
1171    } else {
1172      this.opcode('lookupOnContext', id.parts[0]);
1173    }
1174
1175    for(var i=1, l=id.parts.length; i<l; i++) {
1176      this.opcode('lookup', id.parts[i]);
1177    }
1178  },
1179
1180  DATA: function(data) {
1181    this.options.data = true;
1182    if (data.id.isScoped || data.id.depth) {
1183      throw new Handlebars.Exception('Scoped data references are not supported: ' + data.original);
1184    }
1185
1186    this.opcode('lookupData');
1187    var parts = data.id.parts;
1188    for(var i=0, l=parts.length; i<l; i++) {
1189      this.opcode('lookup', parts[i]);
1190    }
1191  },
1192
1193  STRING: function(string) {
1194    this.opcode('pushString', string.string);
1195  },
1196
1197  INTEGER: function(integer) {
1198    this.opcode('pushLiteral', integer.integer);
1199  },
1200
1201  BOOLEAN: function(bool) {
1202    this.opcode('pushLiteral', bool.bool);
1203  },
1204
1205  comment: function() {},
1206
1207  // HELPERS
1208  opcode: function(name) {
1209    this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
1210  },
1211
1212  declare: function(name, value) {
1213    this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
1214  },
1215
1216  addDepth: function(depth) {
1217    if(isNaN(depth)) { throw new Error("EWOT"); }
1218    if(depth === 0) { return; }
1219
1220    if(!this.depths[depth]) {
1221      this.depths[depth] = true;
1222      this.depths.list.push(depth);
1223    }
1224  },
1225
1226  classifyMustache: function(mustache) {
1227    var isHelper   = mustache.isHelper;
1228    var isEligible = mustache.eligibleHelper;
1229    var options    = this.options;
1230
1231    // if ambiguous, we can possibly resolve the ambiguity now
1232    if (isEligible && !isHelper) {
1233      var name = mustache.id.parts[0];
1234
1235      if (options.knownHelpers[name]) {
1236        isHelper = true;
1237      } else if (options.knownHelpersOnly) {
1238        isEligible = false;
1239      }
1240    }
1241
1242    if (isHelper) { return "helper"; }
1243    else if (isEligible) { return "ambiguous"; }
1244    else { return "simple"; }
1245  },
1246
1247  pushParams: function(params) {
1248    var i = params.length, param;
1249
1250    while(i--) {
1251      param = params[i];
1252
1253      if(this.options.stringParams) {
1254        if(param.depth) {
1255          this.addDepth(param.depth);
1256        }
1257
1258        this.opcode('getContext', param.depth || 0);
1259        this.opcode('pushStringParam', param.stringModeValue, param.type);
1260      } else {
1261        this[param.type](param);
1262      }
1263    }
1264  },
1265
1266  setupMustacheParams: function(mustache) {
1267    var params = mustache.params;
1268    this.pushParams(params);
1269
1270    if(mustache.hash) {
1271      this.hash(mustache.hash);
1272    } else {
1273      this.opcode('emptyHash');
1274    }
1275
1276    return params;
1277  },
1278
1279  // this will replace setupMustacheParams when we're done
1280  setupFullMustacheParams: function(mustache, program, inverse) {
1281    var params = mustache.params;
1282    this.pushParams(params);
1283
1284    this.opcode('pushProgram', program);
1285    this.opcode('pushProgram', inverse);
1286
1287    if(mustache.hash) {
1288      this.hash(mustache.hash);
1289    } else {
1290      this.opcode('emptyHash');
1291    }
1292
1293    return params;
1294  }
1295};
1296
1297var Literal = function(value) {
1298  this.value = value;
1299};
1300
1301JavaScriptCompiler.prototype = {
1302  // PUBLIC API: You can override these methods in a subclass to provide
1303  // alternative compiled forms for name lookup and buffering semantics
1304  nameLookup: function(parent, name /* , type*/) {
1305    if (/^[0-9]+$/.test(name)) {
1306      return parent + "[" + name + "]";
1307    } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1308      return parent + "." + name;
1309    }
1310    else {
1311      return parent + "['" + name + "']";
1312    }
1313  },
1314
1315  appendToBuffer: function(string) {
1316    if (this.environment.isSimple) {
1317      return "return " + string + ";";
1318    } else {
1319      return {
1320        appendToBuffer: true,
1321        content: string,
1322        toString: function() { return "buffer += " + string + ";"; }
1323      };
1324    }
1325  },
1326
1327  initializeBuffer: function() {
1328    return this.quotedString("");
1329  },
1330
1331  namespace: "Handlebars",
1332  // END PUBLIC API
1333
1334  compile: function(environment, options, context, asObject) {
1335    this.environment = environment;
1336    this.options = options || {};
1337
1338    Handlebars.log(Handlebars.logger.DEBUG, this.environment.disassemble() + "\n\n");
1339
1340    this.name = this.environment.name;
1341    this.isChild = !!context;
1342    this.context = context || {
1343      programs: [],
1344      environments: [],
1345      aliases: { }
1346    };
1347
1348    this.preamble();
1349
1350    this.stackSlot = 0;
1351    this.stackVars = [];
1352    this.registers = { list: [] };
1353    this.compileStack = [];
1354    this.inlineStack = [];
1355
1356    this.compileChildren(environment, options);
1357
1358    var opcodes = environment.opcodes, opcode;
1359
1360    this.i = 0;
1361
1362    for(l=opcodes.length; this.i<l; this.i++) {
1363      opcode = opcodes[this.i];
1364
1365      if(opcode.opcode === 'DECLARE') {
1366        this[opcode.name] = opcode.value;
1367      } else {
1368        this[opcode.opcode].apply(this, opcode.args);
1369      }
1370    }
1371
1372    return this.createFunctionContext(asObject);
1373  },
1374
1375  nextOpcode: function() {
1376    var opcodes = this.environment.opcodes;
1377    return opcodes[this.i + 1];
1378  },
1379
1380  eat: function() {
1381    this.i = this.i + 1;
1382  },
1383
1384  preamble: function() {
1385    var out = [];
1386
1387    if (!this.isChild) {
1388      var namespace = this.namespace;
1389
1390      var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1391      if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1392      if (this.options.data) { copies = copies + " data = data || {};"; }
1393      out.push(copies);
1394    } else {
1395      out.push('');
1396    }
1397
1398    if (!this.environment.isSimple) {
1399      out.push(", buffer = " + this.initializeBuffer());
1400    } else {
1401      out.push("");
1402    }
1403
1404    // track the last context pushed into place to allow skipping the
1405    // getContext opcode when it would be a noop
1406    this.lastContext = 0;
1407    this.source = out;
1408  },
1409
1410  createFunctionContext: function(asObject) {
1411    var locals = this.stackVars.concat(this.registers.list);
1412
1413    if(locals.length > 0) {
1414      this.source[1] = this.source[1] + ", " + locals.join(", ");
1415    }
1416
1417    // Generate minimizer alias mappings
1418    if (!this.isChild) {
1419      for (var alias in this.context.aliases) {
1420        if (this.context.aliases.hasOwnProperty(alias)) {
1421          this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1422        }
1423      }
1424    }
1425
1426    if (this.source[1]) {
1427      this.source[1] = "var " + this.source[1].substring(2) + ";";
1428    }
1429
1430    // Merge children
1431    if (!this.isChild) {
1432      this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1433    }
1434
1435    if (!this.environment.isSimple) {
1436      this.source.push("return buffer;");
1437    }
1438
1439    var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1440
1441    for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1442      params.push("depth" + this.environment.depths.list[i]);
1443    }
1444
1445    // Perform a second pass over the output to merge content when possible
1446    var source = this.mergeSource();
1447
1448    if (!this.isChild) {
1449      var revision = Handlebars.COMPILER_REVISION,
1450          versions = Handlebars.REVISION_CHANGES[revision];
1451      source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
1452    }
1453
1454    if (asObject) {
1455      params.push(source);
1456
1457      return Function.apply(this, params);
1458    } else {
1459      var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + source + '}';
1460      Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
1461      return functionSource;
1462    }
1463  },
1464  mergeSource: function() {
1465    // WARN: We are not handling the case where buffer is still populated as the source should
1466    // not have buffer append operations as their final action.
1467    var source = '',
1468        buffer;
1469    for (var i = 0, len = this.source.length; i < len; i++) {
1470      var line = this.source[i];
1471      if (line.appendToBuffer) {
1472        if (buffer) {
1473          buffer = buffer + '\n    + ' + line.content;
1474        } else {
1475          buffer = line.content;
1476        }
1477      } else {
1478        if (buffer) {
1479          source += 'buffer += ' + buffer + ';\n  ';
1480          buffer = undefined;
1481        }
1482        source += line + '\n  ';
1483      }
1484    }
1485    return source;
1486  },
1487
1488  // [blockValue]
1489  //
1490  // On stack, before: hash, inverse, program, value
1491  // On stack, after: return value of blockHelperMissing
1492  //
1493  // The purpose of this opcode is to take a block of the form
1494  // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
1495  // replace it on the stack with the result of properly
1496  // invoking blockHelperMissing.
1497  blockValue: function() {
1498    this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1499
1500    var params = ["depth0"];
1501    this.setupParams(0, params);
1502
1503    this.replaceStack(function(current) {
1504      params.splice(1, 0, current);
1505      return "blockHelperMissing.call(" + params.join(", ") + ")";
1506    });
1507  },
1508
1509  // [ambiguousBlockValue]
1510  //
1511  // On stack, before: hash, inverse, program, value
1512  // Compiler value, before: lastHelper=value of last found helper, if any
1513  // On stack, after, if no lastHelper: same as [blockValue]
1514  // On stack, after, if lastHelper: value
1515  ambiguousBlockValue: function() {
1516    this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1517
1518    var params = ["depth0"];
1519    this.setupParams(0, params);
1520
1521    var current = this.topStack();
1522    params.splice(1, 0, current);
1523
1524    // Use the options value generated from the invocation
1525    params[params.length-1] = 'options';
1526
1527    this.source.push("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
1528  },
1529
1530  // [appendContent]
1531  //
1532  // On stack, before: ...
1533  // On stack, after: ...
1534  //
1535  // Appends the string value of `content` to the current buffer
1536  appendContent: function(content) {
1537    this.source.push(this.appendToBuffer(this.quotedString(content)));
1538  },
1539
1540  // [append]
1541  //
1542  // On stack, before: value, ...
1543  // On stack, after: ...
1544  //
1545  // Coerces `value` to a String and appends it to the current buffer.
1546  //
1547  // If `value` is truthy, or 0, it is coerced into a string and appended
1548  // Otherwise, the empty string is appended
1549  append: function() {
1550    // Force anything that is inlined onto the stack so we don't have duplication
1551    // when we examine local
1552    this.flushInline();
1553    var local = this.popStack();
1554    this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1555    if (this.environment.isSimple) {
1556      this.source.push("else { " + this.appendToBuffer("''") + " }");
1557    }
1558  },
1559
1560  // [appendEscaped]
1561  //
1562  // On stack, before: value, ...
1563  // On stack, after: ...
1564  //
1565  // Escape `value` and append it to the buffer
1566  appendEscaped: function() {
1567    this.context.aliases.escapeExpression = 'this.escapeExpression';
1568
1569    this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
1570  },
1571
1572  // [getContext]
1573  //
1574  // On stack, before: ...
1575  // On stack, after: ...
1576  // Compiler value, after: lastContext=depth
1577  //
1578  // Set the value of the `lastContext` compiler value to the depth
1579  getContext: function(depth) {
1580    if(this.lastContext !== depth) {
1581      this.lastContext = depth;
1582    }
1583  },
1584
1585  // [lookupOnContext]
1586  //
1587  // On stack, before: ...
1588  // On stack, after: currentContext[name], ...
1589  //
1590  // Looks up the value of `name` on the current context and pushes
1591  // it onto the stack.
1592  lookupOnContext: function(name) {
1593    this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
1594  },
1595
1596  // [pushContext]
1597  //
1598  // On stack, before: ...
1599  // On stack, after: currentContext, ...
1600  //
1601  // Pushes the value of the current context onto the stack.
1602  pushContext: function() {
1603    this.pushStackLiteral('depth' + this.lastContext);
1604  },
1605
1606  // [resolvePossibleLambda]
1607  //
1608  // On stack, before: value, ...
1609  // On stack, after: resolved value, ...
1610  //
1611  // If the `value` is a lambda, replace it on the stack by
1612  // the return value of the lambda
1613  resolvePossibleLambda: function() {
1614    this.context.aliases.functionType = '"function"';
1615
1616    this.replaceStack(function(current) {
1617      return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
1618    });
1619  },
1620
1621  // [lookup]
1622  //
1623  // On stack, before: value, ...
1624  // On stack, after: value[name], ...
1625  //
1626  // Replace the value on the stack with the result of looking
1627  // up `name` on `value`
1628  lookup: function(name) {
1629    this.replaceStack(function(current) {
1630      return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
1631    });
1632  },
1633
1634  // [lookupData]
1635  //
1636  // On stack, before: ...
1637  // On stack, after: data[id], ...
1638  //
1639  // Push the result of looking up `id` on the current data
1640  lookupData: function(id) {
1641    this.push('data');
1642  },
1643
1644  // [pushStringParam]
1645  //
1646  // On stack, before: ...
1647  // On stack, after: string, currentContext, ...
1648  //
1649  // This opcode is designed for use in string mode, which
1650  // provides the string value of a parameter along with its
1651  // depth rather than resolving it immediately.
1652  pushStringParam: function(string, type) {
1653    this.pushStackLiteral('depth' + this.lastContext);
1654
1655    this.pushString(type);
1656
1657    if (typeof string === 'string') {
1658      this.pushString(string);
1659    } else {
1660      this.pushStackLiteral(string);
1661    }
1662  },
1663
1664  emptyHash: function() {
1665    this.pushStackLiteral('{}');
1666
1667    if (this.options.stringParams) {
1668      this.register('hashTypes', '{}');
1669      this.register('hashContexts', '{}');
1670    }
1671  },
1672  pushHash: function() {
1673    this.hash = {values: [], types: [], contexts: []};
1674  },
1675  popHash: function() {
1676    var hash = this.hash;
1677    this.hash = undefined;
1678
1679    if (this.options.stringParams) {
1680      this.register('hashContexts', '{' + hash.contexts.join(',') + '}');
1681      this.register('hashTypes', '{' + hash.types.join(',') + '}');
1682    }
1683    this.push('{\n    ' + hash.values.join(',\n    ') + '\n  }');
1684  },
1685
1686  // [pushString]
1687  //
1688  // On stack, before: ...
1689  // On stack, after: quotedString(string), ...
1690  //
1691  // Push a quoted version of `string` onto the stack
1692  pushString: function(string) {
1693    this.pushStackLiteral(this.quotedString(string));
1694  },
1695
1696  // [push]
1697  //
1698  // On stack, before: ...
1699  // On stack, after: expr, ...
1700  //
1701  // Push an expression onto the stack
1702  push: function(expr) {
1703    this.inlineStack.push(expr);
1704    return expr;
1705  },
1706
1707  // [pushLiteral]
1708  //
1709  // On stack, before: ...
1710  // On stack, after: value, ...
1711  //
1712  // Pushes a value onto the stack. This operation prevents
1713  // the compiler from creating a temporary variable to hold
1714  // it.
1715  pushLiteral: function(value) {
1716    this.pushStackLiteral(value);
1717  },
1718
1719  // [pushProgram]
1720  //
1721  // On stack, before: ...
1722  // On stack, after: program(guid), ...
1723  //
1724  // Push a program expression onto the stack. This takes
1725  // a compile-time guid and converts it into a runtime-accessible
1726  // expression.
1727  pushProgram: function(guid) {
1728    if (guid != null) {
1729      this.pushStackLiteral(this.programExpression(guid));
1730    } else {
1731      this.pushStackLiteral(null);
1732    }
1733  },
1734
1735  // [invokeHelper]
1736  //
1737  // On stack, before: hash, inverse, program, params..., ...
1738  // On stack, after: result of helper invocation
1739  //
1740  // Pops off the helper's parameters, invokes the helper,
1741  // and pushes the helper's return value onto the stack.
1742  //
1743  // If the helper is not found, `helperMissing` is called.
1744  invokeHelper: function(paramSize, name) {
1745    this.context.aliases.helperMissing = 'helpers.helperMissing';
1746
1747    var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
1748    var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1749
1750    this.push(helper.name + ' || ' + nonHelper);
1751    this.replaceStack(function(name) {
1752      return name + ' ? ' + name + '.call(' +
1753          helper.callParams + ") " + ": helperMissing.call(" +
1754          helper.helperMissingParams + ")";
1755    });
1756  },
1757
1758  // [invokeKnownHelper]
1759  //
1760  // On stack, before: hash, inverse, program, params..., ...
1761  // On stack, after: result of helper invocation
1762  //
1763  // This operation is used when the helper is known to exist,
1764  // so a `helperMissing` fallback is not required.
1765  invokeKnownHelper: function(paramSize, name) {
1766    var helper = this.setupHelper(paramSize, name);
1767    this.push(helper.name + ".call(" + helper.callParams + ")");
1768  },
1769
1770  // [invokeAmbiguous]
1771  //
1772  // On stack, before: hash, inverse, program, params..., ...
1773  // On stack, after: result of disambiguation
1774  //
1775  // This operation is used when an expression like `{{foo}}`
1776  // is provided, but we don't know at compile-time whether it
1777  // is a helper or a path.
1778  //
1779  // This operation emits more code than the other options,
1780  // and can be avoided by passing the `knownHelpers` and
1781  // `knownHelpersOnly` flags at compile-time.
1782  invokeAmbiguous: function(name, helperCall) {
1783    this.context.aliases.functionType = '"function"';
1784
1785    this.pushStackLiteral('{}');    // Hash value
1786    var helper = this.setupHelper(0, name, helperCall);
1787
1788    var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
1789
1790    var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1791    var nextStack = this.nextStack();
1792
1793    this.source.push('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
1794    this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.apply(depth0) : ' + nextStack + '; }');
1795  },
1796
1797  // [invokePartial]
1798  //
1799  // On stack, before: context, ...
1800  // On stack after: result of partial invocation
1801  //
1802  // This operation pops off a context, invokes a partial with that context,
1803  // and pushes the result of the invocation back.
1804  invokePartial: function(name) {
1805    var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
1806
1807    if (this.options.data) {
1808      params.push("data");
1809    }
1810
1811    this.context.aliases.self = "this";
1812    this.push("self.invokePartial(" + params.join(", ") + ")");
1813  },
1814
1815  // [assignToHash]
1816  //
1817  // On stack, before: value, hash, ...
1818  // On stack, after: hash, ...
1819  //
1820  // Pops a value and hash off the stack, assigns `hash[key] = value`
1821  // and pushes the hash back onto the stack.
1822  assignToHash: function(key) {
1823    var value = this.popStack(),
1824        context,
1825        type;
1826
1827    if (this.options.stringParams) {
1828      type = this.popStack();
1829      context = this.popStack();
1830    }
1831
1832    var hash = this.hash;
1833    if (context) {
1834      hash.contexts.push("'" + key + "': " + context);
1835    }
1836    if (type) {
1837      hash.types.push("'" + key + "': " + type);
1838    }
1839    hash.values.push("'" + key + "': (" + value + ")");
1840  },
1841
1842  // HELPERS
1843
1844  compiler: JavaScriptCompiler,
1845
1846  compileChildren: function(environment, options) {
1847    var children = environment.children, child, compiler;
1848
1849    for(var i=0, l=children.length; i<l; i++) {
1850      child = children[i];
1851      compiler = new this.compiler();
1852
1853      var index = this.matchExistingProgram(child);
1854
1855      if (index == null) {
1856        this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
1857        index = this.context.programs.length;
1858        child.index = index;
1859        child.name = 'program' + index;
1860        this.context.programs[index] = compiler.compile(child, options, this.context);
1861        this.context.environments[index] = child;
1862      } else {
1863        child.index = index;
1864        child.name = 'program' + index;
1865      }
1866    }
1867  },
1868  matchExistingProgram: function(child) {
1869    for (var i = 0, len = this.context.environments.length; i < len; i++) {
1870      var environment = this.context.environments[i];
1871      if (environment && environment.equals(child)) {
1872        return i;
1873      }
1874    }
1875  },
1876
1877  programExpression: function(guid) {
1878    this.context.aliases.self = "this";
1879
1880    if(guid == null) {
1881      return "self.noop";
1882    }
1883
1884    var child = this.environment.children[guid],
1885        depths = child.depths.list, depth;
1886
1887    var programParams = [child.index, child.name, "data"];
1888
1889    for(var i=0, l = depths.length; i<l; i++) {
1890      depth = depths[i];
1891
1892      if(depth === 1) { programParams.push("depth0"); }
1893      else { programParams.push("depth" + (depth - 1)); }
1894    }
1895
1896    return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
1897  },
1898
1899  register: function(name, val) {
1900    this.useRegister(name);
1901    this.source.push(name + " = " + val + ";");
1902  },
1903
1904  useRegister: function(name) {
1905    if(!this.registers[name]) {
1906      this.registers[name] = true;
1907      this.registers.list.push(name);
1908    }
1909  },
1910
1911  pushStackLiteral: function(item) {
1912    return this.push(new Literal(item));
1913  },
1914
1915  pushStack: function(item) {
1916    this.flushInline();
1917
1918    var stack = this.incrStack();
1919    if (item) {
1920      this.source.push(stack + " = " + item + ";");
1921    }
1922    this.compileStack.push(stack);
1923    return stack;
1924  },
1925
1926  replaceStack: function(callback) {
1927    var prefix = '',
1928        inline = this.isInline(),
1929        stack;
1930
1931    // If we are currently inline then we want to merge the inline statement into the
1932    // replacement statement via ','
1933    if (inline) {
1934      var top = this.popStack(true);
1935
1936      if (top instanceof Literal) {
1937        // Literals do not need to be inlined
1938        stack = top.value;
1939      } else {
1940        // Get or create the current stack name for use by the inline
1941        var name = this.stackSlot ? this.topStackName() : this.incrStack();
1942
1943        prefix = '(' + this.push(name) + ' = ' + top + '),';
1944        stack = this.topStack();
1945      }
1946    } else {
1947      stack = this.topStack();
1948    }
1949
1950    var item = callback.call(this, stack);
1951
1952    if (inline) {
1953      if (this.inlineStack.length || this.compileStack.length) {
1954        this.popStack();
1955      }
1956      this.push('(' + prefix + item + ')');
1957    } else {
1958      // Prevent modification of the context depth variable. Through replaceStack
1959      if (!/^stack/.test(stack)) {
1960        stack = this.nextStack();
1961      }
1962
1963      this.source.push(stack + " = (" + prefix + item + ");");
1964    }
1965    return stack;
1966  },
1967
1968  nextStack: function() {
1969    return this.pushStack();
1970  },
1971
1972  incrStack: function() {
1973    this.stackSlot++;
1974    if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1975    return this.topStackName();
1976  },
1977  topStackName: function() {
1978    return "stack" + this.stackSlot;
1979  },
1980  flushInline: function() {
1981    var inlineStack = this.inlineStack;
1982    if (inlineStack.length) {
1983      this.inlineStack = [];
1984      for (var i = 0, len = inlineStack.length; i < len; i++) {
1985        var entry = inlineStack[i];
1986        if (entry instanceof Literal) {
1987          this.compileStack.push(entry);
1988        } else {
1989          this.pushStack(entry);
1990        }
1991      }
1992    }
1993  },
1994  isInline: function() {
1995    return this.inlineStack.length;
1996  },
1997
1998  popStack: function(wrapped) {
1999    var inline = this.isInline(),
2000        item = (inline ? this.inlineStack : this.compileStack).pop();
2001
2002    if (!wrapped && (item instanceof Literal)) {
2003      return item.value;
2004    } else {
2005      if (!inline) {
2006        this.stackSlot--;
2007      }
2008      return item;
2009    }
2010  },
2011
2012  topStack: function(wrapped) {
2013    var stack = (this.isInline() ? this.inlineStack : this.compileStack),
2014        item = stack[stack.length - 1];
2015
2016    if (!wrapped && (item instanceof Literal)) {
2017      return item.value;
2018    } else {
2019      return item;
2020    }
2021  },
2022
2023  quotedString: function(str) {
2024    return '"' + str
2025      .replace(/\\/g, '\\\\')
2026      .replace(/"/g, '\\"')
2027      .replace(/\n/g, '\\n')
2028      .replace(/\r/g, '\\r')
2029      .replace(/\u2028/g, '\\u2028')   // Per Ecma-262 7.3 + 7.8.4
2030      .replace(/\u2029/g, '\\u2029') + '"';
2031  },
2032
2033  setupHelper: function(paramSize, name, missingParams) {
2034    var params = [];
2035    this.setupParams(paramSize, params, missingParams);
2036    var foundHelper = this.nameLookup('helpers', name, 'helper');
2037
2038    return {
2039      params: params,
2040      name: foundHelper,
2041      callParams: ["depth0"].concat(params).join(", "),
2042      helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
2043    };
2044  },
2045
2046  // the params and contexts arguments are passed in arrays
2047  // to fill in
2048  setupParams: function(paramSize, params, useRegister) {
2049    var options = [], contexts = [], types = [], param, inverse, program;
2050
2051    options.push("hash:" + this.popStack());
2052
2053    inverse = this.popStack();
2054    program = this.popStack();
2055
2056    // Avoid setting fn and inverse if neither are set. This allows
2057    // helpers to do a check for `if (options.fn)`
2058    if (program || inverse) {
2059      if (!program) {
2060        this.context.aliases.self = "this";
2061        program = "self.noop";
2062      }
2063
2064      if (!inverse) {
2065       this.context.aliases.self = "this";
2066        inverse = "self.noop";
2067      }
2068
2069      options.push("inverse:" + inverse);
2070      options.push("fn:" + program);
2071    }
2072
2073    for(var i=0; i<paramSize; i++) {
2074      param = this.popStack();
2075      params.push(param);
2076
2077      if(this.options.stringParams) {
2078        types.push(this.popStack());
2079        contexts.push(this.popStack());
2080      }
2081    }
2082
2083    if (this.options.stringParams) {
2084      options.push("contexts:[" + contexts.join(",") + "]");
2085      options.push("types:[" + types.join(",") + "]");
2086      options.push("hashContexts:hashContexts");
2087      options.push("hashTypes:hashTypes");
2088    }
2089
2090    if(this.options.data) {
2091      options.push("data:data");
2092    }
2093
2094    options = "{" + options.join(",") + "}";
2095    if (useRegister) {
2096      this.register('options', options);
2097      params.push('options');
2098    } else {
2099      params.push(options);
2100    }
2101    return params.join(", ");
2102  }
2103};
2104
2105var reservedWords = (
2106  "break else new var" +
2107  " case finally return void" +
2108  " catch for switch while" +
2109  " continue function this with" +
2110  " default if throw" +
2111  " delete in try" +
2112  " do instanceof typeof" +
2113  " abstract enum int short" +
2114  " boolean export interface static" +
2115  " byte extends long super" +
2116  " char final native synchronized" +
2117  " class float package throws" +
2118  " const goto private transient" +
2119  " debugger implements protected volatile" +
2120  " double import public let yield"
2121).split(" ");
2122
2123var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
2124
2125for(var i=0, l=reservedWords.length; i<l; i++) {
2126  compilerWords[reservedWords[i]] = true;
2127}
2128
2129JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
2130  if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
2131    return true;
2132  }
2133  return false;
2134};
2135
2136Handlebars.precompile = function(input, options) {
2137  if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
2138    throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
2139  }
2140
2141  options = options || {};
2142  if (!('data' in options)) {
2143    options.data = true;
2144  }
2145  var ast = Handlebars.parse(input);
2146  var environment = new Compiler().compile(ast, options);
2147  return new JavaScriptCompiler().compile(environment, options);
2148};
2149
2150Handlebars.compile = function(input, options) {
2151  if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
2152    throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2153  }
2154
2155  options = options || {};
2156  if (!('data' in options)) {
2157    options.data = true;
2158  }
2159  var compiled;
2160  function compile() {
2161    var ast = Handlebars.parse(input);
2162    var environment = new Compiler().compile(ast, options);
2163    var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
2164    return Handlebars.template(templateSpec);
2165  }
2166
2167  // Template is only compiled on first use and cached after that point.
2168  return function(context, options) {
2169    if (!compiled) {
2170      compiled = compile();
2171    }
2172    return compiled.call(this, context, options);
2173  };
2174};
2175
2176;
2177// lib/handlebars/runtime.js
2178
2179Handlebars.VM = {
2180  template: function(templateSpec) {
2181    // Just add water
2182    var container = {
2183      escapeExpression: Handlebars.Utils.escapeExpression,
2184      invokePartial: Handlebars.VM.invokePartial,
2185      programs: [],
2186      program: function(i, fn, data) {
2187        var programWrapper = this.programs[i];
2188        if(data) {
2189          programWrapper = Handlebars.VM.program(i, fn, data);
2190        } else if (!programWrapper) {
2191          programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
2192        }
2193        return programWrapper;
2194      },
2195      merge: function(param, common) {
2196        var ret = param || common;
2197
2198        if (param && common) {
2199          ret = {};
2200          Handlebars.Utils.extend(ret, common);
2201          Handlebars.Utils.extend(ret, param);
2202        }
2203        return ret;
2204      },
2205      programWithDepth: Handlebars.VM.programWithDepth,
2206      noop: Handlebars.VM.noop,
2207      compilerInfo: null
2208    };
2209
2210    return function(context, options) {
2211      options = options || {};
2212      var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
2213
2214      var compilerInfo = container.compilerInfo || [],
2215          compilerRevision = compilerInfo[0] || 1,
2216          currentRevision = Handlebars.COMPILER_REVISION;
2217
2218      if (compilerRevision !== currentRevision) {
2219        if (compilerRevision < currentRevision) {
2220          var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
2221              compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
2222          throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
2223                "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
2224        } else {
2225          // Use the embedded version info since the runtime doesn't know about this revision yet
2226          throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
2227                "Please update your runtime to a newer version ("+compilerInfo[1]+").";
2228        }
2229      }
2230
2231      return result;
2232    };
2233  },
2234
2235  programWithDepth: function(i, fn, data /*, $depth */) {
2236    var args = Array.prototype.slice.call(arguments, 3);
2237
2238    var program = function(context, options) {
2239      options = options || {};
2240
2241      return fn.apply(this, [context, options.data || data].concat(args));
2242    };
2243    program.program = i;
2244    program.depth = args.length;
2245    return program;
2246  },
2247  program: function(i, fn, data) {
2248    var program = function(context, options) {
2249      options = options || {};
2250
2251      return fn(context, options.data || data);
2252    };
2253    program.program = i;
2254    program.depth = 0;
2255    return program;
2256  },
2257  noop: function() { return ""; },
2258  invokePartial: function(partial, name, context, helpers, partials, data) {
2259    var options = { helpers: helpers, partials: partials, data: data };
2260
2261    if(partial === undefined) {
2262      throw new Handlebars.Exception("The partial " + name + " could not be found");
2263    } else if(partial instanceof Function) {
2264      return partial(context, options);
2265    } else if (!Handlebars.compile) {
2266      throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
2267    } else {
2268      partials[name] = Handlebars.compile(partial, {data: data !== undefined});
2269      return partials[name](context, options);
2270    }
2271  }
2272};
2273
2274Handlebars.template = Handlebars.VM.template;
2275;
2276// lib/handlebars/browser-suffix.js
2277})(Handlebars);
2278;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.