if (!this.mutating || ret) {
} else if (ret !== false) {
Program: function Program(program) {
this.acceptArray(program.body);
MustacheStatement: visitSubExpression,
Decorator: visitSubExpression,
BlockStatement: visitBlock,
DecoratorBlock: visitBlock,
PartialStatement: visitPartial,
PartialBlockStatement: function PartialBlockStatement(partial) {
visitPartial.call(this, partial);
this.acceptKey(partial, 'program');
ContentStatement: function ContentStatement() /* content */{},
CommentStatement: function CommentStatement() /* comment */{},
SubExpression: visitSubExpression,
PathExpression: function PathExpression() /* path */{},
StringLiteral: function StringLiteral() /* string */{},
NumberLiteral: function NumberLiteral() /* number */{},
BooleanLiteral: function BooleanLiteral() /* bool */{},
UndefinedLiteral: function UndefinedLiteral() /* literal */{},
NullLiteral: function NullLiteral() /* literal */{},
Hash: function Hash(hash) {
this.acceptArray(hash.pairs);
HashPair: function HashPair(pair) {
this.acceptRequired(pair, 'value');
function visitSubExpression(mustache) {
this.acceptRequired(mustache, 'path');
this.acceptArray(mustache.params);
this.acceptKey(mustache, 'hash');
function visitBlock(block) {
visitSubExpression.call(this, block);
this.acceptKey(block, 'program');
this.acceptKey(block, 'inverse');
function visitPartial(partial) {
this.acceptRequired(partial, 'name');
this.acceptArray(partial.params);
this.acceptKey(partial, 'hash');
exports['default'] = Visitor;
module.exports = exports['default'];
/***/ (function(module, exports, __webpack_require__) {
var _interopRequireDefault = __webpack_require__(1)['default'];
exports.__esModule = true;
exports.SourceLocation = SourceLocation;
exports.stripFlags = stripFlags;
exports.stripComment = stripComment;
exports.preparePath = preparePath;
exports.prepareMustache = prepareMustache;
exports.prepareRawBlock = prepareRawBlock;
exports.prepareBlock = prepareBlock;
exports.prepareProgram = prepareProgram;
exports.preparePartialBlock = preparePartialBlock;
var _exception = __webpack_require__(6);
var _exception2 = _interopRequireDefault(_exception);
function validateClose(open, close) {
close = close.path ? close.path.original : close;
if (open.path.original !== close) {
var errorNode = { loc: open.path.loc };
throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
function SourceLocation(source, locInfo) {
line: locInfo.first_line,
column: locInfo.first_column
column: locInfo.last_column
if (/^\[.*\]$/.test(token)) {
return token.substring(1, token.length - 1);
function stripFlags(open, close) {
open: open.charAt(2) === '~',
close: close.charAt(close.length - 3) === '~'
function stripComment(comment) {
return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, '');
function preparePath(data, parts, loc) {
var original = data ? '@' : '',
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i].part,
// If we have [] syntax then we do not treat path references as operators,
// i.e. foo.[this] resolves to approximately context.foo['this']
isLiteral = parts[i].original !== part;
original += (parts[i].separator || '') + part;
if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
} else if (part === '..') {
function prepareMustache(path, params, hash, open, strip, locInfo) {
// Must use charAt to support IE pre-10
var escapeFlag = open.charAt(3) || open.charAt(2),
escaped = escapeFlag !== '{' && escapeFlag !== '&';
var decorator = /\*/.test(open);
type: decorator ? 'Decorator' : 'MustacheStatement',
loc: this.locInfo(locInfo)
function prepareRawBlock(openRawBlock, contents, close, locInfo) {
validateClose(openRawBlock, close);
locInfo = this.locInfo(locInfo);
params: openRawBlock.params,
function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
if (close && close.path) {
validateClose(openBlock, close);
var decorator = /\*/.test(openBlock.open);
program.blockParams = openBlock.blockParams;
inverseStrip = undefined;
throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
if (inverseAndProgram.chain) {
inverseAndProgram.program.body[0].closeStrip = close.strip;
inverseStrip = inverseAndProgram.strip;
inverse = inverseAndProgram.program;
type: decorator ? 'DecoratorBlock' : 'BlockStatement',
params: openBlock.params,
openStrip: openBlock.strip,
inverseStrip: inverseStrip,
closeStrip: close && close.strip,
loc: this.locInfo(locInfo)
function prepareProgram(statements, loc) {
if (!loc && statements.length) {
var firstLoc = statements[0].loc,
lastLoc = statements[statements.length - 1].loc;
/* istanbul ignore else */
if (firstLoc && lastLoc) {
line: firstLoc.start.line,
column: firstLoc.start.column
column: lastLoc.end.column
function preparePartialBlock(open, program, close, locInfo) {
validateClose(open, close);
type: 'PartialBlockStatement',
closeStrip: close && close.strip,
loc: this.locInfo(locInfo)
/***/ (function(module, exports, __webpack_require__) {
/* eslint-disable new-cap */
var _Object$create = __webpack_require__(34)['default'];
var _interopRequireDefault = __webpack_require__(1)['default'];
exports.__esModule = true;
exports.Compiler = Compiler;
exports.precompile = precompile;
exports.compile = compile;
var _exception = __webpack_require__(6);
var _exception2 = _interopRequireDefault(_exception);
var _utils = __webpack_require__(5);
var _ast = __webpack_require__(45);
var _ast2 = _interopRequireDefault(_ast);
// the foundHelper register will disambiguate helper lookup from finding a
// function in a context. This is necessary for mustache compatibility, which
// requires that context functions in blocks are evaluated by blockHelperMissing,
// and then proceed as if the resulting value was provided to blockHelperMissing.
equals: function equals(other) {
var len = this.opcodes.length;
if (other.opcodes.length !== len) {
for (var i = 0; i < len; i++) {
var opcode = this.opcodes[i],
otherOpcode = other.opcodes[i];
if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
// We know that length is the same between the two arrays because they are directly tied
// to the opcode behavior above.
len = this.children.length;
for (var i = 0; i < len; i++) {
if (!this.children[i].equals(other.children[i])) {
compile: function compile(program, options) {
this.stringParams = options.stringParams;
this.trackIds = options.trackIds;
options.blockParams = options.blockParams || [];
options.knownHelpers = _utils.extend(_Object$create(null), {
blockHelperMissing: true,
}, options.knownHelpers);
return this.accept(program);
compileProgram: function compileProgram(program) {
var childCompiler = new this.compiler(),
// eslint-disable-line new-cap
result = childCompiler.compile(program, this.options),
this.usePartial = this.usePartial || result.usePartial;
this.children[guid] = result;
this.useDepths = this.useDepths || result.useDepths;
accept: function accept(node) {
/* istanbul ignore next: Sanity code */
throw new _exception2['default']('Unknown type: ' + node.type, node);
this.sourceNode.unshift(node);
var ret = this[node.type](node);
Program: function Program(program) {
this.options.blockParams.unshift(program.blockParams);
bodyLength = body.length;
for (var i = 0; i < bodyLength; i++) {
this.options.blockParams.shift();
this.isSimple = bodyLength === 1;
this.blockParams = program.blockParams ? program.blockParams.length : 0;
BlockStatement: function BlockStatement(block) {
transformLiteralToPath(block);
var program = block.program,
program = program && this.compileProgram(program);
inverse = inverse && this.compileProgram(inverse);
var type = this.classifySexpr(block);
this.helperSexpr(block, program, inverse);
} else if (type === 'simple') {
// now that the simple mustache is resolved, we need to
// evaluate it by executing `blockHelperMissing`
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.opcode('emptyHash');
this.opcode('blockValue', block.path.original);
this.ambiguousSexpr(block, program, inverse);
// now that the simple mustache is resolved, we need to
// evaluate it by executing `blockHelperMissing`
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.opcode('emptyHash');
this.opcode('ambiguousBlockValue');
DecoratorBlock: function DecoratorBlock(decorator) {
var program = decorator.program && this.compileProgram(decorator.program);
var params = this.setupFullMustacheParams(decorator, program, undefined),
this.useDecorators = true;
this.opcode('registerDecorator', params.length, path.original);
PartialStatement: function PartialStatement(partial) {
var program = partial.program;
program = this.compileProgram(partial.program);
var params = partial.params;
throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
} else if (!params.length) {
if (this.options.explicitPartialContext) {
this.opcode('pushLiteral', 'undefined');
params.push({ type: 'PathExpression', parts: [], depth: 0 });
var partialName = partial.name.original,
isDynamic = partial.name.type === 'SubExpression';
this.accept(partial.name);