5 Copyright (C) 2011 by Yehuda Katz
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 var Handlebars = (function() {
28 // handlebars/safe-string.js
29 var __module4__ = (function() {
32 // Build out our basic SafeString type
33 function SafeString(string) {
37 SafeString.prototype.toString = function() {
38 return "" + this.string;
41 __exports__ = SafeString;
45 // handlebars/utils.js
46 var __module3__ = (function(__dependency1__) {
49 var SafeString = __dependency1__;
60 var badChars = /[&<>"'`]/g;
61 var possible = /[&<>"'`]/;
63 function escapeChar(chr) {
64 return escape[chr] || "&";
67 function extend(obj, value) {
68 for(var key in value) {
69 if(value.hasOwnProperty(key)) {
70 obj[key] = value[key];
75 __exports__.extend = extend;var toString = Object.prototype.toString;
76 __exports__.toString = toString;
77 // Sourced from lodash
78 // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
79 var isFunction = function(value) {
80 return typeof value === 'function';
82 // fallback for older versions of Chrome and Safari
83 if (isFunction(/x/)) {
84 isFunction = function(value) {
85 return typeof value === 'function' && toString.call(value) === '[object Function]';
89 __exports__.isFunction = isFunction;
90 var isArray = Array.isArray || function(value) {
91 return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
93 __exports__.isArray = isArray;
95 function escapeExpression(string) {
96 // don't escape SafeStrings, since they're already safe
97 if (string instanceof SafeString) {
98 return string.toString();
99 } else if (!string && string !== 0) {
103 // Force a string conversion as this will be done by the append regardless and
104 // the regex test will do this transparently behind the scenes, causing issues if
105 // an object's to string has escaped characters in it.
106 string = "" + string;
108 if(!possible.test(string)) { return string; }
109 return string.replace(badChars, escapeChar);
112 __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
113 if (!value && value !== 0) {
115 } else if (isArray(value) && value.length === 0) {
122 __exports__.isEmpty = isEmpty;
126 // handlebars/exception.js
127 var __module5__ = (function() {
131 var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
133 function Exception(/* message */) {
134 var tmp = Error.prototype.constructor.apply(this, arguments);
136 // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
137 for (var idx = 0; idx < errorProps.length; idx++) {
138 this[errorProps[idx]] = tmp[errorProps[idx]];
142 Exception.prototype = new Error();
144 __exports__ = Exception;
148 // handlebars/base.js
149 var __module2__ = (function(__dependency1__, __dependency2__) {
151 var __exports__ = {};
152 /*globals Exception, Utils */
153 var Utils = __dependency1__;
154 var Exception = __dependency2__;
156 var VERSION = "1.1.2";
157 __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
158 __exports__.COMPILER_REVISION = COMPILER_REVISION;
159 var REVISION_CHANGES = {
160 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
165 __exports__.REVISION_CHANGES = REVISION_CHANGES;
166 var isArray = Utils.isArray,
167 isFunction = Utils.isFunction,
168 toString = Utils.toString,
169 objectType = '[object Object]';
171 function HandlebarsEnvironment(helpers, partials) {
172 this.helpers = helpers || {};
173 this.partials = partials || {};
175 registerDefaultHelpers(this);
178 __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
179 constructor: HandlebarsEnvironment,
184 registerHelper: function(name, fn, inverse) {
185 if (toString.call(name) === objectType) {
186 if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
187 Utils.extend(this.helpers, name);
189 if (inverse) { fn.not = inverse; }
190 this.helpers[name] = fn;
194 registerPartial: function(name, str) {
195 if (toString.call(name) === objectType) {
196 Utils.extend(this.partials, name);
198 this.partials[name] = str;
203 function registerDefaultHelpers(instance) {
204 instance.registerHelper('helperMissing', function(arg) {
205 if(arguments.length === 2) {
208 throw new Error("Missing helper: '" + arg + "'");
212 instance.registerHelper('blockHelperMissing', function(context, options) {
213 var inverse = options.inverse || function() {}, fn = options.fn;
215 if (isFunction(context)) { context = context.call(this); }
217 if(context === true) {
219 } else if(context === false || context == null) {
220 return inverse(this);
221 } else if (isArray(context)) {
222 if(context.length > 0) {
223 return instance.helpers.each(context, options);
225 return inverse(this);
232 instance.registerHelper('each', function(context, options) {
233 var fn = options.fn, inverse = options.inverse;
234 var i = 0, ret = "", data;
236 if (isFunction(context)) { context = context.call(this); }
239 data = createFrame(options.data);
242 if(context && typeof context === 'object') {
243 if (isArray(context)) {
244 for(var j = context.length; i<j; i++) {
247 data.first = (i === 0)
248 data.last = (i === (context.length-1));
250 ret = ret + fn(context[i], { data: data });
253 for(var key in context) {
254 if(context.hasOwnProperty(key)) {
255 if(data) { data.key = key; }
256 ret = ret + fn(context[key], {data: data});
270 instance.registerHelper('if', function(conditional, options) {
271 if (isFunction(conditional)) { conditional = conditional.call(this); }
273 // Default behavior is to render the positive path if the value is truthy and not empty.
274 // The `includeZero` option may be set to treat the condtional as purely not empty based on the
275 // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
276 if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
277 return options.inverse(this);
279 return options.fn(this);
283 instance.registerHelper('unless', function(conditional, options) {
284 return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
287 instance.registerHelper('with', function(context, options) {
288 if (isFunction(context)) { context = context.call(this); }
290 if (!Utils.isEmpty(context)) return options.fn(context);
293 instance.registerHelper('log', function(context, options) {
294 var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
295 instance.log(level, context);
300 methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
309 // can be overridden in the host environment
310 log: function(level, obj) {
311 if (logger.level <= level) {
312 var method = logger.methodMap[level];
313 if (typeof console !== 'undefined' && console[method]) {
314 console[method].call(console, obj);
319 __exports__.logger = logger;
320 function log(level, obj) { logger.log(level, obj); }
322 __exports__.log = log;var createFrame = function(object) {
324 Utils.extend(obj, object);
327 __exports__.createFrame = createFrame;
329 })(__module3__, __module5__);
331 // handlebars/runtime.js
332 var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
334 var __exports__ = {};
336 var Utils = __dependency1__;
337 var Exception = __dependency2__;
338 var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
339 var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
341 function checkRevision(compilerInfo) {
342 var compilerRevision = compilerInfo && compilerInfo[0] || 1,
343 currentRevision = COMPILER_REVISION;
345 if (compilerRevision !== currentRevision) {
346 if (compilerRevision < currentRevision) {
347 var runtimeVersions = REVISION_CHANGES[currentRevision],
348 compilerVersions = REVISION_CHANGES[compilerRevision];
349 throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+
350 "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
352 // Use the embedded version info since the runtime doesn't know about this revision yet
353 throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+
354 "Please update your runtime to a newer version ("+compilerInfo[1]+").");
359 // TODO: Remove this line and break up compilePartial
361 function template(templateSpec, env) {
363 throw new Error("No environment passed to template");
366 var invokePartialWrapper;
368 invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
369 // TODO : Check this for all inputs and the options handling (partial flag, etc). This feels
370 // like there should be a common exec path
371 var result = invokePartial.apply(this, arguments);
372 if (result) { return result; }
374 var options = { helpers: helpers, partials: partials, data: data };
375 partials[name] = env.compile(partial, { data: data !== undefined }, env);
376 return partials[name](context, options);
379 invokePartialWrapper = function(partial, name /* , context, helpers, partials, data */) {
380 var result = invokePartial.apply(this, arguments);
381 if (result) { return result; }
382 throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
388 escapeExpression: Utils.escapeExpression,
389 invokePartial: invokePartialWrapper,
391 program: function(i, fn, data) {
392 var programWrapper = this.programs[i];
394 programWrapper = program(i, fn, data);
395 } else if (!programWrapper) {
396 programWrapper = this.programs[i] = program(i, fn);
398 return programWrapper;
400 merge: function(param, common) {
401 var ret = param || common;
403 if (param && common && (param !== common)) {
405 Utils.extend(ret, common);
406 Utils.extend(ret, param);
410 programWithDepth: programWithDepth,
415 return function(context, options) {
416 options = options || {};
417 var namespace = options.partial ? options : env,
421 if (!options.partial) {
422 helpers = options.helpers;
423 partials = options.partials;
425 var result = templateSpec.call(
432 if (!options.partial) {
433 checkRevision(container.compilerInfo);
440 __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
441 var args = Array.prototype.slice.call(arguments, 3);
443 var prog = function(context, options) {
444 options = options || {};
446 return fn.apply(this, [context, options.data || data].concat(args));
449 prog.depth = args.length;
453 __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
454 var prog = function(context, options) {
455 options = options || {};
457 return fn(context, options.data || data);
464 __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
465 var options = { partial: true, helpers: helpers, partials: partials, data: data };
467 if(partial === undefined) {
468 throw new Exception("The partial " + name + " could not be found");
469 } else if(partial instanceof Function) {
470 return partial(context, options);
474 __exports__.invokePartial = invokePartial;function noop() { return ""; }
476 __exports__.noop = noop;
478 })(__module3__, __module5__, __module2__);
480 // handlebars.runtime.js
481 var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
484 var base = __dependency1__;
486 // Each of these augment the Handlebars object. No need to setup here.
487 // (This is done to easily share code between commonjs and browse envs)
488 var SafeString = __dependency2__;
489 var Exception = __dependency3__;
490 var Utils = __dependency4__;
491 var runtime = __dependency5__;
493 // For compatibility and usage outside of module systems, make the Handlebars object a namespace
494 var create = function() {
495 var hb = new base.HandlebarsEnvironment();
497 Utils.extend(hb, base);
498 hb.SafeString = SafeString;
499 hb.Exception = Exception;
503 hb.template = function(spec) {
504 return runtime.template(spec, hb);
510 var Handlebars = create();
511 Handlebars.create = create;
513 __exports__ = Handlebars;
515 })(__module2__, __module4__, __module5__, __module3__, __module6__);
517 // handlebars/compiler/ast.js
518 var __module7__ = (function(__dependency1__) {
520 var __exports__ = {};
521 var Exception = __dependency1__;
523 function ProgramNode(statements, inverseStrip, inverse) {
524 this.type = "program";
525 this.statements = statements;
529 this.inverse = new ProgramNode(inverse, inverseStrip);
530 this.strip.right = inverseStrip.left;
531 } else if (inverseStrip) {
532 this.strip.left = inverseStrip.right;
536 __exports__.ProgramNode = ProgramNode;function MustacheNode(rawParams, hash, open, strip) {
537 this.type = "mustache";
541 var escapeFlag = open[3] || open[2];
542 this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
544 var id = this.id = rawParams[0];
545 var params = this.params = rawParams.slice(1);
547 // a mustache is an eligible helper if:
548 // * its id is simple (a single part, not `this` or `..`)
549 var eligibleHelper = this.eligibleHelper = id.isSimple;
551 // a mustache is definitely a helper if:
552 // * it is an eligible helper, and
553 // * it has at least one parameter or hash segment
554 this.isHelper = eligibleHelper && (params.length || hash);
556 // if a mustache is an eligible helper but not a definite
557 // helper, it is ambiguous, and will be resolved in a later
558 // pass or at runtime.
561 __exports__.MustacheNode = MustacheNode;function PartialNode(partialName, context, strip) {
562 this.type = "partial";
563 this.partialName = partialName;
564 this.context = context;
568 __exports__.PartialNode = PartialNode;function BlockNode(mustache, program, inverse, close) {
569 if(mustache.id.original !== close.path.original) {
570 throw new Exception(mustache.id.original + " doesn't match " + close.path.original);
574 this.mustache = mustache;
575 this.program = program;
576 this.inverse = inverse;
579 left: mustache.strip.left,
580 right: close.strip.right
583 (program || inverse).strip.left = mustache.strip.right;
584 (inverse || program).strip.right = close.strip.left;
586 if (inverse && !program) {
587 this.isInverse = true;
591 __exports__.BlockNode = BlockNode;function ContentNode(string) {
592 this.type = "content";
593 this.string = string;
596 __exports__.ContentNode = ContentNode;function HashNode(pairs) {
601 __exports__.HashNode = HashNode;function IdNode(parts) {
608 for(var i=0,l=parts.length; i<l; i++) {
609 var part = parts[i].part;
610 original += (parts[i].separator || '') + part;
612 if (part === ".." || part === "." || part === "this") {
613 if (dig.length > 0) { throw new Exception("Invalid path: " + original); }
614 else if (part === "..") { depth++; }
615 else { this.isScoped = true; }
617 else { dig.push(part); }
620 this.original = original;
622 this.string = dig.join('.');
625 // an ID is simple if it only has one part, and that part is not
627 this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
629 this.stringModeValue = this.string;
632 __exports__.IdNode = IdNode;function PartialNameNode(name) {
633 this.type = "PARTIAL_NAME";
634 this.name = name.original;
637 __exports__.PartialNameNode = PartialNameNode;function DataNode(id) {
642 __exports__.DataNode = DataNode;function StringNode(string) {
643 this.type = "STRING";
646 this.stringModeValue = string;
649 __exports__.StringNode = StringNode;function IntegerNode(integer) {
650 this.type = "INTEGER";
652 this.integer = integer;
653 this.stringModeValue = Number(integer);
656 __exports__.IntegerNode = IntegerNode;function BooleanNode(bool) {
657 this.type = "BOOLEAN";
659 this.stringModeValue = bool === "true";
662 __exports__.BooleanNode = BooleanNode;function CommentNode(comment) {
663 this.type = "comment";
664 this.comment = comment;
667 __exports__.CommentNode = CommentNode;
671 // handlebars/compiler/parser.js
672 var __module9__ = (function() {
675 /* Jison generated parser */
676 var handlebars = (function(){
677 var parser = {trace: function trace() { },
679 symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":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,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"inMustache_repetition0":28,"inMustache_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"hash":35,"hash_repetition_plus0":36,"hashSegment":37,"ID":38,"EQUALS":39,"DATA":40,"pathSegments":41,"SEP":42,"$accept":0,"$end":1},
680 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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",38:"ID",39:"EQUALS",40:"DATA",42:"SEP"},
681 productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[35,1],[37,3],[26,1],[26,1],[26,1],[30,2],[21,1],[41,3],[41,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[36,1],[36,2]],
682 performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
684 var $0 = $$.length - 1;
686 case 1: return new yy.ProgramNode($$[$0-1]);
688 case 2: return new yy.ProgramNode([]);
690 case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0]);
692 case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0]);
694 case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], []);
696 case 6:this.$ = new yy.ProgramNode($$[$0]);
698 case 7:this.$ = new yy.ProgramNode([]);
700 case 8:this.$ = new yy.ProgramNode([]);
702 case 9:this.$ = [$$[$0]];
704 case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
706 case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
708 case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
710 case 13:this.$ = $$[$0];
712 case 14:this.$ = $$[$0];
714 case 15:this.$ = new yy.ContentNode($$[$0]);
716 case 16:this.$ = new yy.CommentNode($$[$0]);
718 case 17:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
720 case 18:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
722 case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
724 case 20:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
726 case 21:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
728 case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]));
730 case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
732 case 24:this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
734 case 25:this.$ = [[$$[$0]], null];
736 case 26:this.$ = $$[$0];
738 case 27:this.$ = new yy.StringNode($$[$0]);
740 case 28:this.$ = new yy.IntegerNode($$[$0]);
742 case 29:this.$ = new yy.BooleanNode($$[$0]);
744 case 30:this.$ = $$[$0];
746 case 31:this.$ = new yy.HashNode($$[$0]);
748 case 32:this.$ = [$$[$0-2], $$[$0]];
750 case 33:this.$ = new yy.PartialNameNode($$[$0]);
752 case 34:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0]));
754 case 35:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0]));
756 case 36:this.$ = new yy.DataNode($$[$0]);
758 case 37:this.$ = new yy.IdNode($$[$0]);
760 case 38: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
762 case 39:this.$ = [{part: $$[$0]}];
766 case 43:$$[$0-1].push($$[$0]);
768 case 46:this.$ = [$$[$0]];
770 case 47:$$[$0-1].push($$[$0]);
774 table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{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]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{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]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:29,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:30,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:31,21:24,30:25,38:[1,28],40:[1,27],41:26},{21:33,26:32,32:[1,34],33:[1,35],38:[1,28],41:26},{1:[2,1]},{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]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,38:[1,28],40:[1,27],41:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,42],24:[2,42],28:43,32:[2,42],33:[2,42],34:[2,42],38:[2,42],40:[2,42]},{18:[2,25],24:[2,25]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],38:[2,37],40:[2,37],42:[1,44]},{21:45,38:[1,28],41:26},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],40:[2,39],42:[2,39]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,40],21:50,27:49,38:[1,28],41:26},{18:[2,33],38:[2,33]},{18:[2,34],38:[2,34]},{18:[2,35],38:[2,35]},{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]},{21:51,38:[1,28],41:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{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]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,44],21:56,24:[2,44],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:55,36:61,37:62,38:[1,63],40:[1,27],41:26},{38:[1,64]},{18:[2,36],24:[2,36],32:[2,36],33:[2,36],34:[2,36],38:[2,36],40:[2,36]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{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,65]},{18:[2,41]},{18:[1,66]},{8:17,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],25:[1,15]},{18:[2,24],24:[2,24]},{18:[2,43],24:[2,43],32:[2,43],33:[2,43],34:[2,43],38:[2,43],40:[2,43]},{18:[2,45],24:[2,45]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],38:[2,26],40:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],38:[2,27],40:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],38:[2,28],40:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],38:[2,29],40:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],38:[2,30],40:[2,30]},{18:[2,31],24:[2,31],37:67,38:[1,68]},{18:[2,46],24:[2,46],38:[2,46]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],39:[1,69],40:[2,39],42:[2,39]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],38:[2,38],40:[2,38],42:[2,38]},{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]},{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]},{18:[2,47],24:[2,47],38:[2,47]},{39:[1,69]},{21:56,30:60,31:70,32:[1,57],33:[1,58],34:[1,59],38:[1,28],40:[1,27],41:26},{18:[2,32],24:[2,32],38:[2,32]}],
775 defaultActions: {3:[2,2],16:[2,1],50:[2,41]},
776 parseError: function parseError(str, hash) {
777 throw new Error(str);
779 parse: function parse(input) {
780 var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
781 this.lexer.setInput(input);
782 this.lexer.yy = this.yy;
783 this.yy.lexer = this.lexer;
784 this.yy.parser = this;
785 if (typeof this.lexer.yylloc == "undefined")
786 this.lexer.yylloc = {};
787 var yyloc = this.lexer.yylloc;
789 var ranges = this.lexer.options && this.lexer.options.ranges;
790 if (typeof this.yy.parseError === "function")
791 this.parseError = this.yy.parseError;
792 function popStack(n) {
793 stack.length = stack.length - 2 * n;
794 vstack.length = vstack.length - n;
795 lstack.length = lstack.length - n;
799 token = self.lexer.lex() || 1;
800 if (typeof token !== "number") {
801 token = self.symbols_[token] || token;
805 var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
807 state = stack[stack.length - 1];
808 if (this.defaultActions[state]) {
809 action = this.defaultActions[state];
811 if (symbol === null || typeof symbol == "undefined") {
814 action = table[state] && table[state][symbol];
816 if (typeof action === "undefined" || !action.length || !action[0]) {
820 for (p in table[state])
821 if (this.terminals_[p] && p > 2) {
822 expected.push("'" + this.terminals_[p] + "'");
824 if (this.lexer.showPosition) {
825 errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
827 errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
829 this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
832 if (action[0] instanceof Array && action.length > 1) {
833 throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
838 vstack.push(this.lexer.yytext);
839 lstack.push(this.lexer.yylloc);
840 stack.push(action[1]);
842 if (!preErrorSymbol) {
843 yyleng = this.lexer.yyleng;
844 yytext = this.lexer.yytext;
845 yylineno = this.lexer.yylineno;
846 yyloc = this.lexer.yylloc;
850 symbol = preErrorSymbol;
851 preErrorSymbol = null;
855 len = this.productions_[action[1]][1];
856 yyval.$ = vstack[vstack.length - len];
857 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};
859 yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
861 r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
862 if (typeof r !== "undefined") {
866 stack = stack.slice(0, -1 * len * 2);
867 vstack = vstack.slice(0, -1 * len);
868 lstack = lstack.slice(0, -1 * len);
870 stack.push(this.productions_[action[1]][0]);
871 vstack.push(yyval.$);
872 lstack.push(yyval._$);
873 newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
874 stack.push(newState);
885 function stripFlags(open, close) {
887 left: open[2] === '~',
888 right: close[0] === '~' || close[1] === '~'
892 /* Jison generated lexer */
893 var lexer = (function(){
895 parseError:function parseError(str, hash) {
896 if (this.yy.parser) {
897 this.yy.parser.parseError(str, hash);
899 throw new Error(str);
902 setInput:function (input) {
904 this._more = this._less = this.done = false;
905 this.yylineno = this.yyleng = 0;
906 this.yytext = this.matched = this.match = '';
907 this.conditionStack = ['INITIAL'];
908 this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
909 if (this.options.ranges) this.yylloc.range = [0,0];
914 var ch = this._input[0];
920 var lines = ch.match(/(?:\r\n?|\n).*/g);
923 this.yylloc.last_line++;
925 this.yylloc.last_column++;
927 if (this.options.ranges) this.yylloc.range[1]++;
929 this._input = this._input.slice(1);
932 unput:function (ch) {
934 var lines = ch.split(/(?:\r\n?|\n)/g);
936 this._input = ch + this._input;
937 this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
938 //this.yyleng -= len;
940 var oldLines = this.match.split(/(?:\r\n?|\n)/g);
941 this.match = this.match.substr(0, this.match.length-1);
942 this.matched = this.matched.substr(0, this.matched.length-1);
944 if (lines.length-1) this.yylineno -= lines.length-1;
945 var r = this.yylloc.range;
947 this.yylloc = {first_line: this.yylloc.first_line,
948 last_line: this.yylineno+1,
949 first_column: this.yylloc.first_column,
951 (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
952 this.yylloc.first_column - len
955 if (this.options.ranges) {
956 this.yylloc.range = [r[0], r[0] + this.yyleng - len];
965 this.unput(this.match.slice(n));
967 pastInput:function () {
968 var past = this.matched.substr(0, this.matched.length - this.match.length);
969 return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
971 upcomingInput:function () {
972 var next = this.match;
973 if (next.length < 20) {
974 next += this._input.substr(0, 20-next.length);
976 return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
978 showPosition:function () {
979 var pre = this.pastInput();
980 var c = new Array(pre.length + 1).join("-");
981 return pre + this.upcomingInput() + "\n" + c+"^";
987 if (!this._input) this.done = true;
999 var rules = this._currentRules();
1000 for (var i=0;i < rules.length; i++) {
1001 tempMatch = this._input.match(this.rules[rules[i]]);
1002 if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1005 if (!this.options.flex) break;
1009 lines = match[0].match(/(?:\r\n?|\n).*/g);
1010 if (lines) this.yylineno += lines.length;
1011 this.yylloc = {first_line: this.yylloc.last_line,
1012 last_line: this.yylineno+1,
1013 first_column: this.yylloc.last_column,
1014 last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1015 this.yytext += match[0];
1016 this.match += match[0];
1017 this.matches = match;
1018 this.yyleng = this.yytext.length;
1019 if (this.options.ranges) {
1020 this.yylloc.range = [this.offset, this.offset += this.yyleng];
1023 this._input = this._input.slice(match[0].length);
1024 this.matched += match[0];
1025 token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1026 if (this.done && this._input) this.done = false;
1027 if (token) return token;
1030 if (this._input === "") {
1033 return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1034 {text: "", token: null, line: this.yylineno});
1037 lex:function lex() {
1038 var r = this.next();
1039 if (typeof r !== 'undefined') {
1045 begin:function begin(condition) {
1046 this.conditionStack.push(condition);
1048 popState:function popState() {
1049 return this.conditionStack.pop();
1051 _currentRules:function _currentRules() {
1052 return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1054 topState:function () {
1055 return this.conditionStack[this.conditionStack.length-2];
1057 pushState:function begin(condition) {
1058 this.begin(condition);
1061 lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1064 function strip(start, end) {
1065 return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1069 var YYSTATE=YY_START
1070 switch($avoiding_name_collisions) {
1072 if(yy_.yytext.slice(-2) === "\\\\") {
1075 } else if(yy_.yytext.slice(-1) === "\\") {
1081 if(yy_.yytext) return 14;
1087 if(yy_.yytext.slice(-1) !== "\\") this.popState();
1088 if(yy_.yytext.slice(-1) === "\\") strip(0,1);
1092 case 3:strip(0,4); this.popState(); return 15;
1108 case 11:this.popState(); this.begin('com');
1110 case 12:strip(3,5); this.popState(); return 15;
1122 case 18:/*ignore whitespace*/
1124 case 19:this.popState(); return 24;
1126 case 20:this.popState(); return 18;
1128 case 21:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
1130 case 22:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
1142 case 28:yy_.yytext = strip(1,2); return 38;
1144 case 29:return 'INVALID';
1150 lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s])))/,/^(?:false(?=([~}\s])))/,/^(?:-?[0-9]+(?=([~}\s])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1151 lexer.conditions = {"mu":{"rules":[4,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],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,30],"inclusive":true}};
1153 parser.lexer = lexer;
1154 function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1156 })();__exports__ = handlebars;
1160 // handlebars/compiler/base.js
1161 var __module8__ = (function(__dependency1__, __dependency2__) {
1163 var __exports__ = {};
1164 var parser = __dependency1__;
1165 var AST = __dependency2__;
1167 __exports__.parser = parser;
1169 function parse(input) {
1170 // Just return if an already-compile AST was passed in.
1171 if(input.constructor === AST.ProgramNode) { return input; }
1174 return parser.parse(input);
1177 __exports__.parse = parse;
1179 })(__module9__, __module7__);
1181 // handlebars/compiler/javascript-compiler.js
1182 var __module11__ = (function(__dependency1__) {
1185 var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
1186 var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
1187 var log = __dependency1__.log;
1189 function Literal(value) {
1193 function JavaScriptCompiler() {}
1195 JavaScriptCompiler.prototype = {
1196 // PUBLIC API: You can override these methods in a subclass to provide
1197 // alternative compiled forms for name lookup and buffering semantics
1198 nameLookup: function(parent, name /* , type*/) {
1201 if (parent.indexOf('depth') === 0) {
1205 if (/^[0-9]+$/.test(name)) {
1206 ret = parent + "[" + name + "]";
1207 } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1208 ret = parent + "." + name;
1211 ret = parent + "['" + name + "']";
1215 return '(' + parent + ' && ' + ret + ')';
1221 appendToBuffer: function(string) {
1222 if (this.environment.isSimple) {
1223 return "return " + string + ";";
1226 appendToBuffer: true,
1228 toString: function() { return "buffer += " + string + ";"; }
1233 initializeBuffer: function() {
1234 return this.quotedString("");
1237 namespace: "Handlebars",
1240 compile: function(environment, options, context, asObject) {
1241 this.environment = environment;
1242 this.options = options || {};
1244 log('debug', this.environment.disassemble() + "\n\n");
1246 this.name = this.environment.name;
1247 this.isChild = !!context;
1248 this.context = context || {
1257 this.stackVars = [];
1258 this.registers = { list: [] };
1259 this.compileStack = [];
1260 this.inlineStack = [];
1262 this.compileChildren(environment, options);
1264 var opcodes = environment.opcodes, opcode;
1268 for(var l=opcodes.length; this.i<l; this.i++) {
1269 opcode = opcodes[this.i];
1271 if(opcode.opcode === 'DECLARE') {
1272 this[opcode.name] = opcode.value;
1274 this[opcode.opcode].apply(this, opcode.args);
1277 // Reset the stripNext flag if it was not set by this operation.
1278 if (opcode.opcode !== this.stripNext) {
1279 this.stripNext = false;
1283 // Flush any trailing content that might be pending.
1284 this.pushSource('');
1286 return this.createFunctionContext(asObject);
1289 preamble: function() {
1292 if (!this.isChild) {
1293 var namespace = this.namespace;
1295 var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1296 if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1297 if (this.options.data) { copies = copies + " data = data || {};"; }
1303 if (!this.environment.isSimple) {
1304 out.push(", buffer = " + this.initializeBuffer());
1309 // track the last context pushed into place to allow skipping the
1310 // getContext opcode when it would be a noop
1311 this.lastContext = 0;
1315 createFunctionContext: function(asObject) {
1316 var locals = this.stackVars.concat(this.registers.list);
1318 if(locals.length > 0) {
1319 this.source[1] = this.source[1] + ", " + locals.join(", ");
1322 // Generate minimizer alias mappings
1323 if (!this.isChild) {
1324 for (var alias in this.context.aliases) {
1325 if (this.context.aliases.hasOwnProperty(alias)) {
1326 this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1331 if (this.source[1]) {
1332 this.source[1] = "var " + this.source[1].substring(2) + ";";
1336 if (!this.isChild) {
1337 this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1340 if (!this.environment.isSimple) {
1341 this.pushSource("return buffer;");
1344 var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1346 for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1347 params.push("depth" + this.environment.depths.list[i]);
1350 // Perform a second pass over the output to merge content when possible
1351 var source = this.mergeSource();
1353 if (!this.isChild) {
1354 var revision = COMPILER_REVISION,
1355 versions = REVISION_CHANGES[revision];
1356 source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
1360 params.push(source);
1362 return Function.apply(this, params);
1364 var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
1365 log('debug', functionSource + "\n\n");
1366 return functionSource;
1369 mergeSource: function() {
1370 // WARN: We are not handling the case where buffer is still populated as the source should
1371 // not have buffer append operations as their final action.
1374 for (var i = 0, len = this.source.length; i < len; i++) {
1375 var line = this.source[i];
1376 if (line.appendToBuffer) {
1378 buffer = buffer + '\n + ' + line.content;
1380 buffer = line.content;
1384 source += 'buffer += ' + buffer + ';\n ';
1387 source += line + '\n ';
1395 // On stack, before: hash, inverse, program, value
1396 // On stack, after: return value of blockHelperMissing
1398 // The purpose of this opcode is to take a block of the form
1399 // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
1400 // replace it on the stack with the result of properly
1401 // invoking blockHelperMissing.
1402 blockValue: function() {
1403 this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1405 var params = ["depth0"];
1406 this.setupParams(0, params);
1408 this.replaceStack(function(current) {
1409 params.splice(1, 0, current);
1410 return "blockHelperMissing.call(" + params.join(", ") + ")";
1414 // [ambiguousBlockValue]
1416 // On stack, before: hash, inverse, program, value
1417 // Compiler value, before: lastHelper=value of last found helper, if any
1418 // On stack, after, if no lastHelper: same as [blockValue]
1419 // On stack, after, if lastHelper: value
1420 ambiguousBlockValue: function() {
1421 this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1423 var params = ["depth0"];
1424 this.setupParams(0, params);
1426 var current = this.topStack();
1427 params.splice(1, 0, current);
1429 // Use the options value generated from the invocation
1430 params[params.length-1] = 'options';
1432 this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
1437 // On stack, before: ...
1438 // On stack, after: ...
1440 // Appends the string value of `content` to the current buffer
1441 appendContent: function(content) {
1442 if (this.pendingContent) {
1443 content = this.pendingContent + content;
1445 if (this.stripNext) {
1446 content = content.replace(/^\s+/, '');
1449 this.pendingContent = content;
1454 // On stack, before: ...
1455 // On stack, after: ...
1457 // Removes any trailing whitespace from the prior content node and flags
1458 // the next operation for stripping if it is a content node.
1460 if (this.pendingContent) {
1461 this.pendingContent = this.pendingContent.replace(/\s+$/, '');
1463 this.stripNext = 'strip';
1468 // On stack, before: value, ...
1469 // On stack, after: ...
1471 // Coerces `value` to a String and appends it to the current buffer.
1473 // If `value` is truthy, or 0, it is coerced into a string and appended
1474 // Otherwise, the empty string is appended
1475 append: function() {
1476 // Force anything that is inlined onto the stack so we don't have duplication
1477 // when we examine local
1479 var local = this.popStack();
1480 this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1481 if (this.environment.isSimple) {
1482 this.pushSource("else { " + this.appendToBuffer("''") + " }");
1488 // On stack, before: value, ...
1489 // On stack, after: ...
1491 // Escape `value` and append it to the buffer
1492 appendEscaped: function() {
1493 this.context.aliases.escapeExpression = 'this.escapeExpression';
1495 this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
1500 // On stack, before: ...
1501 // On stack, after: ...
1502 // Compiler value, after: lastContext=depth
1504 // Set the value of the `lastContext` compiler value to the depth
1505 getContext: function(depth) {
1506 if(this.lastContext !== depth) {
1507 this.lastContext = depth;
1511 // [lookupOnContext]
1513 // On stack, before: ...
1514 // On stack, after: currentContext[name], ...
1516 // Looks up the value of `name` on the current context and pushes
1517 // it onto the stack.
1518 lookupOnContext: function(name) {
1519 this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
1524 // On stack, before: ...
1525 // On stack, after: currentContext, ...
1527 // Pushes the value of the current context onto the stack.
1528 pushContext: function() {
1529 this.pushStackLiteral('depth' + this.lastContext);
1532 // [resolvePossibleLambda]
1534 // On stack, before: value, ...
1535 // On stack, after: resolved value, ...
1537 // If the `value` is a lambda, replace it on the stack by
1538 // the return value of the lambda
1539 resolvePossibleLambda: function() {
1540 this.context.aliases.functionType = '"function"';
1542 this.replaceStack(function(current) {
1543 return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
1549 // On stack, before: value, ...
1550 // On stack, after: value[name], ...
1552 // Replace the value on the stack with the result of looking
1553 // up `name` on `value`
1554 lookup: function(name) {
1555 this.replaceStack(function(current) {
1556 return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
1562 // On stack, before: ...
1563 // On stack, after: data, ...
1565 // Push the data lookup operator
1566 lookupData: function() {
1570 // [pushStringParam]
1572 // On stack, before: ...
1573 // On stack, after: string, currentContext, ...
1575 // This opcode is designed for use in string mode, which
1576 // provides the string value of a parameter along with its
1577 // depth rather than resolving it immediately.
1578 pushStringParam: function(string, type) {
1579 this.pushStackLiteral('depth' + this.lastContext);
1581 this.pushString(type);
1583 if (typeof string === 'string') {
1584 this.pushString(string);
1586 this.pushStackLiteral(string);
1590 emptyHash: function() {
1591 this.pushStackLiteral('{}');
1593 if (this.options.stringParams) {
1594 this.register('hashTypes', '{}');
1595 this.register('hashContexts', '{}');
1598 pushHash: function() {
1599 this.hash = {values: [], types: [], contexts: []};
1601 popHash: function() {
1602 var hash = this.hash;
1603 this.hash = undefined;
1605 if (this.options.stringParams) {
1606 this.register('hashContexts', '{' + hash.contexts.join(',') + '}');
1607 this.register('hashTypes', '{' + hash.types.join(',') + '}');
1609 this.push('{\n ' + hash.values.join(',\n ') + '\n }');
1614 // On stack, before: ...
1615 // On stack, after: quotedString(string), ...
1617 // Push a quoted version of `string` onto the stack
1618 pushString: function(string) {
1619 this.pushStackLiteral(this.quotedString(string));
1624 // On stack, before: ...
1625 // On stack, after: expr, ...
1627 // Push an expression onto the stack
1628 push: function(expr) {
1629 this.inlineStack.push(expr);
1635 // On stack, before: ...
1636 // On stack, after: value, ...
1638 // Pushes a value onto the stack. This operation prevents
1639 // the compiler from creating a temporary variable to hold
1641 pushLiteral: function(value) {
1642 this.pushStackLiteral(value);
1647 // On stack, before: ...
1648 // On stack, after: program(guid), ...
1650 // Push a program expression onto the stack. This takes
1651 // a compile-time guid and converts it into a runtime-accessible
1653 pushProgram: function(guid) {
1655 this.pushStackLiteral(this.programExpression(guid));
1657 this.pushStackLiteral(null);
1663 // On stack, before: hash, inverse, program, params..., ...
1664 // On stack, after: result of helper invocation
1666 // Pops off the helper's parameters, invokes the helper,
1667 // and pushes the helper's return value onto the stack.
1669 // If the helper is not found, `helperMissing` is called.
1670 invokeHelper: function(paramSize, name) {
1671 this.context.aliases.helperMissing = 'helpers.helperMissing';
1673 var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
1674 var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1676 this.push(helper.name + ' || ' + nonHelper);
1677 this.replaceStack(function(name) {
1678 return name + ' ? ' + name + '.call(' +
1679 helper.callParams + ") " + ": helperMissing.call(" +
1680 helper.helperMissingParams + ")";
1684 // [invokeKnownHelper]
1686 // On stack, before: hash, inverse, program, params..., ...
1687 // On stack, after: result of helper invocation
1689 // This operation is used when the helper is known to exist,
1690 // so a `helperMissing` fallback is not required.
1691 invokeKnownHelper: function(paramSize, name) {
1692 var helper = this.setupHelper(paramSize, name);
1693 this.push(helper.name + ".call(" + helper.callParams + ")");
1696 // [invokeAmbiguous]
1698 // On stack, before: hash, inverse, program, params..., ...
1699 // On stack, after: result of disambiguation
1701 // This operation is used when an expression like `{{foo}}`
1702 // is provided, but we don't know at compile-time whether it
1703 // is a helper or a path.
1705 // This operation emits more code than the other options,
1706 // and can be avoided by passing the `knownHelpers` and
1707 // `knownHelpersOnly` flags at compile-time.
1708 invokeAmbiguous: function(name, helperCall) {
1709 this.context.aliases.functionType = '"function"';
1711 this.pushStackLiteral('{}'); // Hash value
1712 var helper = this.setupHelper(0, name, helperCall);
1714 var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
1716 var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1717 var nextStack = this.nextStack();
1719 this.pushSource('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
1720 this.pushSource('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.call(' + helper.callParams + ') : ' + nextStack + '; }');
1725 // On stack, before: context, ...
1726 // On stack after: result of partial invocation
1728 // This operation pops off a context, invokes a partial with that context,
1729 // and pushes the result of the invocation back.
1730 invokePartial: function(name) {
1731 var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
1733 if (this.options.data) {
1734 params.push("data");
1737 this.context.aliases.self = "this";
1738 this.push("self.invokePartial(" + params.join(", ") + ")");
1743 // On stack, before: value, hash, ...
1744 // On stack, after: hash, ...
1746 // Pops a value and hash off the stack, assigns `hash[key] = value`
1747 // and pushes the hash back onto the stack.
1748 assignToHash: function(key) {
1749 var value = this.popStack(),
1753 if (this.options.stringParams) {
1754 type = this.popStack();
1755 context = this.popStack();
1758 var hash = this.hash;
1760 hash.contexts.push("'" + key + "': " + context);
1763 hash.types.push("'" + key + "': " + type);
1765 hash.values.push("'" + key + "': (" + value + ")");
1770 compiler: JavaScriptCompiler,
1772 compileChildren: function(environment, options) {
1773 var children = environment.children, child, compiler;
1775 for(var i=0, l=children.length; i<l; i++) {
1776 child = children[i];
1777 compiler = new this.compiler();
1779 var index = this.matchExistingProgram(child);
1781 if (index == null) {
1782 this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
1783 index = this.context.programs.length;
1784 child.index = index;
1785 child.name = 'program' + index;
1786 this.context.programs[index] = compiler.compile(child, options, this.context);
1787 this.context.environments[index] = child;
1789 child.index = index;
1790 child.name = 'program' + index;
1794 matchExistingProgram: function(child) {
1795 for (var i = 0, len = this.context.environments.length; i < len; i++) {
1796 var environment = this.context.environments[i];
1797 if (environment && environment.equals(child)) {
1803 programExpression: function(guid) {
1804 this.context.aliases.self = "this";
1810 var child = this.environment.children[guid],
1811 depths = child.depths.list, depth;
1813 var programParams = [child.index, child.name, "data"];
1815 for(var i=0, l = depths.length; i<l; i++) {
1818 if(depth === 1) { programParams.push("depth0"); }
1819 else { programParams.push("depth" + (depth - 1)); }
1822 return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
1825 register: function(name, val) {
1826 this.useRegister(name);
1827 this.pushSource(name + " = " + val + ";");
1830 useRegister: function(name) {
1831 if(!this.registers[name]) {
1832 this.registers[name] = true;
1833 this.registers.list.push(name);
1837 pushStackLiteral: function(item) {
1838 return this.push(new Literal(item));
1841 pushSource: function(source) {
1842 if (this.pendingContent) {
1843 this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
1844 this.pendingContent = undefined;
1848 this.source.push(source);
1852 pushStack: function(item) {
1855 var stack = this.incrStack();
1857 this.pushSource(stack + " = " + item + ";");
1859 this.compileStack.push(stack);
1863 replaceStack: function(callback) {
1865 inline = this.isInline(),
1868 // If we are currently inline then we want to merge the inline statement into the
1869 // replacement statement via ','
1871 var top = this.popStack(true);
1873 if (top instanceof Literal) {
1874 // Literals do not need to be inlined
1877 // Get or create the current stack name for use by the inline
1878 var name = this.stackSlot ? this.topStackName() : this.incrStack();
1880 prefix = '(' + this.push(name) + ' = ' + top + '),';
1881 stack = this.topStack();
1884 stack = this.topStack();
1887 var item = callback.call(this, stack);
1890 if (this.inlineStack.length || this.compileStack.length) {
1893 this.push('(' + prefix + item + ')');
1895 // Prevent modification of the context depth variable. Through replaceStack
1896 if (!/^stack/.test(stack)) {
1897 stack = this.nextStack();
1900 this.pushSource(stack + " = (" + prefix + item + ");");
1905 nextStack: function() {
1906 return this.pushStack();
1909 incrStack: function() {
1911 if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1912 return this.topStackName();
1914 topStackName: function() {
1915 return "stack" + this.stackSlot;
1917 flushInline: function() {
1918 var inlineStack = this.inlineStack;
1919 if (inlineStack.length) {
1920 this.inlineStack = [];
1921 for (var i = 0, len = inlineStack.length; i < len; i++) {
1922 var entry = inlineStack[i];
1923 if (entry instanceof Literal) {
1924 this.compileStack.push(entry);
1926 this.pushStack(entry);
1931 isInline: function() {
1932 return this.inlineStack.length;
1935 popStack: function(wrapped) {
1936 var inline = this.isInline(),
1937 item = (inline ? this.inlineStack : this.compileStack).pop();
1939 if (!wrapped && (item instanceof Literal)) {
1949 topStack: function(wrapped) {
1950 var stack = (this.isInline() ? this.inlineStack : this.compileStack),
1951 item = stack[stack.length - 1];
1953 if (!wrapped && (item instanceof Literal)) {
1960 quotedString: function(str) {
1962 .replace(/\\/g, '\\\\')
1963 .replace(/"/g, '\\"')
1964 .replace(/\n/g, '\\n')
1965 .replace(/\r/g, '\\r')
1966 .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
1967 .replace(/\u2029/g, '\\u2029') + '"';
1970 setupHelper: function(paramSize, name, missingParams) {
1972 this.setupParams(paramSize, params, missingParams);
1973 var foundHelper = this.nameLookup('helpers', name, 'helper');
1978 callParams: ["depth0"].concat(params).join(", "),
1979 helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
1983 // the params and contexts arguments are passed in arrays
1985 setupParams: function(paramSize, params, useRegister) {
1986 var options = [], contexts = [], types = [], param, inverse, program;
1988 options.push("hash:" + this.popStack());
1990 inverse = this.popStack();
1991 program = this.popStack();
1993 // Avoid setting fn and inverse if neither are set. This allows
1994 // helpers to do a check for `if (options.fn)`
1995 if (program || inverse) {
1997 this.context.aliases.self = "this";
1998 program = "self.noop";
2002 this.context.aliases.self = "this";
2003 inverse = "self.noop";
2006 options.push("inverse:" + inverse);
2007 options.push("fn:" + program);
2010 for(var i=0; i<paramSize; i++) {
2011 param = this.popStack();
2014 if(this.options.stringParams) {
2015 types.push(this.popStack());
2016 contexts.push(this.popStack());
2020 if (this.options.stringParams) {
2021 options.push("contexts:[" + contexts.join(",") + "]");
2022 options.push("types:[" + types.join(",") + "]");
2023 options.push("hashContexts:hashContexts");
2024 options.push("hashTypes:hashTypes");
2027 if(this.options.data) {
2028 options.push("data:data");
2031 options = "{" + options.join(",") + "}";
2033 this.register('options', options);
2034 params.push('options');
2036 params.push(options);
2038 return params.join(", ");
2042 var reservedWords = (
2043 "break else new var" +
2044 " case finally return void" +
2045 " catch for switch while" +
2046 " continue function this with" +
2047 " default if throw" +
2049 " do instanceof typeof" +
2050 " abstract enum int short" +
2051 " boolean export interface static" +
2052 " byte extends long super" +
2053 " char final native synchronized" +
2054 " class float package throws" +
2055 " const goto private transient" +
2056 " debugger implements protected volatile" +
2057 " double import public let yield"
2060 var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
2062 for(var i=0, l=reservedWords.length; i<l; i++) {
2063 compilerWords[reservedWords[i]] = true;
2066 JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
2067 if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
2073 __exports__ = JavaScriptCompiler;
2077 // handlebars/compiler/compiler.js
2078 var __module10__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
2080 var __exports__ = {};
2081 var Exception = __dependency1__;
2082 var parse = __dependency2__.parse;
2083 var JavaScriptCompiler = __dependency3__;
2084 var AST = __dependency4__;
2086 function Compiler() {}
2088 __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
2089 // function in a context. This is necessary for mustache compatibility, which
2090 // requires that context functions in blocks are evaluated by blockHelperMissing,
2091 // and then proceed as if the resulting value was provided to blockHelperMissing.
2093 Compiler.prototype = {
2096 disassemble: function() {
2097 var opcodes = this.opcodes, opcode, out = [], params, param;
2099 for (var i=0, l=opcodes.length; i<l; i++) {
2100 opcode = opcodes[i];
2102 if (opcode.opcode === 'DECLARE') {
2103 out.push("DECLARE " + opcode.name + "=" + opcode.value);
2106 for (var j=0; j<opcode.args.length; j++) {
2107 param = opcode.args[j];
2108 if (typeof param === "string") {
2109 param = "\"" + param.replace("\n", "\\n") + "\"";
2113 out.push(opcode.opcode + " " + params.join(" "));
2117 return out.join("\n");
2120 equals: function(other) {
2121 var len = this.opcodes.length;
2122 if (other.opcodes.length !== len) {
2126 for (var i = 0; i < len; i++) {
2127 var opcode = this.opcodes[i],
2128 otherOpcode = other.opcodes[i];
2129 if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
2132 for (var j = 0; j < opcode.args.length; j++) {
2133 if (opcode.args[j] !== otherOpcode.args[j]) {
2139 len = this.children.length;
2140 if (other.children.length !== len) {
2143 for (i = 0; i < len; i++) {
2144 if (!this.children[i].equals(other.children[i])) {
2154 compile: function(program, options) {
2157 this.depths = {list: []};
2158 this.options = options;
2160 // These changes will propagate to the other compiler components
2161 var knownHelpers = this.options.knownHelpers;
2162 this.options.knownHelpers = {
2163 'helperMissing': true,
2164 'blockHelperMissing': true,
2172 for (var name in knownHelpers) {
2173 this.options.knownHelpers[name] = knownHelpers[name];
2177 return this.accept(program);
2180 accept: function(node) {
2181 var strip = node.strip || {},
2184 this.opcode('strip');
2187 ret = this[node.type](node);
2190 this.opcode('strip');
2196 program: function(program) {
2197 var statements = program.statements;
2199 for(var i=0, l=statements.length; i<l; i++) {
2200 this.accept(statements[i]);
2202 this.isSimple = l === 1;
2204 this.depths.list = this.depths.list.sort(function(a, b) {
2211 compileProgram: function(program) {
2212 var result = new this.compiler().compile(program, this.options);
2213 var guid = this.guid++, depth;
2215 this.usePartial = this.usePartial || result.usePartial;
2217 this.children[guid] = result;
2219 for(var i=0, l=result.depths.list.length; i<l; i++) {
2220 depth = result.depths.list[i];
2222 if(depth < 2) { continue; }
2223 else { this.addDepth(depth - 1); }
2229 block: function(block) {
2230 var mustache = block.mustache,
2231 program = block.program,
2232 inverse = block.inverse;
2235 program = this.compileProgram(program);
2239 inverse = this.compileProgram(inverse);
2242 var type = this.classifyMustache(mustache);
2244 if (type === "helper") {
2245 this.helperMustache(mustache, program, inverse);
2246 } else if (type === "simple") {
2247 this.simpleMustache(mustache);
2249 // now that the simple mustache is resolved, we need to
2250 // evaluate it by executing `blockHelperMissing`
2251 this.opcode('pushProgram', program);
2252 this.opcode('pushProgram', inverse);
2253 this.opcode('emptyHash');
2254 this.opcode('blockValue');
2256 this.ambiguousMustache(mustache, program, inverse);
2258 // now that the simple mustache is resolved, we need to
2259 // evaluate it by executing `blockHelperMissing`
2260 this.opcode('pushProgram', program);
2261 this.opcode('pushProgram', inverse);
2262 this.opcode('emptyHash');
2263 this.opcode('ambiguousBlockValue');
2266 this.opcode('append');
2269 hash: function(hash) {
2270 var pairs = hash.pairs, pair, val;
2272 this.opcode('pushHash');
2274 for(var i=0, l=pairs.length; i<l; i++) {
2278 if (this.options.stringParams) {
2280 this.addDepth(val.depth);
2282 this.opcode('getContext', val.depth || 0);
2283 this.opcode('pushStringParam', val.stringModeValue, val.type);
2288 this.opcode('assignToHash', pair[0]);
2290 this.opcode('popHash');
2293 partial: function(partial) {
2294 var partialName = partial.partialName;
2295 this.usePartial = true;
2297 if(partial.context) {
2298 this.ID(partial.context);
2300 this.opcode('push', 'depth0');
2303 this.opcode('invokePartial', partialName.name);
2304 this.opcode('append');
2307 content: function(content) {
2308 this.opcode('appendContent', content.string);
2311 mustache: function(mustache) {
2312 var options = this.options;
2313 var type = this.classifyMustache(mustache);
2315 if (type === "simple") {
2316 this.simpleMustache(mustache);
2317 } else if (type === "helper") {
2318 this.helperMustache(mustache);
2320 this.ambiguousMustache(mustache);
2323 if(mustache.escaped && !options.noEscape) {
2324 this.opcode('appendEscaped');
2326 this.opcode('append');
2330 ambiguousMustache: function(mustache, program, inverse) {
2331 var id = mustache.id,
2333 isBlock = program != null || inverse != null;
2335 this.opcode('getContext', id.depth);
2337 this.opcode('pushProgram', program);
2338 this.opcode('pushProgram', inverse);
2340 this.opcode('invokeAmbiguous', name, isBlock);
2343 simpleMustache: function(mustache) {
2344 var id = mustache.id;
2346 if (id.type === 'DATA') {
2348 } else if (id.parts.length) {
2351 // Simplified ID for `this`
2352 this.addDepth(id.depth);
2353 this.opcode('getContext', id.depth);
2354 this.opcode('pushContext');
2357 this.opcode('resolvePossibleLambda');
2360 helperMustache: function(mustache, program, inverse) {
2361 var params = this.setupFullMustacheParams(mustache, program, inverse),
2362 name = mustache.id.parts[0];
2364 if (this.options.knownHelpers[name]) {
2365 this.opcode('invokeKnownHelper', params.length, name);
2366 } else if (this.options.knownHelpersOnly) {
2367 throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
2369 this.opcode('invokeHelper', params.length, name);
2374 this.addDepth(id.depth);
2375 this.opcode('getContext', id.depth);
2377 var name = id.parts[0];
2379 this.opcode('pushContext');
2381 this.opcode('lookupOnContext', id.parts[0]);
2384 for(var i=1, l=id.parts.length; i<l; i++) {
2385 this.opcode('lookup', id.parts[i]);
2389 DATA: function(data) {
2390 this.options.data = true;
2391 if (data.id.isScoped || data.id.depth) {
2392 throw new Exception('Scoped data references are not supported: ' + data.original);
2395 this.opcode('lookupData');
2396 var parts = data.id.parts;
2397 for(var i=0, l=parts.length; i<l; i++) {
2398 this.opcode('lookup', parts[i]);
2402 STRING: function(string) {
2403 this.opcode('pushString', string.string);
2406 INTEGER: function(integer) {
2407 this.opcode('pushLiteral', integer.integer);
2410 BOOLEAN: function(bool) {
2411 this.opcode('pushLiteral', bool.bool);
2414 comment: function() {},
2417 opcode: function(name) {
2418 this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
2421 declare: function(name, value) {
2422 this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
2425 addDepth: function(depth) {
2426 if(isNaN(depth)) { throw new Error("EWOT"); }
2427 if(depth === 0) { return; }
2429 if(!this.depths[depth]) {
2430 this.depths[depth] = true;
2431 this.depths.list.push(depth);
2435 classifyMustache: function(mustache) {
2436 var isHelper = mustache.isHelper;
2437 var isEligible = mustache.eligibleHelper;
2438 var options = this.options;
2440 // if ambiguous, we can possibly resolve the ambiguity now
2441 if (isEligible && !isHelper) {
2442 var name = mustache.id.parts[0];
2444 if (options.knownHelpers[name]) {
2446 } else if (options.knownHelpersOnly) {
2451 if (isHelper) { return "helper"; }
2452 else if (isEligible) { return "ambiguous"; }
2453 else { return "simple"; }
2456 pushParams: function(params) {
2457 var i = params.length, param;
2462 if(this.options.stringParams) {
2464 this.addDepth(param.depth);
2467 this.opcode('getContext', param.depth || 0);
2468 this.opcode('pushStringParam', param.stringModeValue, param.type);
2470 this[param.type](param);
2475 setupMustacheParams: function(mustache) {
2476 var params = mustache.params;
2477 this.pushParams(params);
2480 this.hash(mustache.hash);
2482 this.opcode('emptyHash');
2488 // this will replace setupMustacheParams when we're done
2489 setupFullMustacheParams: function(mustache, program, inverse) {
2490 var params = mustache.params;
2491 this.pushParams(params);
2493 this.opcode('pushProgram', program);
2494 this.opcode('pushProgram', inverse);
2497 this.hash(mustache.hash);
2499 this.opcode('emptyHash');
2506 function precompile(input, options) {
2507 if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
2508 throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
2511 options = options || {};
2512 if (!('data' in options)) {
2513 options.data = true;
2516 var ast = parse(input);
2517 var environment = new Compiler().compile(ast, options);
2518 return new JavaScriptCompiler().compile(environment, options);
2521 __exports__.precompile = precompile;function compile(input, options, env) {
2522 if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
2523 throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2526 options = options || {};
2528 if (!('data' in options)) {
2529 options.data = true;
2534 function compileInput() {
2535 var ast = parse(input);
2536 var environment = new Compiler().compile(ast, options);
2537 var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
2538 return env.template(templateSpec);
2541 // Template is only compiled on first use and cached after that point.
2542 return function(context, options) {
2544 compiled = compileInput();
2546 return compiled.call(this, context, options);
2550 __exports__.compile = compile;
2552 })(__module5__, __module8__, __module11__, __module7__);
2555 var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
2558 var Handlebars = __dependency1__;
2561 var AST = __dependency2__;
2562 var Parser = __dependency3__.parser;
2563 var parse = __dependency3__.parse;
2564 var Compiler = __dependency4__.Compiler;
2565 var compile = __dependency4__.compile;
2566 var precompile = __dependency4__.precompile;
2567 var JavaScriptCompiler = __dependency5__;
2569 var _create = Handlebars.create;
2570 var create = function() {
2573 hb.compile = function(input, options) {
2574 return compile(input, options, hb);
2576 hb.precompile = precompile;
2579 hb.Compiler = Compiler;
2580 hb.JavaScriptCompiler = JavaScriptCompiler;
2587 Handlebars = create();
2588 Handlebars.create = create;
2590 __exports__ = Handlebars;
2592 })(__module1__, __module7__, __module8__, __module10__, __module11__);