2013-12-02 13:15:31 -05:00
/ * !
2014-12-10 11:34:00 -05:00
handlebars v2 . 0.0
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
Copyright ( C ) 2011 - 2014 by Yehuda Katz
2013-06-06 17:50:49 -04:00
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the "Software" ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE .
2013-12-02 13:15:31 -05:00
@ license
2013-06-06 17:50:49 -04:00
* /
2014-04-15 11:22:15 -04:00
/* exported Handlebars */
2014-12-10 11:34:00 -05:00
( function ( root , factory ) {
if ( typeof define === 'function' && define . amd ) {
define ( [ ] , factory ) ;
} else if ( typeof exports === 'object' ) {
module . exports = factory ( ) ;
} else {
root . Handlebars = root . Handlebars || factory ( ) ;
}
} ( this , function ( ) {
2013-12-02 13:15:31 -05:00
// handlebars/safe-string.js
var _ _module4 _ _ = ( function ( ) {
"use strict" ;
var _ _exports _ _ ;
// Build out our basic SafeString type
function SafeString ( string ) {
this . string = string ;
}
SafeString . prototype . toString = function ( ) {
return "" + this . string ;
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
_ _exports _ _ = SafeString ;
return _ _exports _ _ ;
} ) ( ) ;
// handlebars/utils.js
var _ _module3 _ _ = ( function ( _ _dependency1 _ _ ) {
"use strict" ;
var _ _exports _ _ = { } ;
2014-04-15 11:22:15 -04:00
/*jshint -W004 */
2013-12-02 13:15:31 -05:00
var SafeString = _ _dependency1 _ _ ;
var escape = {
"&" : "&" ,
"<" : "<" ,
">" : ">" ,
'"' : """ ,
"'" : "'" ,
"`" : "`"
} ;
var badChars = /[&<>"'`]/g ;
var possible = /[&<>"'`]/ ;
function escapeChar ( chr ) {
2014-12-10 11:34:00 -05:00
return escape [ chr ] ;
2013-06-06 17:50:49 -04:00
}
2014-12-10 11:34:00 -05:00
function extend ( obj /* , ...source */ ) {
for ( var i = 1 ; i < arguments . length ; i ++ ) {
for ( var key in arguments [ i ] ) {
if ( Object . prototype . hasOwnProperty . call ( arguments [ i ] , key ) ) {
obj [ key ] = arguments [ i ] [ key ] ;
}
2013-12-02 13:15:31 -05:00
}
}
2014-12-10 11:34:00 -05:00
return obj ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
_ _exports _ _ . extend = extend ; var toString = Object . prototype . toString ;
_ _exports _ _ . toString = toString ;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function ( value ) {
return typeof value === 'function' ;
} ;
// fallback for older versions of Chrome and Safari
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2013-12-02 13:15:31 -05:00
if ( isFunction ( /x/ ) ) {
isFunction = function ( value ) {
return typeof value === 'function' && toString . call ( value ) === '[object Function]' ;
} ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
var isFunction ;
_ _exports _ _ . isFunction = isFunction ;
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2013-12-02 13:15:31 -05:00
var isArray = Array . isArray || function ( value ) {
return ( value && typeof value === 'object' ) ? toString . call ( value ) === '[object Array]' : false ;
} ;
_ _exports _ _ . isArray = isArray ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
function escapeExpression ( string ) {
// don't escape SafeStrings, since they're already safe
if ( string instanceof SafeString ) {
return string . toString ( ) ;
2014-12-10 11:34:00 -05:00
} else if ( string == null ) {
2013-12-02 13:15:31 -05:00
return "" ;
2014-12-10 11:34:00 -05:00
} else if ( ! string ) {
return string + '' ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = "" + string ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
if ( ! possible . test ( string ) ) { return string ; }
return string . replace ( badChars , escapeChar ) ;
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
_ _exports _ _ . escapeExpression = escapeExpression ; function isEmpty ( value ) {
if ( ! value && value !== 0 ) {
return true ;
} else if ( isArray ( value ) && value . length === 0 ) {
return true ;
2013-06-06 17:50:49 -04:00
} else {
2013-12-02 13:15:31 -05:00
return false ;
2013-06-06 17:50:49 -04:00
}
}
2014-12-10 11:34:00 -05:00
_ _exports _ _ . isEmpty = isEmpty ; function appendContextPath ( contextPath , id ) {
return ( contextPath ? contextPath + '.' : '' ) + id ;
}
_ _exports _ _ . appendContextPath = appendContextPath ;
2013-12-02 13:15:31 -05:00
return _ _exports _ _ ;
} ) ( _ _module4 _ _ ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// handlebars/exception.js
var _ _module5 _ _ = ( function ( ) {
"use strict" ;
var _ _exports _ _ ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
var errorProps = [ 'description' , 'fileName' , 'lineNumber' , 'message' , 'name' , 'number' , 'stack' ] ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
function Exception ( message , node ) {
var line ;
if ( node && node . firstLine ) {
line = node . firstLine ;
message += ' - ' + line + ':' + node . firstColumn ;
}
var tmp = Error . prototype . constructor . call ( this , message ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for ( var idx = 0 ; idx < errorProps . length ; idx ++ ) {
this [ errorProps [ idx ] ] = tmp [ errorProps [ idx ] ] ;
2013-06-06 17:50:49 -04:00
}
2014-04-15 11:22:15 -04:00
if ( line ) {
this . lineNumber = line ;
this . column = node . firstColumn ;
}
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
Exception . prototype = new Error ( ) ;
_ _exports _ _ = Exception ;
return _ _exports _ _ ;
} ) ( ) ;
// handlebars/base.js
var _ _module2 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ ) {
"use strict" ;
var _ _exports _ _ = { } ;
var Utils = _ _dependency1 _ _ ;
var Exception = _ _dependency2 _ _ ;
2014-12-10 11:34:00 -05:00
var VERSION = "2.0.0" ;
_ _exports _ _ . VERSION = VERSION ; var COMPILER _REVISION = 6 ;
2013-12-02 13:15:31 -05:00
_ _exports _ _ . COMPILER _REVISION = COMPILER _REVISION ;
var REVISION _CHANGES = {
1 : '<= 1.0.rc.2' , // 1.0.rc.2 is actually rev2 but doesn't report it
2 : '== 1.0.0-rc.3' ,
3 : '== 1.0.0-rc.4' ,
2014-12-10 11:34:00 -05:00
4 : '== 1.x.x' ,
5 : '== 2.0.0-alpha.x' ,
6 : '>= 2.0.0-beta.1'
2013-12-02 13:15:31 -05:00
} ;
_ _exports _ _ . REVISION _CHANGES = REVISION _CHANGES ;
var isArray = Utils . isArray ,
isFunction = Utils . isFunction ,
toString = Utils . toString ,
objectType = '[object Object]' ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
function HandlebarsEnvironment ( helpers , partials ) {
this . helpers = helpers || { } ;
this . partials = partials || { } ;
2013-07-15 19:47:13 -04:00
2013-12-02 13:15:31 -05:00
registerDefaultHelpers ( this ) ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
_ _exports _ _ . HandlebarsEnvironment = HandlebarsEnvironment ; HandlebarsEnvironment . prototype = {
constructor : HandlebarsEnvironment ,
logger : logger ,
log : log ,
2014-12-10 11:34:00 -05:00
registerHelper : function ( name , fn ) {
2013-12-02 13:15:31 -05:00
if ( toString . call ( name ) === objectType ) {
2014-12-10 11:34:00 -05:00
if ( fn ) { throw new Exception ( 'Arg not supported with multiple helpers' ) ; }
2013-12-02 13:15:31 -05:00
Utils . extend ( this . helpers , name ) ;
} else {
this . helpers [ name ] = fn ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
} ,
2014-12-10 11:34:00 -05:00
unregisterHelper : function ( name ) {
delete this . helpers [ name ] ;
} ,
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
registerPartial : function ( name , partial ) {
2013-12-02 13:15:31 -05:00
if ( toString . call ( name ) === objectType ) {
Utils . extend ( this . partials , name ) ;
} else {
2014-12-10 11:34:00 -05:00
this . partials [ name ] = partial ;
2013-06-06 17:50:49 -04:00
}
2014-12-10 11:34:00 -05:00
} ,
unregisterPartial : function ( name ) {
delete this . partials [ name ] ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
function registerDefaultHelpers ( instance ) {
2014-12-10 11:34:00 -05:00
instance . registerHelper ( 'helperMissing' , function ( /* [args, ]options */ ) {
if ( arguments . length === 1 ) {
// A missing field in a {{foo}} constuct.
2013-12-02 13:15:31 -05:00
return undefined ;
} else {
2014-12-10 11:34:00 -05:00
// Someone is actually trying to call something, blow up.
throw new Exception ( "Missing helper: '" + arguments [ arguments . length - 1 ] . name + "'" ) ;
2013-12-02 13:15:31 -05:00
}
} ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
instance . registerHelper ( 'blockHelperMissing' , function ( context , options ) {
2014-12-10 11:34:00 -05:00
var inverse = options . inverse ,
fn = options . fn ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
if ( context === true ) {
return fn ( this ) ;
} else if ( context === false || context == null ) {
return inverse ( this ) ;
} else if ( isArray ( context ) ) {
if ( context . length > 0 ) {
2014-12-10 11:34:00 -05:00
if ( options . ids ) {
options . ids = [ options . name ] ;
}
2013-12-02 13:15:31 -05:00
return instance . helpers . each ( context , options ) ;
2013-06-06 17:50:49 -04:00
} else {
2013-12-02 13:15:31 -05:00
return inverse ( this ) ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
} else {
2014-12-10 11:34:00 -05:00
if ( options . data && options . ids ) {
var data = createFrame ( options . data ) ;
data . contextPath = Utils . appendContextPath ( options . data . contextPath , options . name ) ;
options = { data : data } ;
}
return fn ( context , options ) ;
2013-12-02 13:15:31 -05:00
}
} ) ;
instance . registerHelper ( 'each' , function ( context , options ) {
2014-12-10 11:34:00 -05:00
if ( ! options ) {
throw new Exception ( 'Must pass iterator to #each' ) ;
}
2013-12-02 13:15:31 -05:00
var fn = options . fn , inverse = options . inverse ;
var i = 0 , ret = "" , data ;
2014-12-10 11:34:00 -05:00
var contextPath ;
if ( options . data && options . ids ) {
contextPath = Utils . appendContextPath ( options . data . contextPath , options . ids [ 0 ] ) + '.' ;
}
2013-12-02 13:15:31 -05:00
if ( isFunction ( context ) ) { context = context . call ( this ) ; }
if ( options . data ) {
data = createFrame ( options . data ) ;
}
if ( context && typeof context === 'object' ) {
if ( isArray ( context ) ) {
for ( var j = context . length ; i < j ; i ++ ) {
if ( data ) {
data . index = i ;
2014-04-15 11:22:15 -04:00
data . first = ( i === 0 ) ;
2013-12-02 13:15:31 -05:00
data . last = ( i === ( context . length - 1 ) ) ;
2014-12-10 11:34:00 -05:00
if ( contextPath ) {
data . contextPath = contextPath + i ;
}
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
ret = ret + fn ( context [ i ] , { data : data } ) ;
}
2013-06-06 17:50:49 -04:00
} else {
2013-12-02 13:15:31 -05:00
for ( var key in context ) {
if ( context . hasOwnProperty ( key ) ) {
2014-12-10 11:34:00 -05:00
if ( data ) {
data . key = key ;
2014-04-15 11:22:15 -04:00
data . index = i ;
data . first = ( i === 0 ) ;
2014-12-10 11:34:00 -05:00
if ( contextPath ) {
data . contextPath = contextPath + key ;
}
2014-04-15 11:22:15 -04:00
}
2013-12-02 13:15:31 -05:00
ret = ret + fn ( context [ key ] , { data : data } ) ;
i ++ ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
if ( i === 0 ) {
ret = inverse ( this ) ;
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
return ret ;
} ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
instance . registerHelper ( 'if' , function ( conditional , options ) {
if ( isFunction ( conditional ) ) { conditional = conditional . call ( this ) ; }
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// Default behavior is to render the positive path if the value is truthy and not empty.
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
if ( ( ! options . hash . includeZero && ! conditional ) || Utils . isEmpty ( conditional ) ) {
return options . inverse ( this ) ;
} else {
return options . fn ( this ) ;
}
} ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
instance . registerHelper ( 'unless' , function ( conditional , options ) {
return instance . helpers [ 'if' ] . call ( this , conditional , { fn : options . inverse , inverse : options . fn , hash : options . hash } ) ;
} ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
instance . registerHelper ( 'with' , function ( context , options ) {
if ( isFunction ( context ) ) { context = context . call ( this ) ; }
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var fn = options . fn ;
if ( ! Utils . isEmpty ( context ) ) {
if ( options . data && options . ids ) {
var data = createFrame ( options . data ) ;
data . contextPath = Utils . appendContextPath ( options . data . contextPath , options . ids [ 0 ] ) ;
options = { data : data } ;
}
return fn ( context , options ) ;
} else {
return options . inverse ( this ) ;
}
2013-12-02 13:15:31 -05:00
} ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
instance . registerHelper ( 'log' , function ( message , options ) {
2013-12-02 13:15:31 -05:00
var level = options . data && options . data . level != null ? parseInt ( options . data . level , 10 ) : 1 ;
2014-12-10 11:34:00 -05:00
instance . log ( level , message ) ;
} ) ;
instance . registerHelper ( 'lookup' , function ( obj , field ) {
return obj && obj [ field ] ;
2013-12-02 13:15:31 -05:00
} ) ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
var logger = {
methodMap : { 0 : 'debug' , 1 : 'info' , 2 : 'warn' , 3 : 'error' } ,
// State enum
DEBUG : 0 ,
INFO : 1 ,
WARN : 2 ,
ERROR : 3 ,
level : 3 ,
// can be overridden in the host environment
2014-12-10 11:34:00 -05:00
log : function ( level , message ) {
2013-12-02 13:15:31 -05:00
if ( logger . level <= level ) {
var method = logger . methodMap [ level ] ;
if ( typeof console !== 'undefined' && console [ method ] ) {
2014-12-10 11:34:00 -05:00
console [ method ] . call ( console , message ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
}
}
2013-12-02 13:15:31 -05:00
} ;
_ _exports _ _ . logger = logger ;
2014-12-10 11:34:00 -05:00
var log = logger . log ;
_ _exports _ _ . log = log ;
var createFrame = function ( object ) {
var frame = Utils . extend ( { } , object ) ;
frame . _parent = object ;
return frame ;
2013-12-02 13:15:31 -05:00
} ;
_ _exports _ _ . createFrame = createFrame ;
return _ _exports _ _ ;
} ) ( _ _module3 _ _ , _ _module5 _ _ ) ;
// handlebars/runtime.js
var _ _module6 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ , _ _dependency3 _ _ ) {
"use strict" ;
var _ _exports _ _ = { } ;
var Utils = _ _dependency1 _ _ ;
var Exception = _ _dependency2 _ _ ;
var COMPILER _REVISION = _ _dependency3 _ _ . COMPILER _REVISION ;
var REVISION _CHANGES = _ _dependency3 _ _ . REVISION _CHANGES ;
2014-12-10 11:34:00 -05:00
var createFrame = _ _dependency3 _ _ . createFrame ;
2013-12-02 13:15:31 -05:00
function checkRevision ( compilerInfo ) {
var compilerRevision = compilerInfo && compilerInfo [ 0 ] || 1 ,
currentRevision = COMPILER _REVISION ;
if ( compilerRevision !== currentRevision ) {
if ( compilerRevision < currentRevision ) {
var runtimeVersions = REVISION _CHANGES [ currentRevision ] ,
compilerVersions = REVISION _CHANGES [ compilerRevision ] ;
2014-04-15 11:22:15 -04:00
throw new Exception ( "Template was precompiled with an older version of Handlebars than the current runtime. " +
2013-12-02 13:15:31 -05:00
"Please update your precompiler to a newer version (" + runtimeVersions + ") or downgrade your runtime to an older version (" + compilerVersions + ")." ) ;
} else {
// Use the embedded version info since the runtime doesn't know about this revision yet
2014-04-15 11:22:15 -04:00
throw new Exception ( "Template was precompiled with a newer version of Handlebars than the current runtime. " +
2013-12-02 13:15:31 -05:00
"Please update your runtime to a newer version (" + compilerInfo [ 1 ] + ")." ) ;
}
2013-06-06 17:50:49 -04:00
}
}
2014-04-15 11:22:15 -04:00
_ _exports _ _ . checkRevision = checkRevision ; // TODO: Remove this line and break up compilePartial
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
function template ( templateSpec , env ) {
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2013-12-02 13:15:31 -05:00
if ( ! env ) {
2014-04-15 11:22:15 -04:00
throw new Exception ( "No environment passed to template" ) ;
2013-12-02 13:15:31 -05:00
}
2014-12-10 11:34:00 -05:00
if ( ! templateSpec || ! templateSpec . main ) {
throw new Exception ( 'Unknown template object: ' + typeof templateSpec ) ;
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// Note: Using env.VM references rather than local var references throughout this section to allow
// for external users to override these as psuedo-supported APIs.
2014-12-10 11:34:00 -05:00
env . VM . checkRevision ( templateSpec . compiler ) ;
var invokePartialWrapper = function ( partial , indent , name , context , hash , helpers , partials , data , depths ) {
if ( hash ) {
context = Utils . extend ( { } , context , hash ) ;
}
var result = env . VM . invokePartial . call ( this , partial , name , context , helpers , partials , data , depths ) ;
if ( result == null && env . compile ) {
var options = { helpers : helpers , partials : partials , data : data , depths : depths } ;
partials [ name ] = env . compile ( partial , { data : data !== undefined , compat : templateSpec . compat } , env ) ;
result = partials [ name ] ( context , options ) ;
}
if ( result != null ) {
if ( indent ) {
var lines = result . split ( '\n' ) ;
for ( var i = 0 , l = lines . length ; i < l ; i ++ ) {
if ( ! lines [ i ] && i + 1 === l ) {
break ;
}
lines [ i ] = indent + lines [ i ] ;
}
result = lines . join ( '\n' ) ;
}
return result ;
2014-04-15 11:22:15 -04:00
} else {
2013-12-02 13:15:31 -05:00
throw new Exception ( "The partial " + name + " could not be compiled when running in runtime-only mode" ) ;
2014-04-15 11:22:15 -04:00
}
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// Just add water
var container = {
2014-12-10 11:34:00 -05:00
lookup : function ( depths , name ) {
var len = depths . length ;
for ( var i = 0 ; i < len ; i ++ ) {
if ( depths [ i ] && depths [ i ] [ name ] != null ) {
return depths [ i ] [ name ] ;
}
}
} ,
lambda : function ( current , context ) {
return typeof current === 'function' ? current . call ( context ) : current ;
} ,
2013-12-02 13:15:31 -05:00
escapeExpression : Utils . escapeExpression ,
invokePartial : invokePartialWrapper ,
2014-12-10 11:34:00 -05:00
fn : function ( i ) {
return templateSpec [ i ] ;
} ,
2013-12-02 13:15:31 -05:00
programs : [ ] ,
2014-12-10 11:34:00 -05:00
program : function ( i , data , depths ) {
var programWrapper = this . programs [ i ] ,
fn = this . fn ( i ) ;
if ( data || depths ) {
programWrapper = program ( this , i , fn , data , depths ) ;
2013-12-02 13:15:31 -05:00
} else if ( ! programWrapper ) {
2014-12-10 11:34:00 -05:00
programWrapper = this . programs [ i ] = program ( this , i , fn ) ;
2013-12-02 13:15:31 -05:00
}
return programWrapper ;
} ,
2014-12-10 11:34:00 -05:00
data : function ( data , depth ) {
while ( data && depth -- ) {
data = data . _parent ;
}
return data ;
} ,
2013-12-02 13:15:31 -05:00
merge : function ( param , common ) {
var ret = param || common ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
if ( param && common && ( param !== common ) ) {
2014-12-10 11:34:00 -05:00
ret = Utils . extend ( { } , common , param ) ;
2013-06-06 17:50:49 -04:00
}
2014-12-10 11:34:00 -05:00
2013-12-02 13:15:31 -05:00
return ret ;
} ,
2014-12-10 11:34:00 -05:00
2014-04-15 11:22:15 -04:00
noop : env . VM . noop ,
2014-12-10 11:34:00 -05:00
compilerInfo : templateSpec . compiler
2013-12-02 13:15:31 -05:00
} ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var ret = function ( context , options ) {
2013-12-02 13:15:31 -05:00
options = options || { } ;
2014-12-10 11:34:00 -05:00
var data = options . data ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
ret . _setup ( options ) ;
if ( ! options . partial && templateSpec . useData ) {
data = initData ( context , data ) ;
2013-06-06 17:50:49 -04:00
}
2014-12-10 11:34:00 -05:00
var depths ;
if ( templateSpec . useDepths ) {
depths = options . depths ? [ context ] . concat ( options . depths ) : [ context ] ;
2013-06-06 17:50:49 -04:00
}
2014-12-10 11:34:00 -05:00
return templateSpec . main . call ( container , context , container . helpers , container . partials , data , depths ) ;
2013-12-02 13:15:31 -05:00
} ;
2014-12-10 11:34:00 -05:00
ret . isTop = true ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
ret . _setup = function ( options ) {
if ( ! options . partial ) {
container . helpers = container . merge ( options . helpers , env . helpers ) ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( templateSpec . usePartial ) {
container . partials = container . merge ( options . partials , env . partials ) ;
}
} else {
container . helpers = options . helpers ;
container . partials = options . partials ;
}
} ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
ret . _child = function ( i , data , depths ) {
if ( templateSpec . useDepths && ! depths ) {
throw new Exception ( 'must pass parent depths' ) ;
}
return program ( container , i , templateSpec [ i ] , data , depths ) ;
2013-06-06 17:50:49 -04:00
} ;
2014-12-10 11:34:00 -05:00
return ret ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
_ _exports _ _ . template = template ; function program ( container , i , fn , data , depths ) {
2013-12-02 13:15:31 -05:00
var prog = function ( context , options ) {
options = options || { } ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
return fn . call ( container , context , container . helpers , container . partials , options . data || data , depths && [ context ] . concat ( depths ) ) ;
2013-12-02 13:15:31 -05:00
} ;
prog . program = i ;
2014-12-10 11:34:00 -05:00
prog . depth = depths ? depths . length : 0 ;
2013-12-02 13:15:31 -05:00
return prog ;
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
_ _exports _ _ . program = program ; function invokePartial ( partial , name , context , helpers , partials , data , depths ) {
var options = { partial : true , helpers : helpers , partials : partials , data : data , depths : depths } ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
if ( partial === undefined ) {
throw new Exception ( "The partial " + name + " could not be found" ) ;
} else if ( partial instanceof Function ) {
return partial ( context , options ) ;
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
_ _exports _ _ . invokePartial = invokePartial ; function noop ( ) { return "" ; }
2014-12-10 11:34:00 -05:00
_ _exports _ _ . noop = noop ; function initData ( context , data ) {
if ( ! data || ! ( 'root' in data ) ) {
data = data ? createFrame ( data ) : { } ;
data . root = context ;
}
return data ;
}
2013-12-02 13:15:31 -05:00
return _ _exports _ _ ;
} ) ( _ _module3 _ _ , _ _module5 _ _ , _ _module2 _ _ ) ;
// handlebars.runtime.js
var _ _module1 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ , _ _dependency3 _ _ , _ _dependency4 _ _ , _ _dependency5 _ _ ) {
"use strict" ;
var _ _exports _ _ ;
2014-04-15 11:22:15 -04:00
/*globals Handlebars: true */
2013-12-02 13:15:31 -05:00
var base = _ _dependency1 _ _ ;
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var SafeString = _ _dependency2 _ _ ;
var Exception = _ _dependency3 _ _ ;
var Utils = _ _dependency4 _ _ ;
var runtime = _ _dependency5 _ _ ;
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function ( ) {
var hb = new base . HandlebarsEnvironment ( ) ;
Utils . extend ( hb , base ) ;
hb . SafeString = SafeString ;
hb . Exception = Exception ;
hb . Utils = Utils ;
2014-12-10 11:34:00 -05:00
hb . escapeExpression = Utils . escapeExpression ;
2013-12-02 13:15:31 -05:00
hb . VM = runtime ;
hb . template = function ( spec ) {
return runtime . template ( spec , hb ) ;
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
return hb ;
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
var Handlebars = create ( ) ;
Handlebars . create = create ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
Handlebars [ 'default' ] = Handlebars ;
2013-12-02 13:15:31 -05:00
_ _exports _ _ = Handlebars ;
return _ _exports _ _ ;
} ) ( _ _module2 _ _ , _ _module4 _ _ , _ _module5 _ _ , _ _module3 _ _ , _ _module6 _ _ ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
// handlebars/compiler/ast.js
var _ _module7 _ _ = ( function ( _ _dependency1 _ _ ) {
"use strict" ;
2014-04-15 11:22:15 -04:00
var _ _exports _ _ ;
2013-12-02 13:15:31 -05:00
var Exception = _ _dependency1 _ _ ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
function LocationInfo ( locInfo ) {
2014-04-15 11:22:15 -04:00
locInfo = locInfo || { } ;
this . firstLine = locInfo . first _line ;
this . firstColumn = locInfo . first _column ;
this . lastColumn = locInfo . last _column ;
this . lastLine = locInfo . last _line ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var AST = {
2014-12-10 11:34:00 -05:00
ProgramNode : function ( statements , strip , locInfo ) {
2014-04-15 11:22:15 -04:00
LocationInfo . call ( this , locInfo ) ;
this . type = "program" ;
this . statements = statements ;
2014-12-10 11:34:00 -05:00
this . strip = strip ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
MustacheNode : function ( rawParams , hash , open , strip , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "mustache" ;
this . strip = strip ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// Open may be a string parsed from the parser or a passed boolean flag
if ( open != null && open . charAt ) {
// Must use charAt to support IE pre-10
var escapeFlag = open . charAt ( 3 ) || open . charAt ( 2 ) ;
this . escaped = escapeFlag !== '{' && escapeFlag !== '&' ;
} else {
this . escaped = ! ! open ;
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( rawParams instanceof AST . SexprNode ) {
this . sexpr = rawParams ;
} else {
// Support old AST API
this . sexpr = new AST . SexprNode ( rawParams , hash ) ;
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// Support old AST API that stored this info in MustacheNode
this . id = this . sexpr . id ;
this . params = this . sexpr . params ;
this . hash = this . sexpr . hash ;
this . eligibleHelper = this . sexpr . eligibleHelper ;
this . isHelper = this . sexpr . isHelper ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
SexprNode : function ( rawParams , hash , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . type = "sexpr" ;
this . hash = hash ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var id = this . id = rawParams [ 0 ] ;
var params = this . params = rawParams . slice ( 1 ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// a mustache is definitely a helper if:
// * it is an eligible helper, and
// * it has at least one parameter or hash segment
2014-12-10 11:34:00 -05:00
this . isHelper = ! ! ( params . length || hash ) ;
// a mustache is an eligible helper if:
// * its id is simple (a single part, not `this` or `..`)
this . eligibleHelper = this . isHelper || id . isSimple ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// if a mustache is an eligible helper but not a definite
// helper, it is ambiguous, and will be resolved in a later
// pass or at runtime.
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
PartialNode : function ( partialName , context , hash , strip , locInfo ) {
2014-04-15 11:22:15 -04:00
LocationInfo . call ( this , locInfo ) ;
this . type = "partial" ;
this . partialName = partialName ;
this . context = context ;
2014-12-10 11:34:00 -05:00
this . hash = hash ;
2014-04-15 11:22:15 -04:00
this . strip = strip ;
2014-12-10 11:34:00 -05:00
this . strip . inlineStandalone = true ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
BlockNode : function ( mustache , program , inverse , strip , locInfo ) {
2014-04-15 11:22:15 -04:00
LocationInfo . call ( this , locInfo ) ;
this . type = 'block' ;
this . mustache = mustache ;
this . program = program ;
this . inverse = inverse ;
2014-12-10 11:34:00 -05:00
this . strip = strip ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( inverse && ! program ) {
this . isInverse = true ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
RawBlockNode : function ( mustache , content , close , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
if ( mustache . sexpr . id . original !== close ) {
throw new Exception ( mustache . sexpr . id . original + " doesn't match " + close , this ) ;
}
content = new AST . ContentNode ( content , locInfo ) ;
this . type = 'block' ;
this . mustache = mustache ;
this . program = new AST . ProgramNode ( [ content ] , { } , locInfo ) ;
} ,
2014-04-15 11:22:15 -04:00
ContentNode : function ( string , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "content" ;
2014-12-10 11:34:00 -05:00
this . original = this . string = string ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
HashNode : function ( pairs , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "hash" ;
this . pairs = pairs ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
IdNode : function ( parts , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "ID" ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var original = "" ,
dig = [ ] ,
2014-12-10 11:34:00 -05:00
depth = 0 ,
depthString = '' ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
for ( var i = 0 , l = parts . length ; i < l ; i ++ ) {
var part = parts [ i ] . part ;
original += ( parts [ i ] . separator || '' ) + part ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( part === ".." || part === "." || part === "this" ) {
if ( dig . length > 0 ) {
throw new Exception ( "Invalid path: " + original , this ) ;
} else if ( part === ".." ) {
depth ++ ;
2014-12-10 11:34:00 -05:00
depthString += '../' ;
2014-04-15 11:22:15 -04:00
} else {
this . isScoped = true ;
}
} else {
dig . push ( part ) ;
}
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . original = original ;
this . parts = dig ;
this . string = dig . join ( '.' ) ;
this . depth = depth ;
2014-12-10 11:34:00 -05:00
this . idName = depthString + this . string ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// an ID is simple if it only has one part, and that part is not
// `..` or `this`.
this . isSimple = parts . length === 1 && ! this . isScoped && depth === 0 ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . stringModeValue = this . string ;
} ,
PartialNameNode : function ( name , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "PARTIAL_NAME" ;
this . name = name . original ;
} ,
DataNode : function ( id , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "DATA" ;
this . id = id ;
2014-12-10 11:34:00 -05:00
this . stringModeValue = id . stringModeValue ;
this . idName = '@' + id . stringModeValue ;
2014-04-15 11:22:15 -04:00
} ,
StringNode : function ( string , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "STRING" ;
this . original =
this . string =
this . stringModeValue = string ;
} ,
2014-12-10 11:34:00 -05:00
NumberNode : function ( number , locInfo ) {
2014-04-15 11:22:15 -04:00
LocationInfo . call ( this , locInfo ) ;
2014-12-10 11:34:00 -05:00
this . type = "NUMBER" ;
2014-04-15 11:22:15 -04:00
this . original =
2014-12-10 11:34:00 -05:00
this . number = number ;
this . stringModeValue = Number ( number ) ;
2014-04-15 11:22:15 -04:00
} ,
BooleanNode : function ( bool , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "BOOLEAN" ;
this . bool = bool ;
this . stringModeValue = bool === "true" ;
} ,
CommentNode : function ( comment , locInfo ) {
LocationInfo . call ( this , locInfo ) ;
this . type = "comment" ;
this . comment = comment ;
2014-12-10 11:34:00 -05:00
this . strip = {
inlineStandalone : true
} ;
2014-04-15 11:22:15 -04:00
}
} ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
2014-04-15 11:22:15 -04:00
// Must be exported as an object rather than the root of the module as the jison lexer
// most modify the object to operate properly.
_ _exports _ _ = AST ;
2013-12-02 13:15:31 -05:00
return _ _exports _ _ ;
} ) ( _ _module5 _ _ ) ;
// handlebars/compiler/parser.js
var _ _module9 _ _ = ( function ( ) {
"use strict" ;
var _ _exports _ _ ;
2014-04-15 11:22:15 -04:00
/* jshint ignore:start */
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2013-12-02 13:15:31 -05:00
/* Jison generated parser */
var handlebars = ( function ( ) {
var parser = { trace : function trace ( ) { } ,
yy : { } ,
2014-12-10 11:34:00 -05:00
symbols _ : { "error" : 2 , "root" : 3 , "program" : 4 , "EOF" : 5 , "program_repetition0" : 6 , "statement" : 7 , "mustache" : 8 , "block" : 9 , "rawBlock" : 10 , "partial" : 11 , "CONTENT" : 12 , "COMMENT" : 13 , "openRawBlock" : 14 , "END_RAW_BLOCK" : 15 , "OPEN_RAW_BLOCK" : 16 , "sexpr" : 17 , "CLOSE_RAW_BLOCK" : 18 , "openBlock" : 19 , "block_option0" : 20 , "closeBlock" : 21 , "openInverse" : 22 , "block_option1" : 23 , "OPEN_BLOCK" : 24 , "CLOSE" : 25 , "OPEN_INVERSE" : 26 , "inverseAndProgram" : 27 , "INVERSE" : 28 , "OPEN_ENDBLOCK" : 29 , "path" : 30 , "OPEN" : 31 , "OPEN_UNESCAPED" : 32 , "CLOSE_UNESCAPED" : 33 , "OPEN_PARTIAL" : 34 , "partialName" : 35 , "param" : 36 , "partial_option0" : 37 , "partial_option1" : 38 , "sexpr_repetition0" : 39 , "sexpr_option0" : 40 , "dataName" : 41 , "STRING" : 42 , "NUMBER" : 43 , "BOOLEAN" : 44 , "OPEN_SEXPR" : 45 , "CLOSE_SEXPR" : 46 , "hash" : 47 , "hash_repetition_plus0" : 48 , "hashSegment" : 49 , "ID" : 50 , "EQUALS" : 51 , "DATA" : 52 , "pathSegments" : 53 , "SEP" : 54 , "$accept" : 0 , "$end" : 1 } ,
terminals _ : { 2 : "error" , 5 : "EOF" , 12 : "CONTENT" , 13 : "COMMENT" , 15 : "END_RAW_BLOCK" , 16 : "OPEN_RAW_BLOCK" , 18 : "CLOSE_RAW_BLOCK" , 24 : "OPEN_BLOCK" , 25 : "CLOSE" , 26 : "OPEN_INVERSE" , 28 : "INVERSE" , 29 : "OPEN_ENDBLOCK" , 31 : "OPEN" , 32 : "OPEN_UNESCAPED" , 33 : "CLOSE_UNESCAPED" , 34 : "OPEN_PARTIAL" , 42 : "STRING" , 43 : "NUMBER" , 44 : "BOOLEAN" , 45 : "OPEN_SEXPR" , 46 : "CLOSE_SEXPR" , 50 : "ID" , 51 : "EQUALS" , 52 : "DATA" , 54 : "SEP" } ,
productions _ : [ 0 , [ 3 , 2 ] , [ 4 , 1 ] , [ 7 , 1 ] , [ 7 , 1 ] , [ 7 , 1 ] , [ 7 , 1 ] , [ 7 , 1 ] , [ 7 , 1 ] , [ 10 , 3 ] , [ 14 , 3 ] , [ 9 , 4 ] , [ 9 , 4 ] , [ 19 , 3 ] , [ 22 , 3 ] , [ 27 , 2 ] , [ 21 , 3 ] , [ 8 , 3 ] , [ 8 , 3 ] , [ 11 , 5 ] , [ 11 , 4 ] , [ 17 , 3 ] , [ 17 , 1 ] , [ 36 , 1 ] , [ 36 , 1 ] , [ 36 , 1 ] , [ 36 , 1 ] , [ 36 , 1 ] , [ 36 , 3 ] , [ 47 , 1 ] , [ 49 , 3 ] , [ 35 , 1 ] , [ 35 , 1 ] , [ 35 , 1 ] , [ 41 , 2 ] , [ 30 , 1 ] , [ 53 , 3 ] , [ 53 , 1 ] , [ 6 , 0 ] , [ 6 , 2 ] , [ 20 , 0 ] , [ 20 , 1 ] , [ 23 , 0 ] , [ 23 , 1 ] , [ 37 , 0 ] , [ 37 , 1 ] , [ 38 , 0 ] , [ 38 , 1 ] , [ 39 , 0 ] , [ 39 , 2 ] , [ 40 , 0 ] , [ 40 , 1 ] , [ 48 , 1 ] , [ 48 , 2 ] ] ,
2013-12-02 13:15:31 -05:00
performAction : function anonymous ( yytext , yyleng , yylineno , yy , yystate , $$ , _$ ) {
var $0 = $$ . length - 1 ;
switch ( yystate ) {
2014-12-10 11:34:00 -05:00
case 1 : yy . prepareProgram ( $$ [ $0 - 1 ] . statements , true ) ; return $$ [ $0 - 1 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 2 : this . $ = new yy . ProgramNode ( yy . prepareProgram ( $$ [ $0 ] ) , { } , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 3 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 4 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 5 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 6 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 7 : this . $ = new yy . ContentNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 8 : this . $ = new yy . CommentNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 9 : this . $ = new yy . RawBlockNode ( $$ [ $0 - 2 ] , $$ [ $0 - 1 ] , $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 10 : this . $ = new yy . MustacheNode ( $$ [ $0 - 1 ] , null , '' , '' , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 11 : this . $ = yy . prepareBlock ( $$ [ $0 - 3 ] , $$ [ $0 - 2 ] , $$ [ $0 - 1 ] , $$ [ $0 ] , false , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 12 : this . $ = yy . prepareBlock ( $$ [ $0 - 3 ] , $$ [ $0 - 2 ] , $$ [ $0 - 1 ] , $$ [ $0 ] , true , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 13 : this . $ = new yy . MustacheNode ( $$ [ $0 - 1 ] , null , $$ [ $0 - 2 ] , yy . stripFlags ( $$ [ $0 - 2 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 14 : this . $ = new yy . MustacheNode ( $$ [ $0 - 1 ] , null , $$ [ $0 - 2 ] , yy . stripFlags ( $$ [ $0 - 2 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 15 : this . $ = { strip : yy . stripFlags ( $$ [ $0 - 1 ] , $$ [ $0 - 1 ] ) , program : $$ [ $0 ] } ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 16 : this . $ = { path : $$ [ $0 - 1 ] , strip : yy . stripFlags ( $$ [ $0 - 2 ] , $$ [ $0 ] ) } ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 17 : this . $ = new yy . MustacheNode ( $$ [ $0 - 1 ] , null , $$ [ $0 - 2 ] , yy . stripFlags ( $$ [ $0 - 2 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 18 : this . $ = new yy . MustacheNode ( $$ [ $0 - 1 ] , null , $$ [ $0 - 2 ] , yy . stripFlags ( $$ [ $0 - 2 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 19 : this . $ = new yy . PartialNode ( $$ [ $0 - 3 ] , $$ [ $0 - 2 ] , $$ [ $0 - 1 ] , yy . stripFlags ( $$ [ $0 - 4 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 20 : this . $ = new yy . PartialNode ( $$ [ $0 - 2 ] , undefined , $$ [ $0 - 1 ] , yy . stripFlags ( $$ [ $0 - 3 ] , $$ [ $0 ] ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 21 : this . $ = new yy . SexprNode ( [ $$ [ $0 - 2 ] ] . concat ( $$ [ $0 - 1 ] ) , $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 22 : this . $ = new yy . SexprNode ( [ $$ [ $0 ] ] , null , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 23 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 24 : this . $ = new yy . StringNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 25 : this . $ = new yy . NumberNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 26 : this . $ = new yy . BooleanNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 27 : this . $ = $$ [ $0 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 28 : $$ [ $0 - 1 ] . isHelper = true ; this . $ = $$ [ $0 - 1 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 29 : this . $ = new yy . HashNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 30 : this . $ = [ $$ [ $0 - 2 ] , $$ [ $0 ] ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 31 : this . $ = new yy . PartialNameNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 32 : this . $ = new yy . PartialNameNode ( new yy . StringNode ( $$ [ $0 ] , this . _$ ) , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 33 : this . $ = new yy . PartialNameNode ( new yy . NumberNode ( $$ [ $0 ] , this . _$ ) ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 34 : this . $ = new yy . DataNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 35 : this . $ = new yy . IdNode ( $$ [ $0 ] , this . _$ ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 36 : $$ [ $0 - 2 ] . push ( { part : $$ [ $0 ] , separator : $$ [ $0 - 1 ] } ) ; this . $ = $$ [ $0 - 2 ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 37 : this . $ = [ { part : $$ [ $0 ] } ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 38 : this . $ = [ ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 39 : $$ [ $0 - 1 ] . push ( $$ [ $0 ] ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 48 : this . $ = [ ] ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 49 : $$ [ $0 - 1 ] . push ( $$ [ $0 ] ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 52 : this . $ = [ $$ [ $0 ] ] ;
2014-04-15 11:22:15 -04:00
break ;
2014-12-10 11:34:00 -05:00
case 53 : $$ [ $0 - 1 ] . push ( $$ [ $0 ] ) ;
2013-12-02 13:15:31 -05:00
break ;
}
2013-06-06 17:50:49 -04:00
} ,
2014-12-10 11:34:00 -05:00
table : [ { 3 : 1 , 4 : 2 , 5 : [ 2 , 38 ] , 6 : 3 , 12 : [ 2 , 38 ] , 13 : [ 2 , 38 ] , 16 : [ 2 , 38 ] , 24 : [ 2 , 38 ] , 26 : [ 2 , 38 ] , 31 : [ 2 , 38 ] , 32 : [ 2 , 38 ] , 34 : [ 2 , 38 ] } , { 1 : [ 3 ] } , { 5 : [ 1 , 4 ] } , { 5 : [ 2 , 2 ] , 7 : 5 , 8 : 6 , 9 : 7 , 10 : 8 , 11 : 9 , 12 : [ 1 , 10 ] , 13 : [ 1 , 11 ] , 14 : 16 , 16 : [ 1 , 20 ] , 19 : 14 , 22 : 15 , 24 : [ 1 , 18 ] , 26 : [ 1 , 19 ] , 28 : [ 2 , 2 ] , 29 : [ 2 , 2 ] , 31 : [ 1 , 12 ] , 32 : [ 1 , 13 ] , 34 : [ 1 , 17 ] } , { 1 : [ 2 , 1 ] } , { 5 : [ 2 , 39 ] , 12 : [ 2 , 39 ] , 13 : [ 2 , 39 ] , 16 : [ 2 , 39 ] , 24 : [ 2 , 39 ] , 26 : [ 2 , 39 ] , 28 : [ 2 , 39 ] , 29 : [ 2 , 39 ] , 31 : [ 2 , 39 ] , 32 : [ 2 , 39 ] , 34 : [ 2 , 39 ] } , { 5 : [ 2 , 3 ] , 12 : [ 2 , 3 ] , 13 : [ 2 , 3 ] , 16 : [ 2 , 3 ] , 24 : [ 2 , 3 ] , 26 : [ 2 , 3 ] , 28 : [ 2 , 3 ] , 29 : [ 2 , 3 ] , 31 : [ 2 , 3 ] , 32 : [ 2 , 3 ] , 34 : [ 2 , 3 ] } , { 5 : [ 2 , 4 ] , 12 : [ 2 , 4 ] , 13 : [ 2 , 4 ] , 16 : [ 2 , 4 ] , 24 : [ 2 , 4 ] , 26 : [ 2 , 4 ] , 28 : [ 2 , 4 ] , 29 : [ 2 , 4 ] , 31 : [ 2 , 4 ] , 32 : [ 2 , 4 ] , 34 : [ 2 , 4 ] } , { 5 : [ 2 , 5 ] , 12 : [ 2 , 5 ] , 13 : [ 2 , 5 ] , 16 : [ 2 , 5 ] , 24 : [ 2 , 5 ] , 26 : [ 2 , 5 ] , 28 : [ 2 , 5 ] , 29 : [ 2 , 5 ] , 31 : [ 2 , 5 ] , 32 : [ 2 , 5 ] , 34 : [ 2 , 5 ] } , { 5 : [ 2 , 6 ] , 12 : [ 2 , 6 ] , 13 : [ 2 , 6 ] , 16 : [ 2 , 6 ] , 24 : [ 2 , 6 ] , 26 : [ 2 , 6 ] , 28 : [ 2 , 6 ] , 29 : [ 2 , 6 ] , 31 : [ 2 , 6 ] , 32 : [ 2 , 6 ] , 34 : [ 2 , 6 ] } , { 5 : [ 2 , 7 ] , 12 : [ 2 , 7 ] , 13 : [ 2 , 7 ] , 16 : [ 2 , 7 ] , 24 : [ 2 , 7 ] , 26 : [ 2 , 7 ] , 28 : [ 2 , 7 ] , 29 : [ 2 , 7 ] , 31 : [ 2 , 7 ] , 32 : [ 2 , 7 ] , 34 : [ 2 , 7 ] } , { 5 : [ 2 , 8 ] , 12 : [ 2 , 8 ] , 13 : [ 2 , 8 ] , 16 : [ 2 , 8 ] , 24 : [ 2 , 8 ] , 26 : [ 2 , 8 ] , 28 : [ 2 , 8 ] , 29 : [ 2 , 8 ] , 31 : [ 2 , 8 ] , 32 : [ 2 , 8 ] , 34 : [ 2 , 8 ] } , { 17 : 21 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 17 : 27 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 4 : 28 , 6 : 3 , 12 : [ 2 , 38 ] , 13 : [ 2 , 38 ] , 16 : [ 2 , 38 ] , 24 : [ 2 , 38 ] , 26 : [ 2 , 38 ] , 28 : [ 2 , 38 ] , 29 : [ 2 , 38 ] , 31 : [ 2 , 38 ] , 32 : [ 2 , 38 ] , 34 : [ 2 , 38 ] } , { 4 : 29 , 6 : 3 , 12 : [ 2 , 38 ] , 13 : [ 2 , 38 ] , 16 : [ 2 , 38 ] , 24 : [ 2 , 38 ] , 26 : [ 2 , 38 ] , 28 : [ 2 , 38 ] , 29 : [ 2 , 38 ] , 31 : [ 2 , 38 ] , 32 : [ 2 , 38 ] , 34 : [ 2 , 38 ] } , { 12 : [ 1 , 30 ] } , { 30 : 32 , 35 : 31 , 42 : [ 1 , 33 ] , 43 : [ 1 , 34 ] , 50 : [ 1 , 26 ] , 53 : 24 } , { 17 : 35 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 17 : 36 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 17 : 37 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 25 : [ 1 , 38 ] } , { 18 : [ 2 , 48 ] , 25 : [ 2 , 48 ] , 33 : [ 2 , 48 ] , 39 : 39 , 42 : [ 2 , 48 ] , 43 : [ 2 , 48 ] , 44 : [ 2 , 48 ] , 45 : [ 2 , 48 ] , 46 : [ 2 , 48 ] , 50 : [ 2 , 48 ] , 52 : [ 2 , 48 ] } , { 18 : [ 2 , 22 ] , 25 : [ 2 , 22 ] , 33 : [ 2 , 22 ] , 46 : [ 2 , 22 ] } , { 18 : [ 2 , 35 ] , 25 : [ 2 , 35 ] , 33 : [ 2 , 35 ] , 42 : [ 2 , 35 ] , 43 : [ 2 , 35 ] , 44 : [ 2 , 35 ] , 45 : [ 2 , 35 ] , 46 : [ 2 , 35 ] , 50 : [ 2 , 35 ] , 52 : [ 2 , 35 ] , 54 : [ 1 , 40 ] } , { 30 : 41 , 50 : [ 1 , 26 ] , 53 : 24 } , { 18 : [ 2 , 37 ] , 25 : [ 2 , 37 ] , 33 : [ 2 , 37 ] , 42 : [ 2 , 37 ] , 43 : [ 2 , 37 ] , 44 : [ 2 , 37 ] , 45 : [ 2 , 37 ] , 46 : [ 2 , 37 ] , 50 : [ 2 , 37 ] , 52 : [ 2 , 37 ] , 54 : [ 2 , 37 ] } , { 33 : [ 1 , 42 ] } , { 20 : 43 , 27 : 44 , 28 : [ 1 , 45 ] , 29 : [ 2 , 40 ] } , { 23 : 46 , 27 : 47 , 28 : [ 1 , 45 ] , 29 : [ 2 , 42 ] } , { 15 : [ 1 , 48 ] } , { 25 : [ 2 , 46 ] , 30 : 51 , 36 : 49 , 38 : 50 , 41 : 55 , 42 : [ 1 , 52 ] , 43 : [ 1 , 53 ] , 44 : [ 1 , 54 ] , 45 : [ 1 , 56 ] , 47 : 57 , 48 : 58 , 49 : 60 , 50 : [ 1 , 59 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 25 : [ 2 , 31 ] , 42 : [ 2 , 31 ] , 43 : [ 2 , 31 ] , 44 : [ 2 , 31 ] , 45 : [ 2 , 31 ] , 50 : [ 2 , 31 ] , 52 : [ 2 , 31 ] } , { 25 : [ 2 , 32 ] , 42 : [ 2 , 32 ] , 43 : [ 2 , 32 ] , 44 : [ 2 , 32 ] , 45 : [ 2 , 32 ] , 50 : [ 2 , 32 ] , 52 : [ 2 , 32 ] } , { 25 : [ 2 , 33 ] , 42 : [ 2 , 33 ] , 43 : [ 2 , 33 ] , 44 : [ 2 , 33 ] , 45 : [ 2 , 33 ] , 50 : [ 2 , 33 ] , 52 : [ 2 , 33 ] } , { 25 : [ 1 , 61 ] } , { 25 : [ 1 , 62 ] } , { 18 : [ 1 , 63 ] } , { 5 : [ 2 , 17 ] , 12 : [ 2 , 17 ] , 13 : [ 2 , 17 ] , 16 : [ 2 , 17 ] , 24 : [ 2 , 17 ] , 26 : [ 2 , 17 ] , 28 : [ 2 , 17 ] , 29 : [ 2 , 17 ] , 31 : [ 2 , 17 ] , 32 : [ 2 , 17 ] , 34 : [ 2 , 17 ] } , { 18 : [ 2 , 50 ] , 25 : [ 2 , 50 ] , 30 : 51 , 33 : [ 2 , 50 ] , 36 : 65 , 40 : 64 , 41 : 55 , 42 : [ 1 , 52 ] , 43 : [ 1 , 53 ] , 44 : [ 1 , 54 ] , 45 : [ 1 , 56 ] , 46 : [ 2 , 50 ] , 47 : 66 , 48 : 58 , 49 : 60 , 50 : [ 1 , 59 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 50 : [ 1 , 67 ] } , { 18 : [ 2 , 34 ] , 25 : [ 2 , 34 ] , 33 : [ 2 , 34 ] , 42 : [ 2 , 34 ] , 43 : [ 2 , 34 ] , 44 : [ 2 , 34 ] , 45 : [ 2 , 34 ] , 46 : [ 2 , 34 ] , 50 : [ 2 , 34 ] , 52 : [ 2 , 34 ] } , { 5 : [ 2 , 18 ] , 12 : [ 2 , 18 ] , 13 : [ 2 , 18 ] , 16 : [ 2 , 18 ] , 24 : [ 2 , 18 ] , 26 : [ 2 , 18 ] , 28 : [ 2 , 18 ] , 29 : [ 2 , 18 ] , 31 : [ 2 , 18 ] , 32 : [ 2 , 18 ] , 34 : [ 2 , 18 ] } , { 21 : 68 , 29 : [ 1 , 69 ] } , { 29 : [ 2 , 41 ] } , { 4 : 70 , 6 : 3 , 12 : [ 2 , 38 ] , 13 : [ 2 , 38 ] , 16 : [ 2 , 38 ] , 24 : [ 2 , 38 ] , 26 : [ 2 , 38 ] , 29 : [ 2 , 38 ] , 31 : [ 2 , 38 ] , 32 : [ 2 , 38 ] , 34 : [ 2 , 38 ] } , { 21 : 71 , 29 : [ 1 , 69 ] } , { 29 : [ 2 , 43 ] } , { 5 : [ 2 , 9 ] , 12 : [ 2 , 9 ] , 13 : [ 2 , 9 ] , 16 : [ 2 , 9 ] , 24 : [ 2 , 9 ] , 26 : [ 2 , 9 ] , 28 : [ 2 , 9 ] , 29 : [ 2 , 9 ] , 31 : [ 2 , 9 ] , 32 : [ 2 , 9 ] , 34 : [ 2 , 9 ] } , { 25 : [ 2 , 44 ] , 37 : 72 , 47 : 73 , 48 : 58 , 49 : 60 , 50 : [ 1 , 74 ] } , { 25 : [ 1 , 75 ] } , { 18 : [ 2 , 23 ] , 25 : [ 2 , 23 ] , 33 : [ 2 , 23 ] , 42 : [ 2 , 23 ] , 43 : [ 2 , 23 ] , 44 : [ 2 , 23 ] , 45 : [ 2 , 23 ] , 46 : [ 2 , 23 ] , 50 : [ 2 , 23 ] , 52 : [ 2 , 23 ] } , { 18 : [ 2 , 24 ] , 25 : [ 2 , 24 ] , 33 : [ 2 , 24 ] , 42 : [ 2 , 24 ] , 43 : [ 2 , 24 ] , 44 : [ 2 , 24 ] , 45 : [ 2 , 24 ] , 46 : [ 2 , 24 ] , 50 : [ 2 , 24 ] , 52 : [ 2 , 24 ] } , { 18 : [ 2 , 25 ] , 25 : [ 2 , 25 ] , 33 : [ 2 , 25 ] , 42 : [ 2 , 25 ] , 43 : [ 2 , 25 ] , 44 : [ 2 , 25 ] , 45 : [ 2 , 25 ] , 46 : [ 2 , 25 ] , 50 : [ 2 , 25 ] , 52 : [ 2 , 25 ] } , { 18 : [ 2 , 26 ] , 25 : [ 2 , 26 ] , 33 : [ 2 , 26 ] , 42 : [ 2 , 26 ] , 43 : [ 2 , 26 ] , 44 : [ 2 , 26 ] , 45 : [ 2 , 26 ] , 46 : [ 2 , 26 ] , 50 : [ 2 , 26 ] , 52 : [ 2 , 26 ] } , { 18 : [ 2 , 27 ] , 25 : [ 2 , 27 ] , 33 : [ 2 , 27 ] , 42 : [ 2 , 27 ] , 43 : [ 2 , 27 ] , 44 : [ 2 , 27 ] , 45 : [ 2 , 27 ] , 46 : [ 2 , 27 ] , 50 : [ 2 , 27 ] , 52 : [ 2 , 27 ] } , { 17 : 76 , 30 : 22 , 41 : 23 , 50 : [ 1 , 26 ] , 52 : [ 1 , 25 ] , 53 : 24 } , { 25 : [ 2 , 47 ] } , { 18 : [ 2 , 29 ] , 25 : [ 2 , 29 ] , 33 : [ 2 , 29 ] , 46 : [ 2 , 29 ] , 49 : 77 , 50 : [ 1 , 74 ] } , { 18 : [ 2 , 37 ] , 25 : [ 2 , 37 ] , 33 : [ 2 , 37 ] , 42 : [ 2 , 37 ] , 43 : [ 2 , 37 ] , 44 : [ 2 , 37 ] , 45 : [ 2 , 37 ] , 46 : [ 2 , 37 ] , 50 : [ 2 , 37 ] , 51 : [ 1 , 78 ] , 52 : [ 2 , 37 ] , 54 : [ 2 , 37 ] } , { 18 : [ 2 , 52 ] , 25 : [ 2 , 52 ] , 33 : [ 2 , 52 ] , 46 : [ 2 , 52 ] , 50 : [ 2 , 52 ] } , { 12 : [ 2 , 13 ] , 13 : [ 2 , 13 ] , 16 : [ 2 , 13 ] , 24 : [ 2 , 13 ] , 26 : [ 2 , 13 ] , 28 : [ 2 , 13 ] , 29 : [ 2 , 13 ] , 31 : [ 2 , 13 ] , 32 : [ 2 , 13 ] , 34 : [ 2 , 13 ] } ,
defaultActions : { 4 : [ 2 , 1 ] , 44 : [ 2 , 41 ] , 47 : [ 2 , 43 ] , 57 : [ 2 , 47 ] , 63 : [ 2 , 10 ] , 70 : [ 2 , 15 ] , 73 : [ 2 , 45 ] } ,
2013-12-02 13:15:31 -05:00
parseError : function parseError ( str , hash ) {
throw new Error ( str ) ;
} ,
parse : function parse ( input ) {
var self = this , stack = [ 0 ] , vstack = [ null ] , lstack = [ ] , table = this . table , yytext = "" , yylineno = 0 , yyleng = 0 , recovering = 0 , TERROR = 2 , EOF = 1 ;
this . lexer . setInput ( input ) ;
this . lexer . yy = this . yy ;
this . yy . lexer = this . lexer ;
this . yy . parser = this ;
if ( typeof this . lexer . yylloc == "undefined" )
this . lexer . yylloc = { } ;
var yyloc = this . lexer . yylloc ;
lstack . push ( yyloc ) ;
var ranges = this . lexer . options && this . lexer . options . ranges ;
if ( typeof this . yy . parseError === "function" )
this . parseError = this . yy . parseError ;
function popStack ( n ) {
stack . length = stack . length - 2 * n ;
vstack . length = vstack . length - n ;
lstack . length = lstack . length - n ;
}
function lex ( ) {
var token ;
token = self . lexer . lex ( ) || 1 ;
if ( typeof token !== "number" ) {
token = self . symbols _ [ token ] || token ;
}
return token ;
}
var symbol , preErrorSymbol , state , action , a , r , yyval = { } , p , len , newState , expected ;
while ( true ) {
state = stack [ stack . length - 1 ] ;
if ( this . defaultActions [ state ] ) {
action = this . defaultActions [ state ] ;
} else {
if ( symbol === null || typeof symbol == "undefined" ) {
symbol = lex ( ) ;
}
action = table [ state ] && table [ state ] [ symbol ] ;
}
if ( typeof action === "undefined" || ! action . length || ! action [ 0 ] ) {
var errStr = "" ;
if ( ! recovering ) {
expected = [ ] ;
for ( p in table [ state ] )
if ( this . terminals _ [ p ] && p > 2 ) {
expected . push ( "'" + this . terminals _ [ p ] + "'" ) ;
}
if ( this . lexer . showPosition ) {
errStr = "Parse error on line " + ( yylineno + 1 ) + ":\n" + this . lexer . showPosition ( ) + "\nExpecting " + expected . join ( ", " ) + ", got '" + ( this . terminals _ [ symbol ] || symbol ) + "'" ;
} else {
errStr = "Parse error on line " + ( yylineno + 1 ) + ": Unexpected " + ( symbol == 1 ? "end of input" : "'" + ( this . terminals _ [ symbol ] || symbol ) + "'" ) ;
}
this . parseError ( errStr , { text : this . lexer . match , token : this . terminals _ [ symbol ] || symbol , line : this . lexer . yylineno , loc : yyloc , expected : expected } ) ;
}
}
if ( action [ 0 ] instanceof Array && action . length > 1 ) {
throw new Error ( "Parse Error: multiple actions possible at state: " + state + ", token: " + symbol ) ;
}
switch ( action [ 0 ] ) {
case 1 :
stack . push ( symbol ) ;
vstack . push ( this . lexer . yytext ) ;
lstack . push ( this . lexer . yylloc ) ;
stack . push ( action [ 1 ] ) ;
symbol = null ;
if ( ! preErrorSymbol ) {
yyleng = this . lexer . yyleng ;
yytext = this . lexer . yytext ;
yylineno = this . lexer . yylineno ;
yyloc = this . lexer . yylloc ;
if ( recovering > 0 )
recovering -- ;
} else {
symbol = preErrorSymbol ;
preErrorSymbol = null ;
}
break ;
case 2 :
len = this . productions _ [ action [ 1 ] ] [ 1 ] ;
yyval . $ = vstack [ vstack . length - len ] ;
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 } ;
if ( ranges ) {
yyval . _$ . range = [ lstack [ lstack . length - ( len || 1 ) ] . range [ 0 ] , lstack [ lstack . length - 1 ] . range [ 1 ] ] ;
}
r = this . performAction . call ( yyval , yytext , yyleng , yylineno , this . yy , action [ 1 ] , vstack , lstack ) ;
if ( typeof r !== "undefined" ) {
return r ;
}
if ( len ) {
stack = stack . slice ( 0 , - 1 * len * 2 ) ;
vstack = vstack . slice ( 0 , - 1 * len ) ;
lstack = lstack . slice ( 0 , - 1 * len ) ;
}
stack . push ( this . productions _ [ action [ 1 ] ] [ 0 ] ) ;
vstack . push ( yyval . $ ) ;
lstack . push ( yyval . _$ ) ;
newState = table [ stack [ stack . length - 2 ] ] [ stack [ stack . length - 1 ] ] ;
stack . push ( newState ) ;
break ;
case 3 :
return true ;
}
}
return true ;
}
} ;
/* Jison generated lexer */
var lexer = ( function ( ) {
var lexer = ( { EOF : 1 ,
parseError : function parseError ( str , hash ) {
if ( this . yy . parser ) {
this . yy . parser . parseError ( str , hash ) ;
} else {
throw new Error ( str ) ;
}
} ,
setInput : function ( input ) {
this . _input = input ;
this . _more = this . _less = this . done = false ;
this . yylineno = this . yyleng = 0 ;
this . yytext = this . matched = this . match = '' ;
this . conditionStack = [ 'INITIAL' ] ;
this . yylloc = { first _line : 1 , first _column : 0 , last _line : 1 , last _column : 0 } ;
if ( this . options . ranges ) this . yylloc . range = [ 0 , 0 ] ;
this . offset = 0 ;
return this ;
} ,
input : function ( ) {
var ch = this . _input [ 0 ] ;
this . yytext += ch ;
this . yyleng ++ ;
this . offset ++ ;
this . match += ch ;
this . matched += ch ;
var lines = ch . match ( /(?:\r\n?|\n).*/g ) ;
if ( lines ) {
this . yylineno ++ ;
this . yylloc . last _line ++ ;
} else {
this . yylloc . last _column ++ ;
}
if ( this . options . ranges ) this . yylloc . range [ 1 ] ++ ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
this . _input = this . _input . slice ( 1 ) ;
return ch ;
} ,
unput : function ( ch ) {
var len = ch . length ;
var lines = ch . split ( /(?:\r\n?|\n)/g ) ;
this . _input = ch + this . _input ;
this . yytext = this . yytext . substr ( 0 , this . yytext . length - len - 1 ) ;
//this.yyleng -= len;
this . offset -= len ;
var oldLines = this . match . split ( /(?:\r\n?|\n)/g ) ;
this . match = this . match . substr ( 0 , this . match . length - 1 ) ;
this . matched = this . matched . substr ( 0 , this . matched . length - 1 ) ;
if ( lines . length - 1 ) this . yylineno -= lines . length - 1 ;
var r = this . yylloc . range ;
this . yylloc = { first _line : this . yylloc . first _line ,
last _line : this . yylineno + 1 ,
first _column : this . yylloc . first _column ,
last _column : lines ?
( lines . length === oldLines . length ? this . yylloc . first _column : 0 ) + oldLines [ oldLines . length - lines . length ] . length - lines [ 0 ] . length :
this . yylloc . first _column - len
} ;
if ( this . options . ranges ) {
this . yylloc . range = [ r [ 0 ] , r [ 0 ] + this . yyleng - len ] ;
}
return this ;
} ,
more : function ( ) {
this . _more = true ;
return this ;
} ,
less : function ( n ) {
this . unput ( this . match . slice ( n ) ) ;
} ,
pastInput : function ( ) {
var past = this . matched . substr ( 0 , this . matched . length - this . match . length ) ;
return ( past . length > 20 ? '...' : '' ) + past . substr ( - 20 ) . replace ( /\n/g , "" ) ;
} ,
upcomingInput : function ( ) {
var next = this . match ;
if ( next . length < 20 ) {
next += this . _input . substr ( 0 , 20 - next . length ) ;
}
return ( next . substr ( 0 , 20 ) + ( next . length > 20 ? '...' : '' ) ) . replace ( /\n/g , "" ) ;
} ,
showPosition : function ( ) {
var pre = this . pastInput ( ) ;
var c = new Array ( pre . length + 1 ) . join ( "-" ) ;
return pre + this . upcomingInput ( ) + "\n" + c + "^" ;
} ,
next : function ( ) {
if ( this . done ) {
return this . EOF ;
}
if ( ! this . _input ) this . done = true ;
var token ,
match ,
tempMatch ,
index ,
col ,
lines ;
if ( ! this . _more ) {
this . yytext = '' ;
this . match = '' ;
}
var rules = this . _currentRules ( ) ;
for ( var i = 0 ; i < rules . length ; i ++ ) {
tempMatch = this . _input . match ( this . rules [ rules [ i ] ] ) ;
if ( tempMatch && ( ! match || tempMatch [ 0 ] . length > match [ 0 ] . length ) ) {
match = tempMatch ;
index = i ;
if ( ! this . options . flex ) break ;
}
}
if ( match ) {
lines = match [ 0 ] . match ( /(?:\r\n?|\n).*/g ) ;
if ( lines ) this . yylineno += lines . length ;
this . yylloc = { first _line : this . yylloc . last _line ,
last _line : this . yylineno + 1 ,
first _column : this . yylloc . last _column ,
last _column : lines ? lines [ lines . length - 1 ] . length - lines [ lines . length - 1 ] . match ( /\r?\n?/ ) [ 0 ] . length : this . yylloc . last _column + match [ 0 ] . length } ;
this . yytext += match [ 0 ] ;
this . match += match [ 0 ] ;
this . matches = match ;
this . yyleng = this . yytext . length ;
if ( this . options . ranges ) {
this . yylloc . range = [ this . offset , this . offset += this . yyleng ] ;
}
this . _more = false ;
this . _input = this . _input . slice ( match [ 0 ] . length ) ;
this . matched += match [ 0 ] ;
token = this . performAction . call ( this , this . yy , this , rules [ index ] , this . conditionStack [ this . conditionStack . length - 1 ] ) ;
if ( this . done && this . _input ) this . done = false ;
if ( token ) return token ;
else return ;
}
if ( this . _input === "" ) {
return this . EOF ;
} else {
return this . parseError ( 'Lexical error on line ' + ( this . yylineno + 1 ) + '. Unrecognized text.\n' + this . showPosition ( ) ,
{ text : "" , token : null , line : this . yylineno } ) ;
}
} ,
lex : function lex ( ) {
var r = this . next ( ) ;
if ( typeof r !== 'undefined' ) {
return r ;
} else {
return this . lex ( ) ;
}
} ,
begin : function begin ( condition ) {
this . conditionStack . push ( condition ) ;
} ,
popState : function popState ( ) {
return this . conditionStack . pop ( ) ;
} ,
_currentRules : function _currentRules ( ) {
return this . conditions [ this . conditionStack [ this . conditionStack . length - 1 ] ] . rules ;
} ,
topState : function ( ) {
return this . conditionStack [ this . conditionStack . length - 2 ] ;
} ,
pushState : function begin ( condition ) {
this . begin ( condition ) ;
} } ) ;
lexer . options = { } ;
lexer . performAction = function anonymous ( yy , yy _ , $avoiding _name _collisions , YY _START ) {
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
function strip ( start , end ) {
return yy _ . yytext = yy _ . yytext . substr ( start , yy _ . yyleng - end ) ;
}
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
var YYSTATE = YY _START
switch ( $avoiding _name _collisions ) {
case 0 :
if ( yy _ . yytext . slice ( - 2 ) === "\\\\" ) {
strip ( 0 , 1 ) ;
this . begin ( "mu" ) ;
} else if ( yy _ . yytext . slice ( - 1 ) === "\\" ) {
strip ( 0 , 1 ) ;
this . begin ( "emu" ) ;
} else {
this . begin ( "mu" ) ;
}
2014-12-10 11:34:00 -05:00
if ( yy _ . yytext ) return 12 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 1 : return 12 ;
2013-12-02 13:15:31 -05:00
break ;
case 2 :
2014-04-15 11:22:15 -04:00
this . popState ( ) ;
2014-12-10 11:34:00 -05:00
return 12 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 3 :
yy _ . yytext = yy _ . yytext . substr ( 5 , yy _ . yyleng - 9 ) ;
this . popState ( ) ;
return 15 ;
break ;
case 4 : return 12 ;
break ;
case 5 : strip ( 0 , 4 ) ; this . popState ( ) ; return 13 ;
break ;
case 6 : return 45 ;
break ;
case 7 : return 46 ;
break ;
case 8 : return 16 ;
break ;
case 9 :
this . popState ( ) ;
this . begin ( 'raw' ) ;
return 18 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 10 : return 34 ;
2014-04-15 11:22:15 -04:00
break ;
2014-12-10 11:34:00 -05:00
case 11 : return 24 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 12 : return 29 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 13 : this . popState ( ) ; return 28 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 14 : this . popState ( ) ; return 28 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 15 : return 26 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 16 : return 26 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 17 : return 32 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 18 : return 31 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 19 : this . popState ( ) ; this . begin ( 'com' ) ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 20 : strip ( 3 , 5 ) ; this . popState ( ) ; return 13 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 21 : return 31 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 22 : return 51 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 23 : return 50 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 24 : return 50 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 25 : return 54 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 26 : // ignore whitespace
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 27 : this . popState ( ) ; return 33 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 28 : this . popState ( ) ; return 25 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 29 : yy _ . yytext = strip ( 1 , 2 ) . replace ( /\\"/g , '"' ) ; return 42 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 30 : yy _ . yytext = strip ( 1 , 2 ) . replace ( /\\'/g , "'" ) ; return 42 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 31 : return 52 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 32 : return 44 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 33 : return 44 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 34 : return 43 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 35 : return 50 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 36 : yy _ . yytext = strip ( 1 , 2 ) ; return 50 ;
2013-12-02 13:15:31 -05:00
break ;
2014-12-10 11:34:00 -05:00
case 37 : return 'INVALID' ;
2014-04-15 11:22:15 -04:00
break ;
2014-12-10 11:34:00 -05:00
case 38 : return 5 ;
2013-12-02 13:15:31 -05:00
break ;
}
} ;
2014-12-10 11:34:00 -05:00
lexer . rules = [ /^(?:[^\x00]*?(?=(\{\{)))/ , /^(?:[^\x00]+)/ , /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/ , /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/ , /^(?:[^\x00]*?(?=(\{\{\{\{\/)))/ , /^(?:[\s\S]*?--\}\})/ , /^(?:\()/ , /^(?:\))/ , /^(?:\{\{\{\{)/ , /^(?:\}\}\}\})/ , /^(?:\{\{(~)?>)/ , /^(?:\{\{(~)?#)/ , /^(?:\{\{(~)?\/)/ , /^(?:\{\{(~)?\^\s*(~)?\}\})/ , /^(?:\{\{(~)?\s*else\s*(~)?\}\})/ , /^(?:\{\{(~)?\^)/ , /^(?:\{\{(~)?\s*else\b)/ , /^(?:\{\{(~)?\{)/ , /^(?:\{\{(~)?&)/ , /^(?:\{\{!--)/ , /^(?:\{\{![\s\S]*?\}\})/ , /^(?:\{\{(~)?)/ , /^(?:=)/ , /^(?:\.\.)/ , /^(?:\.(?=([=~}\s\/.)])))/ , /^(?:[\/.])/ , /^(?:\s+)/ , /^(?:\}(~)?\}\})/ , /^(?:(~)?\}\})/ , /^(?:"(\\["]|[^"])*")/ , /^(?:'(\\[']|[^'])*')/ , /^(?:@)/ , /^(?:true(?=([~}\s)])))/ , /^(?:false(?=([~}\s)])))/ , /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/ , /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/ , /^(?:\[[^\]]*\])/ , /^(?:.)/ , /^(?:$)/ ] ;
lexer . conditions = { "mu" : { "rules" : [ 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 , 32 , 33 , 34 , 35 , 36 , 37 , 38 ] , "inclusive" : false } , "emu" : { "rules" : [ 2 ] , "inclusive" : false } , "com" : { "rules" : [ 5 ] , "inclusive" : false } , "raw" : { "rules" : [ 3 , 4 ] , "inclusive" : false } , "INITIAL" : { "rules" : [ 0 , 1 , 38 ] , "inclusive" : true } } ;
2013-12-02 13:15:31 -05:00
return lexer ; } ) ( )
parser . lexer = lexer ;
function Parser ( ) { this . yy = { } ; } Parser . prototype = parser ; parser . Parser = Parser ;
return new Parser ;
} ) ( ) ; _ _exports _ _ = handlebars ;
2014-04-15 11:22:15 -04:00
/* jshint ignore:end */
2013-12-02 13:15:31 -05:00
return _ _exports _ _ ;
} ) ( ) ;
2014-12-10 11:34:00 -05:00
// handlebars/compiler/helpers.js
var _ _module10 _ _ = ( function ( _ _dependency1 _ _ ) {
"use strict" ;
var _ _exports _ _ = { } ;
var Exception = _ _dependency1 _ _ ;
function stripFlags ( open , close ) {
return {
left : open . charAt ( 2 ) === '~' ,
right : close . charAt ( close . length - 3 ) === '~'
} ;
}
_ _exports _ _ . stripFlags = stripFlags ;
function prepareBlock ( mustache , program , inverseAndProgram , close , inverted , locInfo ) {
/*jshint -W040 */
if ( mustache . sexpr . id . original !== close . path . original ) {
throw new Exception ( mustache . sexpr . id . original + ' doesn\'t match ' + close . path . original , mustache ) ;
}
var inverse = inverseAndProgram && inverseAndProgram . program ;
var strip = {
left : mustache . strip . left ,
right : close . strip . right ,
// Determine the standalone candiacy. Basically flag our content as being possibly standalone
// so our parent can determine if we actually are standalone
openStandalone : isNextWhitespace ( program . statements ) ,
closeStandalone : isPrevWhitespace ( ( inverse || program ) . statements )
} ;
if ( mustache . strip . right ) {
omitRight ( program . statements , null , true ) ;
}
if ( inverse ) {
var inverseStrip = inverseAndProgram . strip ;
if ( inverseStrip . left ) {
omitLeft ( program . statements , null , true ) ;
}
if ( inverseStrip . right ) {
omitRight ( inverse . statements , null , true ) ;
}
if ( close . strip . left ) {
omitLeft ( inverse . statements , null , true ) ;
}
// Find standalone else statments
if ( isPrevWhitespace ( program . statements )
&& isNextWhitespace ( inverse . statements ) ) {
omitLeft ( program . statements ) ;
omitRight ( inverse . statements ) ;
}
} else {
if ( close . strip . left ) {
omitLeft ( program . statements , null , true ) ;
}
}
if ( inverted ) {
return new this . BlockNode ( mustache , inverse , program , strip , locInfo ) ;
} else {
return new this . BlockNode ( mustache , program , inverse , strip , locInfo ) ;
}
}
_ _exports _ _ . prepareBlock = prepareBlock ;
function prepareProgram ( statements , isRoot ) {
for ( var i = 0 , l = statements . length ; i < l ; i ++ ) {
var current = statements [ i ] ,
strip = current . strip ;
if ( ! strip ) {
continue ;
}
var _isPrevWhitespace = isPrevWhitespace ( statements , i , isRoot , current . type === 'partial' ) ,
_isNextWhitespace = isNextWhitespace ( statements , i , isRoot ) ,
openStandalone = strip . openStandalone && _isPrevWhitespace ,
closeStandalone = strip . closeStandalone && _isNextWhitespace ,
inlineStandalone = strip . inlineStandalone && _isPrevWhitespace && _isNextWhitespace ;
if ( strip . right ) {
omitRight ( statements , i , true ) ;
}
if ( strip . left ) {
omitLeft ( statements , i , true ) ;
}
if ( inlineStandalone ) {
omitRight ( statements , i ) ;
if ( omitLeft ( statements , i ) ) {
// If we are on a standalone node, save the indent info for partials
if ( current . type === 'partial' ) {
current . indent = ( /([ \t]+$)/ ) . exec ( statements [ i - 1 ] . original ) ? RegExp . $1 : '' ;
}
}
}
if ( openStandalone ) {
omitRight ( ( current . program || current . inverse ) . statements ) ;
// Strip out the previous content node if it's whitespace only
omitLeft ( statements , i ) ;
}
if ( closeStandalone ) {
// Always strip the next node
omitRight ( statements , i ) ;
omitLeft ( ( current . inverse || current . program ) . statements ) ;
}
}
return statements ;
}
_ _exports _ _ . prepareProgram = prepareProgram ; function isPrevWhitespace ( statements , i , isRoot ) {
if ( i === undefined ) {
i = statements . length ;
}
// Nodes that end with newlines are considered whitespace (but are special
// cased for strip operations)
var prev = statements [ i - 1 ] ,
sibling = statements [ i - 2 ] ;
if ( ! prev ) {
return isRoot ;
}
if ( prev . type === 'content' ) {
return ( sibling || ! isRoot ? ( /\r?\n\s*?$/ ) : ( /(^|\r?\n)\s*?$/ ) ) . test ( prev . original ) ;
}
}
function isNextWhitespace ( statements , i , isRoot ) {
if ( i === undefined ) {
i = - 1 ;
}
var next = statements [ i + 1 ] ,
sibling = statements [ i + 2 ] ;
if ( ! next ) {
return isRoot ;
}
if ( next . type === 'content' ) {
return ( sibling || ! isRoot ? ( /^\s*?\r?\n/ ) : ( /^\s*?(\r?\n|$)/ ) ) . test ( next . original ) ;
}
}
// Marks the node to the right of the position as omitted.
// I.e. {{foo}}' ' will mark the ' ' node as omitted.
//
// If i is undefined, then the first child will be marked as such.
//
// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitRight ( statements , i , multiple ) {
var current = statements [ i == null ? 0 : i + 1 ] ;
if ( ! current || current . type !== 'content' || ( ! multiple && current . rightStripped ) ) {
return ;
}
var original = current . string ;
current . string = current . string . replace ( multiple ? ( /^\s+/ ) : ( /^[ \t]*\r?\n?/ ) , '' ) ;
current . rightStripped = current . string !== original ;
}
// Marks the node to the left of the position as omitted.
// I.e. ' '{{foo}} will mark the ' ' node as omitted.
//
// If i is undefined then the last child will be marked as such.
//
// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitLeft ( statements , i , multiple ) {
var current = statements [ i == null ? statements . length - 1 : i - 1 ] ;
if ( ! current || current . type !== 'content' || ( ! multiple && current . leftStripped ) ) {
return ;
}
// We omit the last node if it's whitespace only and not preceeded by a non-content node.
var original = current . string ;
current . string = current . string . replace ( multiple ? ( /\s+$/ ) : ( /[ \t]+$/ ) , '' ) ;
current . leftStripped = current . string !== original ;
return current . leftStripped ;
}
return _ _exports _ _ ;
} ) ( _ _module5 _ _ ) ;
2013-12-02 13:15:31 -05:00
// handlebars/compiler/base.js
2014-12-10 11:34:00 -05:00
var _ _module8 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ , _ _dependency3 _ _ , _ _dependency4 _ _ ) {
2013-12-02 13:15:31 -05:00
"use strict" ;
var _ _exports _ _ = { } ;
var parser = _ _dependency1 _ _ ;
var AST = _ _dependency2 _ _ ;
2014-12-10 11:34:00 -05:00
var Helpers = _ _dependency3 _ _ ;
var extend = _ _dependency4 _ _ . extend ;
2013-12-02 13:15:31 -05:00
_ _exports _ _ . parser = parser ;
2014-12-10 11:34:00 -05:00
var yy = { } ;
extend ( yy , Helpers , AST ) ;
2013-12-02 13:15:31 -05:00
function parse ( input ) {
// Just return if an already-compile AST was passed in.
2014-12-10 11:34:00 -05:00
if ( input . constructor === AST . ProgramNode ) { return input ; }
parser . yy = yy ;
2013-12-02 13:15:31 -05:00
return parser . parse ( input ) ;
}
_ _exports _ _ . parse = parse ;
return _ _exports _ _ ;
2014-12-10 11:34:00 -05:00
} ) ( _ _module9 _ _ , _ _module7 _ _ , _ _module10 _ _ , _ _module3 _ _ ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// handlebars/compiler/compiler.js
2014-12-10 11:34:00 -05:00
var _ _module11 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ ) {
2013-12-02 13:15:31 -05:00
"use strict" ;
2014-04-15 11:22:15 -04:00
var _ _exports _ _ = { } ;
var Exception = _ _dependency1 _ _ ;
2014-12-10 11:34:00 -05:00
var isArray = _ _dependency2 _ _ . isArray ;
var slice = [ ] . slice ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
function Compiler ( ) { }
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
_ _exports _ _ . Compiler = Compiler ; // 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.
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
Compiler . prototype = {
compiler : Compiler ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
equals : function ( other ) {
var len = this . opcodes . length ;
if ( other . opcodes . length !== len ) {
return false ;
2013-06-06 17:50:49 -04:00
}
2014-04-15 11:22:15 -04:00
for ( var i = 0 ; i < len ; i ++ ) {
var opcode = this . opcodes [ i ] ,
otherOpcode = other . opcodes [ i ] ;
2014-12-10 11:34:00 -05:00
if ( opcode . opcode !== otherOpcode . opcode || ! argEquals ( opcode . args , otherOpcode . args ) ) {
2014-04-15 11:22:15 -04:00
return false ;
}
2013-12-02 13:15:31 -05:00
}
2014-12-10 11:34:00 -05:00
// We know that length is the same between the two arrays because they are directly tied
// to the opcode behavior above.
2014-04-15 11:22:15 -04:00
len = this . children . length ;
for ( i = 0 ; i < len ; i ++ ) {
if ( ! this . children [ i ] . equals ( other . children [ i ] ) ) {
return false ;
}
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
return true ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
guid : 0 ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
compile : function ( program , options ) {
this . opcodes = [ ] ;
this . children = [ ] ;
this . depths = { list : [ ] } ;
this . options = options ;
2014-12-10 11:34:00 -05:00
this . stringParams = options . stringParams ;
this . trackIds = options . trackIds ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// These changes will propagate to the other compiler components
var knownHelpers = this . options . knownHelpers ;
this . options . knownHelpers = {
'helperMissing' : true ,
'blockHelperMissing' : true ,
'each' : true ,
'if' : true ,
'unless' : true ,
'with' : true ,
2014-12-10 11:34:00 -05:00
'log' : true ,
'lookup' : true
2013-12-02 13:15:31 -05:00
} ;
2014-04-15 11:22:15 -04:00
if ( knownHelpers ) {
for ( var name in knownHelpers ) {
this . options . knownHelpers [ name ] = knownHelpers [ name ] ;
}
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
return this . accept ( program ) ;
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
accept : function ( node ) {
2014-12-10 11:34:00 -05:00
return this [ node . type ] ( node ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
program : function ( program ) {
var statements = program . statements ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
for ( var i = 0 , l = statements . length ; i < l ; i ++ ) {
this . accept ( statements [ i ] ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
this . isSimple = l === 1 ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
this . depths . list = this . depths . list . sort ( function ( a , b ) {
return a - b ;
} ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
return this ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
compileProgram : function ( program ) {
var result = new this . compiler ( ) . compile ( program , this . options ) ;
var guid = this . guid ++ , depth ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
this . usePartial = this . usePartial || result . usePartial ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . children [ guid ] = result ;
for ( var i = 0 , l = result . depths . list . length ; i < l ; i ++ ) {
depth = result . depths . list [ i ] ;
if ( depth < 2 ) { continue ; }
else { this . addDepth ( depth - 1 ) ; }
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
return guid ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
block : function ( block ) {
var mustache = block . mustache ,
program = block . program ,
inverse = block . inverse ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( program ) {
program = this . compileProgram ( program ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( inverse ) {
inverse = this . compileProgram ( inverse ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var sexpr = mustache . sexpr ;
var type = this . classifySexpr ( sexpr ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( type === "helper" ) {
this . helperSexpr ( sexpr , program , inverse ) ;
} else if ( type === "simple" ) {
this . simpleSexpr ( sexpr ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// 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' ) ;
2014-12-10 11:34:00 -05:00
this . opcode ( 'blockValue' , sexpr . id . original ) ;
2014-04-15 11:22:15 -04:00
} else {
this . ambiguousSexpr ( sexpr , 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' ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . opcode ( 'append' ) ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
hash : function ( hash ) {
2014-12-10 11:34:00 -05:00
var pairs = hash . pairs , i , l ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . opcode ( 'pushHash' ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
for ( i = 0 , l = pairs . length ; i < l ; i ++ ) {
this . pushParam ( pairs [ i ] [ 1 ] ) ;
}
while ( i -- ) {
this . opcode ( 'assignToHash' , pairs [ i ] [ 0 ] ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
this . opcode ( 'popHash' ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
partial : function ( partial ) {
var partialName = partial . partialName ;
this . usePartial = true ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( partial . hash ) {
this . accept ( partial . hash ) ;
2014-04-15 11:22:15 -04:00
} else {
2014-12-10 11:34:00 -05:00
this . opcode ( 'push' , 'undefined' ) ;
2014-04-15 11:22:15 -04:00
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( partial . context ) {
this . accept ( partial . context ) ;
} else {
this . opcode ( 'getContext' , 0 ) ;
this . opcode ( 'pushContext' ) ;
}
this . opcode ( 'invokePartial' , partialName . name , partial . indent || '' ) ;
2014-04-15 11:22:15 -04:00
this . opcode ( 'append' ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
content : function ( content ) {
2014-12-10 11:34:00 -05:00
if ( content . string ) {
this . opcode ( 'appendContent' , content . string ) ;
}
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
mustache : function ( mustache ) {
this . sexpr ( mustache . sexpr ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
if ( mustache . escaped && ! this . options . noEscape ) {
this . opcode ( 'appendEscaped' ) ;
} else {
this . opcode ( 'append' ) ;
}
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
ambiguousSexpr : function ( sexpr , program , inverse ) {
var id = sexpr . id ,
name = id . parts [ 0 ] ,
isBlock = program != null || inverse != null ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . opcode ( 'getContext' , id . depth ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . opcode ( 'pushProgram' , program ) ;
this . opcode ( 'pushProgram' , inverse ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
this . ID ( id ) ;
2014-04-15 11:22:15 -04:00
this . opcode ( 'invokeAmbiguous' , name , isBlock ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
simpleSexpr : function ( sexpr ) {
var id = sexpr . id ;
if ( id . type === 'DATA' ) {
this . DATA ( id ) ;
} else if ( id . parts . length ) {
this . ID ( id ) ;
} else {
// Simplified ID for `this`
this . addDepth ( id . depth ) ;
this . opcode ( 'getContext' , id . depth ) ;
this . opcode ( 'pushContext' ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
this . opcode ( 'resolvePossibleLambda' ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
helperSexpr : function ( sexpr , program , inverse ) {
var params = this . setupFullMustacheParams ( sexpr , program , inverse ) ,
2014-12-10 11:34:00 -05:00
id = sexpr . id ,
name = id . parts [ 0 ] ;
2014-04-15 11:22:15 -04:00
if ( this . options . knownHelpers [ name ] ) {
this . opcode ( 'invokeKnownHelper' , params . length , name ) ;
} else if ( this . options . knownHelpersOnly ) {
throw new Exception ( "You specified knownHelpersOnly, but used the unknown helper " + name , sexpr ) ;
} else {
2014-12-10 11:34:00 -05:00
id . falsy = true ;
this . ID ( id ) ;
this . opcode ( 'invokeHelper' , params . length , id . original , id . isSimple ) ;
2013-12-02 13:15:31 -05:00
}
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
sexpr : function ( sexpr ) {
var type = this . classifySexpr ( sexpr ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( type === "simple" ) {
this . simpleSexpr ( sexpr ) ;
} else if ( type === "helper" ) {
this . helperSexpr ( sexpr ) ;
} else {
this . ambiguousSexpr ( sexpr ) ;
}
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
ID : function ( id ) {
this . addDepth ( id . depth ) ;
this . opcode ( 'getContext' , id . depth ) ;
var name = id . parts [ 0 ] ;
if ( ! name ) {
2014-12-10 11:34:00 -05:00
// Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
2014-04-15 11:22:15 -04:00
this . opcode ( 'pushContext' ) ;
} else {
2014-12-10 11:34:00 -05:00
this . opcode ( 'lookupOnContext' , id . parts , id . falsy , id . isScoped ) ;
2014-04-15 11:22:15 -04:00
}
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
DATA : function ( data ) {
this . options . data = true ;
2014-12-10 11:34:00 -05:00
this . opcode ( 'lookupData' , data . id . depth , data . id . parts ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
STRING : function ( string ) {
this . opcode ( 'pushString' , string . string ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-12-10 11:34:00 -05:00
NUMBER : function ( number ) {
this . opcode ( 'pushLiteral' , number . number ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
BOOLEAN : function ( bool ) {
this . opcode ( 'pushLiteral' , bool . bool ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
comment : function ( ) { } ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// HELPERS
opcode : function ( name ) {
2014-12-10 11:34:00 -05:00
this . opcodes . push ( { opcode : name , args : slice . call ( arguments , 1 ) } ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
addDepth : function ( depth ) {
if ( depth === 0 ) { return ; }
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( ! this . depths [ depth ] ) {
this . depths [ depth ] = true ;
this . depths . list . push ( depth ) ;
2013-12-02 13:15:31 -05:00
}
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
classifySexpr : function ( sexpr ) {
var isHelper = sexpr . isHelper ;
var isEligible = sexpr . eligibleHelper ;
var options = this . options ;
// if ambiguous, we can possibly resolve the ambiguity now
2014-12-10 11:34:00 -05:00
// An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
2014-04-15 11:22:15 -04:00
if ( isEligible && ! isHelper ) {
var name = sexpr . id . parts [ 0 ] ;
if ( options . knownHelpers [ name ] ) {
isHelper = true ;
} else if ( options . knownHelpersOnly ) {
isEligible = false ;
}
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( isHelper ) { return "helper" ; }
else if ( isEligible ) { return "ambiguous" ; }
else { return "simple" ; }
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
pushParams : function ( params ) {
2014-12-10 11:34:00 -05:00
for ( var i = 0 , l = params . length ; i < l ; i ++ ) {
this . pushParam ( params [ i ] ) ;
}
} ,
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
pushParam : function ( val ) {
if ( this . stringParams ) {
if ( val . depth ) {
this . addDepth ( val . depth ) ;
}
this . opcode ( 'getContext' , val . depth || 0 ) ;
this . opcode ( 'pushStringParam' , val . stringModeValue , val . type ) ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
if ( val . type === 'sexpr' ) {
// Subexpressions get evaluated and passed in
// in string params mode.
this . sexpr ( val ) ;
}
} else {
if ( this . trackIds ) {
this . opcode ( 'pushId' , val . type , val . idName || val . stringModeValue ) ;
2014-04-15 11:22:15 -04:00
}
2014-12-10 11:34:00 -05:00
this . accept ( val ) ;
2013-12-02 13:15:31 -05:00
}
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
setupFullMustacheParams : function ( sexpr , program , inverse ) {
var params = sexpr . params ;
this . pushParams ( params ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
this . opcode ( 'pushProgram' , program ) ;
this . opcode ( 'pushProgram' , inverse ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
if ( sexpr . hash ) {
this . hash ( sexpr . hash ) ;
} else {
this . opcode ( 'emptyHash' ) ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
return params ;
}
} ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
function precompile ( input , options , env ) {
if ( input == null || ( typeof input !== 'string' && input . constructor !== env . AST . ProgramNode ) ) {
throw new Exception ( "You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input ) ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
options = options || { } ;
if ( ! ( 'data' in options ) ) {
options . data = true ;
}
2014-12-10 11:34:00 -05:00
if ( options . compat ) {
options . useDepths = true ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
var ast = env . parse ( input ) ;
var environment = new env . Compiler ( ) . compile ( ast , options ) ;
return new env . JavaScriptCompiler ( ) . compile ( environment , options ) ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
_ _exports _ _ . precompile = precompile ; function compile ( input , options , env ) {
if ( input == null || ( typeof input !== 'string' && input . constructor !== env . AST . ProgramNode ) ) {
throw new Exception ( "You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input ) ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
options = options || { } ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
if ( ! ( 'data' in options ) ) {
options . data = true ;
}
2014-12-10 11:34:00 -05:00
if ( options . compat ) {
options . useDepths = true ;
}
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
var compiled ;
function compileInput ( ) {
var ast = env . parse ( input ) ;
var environment = new env . Compiler ( ) . compile ( ast , options ) ;
var templateSpec = new env . JavaScriptCompiler ( ) . compile ( environment , options , undefined , true ) ;
return env . template ( templateSpec ) ;
}
// Template is only compiled on first use and cached after that point.
2014-12-10 11:34:00 -05:00
var ret = function ( context , options ) {
2014-04-15 11:22:15 -04:00
if ( ! compiled ) {
compiled = compileInput ( ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
return compiled . call ( this , context , options ) ;
} ;
2014-12-10 11:34:00 -05:00
ret . _setup = function ( options ) {
if ( ! compiled ) {
compiled = compileInput ( ) ;
}
return compiled . _setup ( options ) ;
} ;
ret . _child = function ( i , data , depths ) {
if ( ! compiled ) {
compiled = compileInput ( ) ;
}
return compiled . _child ( i , data , depths ) ;
} ;
return ret ;
2014-04-15 11:22:15 -04:00
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
_ _exports _ _ . compile = compile ; function argEquals ( a , b ) {
if ( a === b ) {
return true ;
}
if ( isArray ( a ) && isArray ( b ) && a . length === b . length ) {
for ( var i = 0 ; i < a . length ; i ++ ) {
if ( ! argEquals ( a [ i ] , b [ i ] ) ) {
return false ;
}
}
return true ;
}
}
2014-04-15 11:22:15 -04:00
return _ _exports _ _ ;
2014-12-10 11:34:00 -05:00
} ) ( _ _module5 _ _ , _ _module3 _ _ ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// handlebars/compiler/javascript-compiler.js
2014-12-10 11:34:00 -05:00
var _ _module12 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ ) {
2014-04-15 11:22:15 -04:00
"use strict" ;
var _ _exports _ _ ;
var COMPILER _REVISION = _ _dependency1 _ _ . COMPILER _REVISION ;
var REVISION _CHANGES = _ _dependency1 _ _ . REVISION _CHANGES ;
var Exception = _ _dependency2 _ _ ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
function Literal ( value ) {
this . value = value ;
}
function JavaScriptCompiler ( ) { }
JavaScriptCompiler . prototype = {
// PUBLIC API: You can override these methods in a subclass to provide
// alternative compiled forms for name lookup and buffering semantics
nameLookup : function ( parent , name /* , type*/ ) {
2014-12-10 11:34:00 -05:00
if ( JavaScriptCompiler . isValidJavaScriptVariableName ( name ) ) {
return parent + "." + name ;
2014-04-15 11:22:15 -04:00
} else {
2014-12-10 11:34:00 -05:00
return parent + "['" + name + "']" ;
2013-12-02 13:15:31 -05:00
}
} ,
2014-12-10 11:34:00 -05:00
depthedLookup : function ( name ) {
this . aliases . lookup = 'this.lookup' ;
return 'lookup(depths, "' + name + '")' ;
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
compilerInfo : function ( ) {
var revision = COMPILER _REVISION ,
versions = REVISION _CHANGES [ revision ] ;
2014-12-10 11:34:00 -05:00
return [ revision , versions ] ;
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
appendToBuffer : function ( string ) {
if ( this . environment . isSimple ) {
return "return " + string + ";" ;
} else {
return {
appendToBuffer : true ,
content : string ,
toString : function ( ) { return "buffer += " + string + ";" ; }
} ;
}
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
initializeBuffer : function ( ) {
return this . quotedString ( "" ) ;
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
namespace : "Handlebars" ,
// END PUBLIC API
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
compile : function ( environment , options , context , asObject ) {
this . environment = environment ;
2014-12-10 11:34:00 -05:00
this . options = options ;
this . stringParams = this . options . stringParams ;
this . trackIds = this . options . trackIds ;
this . precompile = ! asObject ;
2014-04-15 11:22:15 -04:00
this . name = this . environment . name ;
this . isChild = ! ! context ;
this . context = context || {
programs : [ ] ,
2014-12-10 11:34:00 -05:00
environments : [ ]
2014-04-15 11:22:15 -04:00
} ;
this . preamble ( ) ;
this . stackSlot = 0 ;
this . stackVars = [ ] ;
2014-12-10 11:34:00 -05:00
this . aliases = { } ;
2014-04-15 11:22:15 -04:00
this . registers = { list : [ ] } ;
this . hashes = [ ] ;
this . compileStack = [ ] ;
this . inlineStack = [ ] ;
this . compileChildren ( environment , options ) ;
2014-12-10 11:34:00 -05:00
this . useDepths = this . useDepths || environment . depths . list . length || this . options . compat ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
var opcodes = environment . opcodes ,
opcode ,
i ,
l ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
for ( i = 0 , l = opcodes . length ; i < l ; i ++ ) {
opcode = opcodes [ i ] ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
this [ opcode . opcode ] . apply ( this , opcode . args ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
// Flush any trailing content that might be pending.
this . pushSource ( '' ) ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2014-04-15 11:22:15 -04:00
if ( this . stackSlot || this . inlineStack . length || this . compileStack . length ) {
throw new Exception ( 'Compile completed with content left on stack' ) ;
2013-12-02 13:15:31 -05:00
}
2014-12-10 11:34:00 -05:00
var fn = this . createFunctionContext ( asObject ) ;
2014-04-15 11:22:15 -04:00
if ( ! this . isChild ) {
2014-12-10 11:34:00 -05:00
var ret = {
compiler : this . compilerInfo ( ) ,
main : fn
} ;
var programs = this . context . programs ;
for ( i = 0 , l = programs . length ; i < l ; i ++ ) {
if ( programs [ i ] ) {
ret [ i ] = programs [ i ] ;
}
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( this . environment . usePartial ) {
ret . usePartial = true ;
}
if ( this . options . data ) {
ret . useData = true ;
}
if ( this . useDepths ) {
ret . useDepths = true ;
}
if ( this . options . compat ) {
ret . compat = true ;
}
if ( ! asObject ) {
ret . compiler = JSON . stringify ( ret . compiler ) ;
ret = this . objectLiteral ( ret ) ;
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
return ret ;
2014-04-15 11:22:15 -04:00
} else {
2014-12-10 11:34:00 -05:00
return fn ;
2014-04-15 11:22:15 -04:00
}
2014-12-10 11:34:00 -05:00
} ,
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
preamble : function ( ) {
2014-04-15 11:22:15 -04:00
// track the last context pushed into place to allow skipping the
// getContext opcode when it would be a noop
this . lastContext = 0 ;
2014-12-10 11:34:00 -05:00
this . source = [ ] ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
createFunctionContext : function ( asObject ) {
2014-12-10 11:34:00 -05:00
var varDeclarations = '' ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
var locals = this . stackVars . concat ( this . registers . list ) ;
2014-04-15 11:22:15 -04:00
if ( locals . length > 0 ) {
2014-12-10 11:34:00 -05:00
varDeclarations += ", " + locals . join ( ", " ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
// Generate minimizer alias mappings
2014-12-10 11:34:00 -05:00
for ( var alias in this . aliases ) {
if ( this . aliases . hasOwnProperty ( alias ) ) {
varDeclarations += ', ' + alias + '=' + this . aliases [ alias ] ;
2014-04-15 11:22:15 -04:00
}
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
var params = [ "depth0" , "helpers" , "partials" , "data" ] ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( this . useDepths ) {
params . push ( 'depths' ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
// Perform a second pass over the output to merge content when possible
2014-12-10 11:34:00 -05:00
var source = this . mergeSource ( varDeclarations ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
if ( asObject ) {
params . push ( source ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
return Function . apply ( this , params ) ;
2013-12-02 13:15:31 -05:00
} else {
2014-12-10 11:34:00 -05:00
return 'function(' + params . join ( ',' ) + ') {\n ' + source + '}' ;
2013-12-02 13:15:31 -05:00
}
} ,
2014-12-10 11:34:00 -05:00
mergeSource : function ( varDeclarations ) {
2014-04-15 11:22:15 -04:00
var source = '' ,
2014-12-10 11:34:00 -05:00
buffer ,
appendOnly = ! this . forceBuffer ,
appendFirst ;
2014-04-15 11:22:15 -04:00
for ( var i = 0 , len = this . source . length ; i < len ; i ++ ) {
var line = this . source [ i ] ;
if ( line . appendToBuffer ) {
if ( buffer ) {
buffer = buffer + '\n + ' + line . content ;
2013-12-02 13:15:31 -05:00
} else {
2014-04-15 11:22:15 -04:00
buffer = line . content ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} else {
if ( buffer ) {
2014-12-10 11:34:00 -05:00
if ( ! source ) {
appendFirst = true ;
source = buffer + ';\n ' ;
} else {
source += 'buffer += ' + buffer + ';\n ' ;
}
2014-04-15 11:22:15 -04:00
buffer = undefined ;
}
source += line + '\n ' ;
2014-12-10 11:34:00 -05:00
if ( ! this . environment . isSimple ) {
appendOnly = false ;
}
}
}
if ( appendOnly ) {
if ( buffer || ! source ) {
source += 'return ' + ( buffer || '""' ) + ';\n' ;
}
} else {
varDeclarations += ", buffer = " + ( appendFirst ? '' : this . initializeBuffer ( ) ) ;
if ( buffer ) {
source += 'return buffer + ' + buffer + ';\n' ;
} else {
source += 'return buffer;\n' ;
2013-12-02 13:15:31 -05:00
}
}
2014-12-10 11:34:00 -05:00
if ( varDeclarations ) {
source = 'var ' + varDeclarations . substring ( 2 ) + ( appendFirst ? '' : ';\n ' ) + source ;
}
2014-04-15 11:22:15 -04:00
return source ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
// [blockValue]
//
// On stack, before: hash, inverse, program, value
// On stack, after: return value of blockHelperMissing
//
// The purpose of this opcode is to take a block of the form
2014-12-10 11:34:00 -05:00
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
2014-04-15 11:22:15 -04:00
// replace it on the stack with the result of properly
// invoking blockHelperMissing.
2014-12-10 11:34:00 -05:00
blockValue : function ( name ) {
this . aliases . blockHelperMissing = 'helpers.blockHelperMissing' ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
var params = [ this . contextName ( 0 ) ] ;
this . setupParams ( name , 0 , params ) ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
var blockName = this . popStack ( ) ;
params . splice ( 1 , 0 , blockName ) ;
this . push ( 'blockHelperMissing.call(' + params . join ( ', ' ) + ')' ) ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
// [ambiguousBlockValue]
//
// On stack, before: hash, inverse, program, value
// Compiler value, before: lastHelper=value of last found helper, if any
// On stack, after, if no lastHelper: same as [blockValue]
// On stack, after, if lastHelper: value
ambiguousBlockValue : function ( ) {
2014-12-10 11:34:00 -05:00
this . aliases . blockHelperMissing = 'helpers.blockHelperMissing' ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
// We're being a bit cheeky and reusing the options value from the prior exec
var params = [ this . contextName ( 0 ) ] ;
this . setupParams ( '' , 0 , params , true ) ;
this . flushInline ( ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
var current = this . topStack ( ) ;
params . splice ( 1 , 0 , current ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
this . pushSource ( "if (!" + this . lastHelper + ") { " + current + " = blockHelperMissing.call(" + params . join ( ", " ) + "); }" ) ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [appendContent]
//
// On stack, before: ...
// On stack, after: ...
//
// Appends the string value of `content` to the current buffer
appendContent : function ( content ) {
if ( this . pendingContent ) {
content = this . pendingContent + content ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . pendingContent = content ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [append]
//
// On stack, before: value, ...
// On stack, after: ...
//
// Coerces `value` to a String and appends it to the current buffer.
//
// If `value` is truthy, or 0, it is coerced into a string and appended
// Otherwise, the empty string is appended
append : function ( ) {
// Force anything that is inlined onto the stack so we don't have duplication
// when we examine local
this . flushInline ( ) ;
var local = this . popStack ( ) ;
2014-12-10 11:34:00 -05:00
this . pushSource ( 'if (' + local + ' != null) { ' + this . appendToBuffer ( local ) + ' }' ) ;
2014-04-15 11:22:15 -04:00
if ( this . environment . isSimple ) {
this . pushSource ( "else { " + this . appendToBuffer ( "''" ) + " }" ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [appendEscaped]
//
// On stack, before: value, ...
// On stack, after: ...
//
// Escape `value` and append it to the buffer
appendEscaped : function ( ) {
2014-12-10 11:34:00 -05:00
this . aliases . escapeExpression = 'this.escapeExpression' ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
this . pushSource ( this . appendToBuffer ( "escapeExpression(" + this . popStack ( ) + ")" ) ) ;
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// [getContext]
//
// On stack, before: ...
// On stack, after: ...
// Compiler value, after: lastContext=depth
//
// Set the value of the `lastContext` compiler value to the depth
getContext : function ( depth ) {
2014-12-10 11:34:00 -05:00
this . lastContext = depth ;
} ,
// [pushContext]
//
// On stack, before: ...
// On stack, after: currentContext, ...
//
// Pushes the value of the current context onto the stack.
pushContext : function ( ) {
this . pushStackLiteral ( this . contextName ( this . lastContext ) ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [lookupOnContext]
//
// On stack, before: ...
// On stack, after: currentContext[name], ...
//
// Looks up the value of `name` on the current context and pushes
// it onto the stack.
2014-12-10 11:34:00 -05:00
lookupOnContext : function ( parts , falsy , scoped ) {
/*jshint -W083 */
var i = 0 ,
len = parts . length ;
if ( ! scoped && this . options . compat && ! this . lastContext ) {
// The depthed query is expected to handle the undefined logic for the root level that
// is implemented below, so we evaluate that directly in compat mode
this . push ( this . depthedLookup ( parts [ i ++ ] ) ) ;
} else {
this . pushContext ( ) ;
}
for ( ; i < len ; i ++ ) {
this . replaceStack ( function ( current ) {
var lookup = this . nameLookup ( current , parts [ i ] , 'context' ) ;
// We want to ensure that zero and false are handled properly if the context (falsy flag)
// needs to have the special handling for these values.
if ( ! falsy ) {
return ' != null ? ' + lookup + ' : ' + current ;
} else {
// Otherwise we can use generic falsy handling
return ' && ' + lookup ;
}
} ) ;
}
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
// [lookupData]
2014-04-15 11:22:15 -04:00
//
// On stack, before: ...
2014-12-10 11:34:00 -05:00
// On stack, after: data, ...
2014-04-15 11:22:15 -04:00
//
2014-12-10 11:34:00 -05:00
// Push the data lookup operator
lookupData : function ( depth , parts ) {
/*jshint -W083 */
if ( ! depth ) {
this . pushStackLiteral ( 'data' ) ;
} else {
this . pushStackLiteral ( 'this.data(data, ' + depth + ')' ) ;
}
var len = parts . length ;
for ( var i = 0 ; i < len ; i ++ ) {
this . replaceStack ( function ( current ) {
return ' && ' + this . nameLookup ( current , parts [ i ] , 'data' ) ;
} ) ;
}
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [resolvePossibleLambda]
//
// On stack, before: value, ...
// On stack, after: resolved value, ...
//
// If the `value` is a lambda, replace it on the stack by
// the return value of the lambda
resolvePossibleLambda : function ( ) {
2014-12-10 11:34:00 -05:00
this . aliases . lambda = 'this.lambda' ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
this . push ( 'lambda(' + this . popStack ( ) + ', ' + this . contextName ( 0 ) + ')' ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// [pushStringParam]
//
// On stack, before: ...
// On stack, after: string, currentContext, ...
//
// This opcode is designed for use in string mode, which
// provides the string value of a parameter along with its
// depth rather than resolving it immediately.
pushStringParam : function ( string , type ) {
2014-12-10 11:34:00 -05:00
this . pushContext ( ) ;
2014-04-15 11:22:15 -04:00
this . pushString ( type ) ;
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// If it's a subexpression, the string result
// will be pushed after this opcode.
if ( type !== 'sexpr' ) {
if ( typeof string === 'string' ) {
this . pushString ( string ) ;
2013-06-06 17:50:49 -04:00
} else {
2014-04-15 11:22:15 -04:00
this . pushStackLiteral ( string ) ;
2013-06-06 17:50:49 -04:00
}
}
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
emptyHash : function ( ) {
this . pushStackLiteral ( '{}' ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
this . push ( '{}' ) ; // hashIds
}
if ( this . stringParams ) {
2014-04-15 11:22:15 -04:00
this . push ( '{}' ) ; // hashContexts
this . push ( '{}' ) ; // hashTypes
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} ,
pushHash : function ( ) {
if ( this . hash ) {
this . hashes . push ( this . hash ) ;
2013-12-02 13:15:31 -05:00
}
2014-12-10 11:34:00 -05:00
this . hash = { values : [ ] , types : [ ] , contexts : [ ] , ids : [ ] } ;
2014-04-15 11:22:15 -04:00
} ,
popHash : function ( ) {
var hash = this . hash ;
this . hash = this . hashes . pop ( ) ;
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
this . push ( '{' + hash . ids . join ( ',' ) + '}' ) ;
}
if ( this . stringParams ) {
2014-04-15 11:22:15 -04:00
this . push ( '{' + hash . contexts . join ( ',' ) + '}' ) ;
this . push ( '{' + hash . types . join ( ',' ) + '}' ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
this . push ( '{\n ' + hash . values . join ( ',\n ' ) + '\n }' ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [pushString]
//
// On stack, before: ...
// On stack, after: quotedString(string), ...
//
// Push a quoted version of `string` onto the stack
pushString : function ( string ) {
this . pushStackLiteral ( this . quotedString ( string ) ) ;
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
// [push]
//
// On stack, before: ...
// On stack, after: expr, ...
//
// Push an expression onto the stack
push : function ( expr ) {
this . inlineStack . push ( expr ) ;
return expr ;
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [pushLiteral]
//
// On stack, before: ...
// On stack, after: value, ...
//
// Pushes a value onto the stack. This operation prevents
// the compiler from creating a temporary variable to hold
// it.
pushLiteral : function ( value ) {
this . pushStackLiteral ( value ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [pushProgram]
//
// On stack, before: ...
// On stack, after: program(guid), ...
//
// Push a program expression onto the stack. This takes
// a compile-time guid and converts it into a runtime-accessible
// expression.
pushProgram : function ( guid ) {
if ( guid != null ) {
this . pushStackLiteral ( this . programExpression ( guid ) ) ;
} else {
this . pushStackLiteral ( null ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} ,
// [invokeHelper]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of helper invocation
//
// Pops off the helper's parameters, invokes the helper,
// and pushes the helper's return value onto the stack.
//
// If the helper is not found, `helperMissing` is called.
2014-12-10 11:34:00 -05:00
invokeHelper : function ( paramSize , name , isSimple ) {
this . aliases . helperMissing = 'helpers.helperMissing' ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var nonHelper = this . popStack ( ) ;
var helper = this . setupHelper ( paramSize , name ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var lookup = ( isSimple ? helper . name + ' || ' : '' ) + nonHelper + ' || helperMissing' ;
this . push ( '((' + lookup + ').call(' + helper . callParams + '))' ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [invokeKnownHelper]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of helper invocation
//
// This operation is used when the helper is known to exist,
// so a `helperMissing` fallback is not required.
invokeKnownHelper : function ( paramSize , name ) {
var helper = this . setupHelper ( paramSize , name ) ;
this . push ( helper . name + ".call(" + helper . callParams + ")" ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [invokeAmbiguous]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of disambiguation
//
// This operation is used when an expression like `{{foo}}`
// is provided, but we don't know at compile-time whether it
// is a helper or a path.
//
// This operation emits more code than the other options,
// and can be avoided by passing the `knownHelpers` and
// `knownHelpersOnly` flags at compile-time.
invokeAmbiguous : function ( name , helperCall ) {
2014-12-10 11:34:00 -05:00
this . aliases . functionType = '"function"' ;
this . aliases . helperMissing = 'helpers.helperMissing' ;
2014-04-15 11:22:15 -04:00
this . useRegister ( 'helper' ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var nonHelper = this . popStack ( ) ;
2014-04-15 11:22:15 -04:00
this . emptyHash ( ) ;
var helper = this . setupHelper ( 0 , name , helperCall ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var helperName = this . lastHelper = this . nameLookup ( 'helpers' , name , 'helper' ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
this . push (
'((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing'
+ ( helper . paramsInit ? '),(' + helper . paramsInit : '' ) + '),'
+ '(typeof helper === functionType ? helper.call(' + helper . callParams + ') : helper))' ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [invokePartial]
//
// On stack, before: context, ...
// On stack after: result of partial invocation
//
// This operation pops off a context, invokes a partial with that context,
// and pushes the result of the invocation back.
2014-12-10 11:34:00 -05:00
invokePartial : function ( name , indent ) {
var params = [ this . nameLookup ( 'partials' , name , 'partial' ) , "'" + indent + "'" , "'" + name + "'" , this . popStack ( ) , this . popStack ( ) , "helpers" , "partials" ] ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( this . options . data ) {
params . push ( "data" ) ;
2014-12-10 11:34:00 -05:00
} else if ( this . options . compat ) {
params . push ( 'undefined' ) ;
}
if ( this . options . compat ) {
params . push ( 'depths' ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
this . push ( "this.invokePartial(" + params . join ( ", " ) + ")" ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// [assignToHash]
//
2014-12-10 11:34:00 -05:00
// On stack, before: value, ..., hash, ...
// On stack, after: ..., hash, ...
2014-04-15 11:22:15 -04:00
//
2014-12-10 11:34:00 -05:00
// Pops a value off the stack and assigns it to the current hash
2014-04-15 11:22:15 -04:00
assignToHash : function ( key ) {
var value = this . popStack ( ) ,
context ,
2014-12-10 11:34:00 -05:00
type ,
id ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
id = this . popStack ( ) ;
}
if ( this . stringParams ) {
2014-04-15 11:22:15 -04:00
type = this . popStack ( ) ;
context = this . popStack ( ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var hash = this . hash ;
if ( context ) {
hash . contexts . push ( "'" + key + "': " + context ) ;
}
if ( type ) {
hash . types . push ( "'" + key + "': " + type ) ;
}
2014-12-10 11:34:00 -05:00
if ( id ) {
hash . ids . push ( "'" + key + "': " + id ) ;
}
2014-04-15 11:22:15 -04:00
hash . values . push ( "'" + key + "': (" + value + ")" ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
pushId : function ( type , name ) {
if ( type === 'ID' || type === 'DATA' ) {
this . pushString ( name ) ;
} else if ( type === 'sexpr' ) {
this . pushStackLiteral ( 'true' ) ;
} else {
this . pushStackLiteral ( 'null' ) ;
}
} ,
2014-04-15 11:22:15 -04:00
// HELPERS
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
compiler : JavaScriptCompiler ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
compileChildren : function ( environment , options ) {
var children = environment . children , child , compiler ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
for ( var i = 0 , l = children . length ; i < l ; i ++ ) {
child = children [ i ] ;
compiler = new this . compiler ( ) ;
var index = this . matchExistingProgram ( child ) ;
if ( index == null ) {
this . context . programs . push ( '' ) ; // Placeholder to prevent name conflicts for nested children
index = this . context . programs . length ;
child . index = index ;
child . name = 'program' + index ;
2014-12-10 11:34:00 -05:00
this . context . programs [ index ] = compiler . compile ( child , options , this . context , ! this . precompile ) ;
2014-04-15 11:22:15 -04:00
this . context . environments [ index ] = child ;
2014-12-10 11:34:00 -05:00
this . useDepths = this . useDepths || compiler . useDepths ;
2013-12-02 13:15:31 -05:00
} else {
2014-04-15 11:22:15 -04:00
child . index = index ;
child . name = 'program' + index ;
}
}
} ,
matchExistingProgram : function ( child ) {
for ( var i = 0 , len = this . context . environments . length ; i < len ; i ++ ) {
var environment = this . context . environments [ i ] ;
if ( environment && environment . equals ( child ) ) {
return i ;
2013-12-02 13:15:31 -05:00
}
}
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
programExpression : function ( guid ) {
var child = this . environment . children [ guid ] ,
2014-12-10 11:34:00 -05:00
depths = child . depths . list ,
useDepths = this . useDepths ,
depth ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
var programParams = [ child . index , 'data' ] ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
if ( useDepths ) {
programParams . push ( 'depths' ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
return 'this.program(' + programParams . join ( ', ' ) + ')' ;
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
useRegister : function ( name ) {
if ( ! this . registers [ name ] ) {
this . registers [ name ] = true ;
this . registers . list . push ( name ) ;
}
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
pushStackLiteral : function ( item ) {
return this . push ( new Literal ( item ) ) ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
pushSource : function ( source ) {
if ( this . pendingContent ) {
this . source . push ( this . appendToBuffer ( this . quotedString ( this . pendingContent ) ) ) ;
this . pendingContent = undefined ;
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( source ) {
this . source . push ( source ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
pushStack : function ( item ) {
this . flushInline ( ) ;
var stack = this . incrStack ( ) ;
2014-12-10 11:34:00 -05:00
this . pushSource ( stack + " = " + item + ";" ) ;
2014-04-15 11:22:15 -04:00
this . compileStack . push ( stack ) ;
return stack ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
replaceStack : function ( callback ) {
var prefix = '' ,
inline = this . isInline ( ) ,
stack ,
createdStack ,
usedLiteral ;
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
if ( ! this . isInline ( ) ) {
throw new Exception ( 'replaceStack on non-inline' ) ;
}
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
// We want to merge the inline statement into the replacement statement via ','
var top = this . popStack ( true ) ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
if ( top instanceof Literal ) {
// Literals do not need to be inlined
prefix = stack = top . value ;
usedLiteral = true ;
2013-06-06 17:50:49 -04:00
} else {
2014-12-10 11:34:00 -05:00
// Get or create the current stack name for use by the inline
createdStack = ! this . stackSlot ;
var name = ! createdStack ? this . topStackName ( ) : this . incrStack ( ) ;
prefix = '(' + this . push ( name ) + ' = ' + top + ')' ;
2014-04-15 11:22:15 -04:00
stack = this . topStack ( ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var item = callback . call ( this , stack ) ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( ! usedLiteral ) {
this . popStack ( ) ;
2013-12-02 13:15:31 -05:00
}
2014-12-10 11:34:00 -05:00
if ( createdStack ) {
this . stackSlot -- ;
}
this . push ( '(' + prefix + item + ')' ) ;
2014-04-15 11:22:15 -04:00
} ,
2013-12-02 13:15:31 -05:00
2014-04-15 11:22:15 -04:00
incrStack : function ( ) {
this . stackSlot ++ ;
if ( this . stackSlot > this . stackVars . length ) { this . stackVars . push ( "stack" + this . stackSlot ) ; }
return this . topStackName ( ) ;
} ,
topStackName : function ( ) {
return "stack" + this . stackSlot ;
} ,
flushInline : function ( ) {
var inlineStack = this . inlineStack ;
if ( inlineStack . length ) {
this . inlineStack = [ ] ;
for ( var i = 0 , len = inlineStack . length ; i < len ; i ++ ) {
var entry = inlineStack [ i ] ;
if ( entry instanceof Literal ) {
this . compileStack . push ( entry ) ;
} else {
this . pushStack ( entry ) ;
}
}
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
isInline : function ( ) {
return this . inlineStack . length ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
popStack : function ( wrapped ) {
var inline = this . isInline ( ) ,
item = ( inline ? this . inlineStack : this . compileStack ) . pop ( ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( ! wrapped && ( item instanceof Literal ) ) {
return item . value ;
} else {
if ( ! inline ) {
2014-12-10 11:34:00 -05:00
/* istanbul ignore next */
2014-04-15 11:22:15 -04:00
if ( ! this . stackSlot ) {
throw new Exception ( 'Invalid stack pop' ) ;
}
this . stackSlot -- ;
}
return item ;
}
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
topStack : function ( ) {
2014-04-15 11:22:15 -04:00
var stack = ( this . isInline ( ) ? this . inlineStack : this . compileStack ) ,
item = stack [ stack . length - 1 ] ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
if ( item instanceof Literal ) {
2014-04-15 11:22:15 -04:00
return item . value ;
} else {
return item ;
}
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
contextName : function ( context ) {
if ( this . useDepths && context ) {
return 'depths[' + context + ']' ;
} else {
return 'depth' + context ;
}
} ,
2014-04-15 11:22:15 -04:00
quotedString : function ( str ) {
return '"' + str
. replace ( /\\/g , '\\\\' )
. replace ( /"/g , '\\"' )
. replace ( /\n/g , '\\n' )
. replace ( /\r/g , '\\r' )
. replace ( /\u2028/g , '\\u2028' ) // Per Ecma-262 7.3 + 7.8.4
. replace ( /\u2029/g , '\\u2029' ) + '"' ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
objectLiteral : function ( obj ) {
var pairs = [ ] ;
for ( var key in obj ) {
if ( obj . hasOwnProperty ( key ) ) {
pairs . push ( this . quotedString ( key ) + ':' + obj [ key ] ) ;
}
}
return '{' + pairs . join ( ',' ) + '}' ;
} ,
setupHelper : function ( paramSize , name , blockHelper ) {
2014-04-15 11:22:15 -04:00
var params = [ ] ,
2014-12-10 11:34:00 -05:00
paramsInit = this . setupParams ( name , paramSize , params , blockHelper ) ;
2014-04-15 11:22:15 -04:00
var foundHelper = this . nameLookup ( 'helpers' , name , 'helper' ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
return {
params : params ,
paramsInit : paramsInit ,
name : foundHelper ,
2014-12-10 11:34:00 -05:00
callParams : [ this . contextName ( 0 ) ] . concat ( params ) . join ( ", " )
2014-04-15 11:22:15 -04:00
} ;
2013-12-02 13:15:31 -05:00
} ,
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
setupOptions : function ( helper , paramSize , params ) {
var options = { } , contexts = [ ] , types = [ ] , ids = [ ] , param , inverse , program ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
options . name = this . quotedString ( helper ) ;
options . hash = this . popStack ( ) ;
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
options . hashIds = this . popStack ( ) ;
}
if ( this . stringParams ) {
options . hashTypes = this . popStack ( ) ;
options . hashContexts = this . popStack ( ) ;
2013-12-02 13:15:31 -05:00
}
2014-04-15 11:22:15 -04:00
inverse = this . popStack ( ) ;
program = this . popStack ( ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
// Avoid setting fn and inverse if neither are set. This allows
// helpers to do a check for `if (options.fn)`
if ( program || inverse ) {
if ( ! program ) {
2014-12-10 11:34:00 -05:00
program = 'this.noop' ;
2014-04-15 11:22:15 -04:00
}
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( ! inverse ) {
2014-12-10 11:34:00 -05:00
inverse = 'this.noop' ;
2014-04-15 11:22:15 -04:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
options . fn = program ;
options . inverse = inverse ;
2014-04-15 11:22:15 -04:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
// The parameters go on to the stack in order (making sure that they are evaluated in order)
// so we need to pop them off the stack in reverse order
var i = paramSize ;
while ( i -- ) {
2014-04-15 11:22:15 -04:00
param = this . popStack ( ) ;
2014-12-10 11:34:00 -05:00
params [ i ] = param ;
2014-04-15 11:22:15 -04:00
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
ids [ i ] = this . popStack ( ) ;
}
if ( this . stringParams ) {
types [ i ] = this . popStack ( ) ;
contexts [ i ] = this . popStack ( ) ;
2013-12-02 13:15:31 -05:00
}
2013-06-06 17:50:49 -04:00
}
2013-12-02 13:15:31 -05:00
2014-12-10 11:34:00 -05:00
if ( this . trackIds ) {
options . ids = "[" + ids . join ( "," ) + "]" ;
}
if ( this . stringParams ) {
options . types = "[" + types . join ( "," ) + "]" ;
options . contexts = "[" + contexts . join ( "," ) + "]" ;
2014-04-15 11:22:15 -04:00
}
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
if ( this . options . data ) {
options . data = "data" ;
2013-06-06 17:50:49 -04:00
}
2014-04-15 11:22:15 -04:00
return options ;
2013-12-02 13:15:31 -05:00
} ,
2014-04-15 11:22:15 -04:00
// the params and contexts arguments are passed in arrays
// to fill in
2014-12-10 11:34:00 -05:00
setupParams : function ( helperName , paramSize , params , useRegister ) {
var options = this . objectLiteral ( this . setupOptions ( helperName , paramSize , params ) ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
if ( useRegister ) {
this . useRegister ( 'options' ) ;
params . push ( 'options' ) ;
return 'options=' + options ;
2013-12-02 13:15:31 -05:00
} else {
2014-04-15 11:22:15 -04:00
params . push ( options ) ;
return '' ;
2013-06-06 17:50:49 -04:00
}
}
2013-12-02 13:15:31 -05:00
} ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var reservedWords = (
"break else new var" +
" case finally return void" +
" catch for switch while" +
" continue function this with" +
" default if throw" +
" delete in try" +
" do instanceof typeof" +
" abstract enum int short" +
" boolean export interface static" +
" byte extends long super" +
" char final native synchronized" +
" class float package throws" +
" const goto private transient" +
" debugger implements protected volatile" +
" double import public let yield"
) . split ( " " ) ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
var compilerWords = JavaScriptCompiler . RESERVED _WORDS = { } ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
for ( var i = 0 , l = reservedWords . length ; i < l ; i ++ ) {
compilerWords [ reservedWords [ i ] ] = true ;
2013-06-06 17:50:49 -04:00
}
2014-04-15 11:22:15 -04:00
JavaScriptCompiler . isValidJavaScriptVariableName = function ( name ) {
2014-12-10 11:34:00 -05:00
return ! JavaScriptCompiler . RESERVED _WORDS [ name ] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/ . test ( name ) ;
2014-04-15 11:22:15 -04:00
} ;
2013-06-06 17:50:49 -04:00
2014-04-15 11:22:15 -04:00
_ _exports _ _ = JavaScriptCompiler ;
2013-12-02 13:15:31 -05:00
return _ _exports _ _ ;
2014-04-15 11:22:15 -04:00
} ) ( _ _module2 _ _ , _ _module5 _ _ ) ;
2013-12-02 13:15:31 -05:00
// handlebars.js
var _ _module0 _ _ = ( function ( _ _dependency1 _ _ , _ _dependency2 _ _ , _ _dependency3 _ _ , _ _dependency4 _ _ , _ _dependency5 _ _ ) {
"use strict" ;
var _ _exports _ _ ;
2014-04-15 11:22:15 -04:00
/*globals Handlebars: true */
2013-12-02 13:15:31 -05:00
var Handlebars = _ _dependency1 _ _ ;
// Compiler imports
var AST = _ _dependency2 _ _ ;
var Parser = _ _dependency3 _ _ . parser ;
var parse = _ _dependency3 _ _ . parse ;
var Compiler = _ _dependency4 _ _ . Compiler ;
var compile = _ _dependency4 _ _ . compile ;
var precompile = _ _dependency4 _ _ . precompile ;
var JavaScriptCompiler = _ _dependency5 _ _ ;
var _create = Handlebars . create ;
var create = function ( ) {
var hb = _create ( ) ;
hb . compile = function ( input , options ) {
return compile ( input , options , hb ) ;
} ;
2014-04-15 11:22:15 -04:00
hb . precompile = function ( input , options ) {
return precompile ( input , options , hb ) ;
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
hb . AST = AST ;
hb . Compiler = Compiler ;
hb . JavaScriptCompiler = JavaScriptCompiler ;
hb . Parser = Parser ;
hb . parse = parse ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
return hb ;
} ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
Handlebars = create ( ) ;
Handlebars . create = create ;
2013-06-06 17:50:49 -04:00
2014-12-10 11:34:00 -05:00
Handlebars [ 'default' ] = Handlebars ;
2013-12-02 13:15:31 -05:00
_ _exports _ _ = Handlebars ;
return _ _exports _ _ ;
2014-12-10 11:34:00 -05:00
} ) ( _ _module1 _ _ , _ _module7 _ _ , _ _module8 _ _ , _ _module11 _ _ , _ _module12 _ _ ) ;
2013-06-06 17:50:49 -04:00
2013-12-02 13:15:31 -05:00
return _ _module0 _ _ ;
2014-12-10 11:34:00 -05:00
} ) ) ;