Twig.js 0.5.5
-Copyright (c) 2011-2012 John Roepke
+ twig.js
twig.js Twig.js 0.5.6
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
var Twig = ( function ( Twig ) {
- Twig . VERSION = "0.5.5" ;
+ Twig . VERSION = "0.5.6" ;
return Twig ;
})( Twig || {}); Twig.js
-Copyright (c) 2011-2012 John Roepke
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
var Twig = ( function ( Twig ) {
@@ -1259,7 +1259,7 @@
return Twig ;
})( Twig || { }); Twig.js
-Copyright (c) 2011-2012 John Roepke
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
twig.logic.js
@@ -1289,7 +1289,9 @@
endblock : 'Twig.logic.type.endblock' ,
extends_ : 'Twig.logic.type.extends' ,
use : 'Twig.logic.type.use' ,
- include : 'Twig.logic.type.include'
+ include : 'Twig.logic.type.include' ,
+ spaceless : 'Twig.logic.type.spaceless' ,
+ endspaceless : 'Twig.logic.type.endspaceless'
}; Regular expressions for handling logic tokens.
Properties:
@@ -1794,6 +1796,27 @@
output : template . render ( innerContext )
};
}
+ },
+ {
+ type : Twig . logic . type . spaceless ,
+ regex : /^spaceless$/ ,
+ next : [
+ Twig . logic . type . endspaceless
+ ],
+ open : true , Parse the html and return it without any spaces between tags
parse : function ( token , context , chain ) {
+ var // Parse the output without any filter
+ unfiltered = Twig . parse . apply ( this , [ token . output , context ]), A regular expression to find closing and opening tags with spaces between them
rBetweenTagSpaces = />\s+</g , Replace all space between closing and opening html tags
output = unfiltered . replace ( rBetweenTagSpaces , '><' ). trim ();
+
+ return {
+ chain : chain ,
+ output : output
+ };
+ }
+ }, Add the {% endspaceless %} token
{
+ type : Twig . logic . type . endspaceless ,
+ regex : /^endspaceless$/ ,
+ next : [ ],
+ open : false
}
];
@@ -1841,7 +1864,7 @@
Twig . logic . extendType ( definition . type );
}
Twig . logic . handler [ definition . type ] = definition ;
- }; Extend with built-in expressions
while ( Twig . logic . definitions . length > 0 ) {
+ }; Extend with built-in expressions
while ( Twig . logic . definitions . length > 0 ) {
Twig . logic . extend ( Twig . logic . definitions . shift ());
}
@@ -1855,7 +1878,7 @@
Twig . logic . compile = function ( raw_token ) {
var expression = raw_token . value . trim (),
token = Twig . logic . tokenize . apply ( this , [ expression ]),
- token_template = Twig . logic . handler [ token . type ]; Check if the token needs compiling
if ( token_template . compile ) {
+ token_template = Twig . logic . handler [ token . type ]; Check if the token needs compiling
if ( token_template . compile ) {
token = token_template . compile . apply ( this , [ token ]);
Twig . log . trace ( "Twig.logic.compile: " , "Compiled logic token to " , token );
}
@@ -1879,16 +1902,16 @@
token_regex = null ,
regex_array = null ,
regex = null ,
- match = null ; Ignore whitespace around expressions.
expression = expression . trim ();
+ match = null ; Ignore whitespace around expressions.
expression = expression . trim ();
for ( token_template_type in Twig . logic . handler ) {
- if ( Twig . logic . handler . hasOwnProperty ( token_template_type )) { Get the type and regex for this template type
token_type = Twig . logic . handler [ token_template_type ]. type ;
- token_regex = Twig . logic . handler [ token_template_type ]. regex ; Handle multiple regular expressions per type.
regex_array = [];
+ if ( Twig . logic . handler . hasOwnProperty ( token_template_type )) { Get the type and regex for this template type
token_type = Twig . logic . handler [ token_template_type ]. type ;
+ token_regex = Twig . logic . handler [ token_template_type ]. regex ; Handle multiple regular expressions per type.
regex_array = [];
if ( token_regex instanceof Array ) {
regex_array = token_regex ;
} else {
regex_array . push ( token_regex );
- } Check regular expressions in the order they were specified in the definition.
while ( regex_array . length > 0 ) {
+ } Check regular expressions in the order they were specified in the definition.
while ( regex_array . length > 0 ) {
regex = regex_array . shift ();
match = regex . exec ( expression . trim ());
if ( match !== null ) {
@@ -1899,7 +1922,7 @@
}
}
}
- } No regex matches
throw new Twig . Error ( "Unable to parse '" + expression . trim () + "'" );
+ } No regex matches
throw new Twig . Error ( "Unable to parse '" + expression . trim () + "'" );
};
/**
@@ -1940,11 +1963,11 @@
return Twig ;
-})( Twig || { }); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { });
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.expression.js
+ twig.expression.js
This file handles tokenizing, compiling and parsing expressions.
var Twig = ( function ( Twig ) {
"use strict" ;
@@ -1996,7 +2019,7 @@
test : 'Twig.expression.type.test'
};
- Twig . expression . set = { What can follow an expression (in general)
operations : [
+ Twig . expression . set = { What can follow an expression (in general)
operations : [
Twig . expression . type . filter ,
Twig . expression . type . operator . unary ,
Twig . expression . type . operator . binary ,
@@ -2017,9 +2040,9 @@
Twig . expression . type . array . start ,
Twig . expression . type . object . start
]
- }; Most expressions allow a '.' or '[' after them, so we provide a convenience set
Twig . expression . set . operations_extended = Twig . expression . set . operations . concat ([
+ }; Most expressions allow a '.' or '[' after them, so we provide a convenience set
Twig . expression . set . operations_extended = Twig . expression . set . operations . concat ([
Twig . expression . type . key . period ,
- Twig . expression . type . key . brackets ]); Some commonly used compile and parse functions.
Twig . expression . fn = {
+ Twig . expression . type . key . brackets ]); Some commonly used compile and parse functions.
Twig . expression . fn = {
compile : {
push : function ( token , stack , output ) {
output . push ( token );
@@ -2037,7 +2060,7 @@
stack . push ( token . value );
}
}
- }; The regular expressions and compile/parse logic used to match tokens in expressions.
+ }; The regular expressions and compile/parse logic used to match tokens in expressions.
Properties:
@@ -2078,14 +2101,14 @@
}
},
{
- type : Twig . expression . type . comma , Match a comma
regex : /^,/ ,
+ type : Twig . expression . type . comma , Match a comma
regex : /^,/ ,
next : Twig . expression . set . expressions ,
compile : function ( token , stack , output ) {
var i = stack . length - 1 ,
stack_token ;
delete token . match ;
- delete token . value ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
+ delete token . value ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
stack_token = stack . pop ();
if ( stack_token . type === Twig . expression . type . object . start
|| stack_token . type === Twig . expression . type . parameter . start
@@ -2099,7 +2122,7 @@
}
},
{
- type : Twig . expression . type . operator . binary , Match any of +, , /, -, %, ~, <, <=, >, >=, !=, ==, * , ?, :, and, or, not
regex : /(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/ ,
+ type : Twig . expression . type . operator . binary , Match any of +, , /, -, %, ~, <, <=, >, >=, !=, ==, * , ?, :, and, or, not
regex : /(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/ ,
next : Twig . expression . set . expressions . concat ([ Twig . expression . type . operator . unary ]),
compile : function ( token , stack , output ) {
delete token . match ;
@@ -2124,7 +2147,7 @@
output . push ( temp );
}
- if ( value === ":" ) { Check if this is a ternary or object key being set
if ( stack [ stack . length - 1 ] && stack [ stack . length - 1 ]. value === "?" ) { Continue as normal for a ternary
This is not a ternary so we push the token to the output where it can be handled
+ if ( value === ":" ) {
Check if this is a ternary or object key being set
if ( stack [ stack . length - 1 ] && stack [ stack . length - 1 ]. value === "?" ) { Continue as normal for a ternary
This is not a ternary so we push the token to the output where it can be handled
when the assocated object is closed.
var key_token = output . pop ();
if ( key_token . type === Twig . expression . type . string ||
@@ -2144,14 +2167,14 @@
}
},
parse : function ( token , stack , context ) {
- if ( token . key ) { handle ternary ':' operator
stack . push ( token );
+ if ( token . key ) { handle ternary ':' operator
stack . push ( token );
} else {
Twig . expression . operator . parse ( token . value , stack );
}
}
},
{
- type : Twig . expression . type . operator . unary , Match any of not
regex : /(^not\s+)/ ,
+ type : Twig . expression . type . operator . unary , Match any of not
regex : /(^not\s+)/ ,
next : Twig . expression . set . expressions ,
compile : function ( token , stack , output ) {
delete token . match ;
@@ -2186,11 +2209,11 @@
/**
* Match a string. This is anything between a pair of single or double quotes.
*/
- type : Twig . expression . type . string , See: http://blog.stevenlevithan.com/archives/match-quoted-string
regex : /^(["'])(?:(?=(\\?))\2.)*?\1/ ,
+ type : Twig . expression . type . string , See: http://blog.stevenlevithan.com/archives/match-quoted-string
regex : /^(["'])(?:(?=(\\?))\2.)*?\1/ ,
next : Twig . expression . set . operations ,
compile : function ( token , stack , output ) {
var value = token . value ;
- delete token . match Remove the quotes from the string
if ( value . substring ( 0 , 1 ) === '"' ) {
+ delete token . match Remove the quotes from the string
if ( value . substring ( 0 , 1 ) === '"' ) {
value = value . replace ( '\\"' , '"' );
} else {
value = value . replace ( "\\'" , "'" );
@@ -2226,13 +2249,13 @@
while ( stack . length > 0 && stack_token . type != Twig . expression . type . parameter . start ) {
output . push ( stack_token );
stack_token = stack . pop ();
- } Move contents of parens into preceding filter
var param_stack = [];
- while ( token . type !== Twig . expression . type . parameter . start ) { Add token to arguments stack
param_stack . unshift ( token );
+ } Move contents of parens into preceding filter
var param_stack = [];
+ while ( token . type !== Twig . expression . type . parameter . start ) { Add token to arguments stack
param_stack . unshift ( token );
token = output . pop ();
}
param_stack . unshift ( token );
- var is_expression = false ; Get the token preceding the parameters
token = output [ output . length - 1 ];
+ var is_expression = false ; Get the token preceding the parameters
token = output [ output . length - 1 ];
if ( token === undefined ||
( token . type !== Twig . expression . type . _function &&
@@ -2241,7 +2264,7 @@
token . type !== Twig . expression . type . key . brackets &&
token . type !== Twig . expression . type . key . period )) {
- end_token . expression = true ; remove start and end token from stack
param_stack . pop ();
+ end_token . expression = true ; remove start and end token from stack
param_stack . pop ();
param_stack . shift ();
end_token . params = param_stack ;
@@ -2265,7 +2288,7 @@
} else {
while ( stack . length > 0 ) {
- value = stack . pop (); Push values into the array until the start of the array
if ( value && value . type && value . type == Twig . expression . type . parameter . start ) {
+ value = stack . pop (); Push values into the array until the start of the array
if ( value && value . type && value . type == Twig . expression . type . parameter . start ) {
array_ended = true ;
break ;
}
@@ -2299,7 +2322,7 @@
next : Twig . expression . set . operations_extended ,
compile : function ( token , stack , output ) {
var i = stack . length - 1 ,
- stack_token ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
+ stack_token ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
stack_token = stack . pop ();
if ( stack_token . type === Twig . expression . type . array . start ) {
break ;
@@ -2314,7 +2337,7 @@
value = null ;
while ( stack . length > 0 ) {
- value = stack . pop (); Push values into the array until the start of the array
if ( value . type && value . type == Twig . expression . type . array . start ) {
+ value = stack . pop (); Push values into the array until the start of the array
if ( value . type && value . type == Twig . expression . type . array . start ) {
array_ended = true ;
break ;
}
@@ -2326,7 +2349,7 @@
stack . push ( new_array );
}
- }, Token that represents the start of a hash map '}'
+ }, Token that represents the start of a hash map '}'
Hash maps take the form:
{ "key": 'value', "another_key": item }
@@ -2337,7 +2360,7 @@
next : Twig . expression . set . expressions . concat ([ Twig . expression . type . object . end ]),
compile : Twig . expression . fn . compile . push_both ,
parse : Twig . expression . fn . parse . push
- }, Token that represents the end of a Hash Map '}'
+ }, Token that represents the end of a Hash Map '}'
This is where the logic for building the internal
representation of a hash map is defined.
{
@@ -2346,7 +2369,7 @@
next : Twig . expression . set . operations_extended ,
compile : function ( token , stack , output ) {
var i = stack . length - 1 ,
- stack_token ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
+ stack_token ; pop tokens off the stack until the start of the object
for (; i >= 0 ; i -- ) {
stack_token = stack . pop ();
if ( stack_token && stack_token . type === Twig . expression . type . object . start ) {
break ;
@@ -2364,7 +2387,7 @@
value = null ;
while ( stack . length > 0 ) {
- token = stack . pop (); Push values into the array until the start of the object
if ( token && token . type && token . type === Twig . expression . type . object . start ) {
+ token = stack . pop (); Push values into the array until the start of the object
if ( token && token . type && token . type === Twig . expression . type . object . start ) {
object_ended = true ;
break ;
}
@@ -2372,10 +2395,10 @@
if ( ! has_value ) {
throw new Twig . Error ( "Missing value for key '" + token . key + "' in object definition." );
}
- new_object [ token . key ] = value ; Preserve the order that elements are added to the map
+ new_object [ token . key ] = value ;
Preserve the order that elements are added to the map
This is necessary since JavaScript objects don't
guarantee the order of keys
if ( new_object . _keys === undefined ) new_object . _keys = [];
- new_object . _keys . unshift ( token . key ); reset value check
value = null ;
+ new_object . _keys . unshift ( token . key ); reset value check
value = null ;
has_value = false ;
} else {
@@ -2389,13 +2412,13 @@
stack . push ( new_object );
}
- }, Token representing a filter
+ }, Token representing a filter
Filters can follow any expression and take the form:
expression|filter(optional, args)
Filter parsing is done in the Twig.filters namespace.
{
- type : Twig . expression . type . filter , match a | then a letter or _, then any number of letters, numbers, _ or -
regex : /^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/ ,
+ type : Twig . expression . type . filter , match a | then a letter or _, then any number of letters, numbers, _ or -
regex : /^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/ ,
next : Twig . expression . set . operations_extended . concat ([
Twig . expression . type . parameter . start ]),
compile : function ( token , stack , output ) {
@@ -2410,14 +2433,14 @@
}
},
{
- type : Twig . expression . type . _function , match any letter or _, then any number of letters, numbers, _ or - followed by (
regex : /^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/ ,
+ type : Twig . expression . type . _function , match any letter or _, then any number of letters, numbers, _ or - followed by (
regex : /^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/ ,
next : Twig . expression . type . parameter . start ,
transform : function ( match , tokens ) {
return '(' ;
},
compile : function ( token , stack , output ) {
var fn = token . match [ 1 ];
- token . fn = fn ; cleanup token
delete token . match ;
+ token . fn = fn ; cleanup token
delete token . match ;
delete token . value ;
output . push ( token );
@@ -2427,9 +2450,9 @@
fn = token . fn ,
value ;
- if ( Twig . functions [ fn ]) { Get the function from the built-in functions
value = Twig . functions [ fn ]. apply ( this , params );
+ if ( Twig . functions [ fn ]) { Get the function from the built-in functions
value = Twig . functions [ fn ]. apply ( this , params );
- } else if ( typeof context [ fn ] == 'function' ) { Get the function from the user/context defined functions
value = context [ fn ]. apply ( context , params );
+ } else if ( typeof context [ fn ] == 'function' ) { Get the function from the user/context defined functions
value = context [ fn ]. apply ( context , params );
} else {
throw new Twig . Error ( fn + ' function does not exist and is not defined in the context' );
@@ -2437,7 +2460,7 @@
stack . push ( value );
}
- }, Token representing a variable.
+ }, Token representing a variable.
Variables can contain letters, numbers, underscores and
dashes, but must start with a letter or underscore.
@@ -2445,14 +2468,14 @@
Variables are retrieved from the render context and take
the value of 'undefined' if the given variable doesn't
exist in the context.
{
- type : Twig . expression . type . variable , match any letter or _, then any number of letters, numbers, _ or -
regex : /^[a-zA-Z_][a-zA-Z0-9_]*/ ,
+ type : Twig . expression . type . variable , match any letter or _, then any number of letters, numbers, _ or -
regex : /^[a-zA-Z_][a-zA-Z0-9_]*/ ,
next : Twig . expression . set . operations_extended . concat ([
Twig . expression . type . parameter . start ]),
compile : Twig . expression . fn . compile . push ,
validate : function ( match , tokens ) {
return Twig . expression . reservedWords . indexOf ( match [ 0 ]) == - 1 ;
},
- parse : function ( token , stack , context ) { Get the variable from the context
var value = Twig . expression . resolve ( context [ token . value ], context );
+ parse : function ( token , stack , context ) { Get the variable from the context
var value = Twig . expression . resolve ( context [ token . value ], context );
stack . push ( value );
}
},
@@ -2482,7 +2505,7 @@
}
}
- var capitalize = function ( value ) { return value . substr ( 0 , 1 ). toUpperCase () + value . substr ( 1 );}; Get the variable from the context
if ( typeof object === 'object' && key in object ) {
+ var capitalize = function ( value ) { return value . substr ( 0 , 1 ). toUpperCase () + value . substr ( 1 );}; Get the variable from the context
if ( typeof object === 'object' && key in object ) {
value = object [ key ];
} else if ( object [ "get" + capitalize ( key )] !== undefined ) {
value = object [ "get" + capitalize ( key )];
@@ -2502,13 +2525,13 @@
compile : function ( token , stack , output ) {
var match = token . match [ 1 ];
delete token . value ;
- delete token . match ; The expression stack for the key
token . stack = Twig . expression . compile ({
+ delete token . match ; The expression stack for the key
token . stack = Twig . expression . compile ({
value : match
}). stack ;
output . push ( token );
},
- parse : function ( token , stack , context ) { Evaluate key
var params = token . params && Twig . expression . parse . apply ( this , [ token . params , context ]),
+ parse : function ( token , stack , context ) { Evaluate key
var params = token . params && Twig . expression . parse . apply ( this , [ token . params , context ]),
key = Twig . expression . parse . apply ( this , [ token . stack , context ]),
object = stack . pop (),
value ;
@@ -2519,7 +2542,7 @@
} else {
return null ;
}
- } Get the variable from the context
if ( typeof object === 'object' && key in object ) {
+ } Get the variable from the context
if ( typeof object === 'object' && key in object ) {
value = object [ key ];
} else {
value = null ;
@@ -2531,7 +2554,7 @@
/**
* Match a null value.
*/
- type : Twig . expression . type . _null , match a number
regex : /^null/ ,
+ type : Twig . expression . type . _null , match a number
regex : /^null/ ,
next : Twig . expression . set . operations ,
compile : function ( token , stack , output ) {
delete token . match ;
@@ -2544,7 +2567,7 @@
/**
* Match a number (integer or decimal)
*/
- type : Twig . expression . type . number , match a number
regex : /^\-?\d+(\.\d+)?/ ,
+ type : Twig . expression . type . number , match a number
regex : /^\-?\d+(\.\d+)?/ ,
next : Twig . expression . set . operations ,
compile : function ( token , stack , output ) {
token . value = Number ( token . value );
@@ -2624,7 +2647,7 @@
throw new Twig . Error ( "Unable to extend logic definition. No type provided for " + definition );
}
Twig . expression . handler [ definition . type ] = definition ;
- }; Extend with built-in expressions
while ( Twig . expression . definitions . length > 0 ) {
+ }; Extend with built-in expressions
while ( Twig . expression . definitions . length > 0 ) {
Twig . expression . extend ( Twig . expression . definitions . shift ());
}
@@ -2636,7 +2659,7 @@
* @return {Array} An array of tokens.
*/
Twig . expression . tokenize = function ( expression ) {
- var tokens = [], Keep an offset of the location in the expression for error messages.
The valid next tokens of the previous token
Match information
type , regex , regex_array , The possible next token for the match
Has a match been found from the definitions
match_found , invalid_matches = [], match_function ;
+ var tokens = [], Keep an offset of the location in the expression for error messages.
The valid next tokens of the previous token
Match information
type , regex , regex_array , The possible next token for the match
Has a match been found from the definitions
match_found , invalid_matches = [], match_function ;
match_function = function () {
var match = Array . prototype . slice . apply ( arguments ),
@@ -2651,8 +2674,8 @@
type + " cannot follow a " + tokens [ tokens . length - 1 ]. type +
" at template:" + exp_offset + " near '" + match [ 0 ]. substring ( 0 , 20 ) +
"...'"
- ); Not a match, don't change the expression
Validate the token if a validation function is provided
if ( Twig . expression . handler [ type ]. validate &&
+ ); Not a match, don't change the expression
Validate the token if a validation function is provided
if ( Twig . expression . handler [ type ]. validate &&
! Twig . expression . handler [ type ]. validate ( match , tokens )) {
return match [ 0 ];
}
@@ -2667,7 +2690,7 @@
match_found = true ;
next = token_next ;
- exp_offset += match [ 0 ]. length ; Does the token need to return output back to the expression string
+ exp_offset += match [ 0 ]. length ;
Does the token need to return output back to the expression string
e.g. a function match of cycle( might return the '(' back to the expression
This allows look-ahead to differentiate between token types (e.g. functions and variable names)
if ( Twig . expression . handler [ type ]. transform ) {
return Twig . expression . handler [ type ]. transform ( match , tokens );
@@ -2682,7 +2705,7 @@
for ( type in Twig . expression . handler ) {
if ( Twig . expression . handler . hasOwnProperty ( type )) {
token_next = Twig . expression . handler [ type ]. next ;
- regex = Twig . expression . handler [ type ]. regex ; Twig.log.trace("Checking type ", type, " on ", expression);
if ( regex instanceof Array ) {
+ regex = Twig . expression . handler [ type ]. regex ; Twig.log.trace("Checking type ", type, " on ", expression);
if ( regex instanceof Array ) {
regex_array = regex ;
} else {
regex_array = [ regex ];
@@ -2692,7 +2715,7 @@
while ( regex_array . length > 0 ) {
regex = regex_array . pop ();
expression = expression . replace ( regex , match_function );
- } An expression token has been matched. Break the for loop and start trying to
+ }
An expression token has been matched. Break the for loop and start trying to
match the next template (if expression isn't empty.)
if ( match_found ) {
break ;
}
@@ -2719,18 +2742,18 @@
* @return {Object} The compiled token.
*/
Twig . expression . compile = function ( raw_token ) {
- var expression = raw_token . value , Tokenize expression
tokens = Twig . expression . tokenize ( expression ),
+ var expression = raw_token . value , Tokenize expression
tokens = Twig . expression . tokenize ( expression ),
token = null ,
output = [],
stack = [],
token_template = null ;
- Twig . log . trace ( "Twig.expression.compile: " , "Compiling " , expression ); Push tokens into RPN stack using the Sunting-yard algorithm
+ Twig . log . trace ( "Twig.expression.compile: " , "Compiling " , expression );
Push tokens into RPN stack using the Sunting-yard algorithm
See http://en.wikipedia.org/wiki/Shuntingyard algorithm
while ( tokens . length > 0 ) {
token = tokens . shift ();
token_template = Twig . expression . handler [ token . type ];
- Twig . log . trace ( "Twig.expression.compile: " , "Compiling " , token ); Compile the template
token_template . compile && token_template . compile ( token , stack , output );
+ Twig . log . trace ( "Twig.expression.compile: " , "Compiling " , token ); Compile the template
token_template . compile && token_template . compile ( token , stack , output );
Twig . log . trace ( "Twig.expression.compile: " , "Stack is" , stack );
Twig . log . trace ( "Twig.expression.compile: " , "Output is" , output );
@@ -2760,25 +2783,25 @@
* the given expression.
*/
Twig . expression . parse = function ( tokens , context ) {
- var that = this ; If the token isn't an array, make it one.
if ( ! ( tokens instanceof Array )) {
+ var that = this ; If the token isn't an array, make it one.
if ( ! ( tokens instanceof Array )) {
tokens = [ tokens ];
- } The output stack
The output stack
var stack = [],
token_template = null ;
tokens . forEach ( function ( token ) {
token_template = Twig . expression . handler [ token . type ];
token_template . parse && token_template . parse . apply ( that , [ token , stack , context ]);
- }); Pop the final value off the stack
return stack . pop ();
+ }); Pop the final value off the stack
return stack . pop ();
};
return Twig ;
-})( Twig || { } ); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { } );
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.expression.operator.js
+ twig.expression.operator.js
This file handles operator lookups and parsing.
var Twig = ( function ( Twig ) {
"use strict" ;
@@ -2803,11 +2826,11 @@
token . precidence = 20 ;
token . associativity = Twig . expression . operator . leftToRight ;
break ;
-
+
case ',' :
token . precidence = 18 ;
token . associativity = Twig . expression . operator . leftToRight ;
- break ; Ternary
Ternary
case '?' :
case ':' :
token . precidence = 16 ;
token . associativity = Twig . expression . operator . rightToLeft ;
@@ -2875,8 +2898,8 @@
Twig . log . trace ( "Twig.expression.operator.parse: " , "Handling " , operator );
var a , b , c ;
switch ( operator ) {
- case ':' : Ignore
Ignore
break ;
+
case '?' :
c = stack . pop (); // false expr
b = stack . pop (); // true expr
@@ -2887,7 +2910,7 @@
stack . push ( c );
}
break ;
-
+
case '+' :
b = parseFloat ( stack . pop ());
a = parseFloat ( stack . pop ());
@@ -3008,28 +3031,28 @@
a = stack . pop ();
stack . push ( ! containment ( a , b ) );
break ;
-
+
case 'in' :
b = stack . pop ();
a = stack . pop ();
stack . push ( containment ( a , b ) );
break ;
-
+
case '..' :
b = stack . pop ();
a = stack . pop ();
stack . push ( Twig . functions . range ( a , b ) );
break ;
-
+
default :
throw new Twig . Error ( operator + " is an unknown operator." );
}
};
-
+
var containment = function ( a , b ) {
if ( b . indexOf != undefined ) {
return b . indexOf ( a ) > - 1 ;
-
+
} else {
var el ;
for ( el in b ) {
@@ -3043,18 +3066,18 @@
return Twig ;
-})( Twig || { } ); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { } );
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.filters.js
+ twig.filters.js
-This file handles parsing filters.
var Twig = ( function ( Twig ) { Determine object type
function is ( type , obj ) {
+This file handles parsing filters.
var Twig = ( function ( Twig ) { Determine object type
function is ( type , obj ) {
var clas = Object . prototype . toString . call ( obj ). slice ( 8 , - 1 );
return obj !== undefined && obj !== null && clas === type ;
}
- Twig . filters = { String Filters
upper : function ( value ) {
+ Twig . filters = { String Filters
upper : function ( value ) {
if ( typeof value !== "string" ) {
return value ;
}
@@ -3096,7 +3119,7 @@
} else {
return 0 ;
}
- }, Array/Object Filters
reverse : function ( value ) {
+ }, Array/Object Filters
reverse : function ( value ) {
if ( is ( "Array" , value )) {
return value . reverse ();
} else if ( is ( "String" , value )) {
@@ -3110,7 +3133,7 @@
sort : function ( value ) {
if ( is ( "Array" , value )) {
return value . sort ();
- } else if ( value instanceof Object ) { Sorting objects isn't obvious since the order of
+ } else if ( value instanceof Object ) {
Sorting objects isn't obvious since the order of
returned keys isn't guaranteedin JavaScript.
Because of this we use a "hidden" key called _keys to
store the keys in the order we want to return them.
delete value . _keys ;
@@ -3142,7 +3165,7 @@
if ( value === undefined ){
return ;
}
-
+
return encodeURIComponent ( value );
},
join : function ( value , params ) {
@@ -3192,7 +3215,7 @@
merge : function ( value , params ) {
var obj = [],
arr_index = 0 ,
- keyset = []; Check to see if all the objects being merged are arrays
if ( ! ( value instanceof Array )) { Create obj as an Object
obj = { };
+ keyset = []; Check to see if all the objects being merged are arrays
if ( ! ( value instanceof Array )) { Create obj as an Object
obj = { };
} else {
params . forEach ( function ( param ) {
if ( ! ( param instanceof Array )) {
@@ -3214,7 +3237,7 @@
keyset = value . _keys || Object . keys ( value );
keyset . forEach ( function ( key ) {
obj [ key ] = value [ key ];
- obj . _keys . push ( key ); Handle edge case where a number index in an object is greater than
+ obj . _keys . push ( key );
Handle edge case where a number index in an object is greater than
the array counter. In such a case, the array counter is increased
one past the index.
@@ -3225,7 +3248,7 @@
arr_index = int_key + 1 ;
}
});
- } mixin the merge arrays
params . forEach ( function ( param ) {
+ } mixin the merge arrays
params . forEach ( function ( param ) {
if ( param instanceof Array ) {
param . forEach ( function ( val ) {
if ( obj . _keys ) obj . _keys . push ( arr_index );
@@ -3287,7 +3310,7 @@
if ( value === undefined ){
return ;
}
-
+
return Twig . lib . strip_tags ( value );
},
@@ -3320,7 +3343,7 @@
/**
* Adapted from: http://phpjs.org/functions/number_format:481
- */
+ */
number_format : function ( value , params ) {
var number = value ,
decimals = ( params && params [ 0 ]) ? params [ 0 ] : undefined ,
@@ -3334,7 +3357,7 @@
toFixedFix = function ( n , prec ) {
var k = Math . pow ( 10 , prec );
return '' + Math . round ( n * k ) / k ;
- }; Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = ( prec ? toFixedFix ( n , prec ) : '' + Math . round ( n )). split ( '.' );
+ }; Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = ( prec ? toFixedFix ( n , prec ) : '' + Math . round ( n )). split ( '.' );
if ( s [ 0 ]. length > 3 ) {
s [ 0 ] = s [ 0 ]. replace ( /\B(?=(?:\d{3})+(?!\d))/g , sep );
}
@@ -3381,20 +3404,20 @@
return Twig ;
-})( Twig || { }); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { });
Twig.js
+Copyright (c) 2011-2013 John Roepke
2012 Hadrien Lanneau
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.functions.js
+ twig.functions.js
-This file handles parsing filters.
var Twig = ( function ( Twig ) { Determine object type
function is ( type , obj ) {
+This file handles parsing filters.
var Twig = ( function ( Twig ) { Determine object type
function is ( type , obj ) {
var clas = Object . prototype . toString . call ( obj ). slice ( 8 , - 1 );
return obj !== undefined && obj !== null && clas === type ;
}
- Twig . functions = { attribute, block, constant, date, dump, parent, random,.
Range function from http://phpjs.org/functions/range:499
-Used under an MIT License
range : function ( low , high , step ) { http://kevin.vanzonneveld.net
+ Twig . functions = {
attribute, block, constant, date, dump, parent, random,.
Range function from http://phpjs.org/functions/range:499
+Used under an MIT License
range : function ( low , high , step ) { http://kevin.vanzonneveld.net
+ original by: Waldo Malqui Silva
* example 1: range ( 0, 12 );
* returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@@ -3494,7 +3517,7 @@
} else {
displayVar ( variable );
}
- };
handle no argument case by dumping the entire render context
if ( args . length == 0 ) args . push ( this . context );
+ }; handle no argument case by dumping the entire render context
if ( args . length == 0 ) args . push ( this . context );
args . forEach ( function ( variable ) {
dumpVar ( variable );
@@ -3510,13 +3533,13 @@
dateObj = date ;
} else if ( Twig . lib . is ( "String" , date )) {
dateObj = new Date ( Twig . lib . strtotime ( date ) * 1000 );
- } else if ( Twig . lib . is ( "Number" , date )) { timestamp
dateObj = new Date ( date * 1000 );
+ } else if ( Twig . lib . is ( "Number" , date )) { timestamp
dateObj = new Date ( date * 1000 );
} else {
throw new Twig . Error ( "Unable to parse date " + date );
}
return dateObj ;
},
- parent : function () { Add a placeholder
return Twig . placeholders . parent ;
+ parent : function () { Add a placeholder
return Twig . placeholders . parent ;
}
};
@@ -3533,17 +3556,17 @@
return Twig ;
-})( Twig || { }); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { });
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.tests.js
+ twig.tests.js
This file handles expression tests. (is empty, is not defined, etc...)
var Twig = ( function ( Twig ) {
"use strict" ;
Twig . tests = {
empty : function ( value ) {
- if ( value === null || value === undefined ) return true ; Handler numbers
if ( typeof value === "number" ) return false ; // numbers are never "empty" Handle strings and arrays
if ( value . length && value . length > 0 ) return false ; Handle objects
for ( var key in value ) {
+ if ( value === null || value === undefined ) return true ; Handler numbers
if ( typeof value === "number" ) return false ; // numbers are never "empty" Handle strings and arrays
if ( value . length && value . length > 0 ) return false ; Handle objects
for ( var key in value ) {
if ( value . hasOwnProperty ( key )) return false ;
}
return true ;
@@ -3586,11 +3609,11 @@
};
return Twig ;
-})( Twig || { } ); Twig.js
-Copyright (c) 2011-2012 John Roepke
+})( Twig || { } );
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.function.js
+ twig.function.js
This file provides extension points and other hooks into the twig functionality.
var Twig = ( function ( Twig ) {
"use strict" ;
@@ -3659,15 +3682,15 @@
}, params . load , params . error );
}
- }; Extend Twig with a new filter.
Twig . exports . extendFilter = function ( filter , definition ) {
+ }; Extend Twig with a new filter.
Twig . exports . extendFilter = function ( filter , definition ) {
Twig . filter . extend ( filter , definition );
- }; Extend Twig with a new function.
Twig . exports . extendFunction = function ( fn , definition ) {
+ }; Extend Twig with a new function.
Twig . exports . extendFunction = function ( fn , definition ) {
Twig . _function . extend ( fn , definition );
- }; Extend Twig with a new test.
Twig . exports . extendTest = function ( test , definition ) {
+ }; Extend Twig with a new test.
Twig . exports . extendTest = function ( test , definition ) {
Twig . test . extend ( test , definition );
- }; Extend Twig with a new definition.
Twig . exports . extendTag = function ( definition ) {
+ }; Extend Twig with a new definition.
Twig . exports . extendTag = function ( definition ) {
Twig . logic . extend ( definition );
- }; Provide an environment for extending Twig core.
+ };
Provide an environment for extending Twig core.
Calls fn with the internal Twig object.
Twig . exports . extend = function ( fn ) {
fn ( Twig );
};
@@ -3684,7 +3707,7 @@
Twig . exports . compile = function ( markup , options ) {
var id = options . filename ,
path = options . filename ,
- template ; Try to load the template from the cache
template = new Twig . Template ({
+ template ; Try to load the template from the cache
template = new Twig . Template ({
data : markup ,
path : path ,
id : id ,
@@ -3704,7 +3727,7 @@
* @param {Function} fn callback.
*/
- Twig . exports . renderFile = function ( path , options , fn ) { handle callback in options
if ( 'function' == typeof options ) {
+ Twig . exports . renderFile = function ( path , options , fn ) { handle callback in options
if ( 'function' == typeof options ) {
fn = options ;
options = {};
}
@@ -3714,9 +3737,9 @@
var params = {
path : path ,
base : options . settings [ 'views' ],
- load : function ( template ) { render and return template
fn ( null , template . render ( options ));
+ load : function ( template ) { render and return template
fn ( null , template . render ( options ));
}
- }; mixin any options provided to the express app.
var view_options = options . settings [ 'twig options' ];
+ }; mixin any options provided to the express app.
var view_options = options . settings [ 'twig options' ];
if ( view_options ) {
for ( var option in view_options ) if ( view_options . hasOwnProperty ( option )) {
@@ -3725,7 +3748,7 @@
}
Twig . exports . twig ( params );
- }; Express 3 handler
Twig . exports . __express = Twig . exports . renderFile ;
+ }; Express 3 handler
Twig . exports . __express = Twig . exports . renderFile ;
/**
* Shoud Twig.js cache templates.
@@ -3739,23 +3762,22 @@
}
return Twig ;
-}) ( Twig || { }); Twig.js
-Copyright (c) 2011-2012 John Roepke
+}) ( Twig || { });
Twig.js
+Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.tests.js
+ twig.tests.js
This file handles compiling templates into JS
var Twig = ( function ( Twig ) {
/**
* Namespace for compilation.
*/
- Twig . compiler = {
+ Twig . compiler = {
module : {}
- };
- Compile a Twig Template to output.
Twig . compiler . compile = function ( template , options ) { Get tokens
var tokens = JSON . stringify ( template . tokens )
+ }; Compile a Twig Template to output.
Twig . compiler . compile = function ( template , options ) { Get tokens
var tokens = JSON . stringify ( template . tokens )
, id = template . id
, output ;
-
+
if ( options . module ) {
if ( Twig . compiler . module [ options . module ] === undefined ) {
throw new Twig . Error ( "Unable to find module type " + options . module );
@@ -3766,7 +3788,7 @@
}
return output ;
};
-
+
Twig . compiler . module = {
amd : function ( id , tokens , pathToTwig ) {
return 'define(["' + pathToTwig + '"], function (Twig) {\n\tvar twig = Twig.twig;\n' + Twig . compiler . wrap ( id , tokens ) + '\n\treturn templates;\n});' ;
@@ -3782,25 +3804,29 @@
+ '\n});'
}
};
-
+
Twig . compiler . wrap = function ( id , tokens ) {
return 'twig({id:"' + id . replace ( '"' , '\\"' ) + '", data:' + tokens + ', precompiled: true});\n' ;
};
-
+
return Twig ;
-})( Twig || {}); // Twig.js Copyright (c) 2011-2012 John Roepke
+})( Twig || {}); // Twig.js
Copyright (c) 2011-2013 John Roepke
Available under the BSD 2-Clause License
https://github.com/justjohn/twig.js
-
twig.module.js
+ twig.module.js
-Provide a CommonJS module export.
if ( typeof module !== 'undefined' && module . declare ) { Provide a CommonJS Modules/2.0 draft 8 module
module . declare ([], function ( require , exports , module ) { Add exports from the Twig exports
for ( key in Twig . exports ) {
+Provide a CommonJS module export.
if ( typeof module !== 'undefined' && module . declare ) { Provide a CommonJS Modules/2.0 draft 8 module
module . declare ([], function ( require , exports , module ) { Add exports from the Twig exports
for ( key in Twig . exports ) {
if ( Twig . exports . hasOwnProperty ( key )) {
exports [ key ] = Twig . exports [ key ];
- }
+ }
}
});
-} else if ( typeof module !== 'undefined' && module . exports ) { Provide a CommonJS Modules/1.1 module
module . exports = Twig . exports ;
-} else { Export for browser use
window . twig = Twig . exports . twig ;
+} else if ( typeof define == 'function' && define . amd ) {
+ define ( function () {
+ return Twig . exports ;
+ });
+} else if ( typeof module !== 'undefined' && module . exports ) { Provide a CommonJS Modules/1.1 module
module . exports = Twig . exports ;
+} else { Export for browser use
window . twig = Twig . exports . twig ;
window . Twig = Twig . exports ;
}
diff --git a/package.json b/package.json
index d1f76109..542f25b1 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"author": "John Roepke (http://john.sh/)",
"name": "twig",
"description": "JS port of the Twig templating language.",
- "version": "0.5.5",
+ "version": "0.5.6",
"homepage": "https://github.com/justjohn/twig.js",
"licenses": [
{ "type": "BSD-2-Clause",
diff --git a/src/twig.compiler.js b/src/twig.compiler.js
index 93d98cd6..ef7a9fd7 100644
--- a/src/twig.compiler.js
+++ b/src/twig.compiler.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -10,17 +10,17 @@ var Twig = (function (Twig) {
/**
* Namespace for compilation.
*/
- Twig.compiler = {
+ Twig.compiler = {
module: {}
};
-
+
// Compile a Twig Template to output.
Twig.compiler.compile = function(template, options) {
// Get tokens
var tokens = JSON.stringify(template.tokens)
, id = template.id
, output;
-
+
if (options.module) {
if (Twig.compiler.module[options.module] === undefined) {
throw new Twig.Error("Unable to find module type " + options.module);
@@ -31,7 +31,7 @@ var Twig = (function (Twig) {
}
return output;
};
-
+
Twig.compiler.module = {
amd: function(id, tokens, pathToTwig) {
return 'define(["' + pathToTwig + '"], function (Twig) {\n\tvar twig = Twig.twig;\n' + Twig.compiler.wrap(id, tokens) + '\n\treturn templates;\n});';
@@ -47,10 +47,10 @@ var Twig = (function (Twig) {
+ '\n});'
}
};
-
+
Twig.compiler.wrap = function(id, tokens) {
return 'twig({id:"'+id.replace('"', '\\"')+'", data:'+tokens+', precompiled: true});\n';
};
-
+
return Twig;
})(Twig || {});
\ No newline at end of file
diff --git a/src/twig.core.js b/src/twig.core.js
index 744cf5fa..398ad164 100644
--- a/src/twig.core.js
+++ b/src/twig.core.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/src/twig.exports.js b/src/twig.exports.js
index a0784c0f..0e02f2f1 100644
--- a/src/twig.exports.js
+++ b/src/twig.exports.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/src/twig.expression.js b/src/twig.expression.js
index 895395ff..2fd25e71 100644
--- a/src/twig.expression.js
+++ b/src/twig.expression.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/src/twig.expression.operator.js b/src/twig.expression.operator.js
index e3a48af2..b3f0c3d5 100644
--- a/src/twig.expression.operator.js
+++ b/src/twig.expression.operator.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -29,7 +29,7 @@ var Twig = (function (Twig) {
token.precidence = 20;
token.associativity = Twig.expression.operator.leftToRight;
break;
-
+
case ',':
token.precidence = 18;
token.associativity = Twig.expression.operator.leftToRight;
@@ -107,7 +107,7 @@ var Twig = (function (Twig) {
case ':':
// Ignore
break;
-
+
case '?':
c = stack.pop(); // false expr
b = stack.pop(); // true expr
@@ -118,7 +118,7 @@ var Twig = (function (Twig) {
stack.push(c);
}
break;
-
+
case '+':
b = parseFloat(stack.pop());
a = parseFloat(stack.pop());
@@ -239,28 +239,28 @@ var Twig = (function (Twig) {
a = stack.pop();
stack.push( !containment(a, b) );
break;
-
+
case 'in':
b = stack.pop();
a = stack.pop();
stack.push( containment(a, b) );
break;
-
+
case '..':
b = stack.pop();
a = stack.pop();
stack.push( Twig.functions.range(a, b) );
break;
-
+
default:
throw new Twig.Error(operator + " is an unknown operator.");
}
};
-
+
var containment = function(a, b) {
if (b.indexOf != undefined) {
return b.indexOf(a) > -1;
-
+
} else {
var el;
for (el in b) {
diff --git a/src/twig.filters.js b/src/twig.filters.js
index 7e0d9799..8f57439f 100644
--- a/src/twig.filters.js
+++ b/src/twig.filters.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -110,7 +110,7 @@ var Twig = (function (Twig) {
if (value === undefined){
return;
}
-
+
return encodeURIComponent(value);
},
join: function(value, params) {
@@ -266,7 +266,7 @@ var Twig = (function (Twig) {
if (value === undefined){
return;
}
-
+
return Twig.lib.strip_tags(value);
},
@@ -299,7 +299,7 @@ var Twig = (function (Twig) {
/**
* Adapted from: http://phpjs.org/functions/number_format:481
- */
+ */
number_format: function(value, params) {
var number = value,
decimals = (params && params[0]) ? params[0] : undefined,
diff --git a/src/twig.functions.js b/src/twig.functions.js
index 201cbf5c..72509e90 100644
--- a/src/twig.functions.js
+++ b/src/twig.functions.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// 2012 Hadrien Lanneau
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -17,7 +17,7 @@ var Twig = (function (Twig) {
Twig.functions = {
// attribute, block, constant, date, dump, parent, random,.
-
+
// Range function from http://phpjs.org/functions/range:499
// Used under an MIT License
range: function (low, high, step) {
diff --git a/src/twig.header.js b/src/twig.header.js
index a357dda5..ed47ddd7 100644
--- a/src/twig.header.js
+++ b/src/twig.header.js
@@ -1,11 +1,11 @@
-// Twig.js 0.5.5
-// Copyright (c) 2011-2012 John Roepke
+// Twig.js 0.5.6
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
var Twig = (function (Twig) {
- Twig.VERSION = "0.5.5";
+ Twig.VERSION = "0.5.6";
return Twig;
})(Twig || {});
diff --git a/src/twig.logic.js b/src/twig.logic.js
index 971ff918..f2678dc2 100644
--- a/src/twig.logic.js
+++ b/src/twig.logic.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/src/twig.module.js b/src/twig.module.js
index ea8780a1..07a832a1 100644
--- a/src/twig.module.js
+++ b/src/twig.module.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/src/twig.tests.js b/src/twig.tests.js
index 73b926b5..b60a2bba 100644
--- a/src/twig.tests.js
+++ b/src/twig.tests.js
@@ -1,5 +1,5 @@
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/twig.js b/twig.js
index 452261e9..cc7f7ddb 100644
--- a/twig.js
+++ b/twig.js
@@ -1,16 +1,16 @@
-// Twig.js 0.5.5
-// Copyright (c) 2011-2012 John Roepke
+// Twig.js 0.5.6
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
var Twig = (function (Twig) {
- Twig.VERSION = "0.5.5";
+ Twig.VERSION = "0.5.6";
return Twig;
})(Twig || {});
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -1518,7 +1518,7 @@ var Twig = (function(Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -2317,7 +2317,7 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -3297,7 +3297,7 @@ var Twig = (function (Twig) {
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -3327,7 +3327,7 @@ var Twig = (function (Twig) {
token.precidence = 20;
token.associativity = Twig.expression.operator.leftToRight;
break;
-
+
case ',':
token.precidence = 18;
token.associativity = Twig.expression.operator.leftToRight;
@@ -3405,7 +3405,7 @@ var Twig = (function (Twig) {
case ':':
// Ignore
break;
-
+
case '?':
c = stack.pop(); // false expr
b = stack.pop(); // true expr
@@ -3416,7 +3416,7 @@ var Twig = (function (Twig) {
stack.push(c);
}
break;
-
+
case '+':
b = parseFloat(stack.pop());
a = parseFloat(stack.pop());
@@ -3537,28 +3537,28 @@ var Twig = (function (Twig) {
a = stack.pop();
stack.push( !containment(a, b) );
break;
-
+
case 'in':
b = stack.pop();
a = stack.pop();
stack.push( containment(a, b) );
break;
-
+
case '..':
b = stack.pop();
a = stack.pop();
stack.push( Twig.functions.range(a, b) );
break;
-
+
default:
throw new Twig.Error(operator + " is an unknown operator.");
}
};
-
+
var containment = function(a, b) {
if (b.indexOf != undefined) {
return b.indexOf(a) > -1;
-
+
} else {
var el;
for (el in b) {
@@ -3574,7 +3574,7 @@ var Twig = (function (Twig) {
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -3685,7 +3685,7 @@ var Twig = (function (Twig) {
if (value === undefined){
return;
}
-
+
return encodeURIComponent(value);
},
join: function(value, params) {
@@ -3841,7 +3841,7 @@ var Twig = (function (Twig) {
if (value === undefined){
return;
}
-
+
return Twig.lib.strip_tags(value);
},
@@ -3874,7 +3874,7 @@ var Twig = (function (Twig) {
/**
* Adapted from: http://phpjs.org/functions/number_format:481
- */
+ */
number_format: function(value, params) {
var number = value,
decimals = (params && params[0]) ? params[0] : undefined,
@@ -3939,7 +3939,7 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// 2012 Hadrien Lanneau
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -3957,7 +3957,7 @@ var Twig = (function (Twig) {
Twig.functions = {
// attribute, block, constant, date, dump, parent, random,.
-
+
// Range function from http://phpjs.org/functions/range:499
// Used under an MIT License
range: function (low, high, step) {
@@ -4110,7 +4110,7 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4172,7 +4172,7 @@ var Twig = (function (Twig) {
return Twig;
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4358,7 +4358,7 @@ var Twig = (function (Twig) {
}) (Twig || { });
// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4369,17 +4369,17 @@ var Twig = (function (Twig) {
/**
* Namespace for compilation.
*/
- Twig.compiler = {
+ Twig.compiler = {
module: {}
};
-
+
// Compile a Twig Template to output.
Twig.compiler.compile = function(template, options) {
// Get tokens
var tokens = JSON.stringify(template.tokens)
, id = template.id
, output;
-
+
if (options.module) {
if (Twig.compiler.module[options.module] === undefined) {
throw new Twig.Error("Unable to find module type " + options.module);
@@ -4390,7 +4390,7 @@ var Twig = (function (Twig) {
}
return output;
};
-
+
Twig.compiler.module = {
amd: function(id, tokens, pathToTwig) {
return 'define(["' + pathToTwig + '"], function (Twig) {\n\tvar twig = Twig.twig;\n' + Twig.compiler.wrap(id, tokens) + '\n\treturn templates;\n});';
@@ -4406,14 +4406,14 @@ var Twig = (function (Twig) {
+ '\n});'
}
};
-
+
Twig.compiler.wrap = function(id, tokens) {
return 'twig({id:"'+id.replace('"', '\\"')+'", data:'+tokens+', precompiled: true});\n';
};
-
+
return Twig;
})(Twig || {});// Twig.js
-// Copyright (c) 2011-2012 John Roepke
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/twig.min.js b/twig.min.js
index 38cef01a..c3609de1 100644
--- a/twig.min.js
+++ b/twig.min.js
@@ -1,6 +1,6 @@
-// Twig.js 0.5.5
-// Copyright (c) 2011-2012 John Roepke
+// Twig.js 0.5.6
+// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
-var Twig=function(a){return a.VERSION="0.5.5",a}(Twig||{}),Twig=function(a){function b(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a}function c(b,c){var d,e,f="/",g=[],h;if(b.url)d=b.url;else{if(!b.path)throw new a.Error("Cannot extend an inline template.");var i=require("path"),j=i.sep||f,k=new RegExp("^\\.{1,2}"+j.replace("\\","\\\\"));b.base!==undefined&&c.match(k)==null?(c=c.replace(b.base,""),d=b.base+j):d=b.path,d=d.replace(j+j,j),f=j}e=d.split(f),e.pop(),e=e.concat(c.split(f));while(e.length>0)h=e.shift(),h!="."&&(h==".."&&g.length>0&&g[g.length-1]!=".."?g.pop():g.push(h));return g.join(f)}return"use strict",a.trace=!1,a.debug=!1,a.cache=!0,a.placeholders={parent:"{{|PARENT|}}"},a.Error=function(a){this.message=a,this.name="TwigException",this.type="TwigException"},a.Error.prototype.toString=function(){return this.name+": "+this.message},a.log={trace:function(){a.trace&&console&&console.log(Array.prototype.slice.call(arguments))},debug:function(){a.debug&&console&&console.log(Array.prototype.slice.call(arguments))}},a.token={},a.token.type={output:"output",logic:"logic",comment:"comment",raw:"raw"},a.token.definitions={output:{type:a.token.type.output,open:"{{",close:"}}"},logic:{type:a.token.type.logic,open:"{%",close:"%}"},comment:{type:a.token.type.comment,open:"{#",close:"#}"}},a.token.strings=['"',"'"],a.token.findStart=function(b){var c={position:null,def:null},d,e,f;for(d in a.token.definitions)a.token.definitions.hasOwnProperty(d)&&(e=a.token.definitions[d],f=b.indexOf(e.open),a.log.trace("Twig.token.findStart: ","Searching for ",e.open," found at ",f),f>=0&&(c.position===null||f=0))throw new a.Error("Unable to find closing bracket '"+c.close+"'"+" opened near template position "+d);e=j,f=!0,o=a.token.strings.length;for(n=0;n0&&l0)e=a.token.findStart(b),a.log.trace("Twig.tokenize: ","Found token: ",e),e.position!==null?(e.position>0&&c.push({type:a.token.type.raw,value:b.substring(0,e.position)}),b=b.substr(e.position+e.def.open.length),d+=e.position+e.def.open.length,f=a.token.findEnd(b,e.def,d),a.log.trace("Twig.tokenize: ","Token ends at ",f),c.push({type:e.def.type,value:b.substring(0,f).trim()}),b=b.substr(f+e.def.close.length),d+=f+e.def.close.length):(c.push({type:a.token.type.raw,value:b}),b="");return c},a.compile=function(b){var c=[],d=[],e=[],f=null,g=null,h=null,i=null,j=null,k=null,l=null,m=null,n=null;while(b.length>0){f=b.shift(),a.log.trace("Compiling token ",f);switch(f.type){case a.token.type.raw:d.length>0?e.push(f):c.push(f);break;case a.token.type.logic:g=a.logic.compile.apply(this,[f]),l=g.type,m=a.logic.handler[l].open,n=a.logic.handler[l].next,a.log.trace("Twig.compile: ","Compiled logic token to ",g," next is: ",n," open is : ",m);if(m!==undefined&&!m){i=d.pop(),j=a.logic.handler[i.type];if(j.next.indexOf(l)<0)throw new Error(l+" not expected after a "+i.type);i.output=i.output||[],i.output=i.output.concat(e),e=[],k={type:a.token.type.logic,token:i},d.length>0?e.push(k):c.push(k)}n!==undefined&&n.length>0?(a.log.trace("Twig.compile: ","Pushing ",g," to logic stack."),d.length>0&&(i=d.pop(),i.output=i.output||[],i.output=i.output.concat(e),d.push(i),e=[]),d.push(g)):m!==undefined&&m&&(k={type:a.token.type.logic,token:g},d.length>0?e.push(k):c.push(k));break;case a.token.type.comment:break;case a.token.type.output:a.expression.compile.apply(this,[f]),d.length>0?e.push(f):c.push(f)}a.log.trace("Twig.compile: "," Output: ",c," Logic Stack: ",d," Pending Output: ",e)}if(d.length>0)throw h=d.pop(),new Error("Unable to find an end tag for "+h.type+", expecting one of "+h.next);return c},a.parse=function(b,c){var d=[],e=!0,f=this;return c=c||{},b.forEach(function(g){a.log.debug("Twig.parse: ","Parsing token: ",g);switch(g.type){case a.token.type.raw:d.push(g.value);break;case a.token.type.logic:var h=g.token,i=a.logic.parse.apply(f,[h,c,e]);i.chain!==undefined&&(e=i.chain),i.context!==undefined&&(c=i.context),i.output!==undefined&&d.push(i.output);break;case a.token.type.comment:break;case a.token.type.output:a.log.debug("Twig.parse: ","Output token: ",g.stack),d.push(a.expression.parse.apply(f,[g.stack,c]))}}),d.join("")},a.prepare=function(b){var c,d;return a.log.debug("Twig.prepare: ","Tokenizing ",b),d=a.tokenize.apply(this,[b]),a.log.debug("Twig.prepare: ","Compiling ",d),c=a.compile.apply(this,[d]),a.log.debug("Twig.prepare: ","Compiled ",c),c},a.Templates={registry:{}},a.validateId=function(b){if(b==="prototype")throw new a.Error(b+" is not a valid twig identifier");if(a.Templates.registry.hasOwnProperty(b))throw new a.Error("There is already a template with the ID "+b);return!0},a.Templates.save=function(b){if(b.id===undefined)throw new a.Error("Unable to save template with no id");a.Templates.registry[b.id]=b},a.Templates.load=function(b){return a.Templates.registry.hasOwnProperty(b)?a.Templates.registry[b]:null},a.Templates.loadRemote=function(b,c,d,e){var f=c.id,g=c.method,h=c.async,i=c.precompiled,j=null;h===undefined&&(h=!0),f===undefined&&(f=b),c.id=f;if(a.cache&&a.Templates.registry.hasOwnProperty(f))return d&&d(a.Templates.registry[f]),a.Templates.registry[f];if(g=="ajax"){if(typeof XMLHttpRequest=="undefined")throw new a.Error("Unsupported platform: Unable to do remote requests because there is no XMLHTTPRequest implementation");var k=new XMLHttpRequest;k.onreadystatechange=function(){var e=null;k.readyState==4&&(a.log.debug("Got template ",k.responseText),i===!0?e=JSON.parse(k.responseText):e=k.responseText,c.url=b,c.data=e,j=new a.Template(c),d&&d(j))},k.open("GET",b,h),k.send()}else(function(){var f=require("fs"),g=require("path"),k=null,l=function(f,g){if(f){e&&e(f);return}i===!0&&(g=JSON.parse(g)),c.data=g,c.path=b,j=new a.Template(c),d&&d(j)};if(h===!0)f.stat(b,function(c,d){if(c||!d.isFile())throw new a.Error("Unable to find template file "+b);f.readFile(b,"utf8",l)});else{if(!f.statSync(b).isFile())throw new a.Error("Unable to find template file "+b);k=f.readFileSync(b,"utf8"),l(undefined,k)}})();return h===!1?j:!0},a.Template=function(c){var d=c.data,e=c.id,f=c.blocks,g=c.base,h=c.path,i=c.url,j=c.options;this.id=e,this.base=g,this.path=h,this.url=i,this.options=j,this.reset(f),b("String",d)?this.tokens=a.prepare.apply(this,[d]):this.tokens=d,e!==undefined&&a.Templates.save(this)},a.Template.prototype.reset=function(b){a.log.debug("Twig.Template.reset","Reseting template "+this.id),this.blocks={},this.child={blocks:b||{}},this.extend=null},a.Template.prototype.render=function(b,d){d=d||{};var e,f;return this.context=b||{},this.reset(),d.blocks&&(this.blocks=d.blocks),e=a.parse.apply(this,[this.tokens,this.context]),this.extend?(f=c(this,this.extend),this.parent=a.Templates.loadRemote(f,{method:this.url?"ajax":"fs",base:this.base,async:!1,id:f,options:this.options}),this.parent.render(this.context,{blocks:this.blocks})):d.output=="blocks"?this.blocks:e},a.Template.prototype.importFile=function(b){var d=c(this,b),e=a.Templates.loadRemote(d,{method:this.url?"ajax":"fs",async:!1,options:this.options,id:d});return e},a.Template.prototype.importBlocks=function(a,b){var c=this.importFile(a),d=this.context,e=this,f;b=b||!1,c.render(d),Object.keys(c.blocks).forEach(function(a){if(b||e.blocks[a]===undefined)e.blocks[a]=c.blocks[a]})},a.Template.prototype.compile=function(b){return a.compiler.compile(this,b)},a}(Twig||{});(function(){"use strict",String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(c===0)return-1;var d=0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==Infinity&&d!==-Infinity&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var e=d>=0?d:Math.max(c-Math.abs(d),0);for(;e>>0;if({}.toString.call(a)!="[object Function]")throw new TypeError(a+" is not a function");b&&(c=b),d=0;while(d0;c[--b]=a);return c.join("")}var d=function(){return d.cache.hasOwnProperty(arguments[0])||(d.cache[arguments[0]]=d.parse(arguments[0])),d.format.call(null,d.cache[arguments[0]],arguments)};return d.format=function(d,e){var f=1,g=d.length,h="",i,j=[],k,l,m,n,o,p;for(k=0;k=0?"+"+i:i,o=m[4]?m[4]=="0"?"0":m[4].charAt(1):" ",p=m[6]-String(i).length,n=m[6]?c(o,p):"",j.push(m[5]?i+n:n+i)}}return j.join("")},d.cache={},d.parse=function(a){var b=a,c=[],d=[],e=0;while(b){if((c=/^[^\x25]+/.exec(b))!==null)d.push(c[0]);else if((c=/^\x25{2}/.exec(b))!==null)d.push("%");else{if((c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b))===null)throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(g))===null)throw"[sprintf] huh?";f.push(h[1]);while((g=g.substring(h[0].length))!=="")if((h=/^\.([a-z_][a-z_\d]*)/i.exec(g))!==null)f.push(h[1]);else{if((h=/^\[(\d+)\]/.exec(g))===null)throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(e===3)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},d}(),c=function(a,c){return c.unshift(a),b.apply(null,c)};return a.lib.sprintf=b,a.lib.vsprintf=c,function(){function f(a){return(a=Math.abs(a)%100)%10==1&&a!=11?"st":a%10==2&&a!=12?"nd":a%10==3&&a!=13?"rd":"th"}function g(a){var b=new Date(a.getFullYear()+1,0,4);return(b-a)/864e5<7&&(a.getDay()+6)%7<(b.getDay()+6)%7?b.getFullYear():a.getMonth()>0||a.getDate()>=4?a.getFullYear():a.getFullYear()-((a.getDay()+6)%7-a.getDate()>2?1:0)}function h(a){var b=new Date(g(a),0,4);return b.setDate(b.getDate()-(b.getDay()+6)%7),parseInt((a-b)/6048e5)+1}var b="Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),c="Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),d="Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),e="January,February,March,April,May,June,July,August,September,October,November,December".split(",");a.lib.formatDate=function(a,i){if(typeof i!="string"||/^\s*$/.test(i))return a+"";var j=new Date(a.getFullYear(),0,1),k=a;return i.replace(/[dDjlNSwzWFmMntLoYyaABgGhHisu]/g,function(a){switch(a){case"d":return("0"+k.getDate()).replace(/^.+(..)$/,"$1");case"D":return b[k.getDay()];case"j":return k.getDate();case"l":return c[k.getDay()];case"N":return(k.getDay()+6)%7+1;case"S":return f(k.getDate());case"w":return k.getDay();case"z":return Math.ceil((j-k)/864e5);case"W":return("0"+h(k)).replace(/^.(..)$/,"$1");case"F":return e[k.getMonth()];case"m":return("0"+(k.getMonth()+1)).replace(/^.+(..)$/,"$1");case"M":return d[k.getMonth()];case"n":return k.getMonth()+1;case"t":return(new Date(k.getFullYear(),k.getMonth()+1,-1)).getDate();case"L":return(new Date(k.getFullYear(),1,29)).getDate()==29?1:0;case"o":return g(k);case"Y":return k.getFullYear();case"y":return(k.getFullYear()+"").replace(/^.+(..)$/,"$1");case"a":return k.getHours()<12?"am":"pm";case"A":return k.getHours()<12?"AM":"PM";case"B":return Math.floor(((k.getUTCHours()+1)%24+k.getUTCMinutes()/60+k.getUTCSeconds()/3600)*1e3/24);case"g":return k.getHours()%12!=0?k.getHours()%12:12;case"G":return k.getHours();case"h":return("0"+(k.getHours()%12!=0?k.getHours()%12:12)).replace(/^.+(..)$/,"$1");case"H":return("0"+k.getHours()).replace(/^.+(..)$/,"$1");case"i":return("0"+k.getMinutes()).replace(/^.+(..)$/,"$1");case"s":return("0"+k.getSeconds()).replace(/^.+(..)$/,"$1");case"u":return k.getMilliseconds()}})}}(),a.lib.strip_tags=function(a,b){b=(((b||"")+"").toLowerCase().match(/<[a-z][a-z0-9]*>/g)||[]).join("");var c=/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,d=/|<\?(?:php)?[\s\S]*?\?>/gi;return a.replace(d,"").replace(c,function(a,c){return b.indexOf("<"+c.toLowerCase()+">")>-1?a:""})},a.lib.strtotime=function(a,b){var c,d,e,f,g="";a=a.replace(/\s{2,}|^\s|\s$/g," "),a=a.replace(/[\t\r\n]/g,"");if(a==="now")return b===null||isNaN(b)?(new Date).getTime()/1e3|0:b|0;if(!isNaN(g=Date.parse(a)))return g/1e3|0;b?b=new Date(b*1e3):b=new Date,a=a.toLowerCase();var h={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]},i=function(a){var c=a[2]&&a[2]==="ago",d=(d=a[0]==="last"?-1:1)*(c?-1:1);switch(a[0]){case"last":case"next":switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d);break;case"mon":if(a[1]==="month"){b.setMonth(b.getMonth()+d);break};default:var e=h.day[a[1].substring(0,3)];if(typeof e!="undefined"){var f=e-b.getDay();f===0?f=7*d:f>0?a[0]==="last"&&(f-=7):a[0]==="next"&&(f+=7),b.setDate(b.getDate()+f),b.setHours(0,0,0,0)}}break;default:if(!/\d+/.test(a[0]))return!1;d*=parseInt(a[0],10);switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"mon":b.setMonth(b.getMonth()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d)}}return!0};e=a.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(e!==null)return e[2]?e[3]||(e[2]+=":00"):e[2]="00:00:00",f=e[1].split(/-/g),f[1]=h.mon[f[1]-1]||f[1],f[0]=+f[0],f[0]=f[0]>=0&&f[0]<=69?"20"+(f[0]<10?"0"+f[0]:f[0]+""):f[0]>=70&&f[0]<=99?"19"+f[0]:f[0]+"",parseInt(this.strtotime(f[2]+" "+f[1]+" "+f[0]+" "+e[2])+(e[4]?e[4]/1e3:""),10);var j="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";e=a.match(new RegExp(j,"gi"));if(e===null)return!1;for(c=0,d=e.length;c=0){f=c.split(",");if(f.length!==2)throw new a.Error("Invalid expression in for loop: "+c);b.key_var=f[0].trim(),b.value_var=f[1].trim()}else b.value_var=c;return b.expression=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack,e&&(b.conditional=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack),delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=[],g,h=0,i,j=this,k=b.conditional,l=function(a,b){var d=k!==undefined;return{index:a+1,index0:a,revindex:d?undefined:b-a,revindex0:d?undefined:b-a-1,first:a===0,last:d?undefined:a===b-1,length:d?undefined:b,parent:c}},m=function(d,e){var i=a.lib.copy(c);i[b.value_var]=e,b.key_var&&(i[b.key_var]=d),i.loop=l(h,g);if(k===undefined||a.expression.parse.apply(j,[k,i]))f.push(a.parse.apply(j,[b.output,i])),h+=1};return e instanceof Array?(g=e.length,e.forEach(function(a){var b=h;m(b,a)})):e instanceof Object&&(e._keys!==undefined?i=e._keys:i=Object.keys(e),g=i.length,i.forEach(function(a){if(a==="_keys")return;m(a,e[a])})),d=f.length===0,{chain:d,output:f.join("")}}},{type:a.logic.type.endfor,regex:/^endfor$/,next:[],open:!1},{type:a.logic.type.set,regex:/^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim(),d=b.match[2],e=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack;return b.key=c,b.expression=e,delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=b.key;return this.context[f]=e,c[f]=e,{chain:d,context:c}}},{type:a.logic.type.filter,regex:/^filter\s+(.+)$/,next:[a.logic.type.endfilter],open:!0,compile:function(b){var c="|"+b.match[1].trim();return b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,delete b.match,b},parse:function(b,c,d){var e=a.parse.apply(this,[b.output,c]),f=[{type:a.expression.type.string,value:e}].concat(b.stack),g=a.expression.parse.apply(this,[f,c]);return{chain:d,output:g}}},{type:a.logic.type.endfilter,regex:/^endfilter$/,next:[],open:!1},{type:a.logic.type.block,regex:/^block\s+([a-zA-Z0-9_]+)$/,next:[a.logic.type.endblock],open:!0,compile:function(a){return a.block=a.match[1].trim(),delete a.match,a},parse:function(b,c,d){var e="",f="",g=this.blocks[b.block]&&this.blocks[b.block].indexOf(a.placeholders.parent)>-1;if(this.blocks[b.block]===undefined||g)e=a.expression.parse.apply(this,[{type:a.expression.type.string,value:a.parse.apply(this,[b.output,c])},c]),g?this.blocks[b.block]=this.blocks[b.block].replace(a.placeholders.parent,e):this.blocks[b.block]=e;return this.child.blocks[b.block]?f=this.child.blocks[b.block]:f=this.blocks[b.block],{chain:d,output:f}}},{type:a.logic.type.endblock,regex:/^endblock$/,next:[],open:!1},{type:a.logic.type.extends_,regex:/^extends\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.extend=e,{chain:d,output:""}}},{type:a.logic.type.use,regex:/^use\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.importBlocks(e),{chain:d,output:""}}},{type:a.logic.type.include,regex:/^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,next:[],open:!0,compile:function(b){var c=b.match,d=c[1]!==undefined,e=c[2].trim(),f=c[3],g=c[4]!==undefined;return delete b.match,b.only=g,b.includeMissing=d,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack,f!==undefined&&(b.withStack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:f.trim()}]).stack),b},parse:function(b,c,d){var e={},f,g,h;if(!b.only)for(g in c)c.hasOwnProperty(g)&&(e[g]=c[g]);if(b.withStack!==undefined){f=a.expression.parse.apply(this,[b.withStack,c]);for(g in f)f.hasOwnProperty(g)&&(e[g]=f[g])}var i=a.expression.parse.apply(this,[b.stack,e]);return h=this.importFile(i),{chain:d,output:h.render(e)}}},{type:a.logic.type.spaceless,regex:/^spaceless$/,next:[a.logic.type.endspaceless],open:!0,parse:function(b,c,d){var e=a.parse.apply(this,[b.output,c]),f=/>\s+ <").trim();return{chain:d,output:g}}},{type:a.logic.type.endspaceless,regex:/^endspaceless$/,next:[],open:!1}],a.logic.handler={},a.logic.extendType=function(b,c){c=c||"Twig.logic.type"+b,a.logic.type[b]=c},a.logic.extend=function(b){if(!b.type)throw new a.Error("Unable to extend logic definition. No type provided for "+b);if(a.logic.type[b.type])throw new a.Error("Unable to extend logic definitions. Type "+b.type+" is already defined.");a.logic.extendType(b.type),a.logic.handler[b.type]=b};while(a.logic.definitions.length>0)a.logic.extend(a.logic.definitions.shift());return a.logic.compile=function(b){var c=b.value.trim(),d=a.logic.tokenize.apply(this,[c]),e=a.logic.handler[d.type];return e.compile&&(d=e.compile.apply(this,[d]),a.log.trace("Twig.logic.compile: ","Compiled logic token to ",d)),d},a.logic.tokenize=function(b){var c={},d=null,e=null,f=null,g=null,h=null,i=null;b=b.trim();for(d in a.logic.handler)if(a.logic.handler.hasOwnProperty(d)){e=a.logic.handler[d].type,f=a.logic.handler[d].regex,g=[],f instanceof Array?g=f:g.push(f);while(g.length>0){h=g.shift(),i=h.exec(b.trim());if(i!==null)return c.type=e,c.match=i,a.log.trace("Twig.logic.tokenize: ","Matched a ",e," regular expression of ",i),c}}throw new a.Error("Unable to parse '"+b.trim()+"'")},a.logic.parse=function(b,c,d){var e="",f;return c=c||{},a.log.debug("Twig.logic.parse: ","Parsing logic token ",b),f=a.logic.handler[b.type],f.parse&&(e=f.parse.apply(this,[b,c,d])),e},a}(Twig||{}),Twig=function(a){"use strict",a.expression={},a.expression.reservedWords=["true","false","null"],a.expression.type={comma:"Twig.expression.type.comma",operator:{unary:"Twig.expression.type.operator.unary",binary:"Twig.expression.type.operator.binary"},string:"Twig.expression.type.string",bool:"Twig.expression.type.bool",array:{start:"Twig.expression.type.array.start",end:"Twig.expression.type.array.end"},object:{start:"Twig.expression.type.object.start",end:"Twig.expression.type.object.end"},parameter:{start:"Twig.expression.type.parameter.start",end:"Twig.expression.type.parameter.end"},key:{period:"Twig.expression.type.key.period",brackets:"Twig.expression.type.key.brackets"},filter:"Twig.expression.type.filter",_function:"Twig.expression.type._function",variable:"Twig.expression.type.variable",number:"Twig.expression.type.number",_null:"Twig.expression.type.null",test:"Twig.expression.type.test"},a.expression.set={operations:[a.expression.type.filter,a.expression.type.operator.unary,a.expression.type.operator.binary,a.expression.type.array.end,a.expression.type.object.end,a.expression.type.parameter.end,a.expression.type.comma,a.expression.type.test],expressions:[a.expression.type._function,a.expression.type.bool,a.expression.type.string,a.expression.type.variable,a.expression.type.number,a.expression.type._null,a.expression.type.parameter.start,a.expression.type.array.start,a.expression.type.object.start]},a.expression.set.operations_extended=a.expression.set.operations.concat([a.expression.type.key.period,a.expression.type.key.brackets]),a.expression.fn={compile:{push:function(a,b,c){c.push(a)},push_both:function(a,b,c){c.push(a),b.push(a)}},parse:{push:function(a,b,c){b.push(a)},push_value:function(a,b,c){b.push(a.value)}}},a.expression.definitions=[{type:a.expression.type.test,regex:/^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/,next:a.expression.set.operations.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.filter=a.match[2],a.modifier=a.match[1],delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]),g=a.test(b.filter,e,f);b.modifier=="not"?c.push(!g):c.push(g)}},{type:a.expression.type.comma,regex:/^,/,next:a.expression.set.expressions,compile:function(b,c,d){var e=c.length-1,f;delete b.match,delete b.value;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.object.start||f.type===a.expression.type.parameter.start||f.type===a.expression.type.array.start){c.push(f);break}d.push(f)}d.push(b)}},{type:a.expression.type.operator.binary,regex:/(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/,next:a.expression.set.expressions.concat([a.expression.type.operator.unary]),compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}if(e===":"){if(!c[c.length-1]||c[c.length-1].value!=="?"){var h=d.pop();if(h.type!==a.expression.type.string&&h.type!==a.expression.type.variable&&h.type!==a.expression.type.number)throw new a.Error("Unexpected value before ':' of "+h.type+" = "+h.value);b.key=h.value,d.push(b);return}}else c.push(f)},parse:function(b,c,d){b.key?c.push(b):a.expression.operator.parse(b.value,c)}},{type:a.expression.type.operator.unary,regex:/(^not\s+)/,next:a.expression.set.expressions,compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}c.push(f)},parse:function(b,c,d){a.expression.operator.parse(b.value,c)}},{type:a.expression.type.string,regex:/^(["'])(?:(?=(\\?))\2.)*?\1/,next:a.expression.set.operations,compile:function(b,c,d){var e=b.value;delete b.match,e.substring(0,1)==='"'?e=e.replace('\\"','"'):e=e.replace("\\'","'"),b.value=e.substring(1,e.length-1),a.log.trace("Twig.expression.compile: ","String value: ",b.value),d.push(b)},parse:a.expression.fn.parse.push_value},{type:a.expression.type.parameter.start,regex:/^\(/,next:a.expression.set.expressions.concat([a.expression.type.parameter.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.parameter.end,regex:/^\)/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e,f=b;e=c.pop();while(c.length>0&&e.type!=a.expression.type.parameter.start)d.push(e),e=c.pop();var g=[];while(b.type!==a.expression.type.parameter.start)g.unshift(b),b=d.pop();g.unshift(b);var h=!1;b=d[d.length-1],b===undefined||b.type!==a.expression.type._function&&b.type!==a.expression.type.filter&&b.type!==a.expression.type.test&&b.type!==a.expression.type.key.brackets&&b.type!==a.expression.type.key.period?(f.expression=!0,g.pop(),g.shift(),f.params=g,d.push(f)):(f.expression=!1,b.params=g)},parse:function(b,c,d){var e=[],f=!1,g=null;if(b.expression)g=a.expression.parse.apply(this,[b.params,d]),c.push(g);else{while(c.length>0){g=c.pop();if(g&&g.type&&g.type==a.expression.type.parameter.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of parameter set.");c.push(e)}}},{type:a.expression.type.array.start,regex:/^\[/,next:a.expression.set.expressions.concat([a.expression.type.array.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.array.end,regex:/^\]/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.array.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e=[],f=!1,g=null;while(c.length>0){g=c.pop();if(g.type&&g.type==a.expression.type.array.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of array.");c.push(e)}},{type:a.expression.type.object.start,regex:/^\{/,next:a.expression.set.expressions.concat([a.expression.type.object.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.object.end,regex:/^\}/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f&&f.type===a.expression.type.object.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e={},f=!1,g=null,h=null,i=!1,j=null;while(c.length>0){g=c.pop();if(g&&g.type&&g.type===a.expression.type.object.start){f=!0;break}if(g&&g.type&&(g.type===a.expression.type.operator.binary||g.type===a.expression.type.operator.unary)&&g.key){if(!i)throw new a.Error("Missing value for key '"+g.key+"' in object definition.");e[g.key]=j,e._keys===undefined&&(e._keys=[]),e._keys.unshift(g.key),j=null,i=!1}else i=!0,j=g}if(!f)throw new a.Error("Unexpected end of object.");c.push(e)}},{type:a.expression.type.filter,regex:/^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.value=a.match[1],c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]);c.push(a.filter.apply(this,[b.value,e,f]))}},{type:a.expression.type._function,regex:/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/,next:a.expression.type.parameter.start,transform:function(a,b){return"("},compile:function(a,b,c){var d=a.match[1];a.fn=d,delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params,d]),f=b.fn,g;if(a.functions[f])g=a.functions[f].apply(this,e);else{if(typeof d[f]!="function")throw new a.Error(f+" function does not exist and is not defined in the context");g=d[f].apply(d,e)}c.push(g)}},{type:a.expression.type.variable,regex:/^[a-zA-Z_][a-zA-Z0-9_]*/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:a.expression.fn.compile.push,validate:function(b,c){return a
+var Twig=function(a){return a.VERSION="0.5.6",a}(Twig||{}),Twig=function(a){function b(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a}function c(b,c){var d,e,f="/",g=[],h;if(b.url)d=b.url;else{if(!b.path)throw new a.Error("Cannot extend an inline template.");var i=require("path"),j=i.sep||f,k=new RegExp("^\\.{1,2}"+j.replace("\\","\\\\"));b.base!==undefined&&c.match(k)==null?(c=c.replace(b.base,""),d=b.base+j):d=b.path,d=d.replace(j+j,j),f=j}e=d.split(f),e.pop(),e=e.concat(c.split(f));while(e.length>0)h=e.shift(),h!="."&&(h==".."&&g.length>0&&g[g.length-1]!=".."?g.pop():g.push(h));return g.join(f)}return"use strict",a.trace=!1,a.debug=!1,a.cache=!0,a.placeholders={parent:"{{|PARENT|}}"},a.Error=function(a){this.message=a,this.name="TwigException",this.type="TwigException"},a.Error.prototype.toString=function(){return this.name+": "+this.message},a.log={trace:function(){a.trace&&console&&console.log(Array.prototype.slice.call(arguments))},debug:function(){a.debug&&console&&console.log(Array.prototype.slice.call(arguments))}},a.token={},a.token.type={output:"output",logic:"logic",comment:"comment",raw:"raw"},a.token.definitions={output:{type:a.token.type.output,open:"{{",close:"}}"},logic:{type:a.token.type.logic,open:"{%",close:"%}"},comment:{type:a.token.type.comment,open:"{#",close:"#}"}},a.token.strings=['"',"'"],a.token.findStart=function(b){var c={position:null,def:null},d,e,f;for(d in a.token.definitions)a.token.definitions.hasOwnProperty(d)&&(e=a.token.definitions[d],f=b.indexOf(e.open),a.log.trace("Twig.token.findStart: ","Searching for ",e.open," found at ",f),f>=0&&(c.position===null||f=0))throw new a.Error("Unable to find closing bracket '"+c.close+"'"+" opened near template position "+d);e=j,f=!0,o=a.token.strings.length;for(n=0;n0&&l0)e=a.token.findStart(b),a.log.trace("Twig.tokenize: ","Found token: ",e),e.position!==null?(e.position>0&&c.push({type:a.token.type.raw,value:b.substring(0,e.position)}),b=b.substr(e.position+e.def.open.length),d+=e.position+e.def.open.length,f=a.token.findEnd(b,e.def,d),a.log.trace("Twig.tokenize: ","Token ends at ",f),c.push({type:e.def.type,value:b.substring(0,f).trim()}),b=b.substr(f+e.def.close.length),d+=f+e.def.close.length):(c.push({type:a.token.type.raw,value:b}),b="");return c},a.compile=function(b){var c=[],d=[],e=[],f=null,g=null,h=null,i=null,j=null,k=null,l=null,m=null,n=null;while(b.length>0){f=b.shift(),a.log.trace("Compiling token ",f);switch(f.type){case a.token.type.raw:d.length>0?e.push(f):c.push(f);break;case a.token.type.logic:g=a.logic.compile.apply(this,[f]),l=g.type,m=a.logic.handler[l].open,n=a.logic.handler[l].next,a.log.trace("Twig.compile: ","Compiled logic token to ",g," next is: ",n," open is : ",m);if(m!==undefined&&!m){i=d.pop(),j=a.logic.handler[i.type];if(j.next.indexOf(l)<0)throw new Error(l+" not expected after a "+i.type);i.output=i.output||[],i.output=i.output.concat(e),e=[],k={type:a.token.type.logic,token:i},d.length>0?e.push(k):c.push(k)}n!==undefined&&n.length>0?(a.log.trace("Twig.compile: ","Pushing ",g," to logic stack."),d.length>0&&(i=d.pop(),i.output=i.output||[],i.output=i.output.concat(e),d.push(i),e=[]),d.push(g)):m!==undefined&&m&&(k={type:a.token.type.logic,token:g},d.length>0?e.push(k):c.push(k));break;case a.token.type.comment:break;case a.token.type.output:a.expression.compile.apply(this,[f]),d.length>0?e.push(f):c.push(f)}a.log.trace("Twig.compile: "," Output: ",c," Logic Stack: ",d," Pending Output: ",e)}if(d.length>0)throw h=d.pop(),new Error("Unable to find an end tag for "+h.type+", expecting one of "+h.next);return c},a.parse=function(b,c){var d=[],e=!0,f=this;return c=c||{},b.forEach(function(g){a.log.debug("Twig.parse: ","Parsing token: ",g);switch(g.type){case a.token.type.raw:d.push(g.value);break;case a.token.type.logic:var h=g.token,i=a.logic.parse.apply(f,[h,c,e]);i.chain!==undefined&&(e=i.chain),i.context!==undefined&&(c=i.context),i.output!==undefined&&d.push(i.output);break;case a.token.type.comment:break;case a.token.type.output:a.log.debug("Twig.parse: ","Output token: ",g.stack),d.push(a.expression.parse.apply(f,[g.stack,c]))}}),d.join("")},a.prepare=function(b){var c,d;return a.log.debug("Twig.prepare: ","Tokenizing ",b),d=a.tokenize.apply(this,[b]),a.log.debug("Twig.prepare: ","Compiling ",d),c=a.compile.apply(this,[d]),a.log.debug("Twig.prepare: ","Compiled ",c),c},a.Templates={registry:{}},a.validateId=function(b){if(b==="prototype")throw new a.Error(b+" is not a valid twig identifier");if(a.Templates.registry.hasOwnProperty(b))throw new a.Error("There is already a template with the ID "+b);return!0},a.Templates.save=function(b){if(b.id===undefined)throw new a.Error("Unable to save template with no id");a.Templates.registry[b.id]=b},a.Templates.load=function(b){return a.Templates.registry.hasOwnProperty(b)?a.Templates.registry[b]:null},a.Templates.loadRemote=function(b,c,d,e){var f=c.id,g=c.method,h=c.async,i=c.precompiled,j=null;h===undefined&&(h=!0),f===undefined&&(f=b),c.id=f;if(a.cache&&a.Templates.registry.hasOwnProperty(f))return d&&d(a.Templates.registry[f]),a.Templates.registry[f];if(g=="ajax"){if(typeof XMLHttpRequest=="undefined")throw new a.Error("Unsupported platform: Unable to do remote requests because there is no XMLHTTPRequest implementation");var k=new XMLHttpRequest;k.onreadystatechange=function(){var e=null;k.readyState==4&&(a.log.debug("Got template ",k.responseText),i===!0?e=JSON.parse(k.responseText):e=k.responseText,c.url=b,c.data=e,j=new a.Template(c),d&&d(j))},k.open("GET",b,h),k.send()}else(function(){var f=require("fs"),g=require("path"),k=null,l=function(f,g){if(f){e&&e(f);return}i===!0&&(g=JSON.parse(g)),c.data=g,c.path=b,j=new a.Template(c),d&&d(j)};if(h===!0)f.stat(b,function(c,d){if(c||!d.isFile())throw new a.Error("Unable to find template file "+b);f.readFile(b,"utf8",l)});else{if(!f.statSync(b).isFile())throw new a.Error("Unable to find template file "+b);k=f.readFileSync(b,"utf8"),l(undefined,k)}})();return h===!1?j:!0},a.Template=function(c){var d=c.data,e=c.id,f=c.blocks,g=c.base,h=c.path,i=c.url,j=c.options;this.id=e,this.base=g,this.path=h,this.url=i,this.options=j,this.reset(f),b("String",d)?this.tokens=a.prepare.apply(this,[d]):this.tokens=d,e!==undefined&&a.Templates.save(this)},a.Template.prototype.reset=function(b){a.log.debug("Twig.Template.reset","Reseting template "+this.id),this.blocks={},this.child={blocks:b||{}},this.extend=null},a.Template.prototype.render=function(b,d){d=d||{};var e,f;return this.context=b||{},this.reset(),d.blocks&&(this.blocks=d.blocks),e=a.parse.apply(this,[this.tokens,this.context]),this.extend?(f=c(this,this.extend),this.parent=a.Templates.loadRemote(f,{method:this.url?"ajax":"fs",base:this.base,async:!1,id:f,options:this.options}),this.parent.render(this.context,{blocks:this.blocks})):d.output=="blocks"?this.blocks:e},a.Template.prototype.importFile=function(b){var d=c(this,b),e=a.Templates.loadRemote(d,{method:this.url?"ajax":"fs",async:!1,options:this.options,id:d});return e},a.Template.prototype.importBlocks=function(a,b){var c=this.importFile(a),d=this.context,e=this,f;b=b||!1,c.render(d),Object.keys(c.blocks).forEach(function(a){if(b||e.blocks[a]===undefined)e.blocks[a]=c.blocks[a]})},a.Template.prototype.compile=function(b){return a.compiler.compile(this,b)},a}(Twig||{});(function(){"use strict",String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(c===0)return-1;var d=0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==Infinity&&d!==-Infinity&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var e=d>=0?d:Math.max(c-Math.abs(d),0);for(;e>>0;if({}.toString.call(a)!="[object Function]")throw new TypeError(a+" is not a function");b&&(c=b),d=0;while(d0;c[--b]=a);return c.join("")}var d=function(){return d.cache.hasOwnProperty(arguments[0])||(d.cache[arguments[0]]=d.parse(arguments[0])),d.format.call(null,d.cache[arguments[0]],arguments)};return d.format=function(d,e){var f=1,g=d.length,h="",i,j=[],k,l,m,n,o,p;for(k=0;k=0?"+"+i:i,o=m[4]?m[4]=="0"?"0":m[4].charAt(1):" ",p=m[6]-String(i).length,n=m[6]?c(o,p):"",j.push(m[5]?i+n:n+i)}}return j.join("")},d.cache={},d.parse=function(a){var b=a,c=[],d=[],e=0;while(b){if((c=/^[^\x25]+/.exec(b))!==null)d.push(c[0]);else if((c=/^\x25{2}/.exec(b))!==null)d.push("%");else{if((c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b))===null)throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(g))===null)throw"[sprintf] huh?";f.push(h[1]);while((g=g.substring(h[0].length))!=="")if((h=/^\.([a-z_][a-z_\d]*)/i.exec(g))!==null)f.push(h[1]);else{if((h=/^\[(\d+)\]/.exec(g))===null)throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(e===3)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},d}(),c=function(a,c){return c.unshift(a),b.apply(null,c)};return a.lib.sprintf=b,a.lib.vsprintf=c,function(){function f(a){return(a=Math.abs(a)%100)%10==1&&a!=11?"st":a%10==2&&a!=12?"nd":a%10==3&&a!=13?"rd":"th"}function g(a){var b=new Date(a.getFullYear()+1,0,4);return(b-a)/864e5<7&&(a.getDay()+6)%7<(b.getDay()+6)%7?b.getFullYear():a.getMonth()>0||a.getDate()>=4?a.getFullYear():a.getFullYear()-((a.getDay()+6)%7-a.getDate()>2?1:0)}function h(a){var b=new Date(g(a),0,4);return b.setDate(b.getDate()-(b.getDay()+6)%7),parseInt((a-b)/6048e5)+1}var b="Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),c="Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),d="Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),e="January,February,March,April,May,June,July,August,September,October,November,December".split(",");a.lib.formatDate=function(a,i){if(typeof i!="string"||/^\s*$/.test(i))return a+"";var j=new Date(a.getFullYear(),0,1),k=a;return i.replace(/[dDjlNSwzWFmMntLoYyaABgGhHisu]/g,function(a){switch(a){case"d":return("0"+k.getDate()).replace(/^.+(..)$/,"$1");case"D":return b[k.getDay()];case"j":return k.getDate();case"l":return c[k.getDay()];case"N":return(k.getDay()+6)%7+1;case"S":return f(k.getDate());case"w":return k.getDay();case"z":return Math.ceil((j-k)/864e5);case"W":return("0"+h(k)).replace(/^.(..)$/,"$1");case"F":return e[k.getMonth()];case"m":return("0"+(k.getMonth()+1)).replace(/^.+(..)$/,"$1");case"M":return d[k.getMonth()];case"n":return k.getMonth()+1;case"t":return(new Date(k.getFullYear(),k.getMonth()+1,-1)).getDate();case"L":return(new Date(k.getFullYear(),1,29)).getDate()==29?1:0;case"o":return g(k);case"Y":return k.getFullYear();case"y":return(k.getFullYear()+"").replace(/^.+(..)$/,"$1");case"a":return k.getHours()<12?"am":"pm";case"A":return k.getHours()<12?"AM":"PM";case"B":return Math.floor(((k.getUTCHours()+1)%24+k.getUTCMinutes()/60+k.getUTCSeconds()/3600)*1e3/24);case"g":return k.getHours()%12!=0?k.getHours()%12:12;case"G":return k.getHours();case"h":return("0"+(k.getHours()%12!=0?k.getHours()%12:12)).replace(/^.+(..)$/,"$1");case"H":return("0"+k.getHours()).replace(/^.+(..)$/,"$1");case"i":return("0"+k.getMinutes()).replace(/^.+(..)$/,"$1");case"s":return("0"+k.getSeconds()).replace(/^.+(..)$/,"$1");case"u":return k.getMilliseconds()}})}}(),a.lib.strip_tags=function(a,b){b=(((b||"")+"").toLowerCase().match(/<[a-z][a-z0-9]*>/g)||[]).join("");var c=/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,d=/|<\?(?:php)?[\s\S]*?\?>/gi;return a.replace(d,"").replace(c,function(a,c){return b.indexOf("<"+c.toLowerCase()+">")>-1?a:""})},a.lib.strtotime=function(a,b){var c,d,e,f,g="";a=a.replace(/\s{2,}|^\s|\s$/g," "),a=a.replace(/[\t\r\n]/g,"");if(a==="now")return b===null||isNaN(b)?(new Date).getTime()/1e3|0:b|0;if(!isNaN(g=Date.parse(a)))return g/1e3|0;b?b=new Date(b*1e3):b=new Date,a=a.toLowerCase();var h={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]},i=function(a){var c=a[2]&&a[2]==="ago",d=(d=a[0]==="last"?-1:1)*(c?-1:1);switch(a[0]){case"last":case"next":switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d);break;case"mon":if(a[1]==="month"){b.setMonth(b.getMonth()+d);break};default:var e=h.day[a[1].substring(0,3)];if(typeof e!="undefined"){var f=e-b.getDay();f===0?f=7*d:f>0?a[0]==="last"&&(f-=7):a[0]==="next"&&(f+=7),b.setDate(b.getDate()+f),b.setHours(0,0,0,0)}}break;default:if(!/\d+/.test(a[0]))return!1;d*=parseInt(a[0],10);switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"mon":b.setMonth(b.getMonth()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d)}}return!0};e=a.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(e!==null)return e[2]?e[3]||(e[2]+=":00"):e[2]="00:00:00",f=e[1].split(/-/g),f[1]=h.mon[f[1]-1]||f[1],f[0]=+f[0],f[0]=f[0]>=0&&f[0]<=69?"20"+(f[0]<10?"0"+f[0]:f[0]+""):f[0]>=70&&f[0]<=99?"19"+f[0]:f[0]+"",parseInt(this.strtotime(f[2]+" "+f[1]+" "+f[0]+" "+e[2])+(e[4]?e[4]/1e3:""),10);var j="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";e=a.match(new RegExp(j,"gi"));if(e===null)return!1;for(c=0,d=e.length;c=0){f=c.split(",");if(f.length!==2)throw new a.Error("Invalid expression in for loop: "+c);b.key_var=f[0].trim(),b.value_var=f[1].trim()}else b.value_var=c;return b.expression=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack,e&&(b.conditional=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack),delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=[],g,h=0,i,j=this,k=b.conditional,l=function(a,b){var d=k!==undefined;return{index:a+1,index0:a,revindex:d?undefined:b-a,revindex0:d?undefined:b-a-1,first:a===0,last:d?undefined:a===b-1,length:d?undefined:b,parent:c}},m=function(d,e){var i=a.lib.copy(c);i[b.value_var]=e,b.key_var&&(i[b.key_var]=d),i.loop=l(h,g);if(k===undefined||a.expression.parse.apply(j,[k,i]))f.push(a.parse.apply(j,[b.output,i])),h+=1};return e instanceof Array?(g=e.length,e.forEach(function(a){var b=h;m(b,a)})):e instanceof Object&&(e._keys!==undefined?i=e._keys:i=Object.keys(e),g=i.length,i.forEach(function(a){if(a==="_keys")return;m(a,e[a])})),d=f.length===0,{chain:d,output:f.join("")}}},{type:a.logic.type.endfor,regex:/^endfor$/,next:[],open:!1},{type:a.logic.type.set,regex:/^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim(),d=b.match[2],e=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack;return b.key=c,b.expression=e,delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=b.key;return this.context[f]=e,c[f]=e,{chain:d,context:c}}},{type:a.logic.type.filter,regex:/^filter\s+(.+)$/,next:[a.logic.type.endfilter],open:!0,compile:function(b){var c="|"+b.match[1].trim();return b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,delete b.match,b},parse:function(b,c,d){var e=a.parse.apply(this,[b.output,c]),f=[{type:a.expression.type.string,value:e}].concat(b.stack),g=a.expression.parse.apply(this,[f,c]);return{chain:d,output:g}}},{type:a.logic.type.endfilter,regex:/^endfilter$/,next:[],open:!1},{type:a.logic.type.block,regex:/^block\s+([a-zA-Z0-9_]+)$/,next:[a.logic.type.endblock],open:!0,compile:function(a){return a.block=a.match[1].trim(),delete a.match,a},parse:function(b,c,d){var e="",f="",g=this.blocks[b.block]&&this.blocks[b.block].indexOf(a.placeholders.parent)>-1;if(this.blocks[b.block]===undefined||g)e=a.expression.parse.apply(this,[{type:a.expression.type.string,value:a.parse.apply(this,[b.output,c])},c]),g?this.blocks[b.block]=this.blocks[b.block].replace(a.placeholders.parent,e):this.blocks[b.block]=e;return this.child.blocks[b.block]?f=this.child.blocks[b.block]:f=this.blocks[b.block],{chain:d,output:f}}},{type:a.logic.type.endblock,regex:/^endblock$/,next:[],open:!1},{type:a.logic.type.extends_,regex:/^extends\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.extend=e,{chain:d,output:""}}},{type:a.logic.type.use,regex:/^use\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.importBlocks(e),{chain:d,output:""}}},{type:a.logic.type.include,regex:/^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,next:[],open:!0,compile:function(b){var c=b.match,d=c[1]!==undefined,e=c[2].trim(),f=c[3],g=c[4]!==undefined;return delete b.match,b.only=g,b.includeMissing=d,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack,f!==undefined&&(b.withStack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:f.trim()}]).stack),b},parse:function(b,c,d){var e={},f,g,h;if(!b.only)for(g in c)c.hasOwnProperty(g)&&(e[g]=c[g]);if(b.withStack!==undefined){f=a.expression.parse.apply(this,[b.withStack,c]);for(g in f)f.hasOwnProperty(g)&&(e[g]=f[g])}var i=a.expression.parse.apply(this,[b.stack,e]);return h=this.importFile(i),{chain:d,output:h.render(e)}}},{type:a.logic.type.spaceless,regex:/^spaceless$/,next:[a.logic.type.endspaceless],open:!0,parse:function(b,c,d){var e=a.parse.apply(this,[b.output,c]),f=/>\s+ <").trim();return{chain:d,output:g}}},{type:a.logic.type.endspaceless,regex:/^endspaceless$/,next:[],open:!1}],a.logic.handler={},a.logic.extendType=function(b,c){c=c||"Twig.logic.type"+b,a.logic.type[b]=c},a.logic.extend=function(b){if(!b.type)throw new a.Error("Unable to extend logic definition. No type provided for "+b);if(a.logic.type[b.type])throw new a.Error("Unable to extend logic definitions. Type "+b.type+" is already defined.");a.logic.extendType(b.type),a.logic.handler[b.type]=b};while(a.logic.definitions.length>0)a.logic.extend(a.logic.definitions.shift());return a.logic.compile=function(b){var c=b.value.trim(),d=a.logic.tokenize.apply(this,[c]),e=a.logic.handler[d.type];return e.compile&&(d=e.compile.apply(this,[d]),a.log.trace("Twig.logic.compile: ","Compiled logic token to ",d)),d},a.logic.tokenize=function(b){var c={},d=null,e=null,f=null,g=null,h=null,i=null;b=b.trim();for(d in a.logic.handler)if(a.logic.handler.hasOwnProperty(d)){e=a.logic.handler[d].type,f=a.logic.handler[d].regex,g=[],f instanceof Array?g=f:g.push(f);while(g.length>0){h=g.shift(),i=h.exec(b.trim());if(i!==null)return c.type=e,c.match=i,a.log.trace("Twig.logic.tokenize: ","Matched a ",e," regular expression of ",i),c}}throw new a.Error("Unable to parse '"+b.trim()+"'")},a.logic.parse=function(b,c,d){var e="",f;return c=c||{},a.log.debug("Twig.logic.parse: ","Parsing logic token ",b),f=a.logic.handler[b.type],f.parse&&(e=f.parse.apply(this,[b,c,d])),e},a}(Twig||{}),Twig=function(a){"use strict",a.expression={},a.expression.reservedWords=["true","false","null"],a.expression.type={comma:"Twig.expression.type.comma",operator:{unary:"Twig.expression.type.operator.unary",binary:"Twig.expression.type.operator.binary"},string:"Twig.expression.type.string",bool:"Twig.expression.type.bool",array:{start:"Twig.expression.type.array.start",end:"Twig.expression.type.array.end"},object:{start:"Twig.expression.type.object.start",end:"Twig.expression.type.object.end"},parameter:{start:"Twig.expression.type.parameter.start",end:"Twig.expression.type.parameter.end"},key:{period:"Twig.expression.type.key.period",brackets:"Twig.expression.type.key.brackets"},filter:"Twig.expression.type.filter",_function:"Twig.expression.type._function",variable:"Twig.expression.type.variable",number:"Twig.expression.type.number",_null:"Twig.expression.type.null",test:"Twig.expression.type.test"},a.expression.set={operations:[a.expression.type.filter,a.expression.type.operator.unary,a.expression.type.operator.binary,a.expression.type.array.end,a.expression.type.object.end,a.expression.type.parameter.end,a.expression.type.comma,a.expression.type.test],expressions:[a.expression.type._function,a.expression.type.bool,a.expression.type.string,a.expression.type.variable,a.expression.type.number,a.expression.type._null,a.expression.type.parameter.start,a.expression.type.array.start,a.expression.type.object.start]},a.expression.set.operations_extended=a.expression.set.operations.concat([a.expression.type.key.period,a.expression.type.key.brackets]),a.expression.fn={compile:{push:function(a,b,c){c.push(a)},push_both:function(a,b,c){c.push(a),b.push(a)}},parse:{push:function(a,b,c){b.push(a)},push_value:function(a,b,c){b.push(a.value)}}},a.expression.definitions=[{type:a.expression.type.test,regex:/^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/,next:a.expression.set.operations.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.filter=a.match[2],a.modifier=a.match[1],delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]),g=a.test(b.filter,e,f);b.modifier=="not"?c.push(!g):c.push(g)}},{type:a.expression.type.comma,regex:/^,/,next:a.expression.set.expressions,compile:function(b,c,d){var e=c.length-1,f;delete b.match,delete b.value;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.object.start||f.type===a.expression.type.parameter.start||f.type===a.expression.type.array.start){c.push(f);break}d.push(f)}d.push(b)}},{type:a.expression.type.operator.binary,regex:/(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/,next:a.expression.set.expressions.concat([a.expression.type.operator.unary]),compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}if(e===":"){if(!c[c.length-1]||c[c.length-1].value!=="?"){var h=d.pop();if(h.type!==a.expression.type.string&&h.type!==a.expression.type.variable&&h.type!==a.expression.type.number)throw new a.Error("Unexpected value before ':' of "+h.type+" = "+h.value);b.key=h.value,d.push(b);return}}else c.push(f)},parse:function(b,c,d){b.key?c.push(b):a.expression.operator.parse(b.value,c)}},{type:a.expression.type.operator.unary,regex:/(^not\s+)/,next:a.expression.set.expressions,compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}c.push(f)},parse:function(b,c,d){a.expression.operator.parse(b.value,c)}},{type:a.expression.type.string,regex:/^(["'])(?:(?=(\\?))\2.)*?\1/,next:a.expression.set.operations,compile:function(b,c,d){var e=b.value;delete b.match,e.substring(0,1)==='"'?e=e.replace('\\"','"'):e=e.replace("\\'","'"),b.value=e.substring(1,e.length-1),a.log.trace("Twig.expression.compile: ","String value: ",b.value),d.push(b)},parse:a.expression.fn.parse.push_value},{type:a.expression.type.parameter.start,regex:/^\(/,next:a.expression.set.expressions.concat([a.expression.type.parameter.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.parameter.end,regex:/^\)/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e,f=b;e=c.pop();while(c.length>0&&e.type!=a.expression.type.parameter.start)d.push(e),e=c.pop();var g=[];while(b.type!==a.expression.type.parameter.start)g.unshift(b),b=d.pop();g.unshift(b);var h=!1;b=d[d.length-1],b===undefined||b.type!==a.expression.type._function&&b.type!==a.expression.type.filter&&b.type!==a.expression.type.test&&b.type!==a.expression.type.key.brackets&&b.type!==a.expression.type.key.period?(f.expression=!0,g.pop(),g.shift(),f.params=g,d.push(f)):(f.expression=!1,b.params=g)},parse:function(b,c,d){var e=[],f=!1,g=null;if(b.expression)g=a.expression.parse.apply(this,[b.params,d]),c.push(g);else{while(c.length>0){g=c.pop();if(g&&g.type&&g.type==a.expression.type.parameter.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of parameter set.");c.push(e)}}},{type:a.expression.type.array.start,regex:/^\[/,next:a.expression.set.expressions.concat([a.expression.type.array.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.array.end,regex:/^\]/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.array.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e=[],f=!1,g=null;while(c.length>0){g=c.pop();if(g.type&&g.type==a.expression.type.array.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of array.");c.push(e)}},{type:a.expression.type.object.start,regex:/^\{/,next:a.expression.set.expressions.concat([a.expression.type.object.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.object.end,regex:/^\}/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f&&f.type===a.expression.type.object.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e={},f=!1,g=null,h=null,i=!1,j=null;while(c.length>0){g=c.pop();if(g&&g.type&&g.type===a.expression.type.object.start){f=!0;break}if(g&&g.type&&(g.type===a.expression.type.operator.binary||g.type===a.expression.type.operator.unary)&&g.key){if(!i)throw new a.Error("Missing value for key '"+g.key+"' in object definition.");e[g.key]=j,e._keys===undefined&&(e._keys=[]),e._keys.unshift(g.key),j=null,i=!1}else i=!0,j=g}if(!f)throw new a.Error("Unexpected end of object.");c.push(e)}},{type:a.expression.type.filter,regex:/^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.value=a.match[1],c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]);c.push(a.filter.apply(this,[b.value,e,f]))}},{type:a.expression.type._function,regex:/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/,next:a.expression.type.parameter.start,transform:function(a,b){return"("},compile:function(a,b,c){var d=a.match[1];a.fn=d,delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params,d]),f=b.fn,g;if(a.functions[f])g=a.functions[f].apply(this,e);else{if(typeof d[f]!="function")throw new a.Error(f+" function does not exist and is not defined in the context");g=d[f].apply(d,e)}c.push(g)}},{type:a.expression.type.variable,regex:/^[a-zA-Z_][a-zA-Z0-9_]*/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:a.expression.fn.compile.push,validate:function(b,c){return a
.expression.reservedWords.indexOf(b[0])==-1},parse:function(b,c,d){var e=a.expression.resolve(d[b.value],d);c.push(e)}},{type:a.expression.type.key.period,regex:/^\.([a-zA-Z0-9_]+)/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.key=a.match[1],delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params,d]),f=b.key,g=c.pop(),h;if(g===null||g===undefined){if(this.options.strict_variables)throw new a.Error("Can't access a key "+f+" on an null or undefined object.");return null}var i=function(a){return a.substr(0,1).toUpperCase()+a.substr(1)};typeof g=="object"&&f in g?h=g[f]:g["get"+i(f)]!==undefined?h=g["get"+i(f)]:g["is"+i(f)]!==undefined?h=g["is"+i(f)]:h=null,c.push(a.expression.resolve(h,g,e))}},{type:a.expression.type.key.brackets,regex:/^\[([^\]]*)\]/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(b,c,d){var e=b.match[1];delete b.value,delete b.match,b.stack=a.expression.compile({value:e}).stack,d.push(b)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params,d]),f=a.expression.parse.apply(this,[b.stack,d]),g=c.pop(),h;if(g===null||g===undefined){if(this.options.strict_variables)throw new a.Error("Can't access a key "+f+" on an null or undefined object.");return null}typeof g=="object"&&f in g?h=g[f]:h=null,c.push(a.expression.resolve(h,g,e))}},{type:a.expression.type._null,regex:/^null/,next:a.expression.set.operations,compile:function(a,b,c){delete a.match,a.value=null,c.push(a)},parse:a.expression.fn.parse.push_value},{type:a.expression.type.number,regex:/^\-?\d+(\.\d+)?/,next:a.expression.set.operations,compile:function(a,b,c){a.value=Number(a.value),c.push(a)},parse:a.expression.fn.parse.push_value},{type:a.expression.type.bool,regex:/^(true|false)/,next:a.expression.set.operations,compile:function(a,b,c){a.value=a.match[0]=="true",delete a.match,c.push(a)},parse:a.expression.fn.parse.push_value}],a.expression.resolve=function(a,b,c){return typeof a=="function"?a.apply(b,c||[]):a},a.expression.handler={},a.expression.extendType=function(b){a.expression.type[b]="Twig.expression.type."+b},a.expression.extend=function(b){if(!b.type)throw new a.Error("Unable to extend logic definition. No type provided for "+b);a.expression.handler[b.type]=b};while(a.expression.definitions.length>0)a.expression.extend(a.expression.definitions.shift());return a.expression.tokenize=function(b){var c=[],d=0,e=null,f,g,h,i,j,k=[],l;l=function(){var b=Array.prototype.slice.apply(arguments),g=b.pop(),h=b.pop();return a.log.trace("Twig.expression.tokenize","Matched a ",f," regular expression of ",b),e&&e.indexOf(f)<0?(k.push(f+" cannot follow a "+c[c.length-1].type+" at template:"+d+" near '"+b[0].substring(0,20)+"...'"),b[0]):a.expression.handler[f].validate&&!a.expression.handler[f].validate(b,c)?b[0]:(k=[],c.push({type:f,value:b[0],match:b}),j=!0,e=i,d+=b[0].length,a.expression.handler[f].transform?a.expression.handler[f].transform(b,c):"")},a.log.debug("Twig.expression.tokenize","Tokenizing expression ",b);while(b.length>0){b=b.trim();for(f in a.expression.handler)if(a.expression.handler.hasOwnProperty(f)){i=a.expression.handler[f].next,g=a.expression.handler[f].regex,g instanceof Array?h=g:h=[g],j=!1;while(h.length>0)g=h.pop(),b=b.replace(g,l);if(j)break}if(!j)throw k.length>0?new a.Error(k.join(" OR ")):new a.Error("Unable to parse '"+b+"' at template position"+d)}return a.log.trace("Twig.expression.tokenize","Tokenized to ",c),c},a.expression.compile=function(b){var c=b.value,d=a.expression.tokenize(c),e=null,f=[],g=[],h=null;a.log.trace("Twig.expression.compile: ","Compiling ",c);while(d.length>0)e=d.shift(),h=a.expression.handler[e.type],a.log.trace("Twig.expression.compile: ","Compiling ",e),h.compile&&h.compile(e,g,f),a.log.trace("Twig.expression.compile: ","Stack is",g),a.log.trace("Twig.expression.compile: ","Output is",f);while(g.length>0)f.push(g.pop());return a.log.trace("Twig.expression.compile: ","Final output is",f),b.stack=f,delete b.value,b},a.expression.parse=function(b,c){var d=this;b instanceof Array||(b=[b]);var e=[],f=null;return b.forEach(function(b){f=a.expression.handler[b.type],f.parse&&f.parse.apply(d,[b,e,c])}),e.pop()},a}(Twig||{}),Twig=function(a){"use strict",a.expression.operator={leftToRight:"leftToRight",rightToLeft:"rightToLeft"},a.expression.operator.lookup=function(b,c){switch(b){case"..":case"not in":case"in":c.precidence=20,c.associativity=a.expression.operator.leftToRight;break;case",":c.precidence=18,c.associativity=a.expression.operator.leftToRight;break;case"?":case":":c.precidence=16,c.associativity=a.expression.operator.rightToLeft;break;case"or":c.precidence=14,c.associativity=a.expression.operator.leftToRight;break;case"and":c.precidence=13,c.associativity=a.expression.operator.leftToRight;break;case"==":case"!=":c.precidence=9,c.associativity=a.expression.operator.leftToRight;break;case"<":case"<=":case">":case">=":c.precidence=8,c.associativity=a.expression.operator.leftToRight;break;case"~":case"+":case"-":c.precidence=6,c.associativity=a.expression.operator.leftToRight;break;case"//":case"**":case"*":case"/":case"%":c.precidence=5,c.associativity=a.expression.operator.leftToRight;break;case"not":c.precidence=3,c.associativity=a.expression.operator.rightToLeft;break;default:throw new a.Error(b+" is an unknown operator.")}return c.operator=b,c},a.expression.operator.parse=function(c,d){a.log.trace("Twig.expression.operator.parse: ","Handling ",c);var e,f,g;switch(c){case":":break;case"?":g=d.pop(),f=d.pop(),e=d.pop(),e?d.push(f):d.push(g);break;case"+":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(e+f);break;case"-":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(e-f);break;case"*":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(e*f);break;case"/":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(e/f);break;case"//":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(parseInt(e/f));break;case"%":f=parseFloat(d.pop()),e=parseFloat(d.pop()),d.push(e%f);break;case"~":f=d.pop(),e=d.pop(),d.push((e!==undefined?e.toString():"")+(f!==undefined?f.toString():""));break;case"not":case"!":d.push(!d.pop());break;case"<":f=d.pop(),e=d.pop(),d.push(e":f=d.pop(),e=d.pop(),d.push(e>f);break;case">=":f=d.pop(),e=d.pop(),d.push(e>=f);break;case"===":f=d.pop(),e=d.pop(),d.push(e===f);break;case"==":f=d.pop(),e=d.pop(),d.push(e==f);break;case"!==":f=d.pop(),e=d.pop(),d.push(e!==f);break;case"!=":f=d.pop(),e=d.pop(),d.push(e!=f);break;case"or":f=d.pop(),e=d.pop(),d.push(e||f);break;case"and":f=d.pop(),e=d.pop(),d.push(e&&f);break;case"**":f=d.pop(),e=d.pop(),d.push(Math.pow(e,f));break;case"not in":f=d.pop(),e=d.pop(),d.push(!b(e,f));break;case"in":f=d.pop(),e=d.pop(),d.push(b(e,f));break;case"..":f=d.pop(),e=d.pop(),d.push(a.functions.range(e,f));break;default:throw new a.Error(c+" is an unknown operator.")}};var b=function(a,b){if(b.indexOf!=undefined)return b.indexOf(a)>-1;var c;for(c in b)if(b.hasOwnProperty(c)&&b[c]===a)return!0;return!1};return a}(Twig||{}),Twig=function(a){function b(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a}return a.filters={upper:function(a){return typeof a!="string"?a:a.toUpperCase()},lower:function(a){return typeof a!="string"?a:a.toLowerCase()},capitalize:function(a){return typeof a!="string"?a:a.substr(0,1).toUpperCase()+a.substr(1)},title:function(a){return typeof a!="string"?a:a.replace(/(^|\s)([a-z])/g,function(a,b,c){return b+c.toUpperCase()})},length:function(a){return a instanceof Array||typeof a=="string"?a.length:a instanceof Object?a._keys===undefined?Object.keys(a).length:a._keys.length:0},reverse:function(a){if(b("Array",a))return a.reverse();if(b("String",a))return a.split("").reverse().join("");if(a instanceof Object){var c=a._keys||Object.keys(a).reverse();return a._keys=c,a}},sort:function(a){if(b("Array",a))return a.sort();if(a instanceof Object){delete a._keys;var c=Object.keys(a),d=c.sort(function(b,c){return a[b]>a[c]});return a._keys=d,a}},keys:function(a){if(a===undefined)return;var b=a._keys||Object.keys(a),c=[];return b.forEach(function(b){if(b==="_keys")return;a.hasOwnProperty(b)&&c.push(b)}),c},url_encode:function(a){if(a===undefined)return;return encodeURIComponent(a)},join:function(a,b){if(a===undefined)return;var c="",d=[],e=null;return b&&b[0]&&(c=b[0]),a instanceof Array?d=a:(e=a._keys||Object.keys(a),e.forEach(function(b){if(b==="_keys")return;a.hasOwnProperty(b)&&d.push(a[b])})),d.join(c)},"default":function(b,c){if(c===undefined||c.length!==1)throw new a.Error("default filter expects one argument");return b===undefined||b===null||b===""?c[0]:b},json_encode:function(a){return a&&a.hasOwnProperty("_keys")&&delete a._keys,a===undefined||a===null?"null":JSON.stringify(a)},merge:function(b,c){var d=[],e=0,f=[];b instanceof Array?c.forEach(function(a){a instanceof Array||(d={})}):d={},d instanceof Array||(d._keys=[]),b instanceof Array?b.forEach(function(a){d._keys&&d._keys.unshift(e),d[e]=a,e++}):(f=b._keys||Object.keys(b),f.forEach(function(a){d[a]=b[a],d._keys.push(a);var c=parseInt(a,10);!isNaN(c)&&c>=e&&(e=c+1)})),c.forEach(function(a){a instanceof Array?a.forEach(function(a){d._keys&&d._keys.push(e),d[e]=a,e++}):(f=a._keys||Object.keys(a),f.forEach(function(b){d[b]||d._keys.unshift(b),d[b]=a[b];var c=parseInt(b,10);!isNaN(c)&&c>=e&&(e=c+1)}))});if(c.length===0)throw new a.Error("Filter merge expects at least one parameter");return d},date:function(b,c){if(b===undefined)return;var d=a.functions.date(b);return a.lib.formatDate(d,c[0])},replace:function(a,b){if(a===undefined)return;var c=b[0],d;for(d in c)c.hasOwnProperty(d)&&d!=="_keys"&&(a=a.replace(d,c[d]));return a},format:function(b,c){if(b===undefined)return;return a.lib.vsprintf(b,c)},striptags:function(b){if(b===undefined)return;return a.lib.strip_tags(b)},escape:function(a){if(a===undefined)return;return a.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},e:function(b){return a.filters.escape(b)},nl2br:function(b){if(b===undefined)return;var c=" ";return a.filters.escape(b).replace(/\r\n/g,c).replace(/\r/g,c).replace(/\n/g,c)},number_format:function(a,b){var c=a,d=b&&b[0]?b[0]:undefined,e=b&&b[1]!==undefined?b[1]:".",f=b&&b[2]!==undefined?b[2]:",";c=(c+"").replace(/[^0-9+\-Ee.]/g,"");var g=isFinite(+c)?+c:0,h=isFinite(+d)?Math.abs(d):0,i="",j=function(a,b){var c=Math.pow(10,b);return""+Math.round(a*c)/c};return i=(h?j(g,h):""+Math.round(g)).split("."),i[0].length>3&&(i[0]=i[0].replace(/\B(?=(?:\d{3})+(?!\d))/g,f)),(i[1]||"").length=0;e--)if(d.indexOf(c.charAt(e))===-1){c=c.substring(0,e+1);break}return d.indexOf(c.charAt(0))===-1?c:""}},a.filter=function(b,c,d){if(!a.filters[b])throw"Unable to find filter "+b;return a.filters[b].apply(this,[c,d])},a.filter.extend=function(b,c){a.filters[b]=c},a}(Twig||{}),Twig=function(a){function b(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a}return a.functions={range:function(a,b,c){var d=[],e,f,g,h=c||1,i=!1;!isNaN(a)&&!isNaN(b)?(e=parseInt(a,10),f=parseInt(b,10)):isNaN(a)&&isNaN(b)?(i=!0,e=a.charCodeAt(0),f=b.charCodeAt(0)):(e=isNaN(a)?0:a,f=isNaN(b)?0:b),g=e>f?!1:!0;if(g)while(e<=f)d.push(i?String.fromCharCode(e):e),e+=h;else while(e>=f)d.push(i?String.fromCharCode(e):e),e-=h;return d},cycle:function(a,b){var c=b%a.length;return a[c]},dump:function(){var a="\n",b=" ",c=0,d="",e=Array.prototype.slice.call(arguments),f=function(a){var c="";while(a>0)a--,c+=b;return c},g=function(b){d+=f(c),typeof b=="object"?h(b):typeof b=="function"?d+="function()"+a:typeof b=="string"?d+="string("+b.length+') "'+b+'"'+a:typeof b=="number"?d+="number("+b+")"+a:typeof b=="boolean"&&(d+="bool("+b+")"+a)},h=function(b){var e;if(b===null)d+="NULL"+a;else if(b===undefined)d+="undefined"+a;else if(typeof b=="object"){d+=f(c)+typeof b,c++,d+="("+function(a){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(b)+") {"+a;for(e in b)d+=f(c)+"["+e+"]=> "+a,g(b[e]);c--,d+=f(c)+"}"+a}else g(b)};return e.length==0&&e.push(this.context),e.forEach(function(a){h(a)}),d},date:function(b,c){var d;if(b===undefined)d=new Date;else if(a.lib.is("Date",b))d=b;else if(a.lib.is("String",b))d=new Date(a.lib.strtotime(b)*1e3);else{if(!a.lib.is("Number",b))throw new a.Error("Unable to parse date "+b);d=new Date(b*1e3)}return d},parent:function(){return a.placeholders.parent}},a._function=function(b,c,d){if(!a.functions[b])throw"Unable to find function "+b;return a.functions[b](c,d)},a._function.extend=function(b,c){a.functions[b]=c},a}(Twig||{}),Twig=function(a){return"use strict",a.tests={empty:function(a){if(a===null||a===undefined)return!0;if(typeof a=="number")return!1;if(a.length&&a.length>0)return!1;for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},odd:function(a){return a%2===1},even:function(a){return a%2===0},divisibleby:function(a,b){return a%b[0]===0},defined:function(a){return a!==undefined},none:function(a){return a===null},"null":function(a){return this.none(a)},sameas:function(a,b){return a===b[0]}},a.test=function(b,c,d){if(!a.tests[b])throw"Test "+b+" is not defined.";return a.tests[b](c,d)},a.test.extend=function(b,c){a.tests[b]=c},a}(Twig||{}),Twig=function(a){return"use strict",a.exports={VERSION:a.VERSION},a.exports.twig=function(c){"use strict";var d=c.id,e={strict_variables:c.strict_variables||!1};d&&a.validateId(d),c.debug!==undefined&&(a.debug=c.debug),c.trace!==undefined&&(a.trace=c.trace);if(c.data!==undefined)return new a.Template({data:c.data,module:c.module,id:d,options:e});if(c.ref!==undefined){if(c.id!==undefined)throw new Error("Both ref and id cannot be set on a twig.js template.");return a.Templates.load(c.ref)}if(c.href!==undefined)return a.Templates.loadRemote(c.href,{id:d,method:"ajax",module:c.module,precompiled:c.precompiled,async:c.async,options:e},c.load,c.error);if(c.path!==undefined)return a.Templates.loadRemote(c.path,{id:d,method:"fs",base:c.base,module:c.module,precompiled:c.precompiled,async:c.async,options:e},c.load,c.error)},a.exports.extendFilter=function(b,c){a.filter.extend(b,c)},a.exports.extendFunction=function(b,c){a._function.extend(b,c)},a.exports.extendTest=function(b,c){a.test.extend(b,c)},a.exports.extendTag=function(b){a.logic.extend(b)},a.exports.extend=function(b){b(a)},a.exports.compile=function(b,c){var d=c.filename,e=c.filename,f;return f=new a.Template({data:b,path:e,id:d,options:c.settings["twig options"]}),function(a){return f.render(a)}},a.exports.renderFile=function(b,c,d){"function"==typeof c&&(d=c,c={}),c=c||{};var e={path:b,base:c.settings.views,load:function(a){d(null,a.render(c))}},f=c.settings["twig options"];if(f)for(var g in f)f.hasOwnProperty(g)&&(e[g]=f[g]);a.exports.twig(e)},a.exports.__express=a.exports.renderFile,a.exports.cache=function(b){a.cache=b},a}(Twig||{}),Twig=function(a){return a.compiler={module:{}},a.compiler.compile=function(b,c){var d=JSON.stringify(b.tokens),e=b.id,f;if(c.module){if(a.compiler.module[c.module]===undefined)throw new a.Error("Unable to find module type "+c.module);f=a.compiler.module[c.module](e,d,c.twig)}else f=a.compiler.wrap(e,d);return f},a.compiler.module={amd:function(b,c,d){return'define(["'+d+'"], function (Twig) {\n\tvar twig = Twig.twig;\n'+a.compiler.wrap(b,c)+"\n\treturn templates;\n});"},node:function(b,c){return'var twig = require("twig").twig;\nexports.template = '+a.compiler.wrap(b,c)},cjs2:function(b,c,d){return'module.declare([{ twig: "'+d+'" }], function (require, exports, module) {\n'+'\tvar twig = require("twig").twig;\n'+"\texports.template = "+a.compiler.wrap(b,c)+"\n});"}},a.compiler.wrap=function(a,b){return'twig({id:"'+a.replace('"','\\"')+'", data:'+b+", precompiled: true});\n"},a}(Twig||{});typeof module!="undefined"&&module.declare?module.declare([],function(a,b,c){for(key in Twig.exports)Twig.exports.hasOwnProperty(key)&&(b[key]=Twig.exports[key])}):typeof define=="function"&&define.amd?define(function(){return Twig.exports}):typeof module!="undefined"&&module.exports?module.exports=Twig.exports:(window.twig=Twig.exports.twig,window.Twig=Twig.exports);
\ No newline at end of file