CVE-2021-4264: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') (CWE-1321)
value: A vulnerability was found in LinkedIn dustjs up to 2.x and classified as problematic. Affected by this issue is some unknown functionality. The manipulation leads to improperly controlled modification of object prototype attributes ('prototype pollution'). The attack may be launched remotely. The exploit has been disclosed to the public and may be used. Upgrading to version 3.0.0 is able to address this issue. The name of the patch is ddb6523832465d38c9d80189e9de60519ac307c3. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-216464.
CWE description: The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype.
CVSS v3 base score: 8.8
Published: 2022-12-21T19:15Z
Repository: https://github.com/linkedin/dustjs
Language: JavaScript
Files changed: .gitignore, .travis.yml, dist/dust-core.js, dist/dust-core.min.js, dist/dust-full.js, dist/dust-full.min.js, lib/compiler.js, package.json, test/core.spec.js
Commit date: 2021-10-12 13:57:39 -0700
Commit message: fix for prototype pollution vulnerability

Diff: diff --git a/.gitignore b/.gitignore
index 9b0abf7..b9f4e84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,7 @@ node_modules
 index.html
 tmp
 examples/*/views/**/*.js
 examples/*/lib/*
 !examples/*/lib/main.js
+.vscode
+package-lock.json
diff --git a/.travis.yml b/.travis.yml
index 3e1d0fe..6e1727c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,22 +1,22 @@
 language: node_js
 node_js:
-  - "0.12"
-  - "5"
-  - "6"
+  - "12"
+  - "14"
+  - "16"
 matrix:
   include:
-    - node_js: "0.10"
+    - node_js: "12"
       env:
         - TEST="all"
         - CXX=g++-4.8
 notifications:
   email:
     - jchan@linkedin.com
     - skinast@linkedin.com
 before_install:
-  - npm install -g npm@3
+  - npm install -g npm@6
 before_script:
   - npm update
 sudo: false
 cache:
   directories:
diff --git a/dist/dust-core.js b/dist/dust-core.js
index ce5e905..c503e94 100644
--- a/dist/dust-core.js
+++ b/dist/dust-core.js
@@ -1,8 +1,8 @@
 /*! dustjs-linkedin - v2.7.2
 * http://dustjs.com/
-* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
+* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
 (function (root, factory) {
   if (typeof define === 'function' && define.amd && define.amd.dust === true) {
     define('dust.core', [], factory);
   } else if (typeof exports === 'object') {
     module.exports = factory();
@@ -68,10 +68,13 @@
      */
     dust.log = function(message, type) {
       type = type || INFO;
       if (loggingLevels[type] >= loggingLevels[dust.debugLevel]) {
         log('[DUST:' + type + ']', message);
+        if (type === ERROR && dust.debugLevel === DEBUG && message instanceof Error && message.stack) {
+          log('[DUST:' + type + ']', message.stack);
+        }
       }
     };
 
     dust.debugLevel = NONE;
     if(typeof process !== 'undefined' && process.env && /\bdust\b/.test(process.env.DEBUG)) {
@@ -246,20 +249,29 @@
     return typeof elem === 'function' &&
            elem.__dustBody;
   };
 
   /**
-   * Decide somewhat-naively if something is a Thenable.
+   * Decide somewhat-naively if something is a Thenable.  Matches Promises A+ Spec, section 1.2 “thenable” is an object or function that defines a then method."
    * @param elem {*} object to inspect
    * @return {Boolean} is `elem` a Thenable?
    */
   dust.isThenable = function(elem) {
-    return elem &&
-           typeof elem === 'object' &&
+    return elem &&  /* Beware: `typeof null` is `object` */
+           (typeof elem === 'object' || typeof elem === 'function') &&
            typeof elem.then === 'function';
   };
 
+  /**
+   * Decide if an element is a function but not Thenable; it is prefereable to resolve a thenable function by its `.then` method.
+   * @param elem {*} target of inspection
+   * @return {Boolean} is `elem` a function without a `.then` property?
+   */
+  dust.isNonThenableFunction = function(elem) {
+    return typeof elem === 'function' && !dust.isThenable(elem);
+  };
+
   /**
    * Decide very naively if something is a Stream.
    * @param elem {*} object to inspect
    * @return {Boolean} is `elem` a Stream?
    */
@@ -317,16 +329,21 @@
     this.stack = stack;
     this.global = global;
     this.options = options;
     this.blocks = blocks;
     this.templateName = templateName;
+    this._isContext = true;
   }
 
   dust.makeBase = dust.context = function(global, options) {
     return new Context(undefined, global, options);
   };
 
+  dust.isContext = function(obj) {
+    return typeof obj === "object" && obj._isContext === true;
+  };
+
   /**
    * Factory function that creates a closure scope around a Thenable-callback.
    * Returns a function that can be passed to a Thenable that will resume a
    * Context lookup once the Thenable resolves with new data, adding that new
    * data to the lookup stack.
@@ -336,11 +353,12 @@
       return ctx.push(data)._get(cur, down);
     };
   }
 
   Context.wrap = function(context, name) {
-    if (context instanceof Context) {
+    if (dust.isContext(context)) {
+      context.templateName = name;
       return context;
     }
     return new Context(context, {}, {}, null, name);
   };
 
@@ -427,11 +445,11 @@
         ctx = ctx[down[i]];
         i++;
       }
     }
 
-    if (typeof ctx === 'function') {
+    if (dust.isNonThenableFunction(ctx)) {
       fn = function() {
         try {
           return ctx.apply(ctxThis, arguments);
         } catch (err) {
           dust.log(err, ERROR);
@@ -708,10 +726,15 @@
     this.flushable = true;
     this.root.flush();
     return this;
   };
 
+  /**
+   * Inserts a new chunk that can be used to asynchronously render or write to it
+   * @param callback {Function} The function that will be called with the new chunk
+   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
+   */
   Chunk.prototype.map = function(callback) {
     var cursor = new Chunk(this.root, this.next, this.taps),
         branch = new Chunk(this.root, cursor, this.taps);
 
     this.next = branch;
@@ -723,10 +746,39 @@
       branch.setError(err);
     }
     return cursor;
   };
 
+  /**
+   * Like Chunk#map but additionally resolves a thenable.  If the thenable succeeds the callback is invoked with
+   * a new chunk that can be used to asynchronously render or write to it, otherwise if the thenable is rejected 
+   * then the error body is rendered if available, an error is logged, and the callback is never invoked.
+   * @param {Chunk} The current chunk to insert a new chunk
+   * @param thenable {Thenable} the target thenable to await
+   * @param context {Context} context to use to render the deferred chunk
+   * @param bodies {Object} may optionally contain an "error" for when the thenable is rejected
+   * @param callback {Function} The function that will be called with the new chunk
+   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
+   */
+  function mapThenable(chunk, thenable, context, bodies, callback) {
+    return chunk.map(function(asyncChunk) {
+      thenable.then(function(data) {
+        try {
+          callback(asyncChunk, data);
+        } catch (err) {
+          // handle errors the same way Chunk#map would.  This logic is only here since the thenable defers 
+          // logic such that the try / catch in Chunk#map would not capture it. 
+          dust.log(err, ERROR);
+          asyncChunk.setError(err);
+        }
+      }, function(err) {
+        dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
+        asyncChunk.renderError(err, context, bodies).end();
+      });
+    });
+  }
+
   Chunk.prototype.tap = function(tap) {
     var taps = this.taps;
 
     if (taps) {
       this.taps = taps.push(tap);
@@ -744,11 +796,11 @@
   Chunk.prototype.render = function(body, context) {
     return body(this, context);
   };
 
   Chunk.prototype.reference = function(elem, context, auto, filters) {
-    if (typeof elem === 'function') {
+    if (dust.isNonThenableFunction(elem)) {
       elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
       if (elem instanceof Chunk) {
         return elem;
       } else {
         return this.reference(elem, context, auto, filters);
@@ -769,11 +821,11 @@
     var body = bodies.block,
         skip = bodies['else'],
         chunk = this,
         i, len, head;
 
-    if (typeof elem === 'function' && !dust.isTemplateFn(elem)) {
+    if (dust.isNonThenableFunction(elem) && !dust.isTemplateFn(elem)) {
       try {
         elem = elem.apply(context.current(), [this, context, bodies, params]);
       } catch(err) {
         dust.log(err, ERROR);
         return this.setError(err);
@@ -844,10 +896,16 @@
 
   Chunk.prototype.exists = function(elem, context, bodies) {
     var body = bodies.block,
         skip = bodies['else'];
 
+    if (dust.isThenable(elem)) {
+      return mapThenable(this, elem, context, bodies, function(chunk, data) {
+        chunk.exists(data, context, bodies).end();
+      });
+    }
+
     if (!dust.isEmpty(elem)) {
       if (body) {
         return body(this, context);
       }
       dust.log('No block for exists check in template `' + context.getTemplateName() + '`', DEBUG);
@@ -859,10 +917,16 @@
 
   Chunk.prototype.notexists = function(elem, context, bodies) {
     var body = bodies.block,
         skip = bodies['else'];
 
+    if (dust.isThenable(elem)) {
+      return mapThenable(this, elem, context, bodies, function(chunk, data) {
+        chunk.notexists(data, context, bodies).end();
+      });
+    }
+
     if (dust.isEmpty(elem)) {
       if (body) {
         return body(this, context);
       }
       dust.log('No block for not-exists check in template `' + context.getTemplateName() + '`', DEBUG);
@@ -899,15 +963,13 @@
 
     if (dust.isTemplateFn(elem)) {
       // The eventual result of evaluating `elem` is a partial name
       // Load the partial after getting its name and end the async chunk
       return this.capture(elem, context, function(name, chunk) {
-        partialContext.templateName = name;
         load(name, chunk, partialContext).end();
       });
     } else {
-      partialContext.templateName = elem;
       return load(elem, this, partialContext);
     }
   };
 
   Chunk.prototype.helper = function(name, context, bodies, params, auto) {
@@ -955,31 +1017,35 @@
    * @param auto {String} automatically apply this filter if the Thenable is a reference
    * @param filters {Array} apply these filters if the Thenable is a reference
    * @return {Chunk}
    */
   Chunk.prototype.await = function(thenable, context, bodies, auto, filters) {
-    return this.map(function(chunk) {
-      thenable.then(function(data) {
-        if (bodies) {
-          chunk = chunk.section(data, context, bodies);
-        } else {
-          // Actually a reference. Self-closing sections don't render
-          chunk = chunk.reference(data, context, auto, filters);
-        }
-        chunk.end();
-      }, function(err) {
-        var errorBody = bodies && bodies.error;
-        if(errorBody) {
-          chunk.render(errorBody, context.push(err)).end();
-        } else {
-          dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
-          chunk.end();
-        }
-      });
+    return mapThenable(this, thenable, context, bodies, function(chunk, data) {
+      if (bodies) {
+        chunk.section(data, context, bodies).end();
+      } else {
+        // Actually a reference. Self-closing sections don't render
+        chunk.reference(data, context, auto, filters).end();
+      }
     });
   };
 
+  /**
+   * Render an error body if available
+   * @param err {Error} error that occurred
+   * @param context {Context} context to use to render the error
+   * @param bodies {Object} may optionally contain an "error" which will be rendered
+   * @return {Chunk}
+   */
+  Chunk.prototype.renderError = function(err, context, bodies) {
+    var errorBody = bodies && bodies.error;
+    if (errorBody) {
+      return this.render(errorBody, context.push(err));
+    }
+    return this;
+  };
+
   /**
    * Reserve a chunk to be evaluated with the contents of a streamable.
    * Currently an error event will bomb out the stream. Once an error
    * is received, we push it to an {:error} block if one exists, and log otherwise,
    * then stop listening to the stream.
@@ -987,12 +1053,11 @@
    * @param context {Context} context to use to render each thunk
    * @param bodies {Object} must contain a "body", may contain an "error"
    * @return {Chunk}
    */
   Chunk.prototype.stream = function(stream, context, bodies, auto, filters) {
-    var body = bodies && bodies.block,
-        errorBody = bodies && bodies.error;
+    var body = bodies && bodies.block;
     return this.map(function(chunk) {
       var ended = false;
       stream
         .on('data', function data(thunk) {
           if(ended) {
@@ -1010,15 +1075,12 @@
         })
         .on('error', function error(err) {
           if(ended) {
             return;
           }
-          if(errorBody) {
-            chunk.render(errorBody, context.push(err));
-          } else {
-            dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
-          }
+          chunk.renderError(err, context, bodies);
+          dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
           if(!ended) {
             ended = true;
             chunk.end();
           }
         })
@@ -1141,12 +1203,12 @@
 }));
 
 if (typeof define === "function" && define.amd && define.amd.dust === true) {
     define(["require", "dust.core"], function(require, dust) {
         dust.onLoad = function(name, cb) {
-            require([name], function() {
-                cb();
+            require([name], function(tmpl) {
+                cb(null, tmpl);
             });
         };
         return dust;
     });
 }
diff --git a/dist/dust-core.min.js b/dist/dust-core.min.js
index 18dec80..0b8dc25 100644
--- a/dist/dust-core.min.js
+++ b/dist/dust-core.min.js
@@ -1,4 +1,4 @@
 /*! dustjs-linkedin - v2.7.2
 * http://dustjs.com/
-* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
-!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){return a?"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&b("[DUST:"+d+"]",a)},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},dust.isArray=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0===a?!1:dust.isArray(a)&&!a.length?!0:!a},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&"object"==typeof a&&"function"==typeof a.then},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;f>e;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context(void 0,a,b)},Context.wrap=function(a,b){return a instanceof Context?a:new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&e>i;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return"function"==typeof h?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;d>c;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return this.taps=b?b.push(a):new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return"function"==typeof a?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if("function"==typeof a&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;f>e;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){c.templateName=a,load(a,b,c).end()}):(c.templateName=a,load(a,this,c))},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return this.map(function(f){a.then(function(a){f=c?f.section(a,b,c):f.reference(a,b,d,e),f.end()},function(a){var d=c&&c.error;d?f.render(d,b.push(a)).end():(dust.log("Unhandled promise rejection in `"+b.getTemplateName()+"`",INFO),f.end())})})},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block,g=c&&c.error;return this.map(function(h){var i=!1;a.on("data",function(a){i||(f?h=h.map(function(c){c.render(f,b.push(a)).end()}):c||(h=h.reference(a,b,d,e)))}).on("error",function(a){i||(g?h.render(g,b.push(a)):dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),i||(i=!0,h.end()))}).on("end",function(){i||(i=!0,h.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(){b()})},dust});
\ No newline at end of file
+* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
+!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){if(a)return"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e,this._isContext=!0}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function mapThenable(a,b,c,d,e){return a.map(function(a){b.then(function(b){try{e(a,b)}catch(c){dust.log(c,ERROR),a.setError(c)}},function(b){dust.log("Unhandled promise rejection in `"+c.getTemplateName()+"`",INFO),a.renderError(b,c,d).end()})})}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&(b("[DUST:"+d+"]",a),d===ERROR&&dust.debugLevel===DEBUG&&a instanceof Error&&a.stack&&b("[DUST:"+d+"]",a.stack))},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},Array.isArray?dust.isArray=Array.isArray:dust.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0!==a&&(!(!dust.isArray(a)||a.length)||!a)},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&("object"==typeof a||"function"==typeof a)&&"function"==typeof a.then},dust.isNonThenableFunction=function(a){return"function"==typeof a&&!dust.isThenable(a)},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;e<f;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context((void 0),a,b)},dust.isContext=function(a){return"object"==typeof a&&a._isContext===!0},Context.wrap=function(a,b){return dust.isContext(a)?(a.templateName=b,a):new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&i<e;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return dust.isNonThenableFunction(h)?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;c<d;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return b?this.taps=b.push(a):this.taps=new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return dust.isNonThenableFunction(a)?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if(dust.isNonThenableFunction(a)&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;e<f;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.exists(d,b,c).end()});if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.notexists(d,b,c).end()});if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){load(a,b,c).end()}):load(a,this,c)},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return mapThenable(this,a,b,c,function(a,f){c?a.section(f,b,c).end():a.reference(f,b,d,e).end()})},Chunk.prototype.renderError=function(a,b,c){var d=c&&c.error;return d?this.render(d,b.push(a)):this},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block;return this.map(function(g){var h=!1;a.on("data",function(a){h||(f?g=g.map(function(c){c.render(f,b.push(a)).end()}):c||(g=g.reference(a,b,d,e)))}).on("error",function(a){h||(g.renderError(a,b,c),dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),h||(h=!0,g.end()))}).on("end",function(){h||(h=!0,g.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(a){b(null,a)})},dust});
\ No newline at end of file
diff --git a/dist/dust-full.js b/dist/dust-full.js
index a6bb344..975f509 100644
--- a/dist/dust-full.js
+++ b/dist/dust-full.js
@@ -1,8 +1,8 @@
 /*! dustjs-linkedin - v2.7.2
 * http://dustjs.com/
-* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
+* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
 (function (root, factory) {
   if (typeof define === 'function' && define.amd && define.amd.dust === true) {
     define('dust.core', [], factory);
   } else if (typeof exports === 'object') {
     module.exports = factory();
@@ -68,10 +68,13 @@
      */
     dust.log = function(message, type) {
       type = type || INFO;
       if (loggingLevels[type] >= loggingLevels[dust.debugLevel]) {
         log('[DUST:' + type + ']', message);
+        if (type === ERROR && dust.debugLevel === DEBUG && message instanceof Error && message.stack) {
+          log('[DUST:' + type + ']', message.stack);
+        }
       }
     };
 
     dust.debugLevel = NONE;
     if(typeof process !== 'undefined' && process.env && /\bdust\b/.test(process.env.DEBUG)) {
@@ -246,20 +249,29 @@
     return typeof elem === 'function' &&
            elem.__dustBody;
   };
 
   /**
-   * Decide somewhat-naively if something is a Thenable.
+   * Decide somewhat-naively if something is a Thenable.  Matches Promises A+ Spec, section 1.2 “thenable” is an object or function that defines a then method."
    * @param elem {*} object to inspect
    * @return {Boolean} is `elem` a Thenable?
    */
   dust.isThenable = function(elem) {
-    return elem &&
-           typeof elem === 'object' &&
+    return elem &&  /* Beware: `typeof null` is `object` */
+           (typeof elem === 'object' || typeof elem === 'function') &&
            typeof elem.then === 'function';
   };
 
+  /**
+   * Decide if an element is a function but not Thenable; it is prefereable to resolve a thenable function by its `.then` method.
+   * @param elem {*} target of inspection
+   * @return {Boolean} is `elem` a function without a `.then` property?
+   */
+  dust.isNonThenableFunction = function(elem) {
+    return typeof elem === 'function' && !dust.isThenable(elem);
+  };
+
   /**
    * Decide very naively if something is a Stream.
    * @param elem {*} object to inspect
    * @return {Boolean} is `elem` a Stream?
    */
@@ -317,16 +329,21 @@
     this.stack = stack;
     this.global = global;
     this.options = options;
     this.blocks = blocks;
     this.templateName = templateName;
+    this._isContext = true;
   }
 
   dust.makeBase = dust.context = function(global, options) {
     return new Context(undefined, global, options);
   };
 
+  dust.isContext = function(obj) {
+    return typeof obj === "object" && obj._isContext === true;
+  };
+
   /**
    * Factory function that creates a closure scope around a Thenable-callback.
    * Returns a function that can be passed to a Thenable that will resume a
    * Context lookup once the Thenable resolves with new data, adding that new
    * data to the lookup stack.
@@ -336,11 +353,12 @@
       return ctx.push(data)._get(cur, down);
     };
   }
 
   Context.wrap = function(context, name) {
-    if (context instanceof Context) {
+    if (dust.isContext(context)) {
+      context.templateName = name;
       return context;
     }
     return new Context(context, {}, {}, null, name);
   };
 
@@ -427,11 +445,11 @@
         ctx = ctx[down[i]];
         i++;
       }
     }
 
-    if (typeof ctx === 'function') {
+    if (dust.isNonThenableFunction(ctx)) {
       fn = function() {
         try {
           return ctx.apply(ctxThis, arguments);
         } catch (err) {
           dust.log(err, ERROR);
@@ -708,10 +726,15 @@
     this.flushable = true;
     this.root.flush();
     return this;
   };
 
+  /**
+   * Inserts a new chunk that can be used to asynchronously render or write to it
+   * @param callback {Function} The function that will be called with the new chunk
+   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
+   */
   Chunk.prototype.map = function(callback) {
     var cursor = new Chunk(this.root, this.next, this.taps),
         branch = new Chunk(this.root, cursor, this.taps);
 
     this.next = branch;
@@ -723,10 +746,39 @@
       branch.setError(err);
     }
     return cursor;
   };
 
+  /**
+   * Like Chunk#map but additionally resolves a thenable.  If the thenable succeeds the callback is invoked with
+   * a new chunk that can be used to asynchronously render or write to it, otherwise if the thenable is rejected 
+   * then the error body is rendered if available, an error is logged, and the callback is never invoked.
+   * @param {Chunk} The current chunk to insert a new chunk
+   * @param thenable {Thenable} the target thenable to await
+   * @param context {Context} context to use to render the deferred chunk
+   * @param bodies {Object} may optionally contain an "error" for when the thenable is rejected
+   * @param callback {Function} The function that will be called with the new chunk
+   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
+   */
+  function mapThenable(chunk, thenable, context, bodies, callback) {
+    return chunk.map(function(asyncChunk) {
+      thenable.then(function(data) {
+        try {
+          callback(asyncChunk, data);
+        } catch (err) {
+          // handle errors the same way Chunk#map would.  This logic is only here since the thenable defers 
+          // logic such that the try / catch in Chunk#map would not capture it. 
+          dust.log(err, ERROR);
+          asyncChunk.setError(err);
+        }
+      }, function(err) {
+        dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
+        asyncChunk.renderError(err, context, bodies).end();
+      });
+    });
+  }
+
   Chunk.prototype.tap = function(tap) {
     var taps = this.taps;
 
     if (taps) {
       this.taps = taps.push(tap);
@@ -744,11 +796,11 @@
   Chunk.prototype.render = function(body, context) {
     return body(this, context);
   };
 
   Chunk.prototype.reference = function(elem, context, auto, filters) {
-    if (typeof elem === 'function') {
+    if (dust.isNonThenableFunction(elem)) {
       elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
       if (elem instanceof Chunk) {
         return elem;
       } else {
         return this.reference(elem, context, auto, filters);
@@ -769,11 +821,11 @@
     var body = bodies.block,
         skip = bodies['else'],
         chunk = this,
         i, len, head;
 
-    if (typeof elem === 'function' && !dust.isTemplateFn(elem)) {
+    if (dust.isNonThenableFunction(elem) && !dust.isTemplateFn(elem)) {
       try {
         elem = elem.apply(context.current(), [this, context, bodies, params]);
       } catch(err) {
         dust.log(err, ERROR);
         return this.setError(err);
@@ -844,10 +896,16 @@
 
   Chunk.prototype.exists = function(elem, context, bodies) {
     var body = bodies.block,
         skip = bodies['else'];
 
+    if (dust.isThenable(elem)) {
+      return mapThenable(this, elem, context, bodies, function(chunk, data) {
+        chunk.exists(data, context, bodies).end();
+      });
+    }
+
     if (!dust.isEmpty(elem)) {
       if (body) {
         return body(this, context);
       }
       dust.log('No block for exists check in template `' + context.getTemplateName() + '`', DEBUG);
@@ -859,10 +917,16 @@
 
   Chunk.prototype.notexists = function(elem, context, bodies) {
     var body = bodies.block,
         skip = bodies['else'];
 
+    if (dust.isThenable(elem)) {
+      return mapThenable(this, elem, context, bodies, function(chunk, data) {
+        chunk.notexists(data, context, bodies).end();
+      });
+    }
+
     if (dust.isEmpty(elem)) {
       if (body) {
         return body(this, context);
       }
       dust.log('No block for not-exists check in template `' + context.getTemplateName() + '`', DEBUG);
@@ -899,15 +963,13 @@
 
     if (dust.isTemplateFn(elem)) {
       // The eventual result of evaluating `elem` is a partial name
       // Load the partial after getting its name and end the async chunk
       return this.capture(elem, context, function(name, chunk) {
-        partialContext.templateName = name;
         load(name, chunk, partialContext).end();
       });
     } else {
-      partialContext.templateName = elem;
       return load(elem, this, partialContext);
     }
   };
 
   Chunk.prototype.helper = function(name, context, bodies, params, auto) {
@@ -955,31 +1017,35 @@
    * @param auto {String} automatically apply this filter if the Thenable is a reference
    * @param filters {Array} apply these filters if the Thenable is a reference
    * @return {Chunk}
    */
   Chunk.prototype.await = function(thenable, context, bodies, auto, filters) {
-    return this.map(function(chunk) {
-      thenable.then(function(data) {
-        if (bodies) {
-          chunk = chunk.section(data, context, bodies);
-        } else {
-          // Actually a reference. Self-closing sections don't render
-          chunk = chunk.reference(data, context, auto, filters);
-        }
-        chunk.end();
-      }, function(err) {
-        var errorBody = bodies && bodies.error;
-        if(errorBody) {
-          chunk.render(errorBody, context.push(err)).end();
-        } else {
-          dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
-          chunk.end();
-        }
-      });
+    return mapThenable(this, thenable, context, bodies, function(chunk, data) {
+      if (bodies) {
+        chunk.section(data, context, bodies).end();
+      } else {
+        // Actually a reference. Self-closing sections don't render
+        chunk.reference(data, context, auto, filters).end();
+      }
     });
   };
 
+  /**
+   * Render an error body if available
+   * @param err {Error} error that occurred
+   * @param context {Context} context to use to render the error
+   * @param bodies {Object} may optionally contain an "error" which will be rendered
+   * @return {Chunk}
+   */
+  Chunk.prototype.renderError = function(err, context, bodies) {
+    var errorBody = bodies && bodies.error;
+    if (errorBody) {
+      return this.render(errorBody, context.push(err));
+    }
+    return this;
+  };
+
   /**
    * Reserve a chunk to be evaluated with the contents of a streamable.
    * Currently an error event will bomb out the stream. Once an error
    * is received, we push it to an {:error} block if one exists, and log otherwise,
    * then stop listening to the stream.
@@ -987,12 +1053,11 @@
    * @param context {Context} context to use to render each thunk
    * @param bodies {Object} must contain a "body", may contain an "error"
    * @return {Chunk}
    */
   Chunk.prototype.stream = function(stream, context, bodies, auto, filters) {
-    var body = bodies && bodies.block,
-        errorBody = bodies && bodies.error;
+    var body = bodies && bodies.block;
     return this.map(function(chunk) {
       var ended = false;
       stream
         .on('data', function data(thunk) {
           if(ended) {
@@ -1010,15 +1075,12 @@
         })
         .on('error', function error(err) {
           if(ended) {
             return;
           }
-          if(errorBody) {
-            chunk.render(errorBody, context.push(err));
-          } else {
-            dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
-          }
+          chunk.renderError(err, context, bodies);
+          dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
           if(!ended) {
             ended = true;
             chunk.end();
           }
         })
@@ -1153,218 +1215,217 @@
     // in the browser, store the factory output if we want to use the parser directly
     factory(root.dust);
   }
 }(this, function(dust) {
   var parser = (function() {
+  "use strict";
+
   /*
-   * Generated by PEG.js 0.8.0.
+   * Generated by PEG.js 0.9.0.
    *
-   * http://pegjs.majda.cz/
+   * http://pegjs.org/
    */
 
   function peg$subclass(child, parent) {
     function ctor() { this.constructor = child; }
     ctor.prototype = parent.prototype;
     child.prototype = new ctor();
   }
 
-  function SyntaxError(message, expected, found, offset, line, column) {
+  function peg$SyntaxError(message, expected, found, location) {
     this.message  = message;
     this.expected = expected;
     this.found    = found;
-    this.offset   = offset;
-    this.line     = line;
-    this.column   = column;
-
+    this.location = location;
     this.name     = "SyntaxError";
+
+    if (typeof Error.captureStackTrace === "function") {
+      Error.captureStackTrace(this, peg$SyntaxError);
+    }
   }
 
-  peg$subclass(SyntaxError, Error);
+  peg$subclass(peg$SyntaxError, Error);
 
-  function parse(input) {
+  function peg$parse(input) {
     var options = arguments.length > 1 ? arguments[1] : {},
+        parser  = this,
 
         peg$FAILED = {},
 
         peg$startRuleFunctions = { start: peg$parsestart },
         peg$startRuleFunction  = peg$parsestart,
 
-        peg$c0 = [],
-        peg$c1 = function(p) {
+        peg$c0 = function(p) {
             var body = ["body"].concat(p);
             return withPosition(body);
           },
-        peg$c2 = { type: "other", description: "section" },
-        peg$c3 = peg$FAILED,
-        peg$c4 = null,
-        peg$c5 = function(t, b, e, n) {
+        peg$c1 = { type: "other", description: "section" },
+        peg$c2 = function(t, b, e, n) {
             if( (!n) || (t[1].text !== n.text) ) {
               error("Expected end tag for "+t[1].text+" but it was not found.");
             }
             return true;
           },
-        peg$c6 = void 0,
-        peg$c7 = function(t, b, e, n) {
+        peg$c3 = function(t, b, e, n) {
             e.push(["param", ["literal", "block"], b]);
             t.push(e, ["filters"]);
             return withPosition(t)
           },
-        peg$c8 = "/",
-        peg$c9 = { type: "literal", value: "/", description: "\"/\"" },
-        peg$c10 = function(t) {
+        peg$c4 = "/",
+        peg$c5 = { type: "literal", value: "/", description: "\"/\"" },
+        peg$c6 = function(t) {
             t.push(["bodies"], ["filters"]);
             return withPosition(t)
           },
-        peg$c11 = /^[#?\^<+@%]/,
-        peg$c12 = { type: "class", value: "[#?\\^<+@%]", description: "[#?\\^<+@%]" },
-        peg$c13 = function(t, n, c, p) { return [t, n, c, p] },
-        peg$c14 = { type: "other", description: "end tag" },
-        peg$c15 = function(n) { return n },
-        peg$c16 = ":",
-        peg$c17 = { type: "literal", value: ":", description: "\":\"" },
-        peg$c18 = function(n) {return n},
-        peg$c19 = function(n) { return n ? ["context", n] : ["context"] },
-        peg$c20 = { type: "other", description: "params" },
-        peg$c21 = "=",
-        peg$c22 = { type: "literal", value: "=", description: "\"=\"" },
-        peg$c23 = function(k, v) {return ["param", ["literal", k], v]},
-        peg$c24 = function(p) { return ["params"].concat(p) },
-        peg$c25 = { type: "other", description: "bodies" },
-        peg$c26 = function(p) { return ["bodies"].concat(p) },
-        peg$c27 = { type: "other", description: "reference" },
-        peg$c28 = function(n, f) { return withPosition(["reference", n, f]) },
-        peg$c29 = { type: "other", description: "partial" },
-        peg$c30 = ">",
-        peg$c31 = { type: "literal", value: ">", description: "\">\"" },
-        peg$c32 = "+",
-        peg$c33 = { type: "literal", value: "+", description: "\"+\"" },
-        peg$c34 = function(k) {return ["literal", k]},
-        peg$c35 = function(s, n, c, p) {
+        peg$c7 = /^[#?\^<+@%]/,
+        peg$c8 = { type: "class", value: "[#?^<+@%]", description: "[#?^<+@%]" },
+        peg$c9 = function(t, n, c, p) { return [t, n, c, p] },
+        peg$c10 = { type: "other", description: "end tag" },
+        peg$c11 = function(n) { return n },
+        peg$c12 = ":",
+        peg$c13 = { type: "literal", value: ":", description: "\":\"" },
+        peg$c14 = function(n) {return n},
+        peg$c15 = function(n) { return n ? ["context", n] : ["context"] },
+        peg$c16 = { type: "other", description: "params" },
+        peg$c17 = "=",
+        peg$c18 = { type: "literal", value: "=", description: "\"=\"" },
+        peg$c19 = function(k, v) {return ["param", ["literal", k], v]},
+        peg$c20 = function(p) { return ["params"].concat(p) },
+        peg$c21 = { type: "other", description: "bodies" },
+        peg$c22 = function(p) { return ["bodies"].concat(p) },
+        peg$c23 = { type: "other", description: "reference" },
+        peg$c24 = function(n, f) { return withPosition(["reference", n, f]) },
+        peg$c25 = { type: "other", description: "partial" },
+        peg$c26 = ">",
+        peg$c27 = { type: "literal", value: ">", description: "\">\"" },
+        peg$c28 = "+",
+        peg$c29 = { type: "literal", value: "+", description: "\"+\"" },
+        peg$c30 = function(s, k) {return ["literal", k]},
+        peg$c31 = function(s, n, c, p) {
             var key = (s === ">") ? "partial" : s;
             return withPosition([key, n, c, p])
           },
-        peg$c36 = { type: "other", description: "filters" },
-        peg$c37 = "|",
-        peg$c38 = { type: "literal", value: "|", description: "\"|\"" },
-        peg$c39 = function(f) { return ["filters"].concat(f) },
-        peg$c40 = { type: "other", description: "special" },
-        peg$c41 = "~",
-        peg$c42 = { type: "literal", value: "~", description: "\"~\"" },
-        peg$c43 = function(k) { return withPosition(["special", k]) },
-        peg$c44 = { type: "other", description: "identifier" },
-        peg$c45 = function(p) {
+        peg$c32 = { type: "other", description: "filters" },
+        peg$c33 = "|",
+        peg$c34 = { type: "literal", value: "|", description: "\"|\"" },
+        peg$c35 = function(f) { return ["filters"].concat(f) },
+        peg$c36 = { type: "other", description: "special" },
+        peg$c37 = "~",
+        peg$c38 = { type: "literal", value: "~", description: "\"~\"" },
+        peg$c39 = function(k) { return withPosition(["special", k]) },
+        peg$c40 = { type: "other", description: "identifier" },
+        peg$c41 = function(p) {
             var arr = ["path"].concat(p);
-            arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,'');
+            arr.text = p[1].join('.');
             return arr;
           },
-        peg$c46 = function(k) {
+        peg$c42 = function(k) {
             var arr = ["key", k];
             arr.text = k;
             return arr;
           },
-        peg$c47 = { type: "other", description: "number" },
-        peg$c48 = function(n) { return ['literal', n]; },
-        peg$c49 = { type: "other", description: "float" },
-        peg$c50 = ".",
-        peg$c51 = { type: "literal", value: ".", description: "\".\"" },
-        peg$c52 = function(l, r) { return parseFloat(l + "." + r); },
-        peg$c53 = { type: "other", description: "unsigned_integer" },
-        peg$c54 = /^[0-9]/,
-        peg$c55 = { type: "class", value: "[0-9]", description: "[0-9]" },
-        peg$c56 = function(digits) { return makeInteger(digits); },
-        peg$c57 = { type: "other", description: "signed_integer" },
-        peg$c58 = "-",
-        peg$c59 = { type: "literal", value: "-", description: "\"-\"" },
-        peg$c60 = function(sign, n) { return n * -1; },
-        peg$c61 = { type: "other", description: "integer" },
-        peg$c62 = { type: "other", description: "path" },
-        peg$c63 = function(k, d) {
+        peg$c43 = { type: "other", description: "number" },
+        peg$c44 = function(n) { return ['literal', n]; },
+        peg$c45 = { type: "other", description: "float" },
+        peg$c46 = ".",
+        peg$c47 = { type: "literal", value: ".", description: "\".\"" },
+        peg$c48 = function(l, r) { return parseFloat(l + "." + r); },
+        peg$c49 = { type: "other", description: "unsigned_integer" },
+        peg$c50 = /^[0-9]/,
+        peg$c51 = { type: "class", value: "[0-9]", description: "[0-9]" },
+        peg$c52 = function(digits) { return makeInteger(digits); },
+        peg$c53 = { type: "other", description: "signed_integer" },
+        peg$c54 = "-",
+        peg$c55 = { type: "literal", value: "-", description: "\"-\"" },
+        peg$c56 = function(sign, n) { return n * -1; },
+        peg$c57 = { type: "other", description: "integer" },
+        peg$c58 = { type: "other", description: "path" },
+        peg$c59 = function(k, d) {
             d = d[0];
             if (k && d) {
               d.unshift(k);
               return withPosition([false, d])
             }
             return withPosition([true, d])
           },
-        peg$c64 = function(d) {
+        peg$c60 = function(d) {
             if (d.length > 0) {
               return withPosition([true, d[0]])
             }
             return withPosition([true, []])
           },
-        peg$c65 = { type: "other", description: "key" },
-        peg$c66 = /^[a-zA-Z_$]/,
-        peg$c67 = { type: "class", value: "[a-zA-Z_$]", description: "[a-zA-Z_$]" },
-        peg$c68 = /^[0-9a-zA-Z_$\-]/,
-        peg$c69 = { type: "class", value: "[0-9a-zA-Z_$\\-]", description: "[0-9a-zA-Z_$\\-]" },
-        peg$c70 = function(h, t) { return h + t.join('') },
-        peg$c71 = { type: "other", description: "array" },
-        peg$c72 = function(n) {return n.join('')},
-        peg$c73 = function(a) {return a; },
-        peg$c74 = function(i, nk) { if(nk) { nk.unshift(i); } else {nk = [i] } return nk; },
-        peg$c75 = { type: "other", description: "array_part" },
-        peg$c76 = function(k) {return k},
-        peg$c77 = function(d, a) { if (a) { return d.concat(a); } else { return d; } },
-        peg$c78 = { type: "other", description: "inline" },
-        peg$c79 = "\"",
-        peg$c80 = { type: "literal", value: "\"", description: "\"\\\"\"" },
-        peg$c81 = function() { return withPosition(["literal", ""]) },
-        peg$c82 = function(l) { return withPosition(["literal", l]) },
-        peg$c83 = function(p) { return withPosition(["body"].concat(p)) },
-        peg$c84 = function(l) { return ["buffer", l] },
-        peg$c85 = { type: "other", description: "buffer" },
-        peg$c86 = function(e, w) { return withPosition(["format", e, w.join('')]) },
-        peg$c87 = { type: "any", description: "any character" },
-        peg$c88 = function(c) {return c},
-        peg$c89 = function(b) { return withPosition(["buffer", b.join('')]) },
-        peg$c90 = { type: "other", description: "literal" },
-        peg$c91 = /^[^"]/,
-        peg$c92 = { type: "class", value: "[^\"]", description: "[^\"]" },
-        peg$c93 = function(b) { return b.join('') },
-        peg$c94 = "\\\"",
-        peg$c95 = { type: "literal", value: "\\\"", description: "\"\\\\\\\"\"" },
-        peg$c96 = function() { return '"' },
-        peg$c97 = { type: "other", description: "raw" },
-        peg$c98 = "{`",
-        peg$c99 = { type: "literal", value: "{`", description: "\"{`\"" },
-        peg$c100 = "`}",
-        peg$c101 = { type: "literal", value: "`}", description: "\"`}\"" },
-        peg$c102 = function(character) {return character},
-        peg$c103 = function(rawText) { return withPosition(["raw", rawText.join('')]) },
-        peg$c104 = { type: "other", description: "comment" },
-        peg$c105 = "{!",
-        peg$c106 = { type: "literal", value: "{!", description: "\"{!\"" },
-        peg$c107 = "!}",
-        peg$c108 = { type: "literal", value: "!}", description: "\"!}\"" },
-        peg$c109 = function(c) { return withPosition(["comment", c.join('')]) },
-        peg$c110 = /^[#?\^><+%:@\/~%]/,
-        peg$c111 = { type: "class", value: "[#?\\^><+%:@\\/~%]", description: "[#?\\^><+%:@\\/~%]" },
-        peg$c112 = "{",
-        peg$c113 = { type: "literal", value: "{", description: "\"{\"" },
-        peg$c114 = "}",
-        peg$c115 = { type: "literal", value: "}", description: "\"}\"" },
-        peg$c116 = "[",
-        peg$c117 = { type: "literal", value: "[", description: "\"[\"" },
-        peg$c118 = "]",
-        peg$c119 = { type: "literal", value: "]", description: "\"]\"" },
-        peg$c120 = "\n",
-        peg$c121 = { type: "literal", value: "\n", description: "\"\\n\"" },
-        peg$c122 = "\r\n",
-        peg$c123 = { type: "literal", value: "\r\n", description: "\"\\r\\n\"" },
-        peg$c124 = "\r",
-        peg$c125 = { type: "literal", value: "\r", description: "\"\\r\"" },
-        peg$c126 = "\u2028",
-        peg$c127 = { type: "literal", value: "\u2028", description: "\"\\u2028\"" },
-        peg$c128 = "\u2029",
-        peg$c129 = { type: "literal", value: "\u2029", description: "\"\\u2029\"" },
-        peg$c130 = /^[\t\x0B\f \xA0\uFEFF]/,
-        peg$c131 = { type: "class", value: "[\\t\\x0B\\f \\xA0\\uFEFF]", description: "[\\t\\x0B\\f \\xA0\\uFEFF]" },
+        peg$c61 = { type: "other", description: "key" },
+        peg$c62 = /^[a-zA-Z_$]/,
+        peg$c63 = { type: "class", value: "[a-zA-Z_$]", description: "[a-zA-Z_$]" },
+        peg$c64 = /^[0-9a-zA-Z_$\-]/,
+        peg$c65 = { type: "class", value: "[0-9a-zA-Z_$-]", description: "[0-9a-zA-Z_$-]" },
+        peg$c66 = function(h, t) { return h + t.join('') },
+        peg$c67 = { type: "other", description: "array" },
+        peg$c68 = function(n) {return n.join('')},
+        peg$c69 = function(a) {return a; },
+        peg$c70 = function(i, nk) { if(nk) { nk.unshift(i); } else {nk = [i] } return nk; },
+        peg$c71 = { type: "other", description: "array_part" },
+        peg$c72 = function(k) {return k},
+        peg$c73 = function(d, a) { if (a) { return d.concat(a); } else { return d; } },
+        peg$c74 = { type: "other", description: "inline" },
+        peg$c75 = "\"",
+        peg$c76 = { type: "literal", value: "\"", description: "\"\\\"\"" },
+        peg$c77 = function() { return withPosition(["literal", ""]) },
+        peg$c78 = function(l) { return withPosition(["literal", l]) },
+        peg$c79 = function(p) { return withPosition(["body"].concat(p)) },
+        peg$c80 = function(l) { return ["buffer", l] },
+        peg$c81 = { type: "other", description: "buffer" },
+        peg$c82 = function(e, w) { return withPosition(["format", e, w.join('')]) },
+        peg$c83 = { type: "any", description: "any character" },
+        peg$c84 = function(c) {return c},
+        peg$c85 = function(b) { return withPosition(["buffer", b.join('')]) },
+        peg$c86 = { type: "other", description: "literal" },
+        peg$c87 = /^[^"]/,
+        peg$c88 = { type: "class", value: "[^\"]", description: "[^\"]" },
+        peg$c89 = function(b) { return b.join('') },
+        peg$c90 = "\\\"",
+        peg$c91 = { type: "literal", value: "\\\"", description: "\"\\\\\\\"\"" },
+        peg$c92 = function() { return '"' },
+        peg$c93 = { type: "other", description: "raw" },
+        peg$c94 = "{`",
+        peg$c95 = { type: "literal", value: "{`", description: "\"{`\"" },
+        peg$c96 = "`}",
+        peg$c97 = { type: "literal", value: "`}", description: "\"`}\"" },
+        peg$c98 = function(character) {return character},
+        peg$c99 = function(rawText) { return withPosition(["raw", rawText.join('')]) },
+        peg$c100 = { type: "other", description: "comment" },
+        peg$c101 = "{!",
+        peg$c102 = { type: "literal", value: "{!", description: "\"{!\"" },
+        peg$c103 = "!}",
+        peg$c104 = { type: "literal", value: "!}", description: "\"!}\"" },
+        peg$c105 = function(c) { return withPosition(["comment", c.join('')]) },
+        peg$c106 = /^[#?\^><+%:@\/~%]/,
+        peg$c107 = { type: "class", value: "[#?^><+%:@/~%]", description: "[#?^><+%:@/~%]" },
+        peg$c108 = "{",
+        peg$c109 = { type: "literal", value: "{", description: "\"{\"" },
+        peg$c110 = "}",
+        peg$c111 = { type: "literal", value: "}", description: "\"}\"" },
+        peg$c112 = "[",
+        peg$c113 = { type: "literal", value: "[", description: "\"[\"" },
+        peg$c114 = "]",
+        peg$c115 = { type: "literal", value: "]", description: "\"]\"" },
+        peg$c116 = "\n",
+        peg$c117 = { type: "literal", value: "\n", description: "\"\\n\"" },
+        peg$c118 = "\r\n",
+        peg$c119 = { type: "literal", value: "\r\n", description: "\"\\r\\n\"" },
+        peg$c120 = "\r",
+        peg$c121 = { type: "literal", value: "\r", description: "\"\\r\"" },
+        peg$c122 = "\u2028",
+        peg$c123 = { type: "literal", value: "\u2028", description: "\"\\u2028\"" },
+        peg$c124 = "\u2029",
+        peg$c125 = { type: "literal", value: "\u2029", description: "\"\\u2029\"" },
+        peg$c126 = /^[\t\x0B\f \xA0\uFEFF]/,
+        peg$c127 = { type: "class", value: "[\\t\\v\\f \\u00A0\\uFEFF]", description: "[\\t\\v\\f \\u00A0\\uFEFF]" },
 
         peg$currPos          = 0,
-        peg$reportedPos      = 0,
-        peg$cachedPos        = 0,
-        peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
+        peg$savedPos         = 0,
+        peg$posDetailsCache  = [{ line: 1, column: 1, seenCR: false }],
         peg$maxFailPos       = 0,
         peg$maxFailExpected  = [],
         peg$silentFails      = 0,
 
         peg$result;
@@ -1376,42 +1437,55 @@
 
       peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
     }
 
     function text() {
-      return input.substring(peg$reportedPos, peg$currPos);
-    }
-
-    function offset() {
-      return peg$reportedPos;
-    }
-
-    function line() {
-      return peg$computePosDetails(peg$reportedPos).line;
+      return input.substring(peg$savedPos, peg$currPos);
     }
 
-    function column() {
-      return peg$computePosDetails(peg$reportedPos).column;
+    function location() {
+      return peg$computeLocation(peg$savedPos, peg$currPos);
     }
 
     function expected(description) {
       throw peg$buildException(
         null,
         [{ type: "other", description: description }],
-        peg$reportedPos
+        input.substring(peg$savedPos, peg$currPos),
+        peg$computeLocation(peg$savedPos, peg$currPos)
       );
     }
 
     function error(message) {
-      throw peg$buildException(message, null, peg$reportedPos);
+      throw peg$buildException(
+        message,
+        null,
+        input.substring(peg$savedPos, peg$currPos),
+        peg$computeLocation(peg$savedPos, peg$currPos)
+      );
     }
 
     function peg$computePosDetails(pos) {
-      function advance(details, startPos, endPos) {
-        var p, ch;
+      var details = peg$posDetailsCache[pos],
+          p, ch;
+
+      if (details) {
+        return details;
+      } else {
+        p = pos - 1;
+        while (!peg$posDetailsCache[p]) {
+          p--;
+        }
+
+        details = peg$posDetailsCache[p];
+        details = {
+          line:   details.line,
+          column: details.column,
+          seenCR: details.seenCR
+        };
 
-        for (p = startPos; p < endPos; p++) {
+        while (p < pos) {
           ch = input.charAt(p);
           if (ch === "\n") {
             if (!details.seenCR) { details.line++; }
             details.column = 1;
             details.seenCR = false;
@@ -1421,23 +1495,35 @@
             details.seenCR = true;
           } else {
             details.column++;
             details.seenCR = false;
           }
-        }
-      }
 
-      if (peg$cachedPos !== pos) {
-        if (peg$cachedPos > pos) {
-          peg$cachedPos = 0;
-          peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
+          p++;
         }
-        advance(peg$cachedPosDetails, peg$cachedPos, pos);
-        peg$cachedPos = pos;
+
+        peg$posDetailsCache[pos] = details;
+        return details;
       }
+    }
 
-      return peg$cachedPosDetails;
+    function peg$computeLocation(startPos, endPos) {
+      var startPosDetails = peg$computePosDetails(startPos),
+          endPosDetails   = peg$computePosDetails(endPos);
+
+      return {
+        start: {
+          offset: startPos,
+          line:   startPosDetails.line,
+          column: startPosDetails.column
+        },
+        end: {
+          offset: endPos,
+          line:   endPosDetails.line,
+          column: endPosDetails.column
+        }
+      };
     }
 
     function peg$fail(expected) {
       if (peg$currPos < peg$maxFailPos) { return; }
 
@@ -1447,11 +1533,11 @@
       }
 
       peg$maxFailExpected.push(expected);
     }
 
-    function peg$buildException(message, expected, pos) {
+    function peg$buildException(message, expected, found, location) {
       function cleanupExpected(expected) {
         var i = 1;
 
         expected.sort(function(a, b) {
           if (a.description < b.description) {
@@ -1484,12 +1570,12 @@
             .replace(/\n/g,   '\\n')
             .replace(/\f/g,   '\\f')
             .replace(/\r/g,   '\\r')
             .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
             .replace(/[\x10-\x1F\x80-\xFF]/g,    function(ch) { return '\\x'  + hex(ch); })
-            .replace(/[\u0180-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
-            .replace(/[\u1080-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
+            .replace(/[\u0100-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
+            .replace(/[\u1000-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
         }
 
         var expectedDescs = new Array(expected.length),
             expectedDesc, foundDesc, i;
 
@@ -1506,24 +1592,19 @@
         foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
 
         return "Expected " + expectedDesc + " but " + foundDesc + " found.";
       }
 
-      var posDetails = peg$computePosDetails(pos),
-          found      = pos < input.length ? input.charAt(pos) : null;
-
       if (expected !== null) {
         cleanupExpected(expected);
       }
 
-      return new SyntaxError(
+      return new peg$SyntaxError(
         message !== null ? message : buildMessage(expected, found),
         expected,
         found,
-        pos,
-        posDetails.line,
-        posDetails.column
+        location
       );
     }
 
     function peg$parsestart() {
       var s0;
@@ -1542,12 +1623,12 @@
       while (s2 !== peg$FAILED) {
         s1.push(s2);
         s2 = peg$parsepart();
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c1(s1);
+        peg$savedPos = s0;
+        s1 = peg$c0(s1);
       }
       s0 = s1;
 
       return s0;
     }
@@ -1598,51 +1679,51 @@
             if (s4 !== peg$FAILED) {
               s5 = peg$parsebodies();
               if (s5 !== peg$FAILED) {
                 s6 = peg$parseend_tag();
                 if (s6 === peg$FAILED) {
-                  s6 = peg$c4;
+                  s6 = null;
                 }
                 if (s6 !== peg$FAILED) {
-                  peg$reportedPos = peg$currPos;
-                  s7 = peg$c5(s1, s4, s5, s6);
+                  peg$savedPos = peg$currPos;
+                  s7 = peg$c2(s1, s4, s5, s6);
                   if (s7) {
-                    s7 = peg$c6;
+                    s7 = void 0;
                   } else {
-                    s7 = peg$c3;
+                    s7 = peg$FAILED;
                   }
                   if (s7 !== peg$FAILED) {
-                    peg$reportedPos = s0;
-                    s1 = peg$c7(s1, s4, s5, s6);
+                    peg$savedPos = s0;
+                    s1 = peg$c3(s1, s4, s5, s6);
                     s0 = s1;
                   } else {
                     peg$currPos = s0;
-                    s0 = peg$c3;
+                    s0 = peg$FAILED;
                   }
                 } else {
                   peg$currPos = s0;
-                  s0 = peg$c3;
+                  s0 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       if (s0 === peg$FAILED) {
         s0 = peg$currPos;
         s1 = peg$parsesec_tag_start();
         if (s1 !== peg$FAILED) {
@@ -1652,43 +1733,43 @@
             s2.push(s3);
             s3 = peg$parsews();
           }
           if (s2 !== peg$FAILED) {
             if (input.charCodeAt(peg$currPos) === 47) {
-              s3 = peg$c8;
+              s3 = peg$c4;
               peg$currPos++;
             } else {
               s3 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c9); }
+              if (peg$silentFails === 0) { peg$fail(peg$c5); }
             }
             if (s3 !== peg$FAILED) {
               s4 = peg$parserd();
               if (s4 !== peg$FAILED) {
-                peg$reportedPos = s0;
-                s1 = peg$c10(s1);
+                peg$savedPos = s0;
+                s1 = peg$c6(s1);
                 s0 = s1;
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c2); }
+        if (peg$silentFails === 0) { peg$fail(peg$c1); }
       }
 
       return s0;
     }
 
@@ -1696,16 +1777,16 @@
       var s0, s1, s2, s3, s4, s5, s6;
 
       s0 = peg$currPos;
       s1 = peg$parseld();
       if (s1 !== peg$FAILED) {
-        if (peg$c11.test(input.charAt(peg$currPos))) {
+        if (peg$c7.test(input.charAt(peg$currPos))) {
           s2 = input.charAt(peg$currPos);
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c12); }
+          if (peg$silentFails === 0) { peg$fail(peg$c8); }
         }
         if (s2 !== peg$FAILED) {
           s3 = [];
           s4 = peg$parsews();
           while (s4 !== peg$FAILED) {
@@ -1717,36 +1798,36 @@
             if (s4 !== peg$FAILED) {
               s5 = peg$parsecontext();
               if (s5 !== peg$FAILED) {
                 s6 = peg$parseparams();
                 if (s6 !== peg$FAILED) {
-                  peg$reportedPos = s0;
-                  s1 = peg$c13(s2, s4, s5, s6);
+                  peg$savedPos = s0;
+                  s1 = peg$c9(s2, s4, s5, s6);
                   s0 = s1;
                 } else {
                   peg$currPos = s0;
-                  s0 = peg$c3;
+                  s0 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
 
       return s0;
     }
 
@@ -1756,15 +1837,15 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parseld();
       if (s1 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 47) {
-          s2 = peg$c8;
+          s2 = peg$c4;
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c9); }
+          if (peg$silentFails === 0) { peg$fail(peg$c5); }
         }
         if (s2 !== peg$FAILED) {
           s3 = [];
           s4 = peg$parsews();
           while (s4 !== peg$FAILED) {
@@ -1781,41 +1862,41 @@
                 s6 = peg$parsews();
               }
               if (s5 !== peg$FAILED) {
                 s6 = peg$parserd();
                 if (s6 !== peg$FAILED) {
-                  peg$reportedPos = s0;
-                  s1 = peg$c15(s4);
+                  peg$savedPos = s0;
+                  s1 = peg$c11(s4);
                   s0 = s1;
                 } else {
                   peg$currPos = s0;
-                  s0 = peg$c3;
+                  s0 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c14); }
+        if (peg$silentFails === 0) { peg$fail(peg$c10); }
       }
 
       return s0;
     }
 
@@ -1823,36 +1904,36 @@
       var s0, s1, s2, s3;
 
       s0 = peg$currPos;
       s1 = peg$currPos;
       if (input.charCodeAt(peg$currPos) === 58) {
-        s2 = peg$c16;
+        s2 = peg$c12;
         peg$currPos++;
       } else {
         s2 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c17); }
+        if (peg$silentFails === 0) { peg$fail(peg$c13); }
       }
       if (s2 !== peg$FAILED) {
         s3 = peg$parseidentifier();
         if (s3 !== peg$FAILED) {
-          peg$reportedPos = s1;
-          s2 = peg$c18(s3);
+          peg$savedPos = s1;
+          s2 = peg$c14(s3);
           s1 = s2;
         } else {
           peg$currPos = s1;
-          s1 = peg$c3;
+          s1 = peg$FAILED;
         }
       } else {
         peg$currPos = s1;
-        s1 = peg$c3;
+        s1 = peg$FAILED;
       }
       if (s1 === peg$FAILED) {
-        s1 = peg$c4;
+        s1 = null;
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c19(s1);
+        peg$savedPos = s0;
+        s1 = peg$c15(s1);
       }
       s0 = s1;
 
       return s0;
     }
@@ -1870,49 +1951,49 @@
         while (s4 !== peg$FAILED) {
           s3.push(s4);
           s4 = peg$parsews();
         }
       } else {
-        s3 = peg$c3;
+        s3 = peg$FAILED;
       }
       if (s3 !== peg$FAILED) {
         s4 = peg$parsekey();
         if (s4 !== peg$FAILED) {
           if (input.charCodeAt(peg$currPos) === 61) {
-            s5 = peg$c21;
+            s5 = peg$c17;
             peg$currPos++;
           } else {
             s5 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c22); }
+            if (peg$silentFails === 0) { peg$fail(peg$c18); }
           }
           if (s5 !== peg$FAILED) {
             s6 = peg$parsenumber();
             if (s6 === peg$FAILED) {
               s6 = peg$parseidentifier();
               if (s6 === peg$FAILED) {
                 s6 = peg$parseinline();
               }
             }
             if (s6 !== peg$FAILED) {
-              peg$reportedPos = s2;
-              s3 = peg$c23(s4, s6);
+              peg$savedPos = s2;
+              s3 = peg$c19(s4, s6);
               s2 = s3;
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       } else {
         peg$currPos = s2;
-        s2 = peg$c3;
+        s2 = peg$FAILED;
       }
       while (s2 !== peg$FAILED) {
         s1.push(s2);
         s2 = peg$currPos;
         s3 = [];
@@ -1921,60 +2002,60 @@
           while (s4 !== peg$FAILED) {
             s3.push(s4);
             s4 = peg$parsews();
           }
         } else {
-          s3 = peg$c3;
+          s3 = peg$FAILED;
         }
         if (s3 !== peg$FAILED) {
           s4 = peg$parsekey();
           if (s4 !== peg$FAILED) {
             if (input.charCodeAt(peg$currPos) === 61) {
-              s5 = peg$c21;
+              s5 = peg$c17;
               peg$currPos++;
             } else {
               s5 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c22); }
+              if (peg$silentFails === 0) { peg$fail(peg$c18); }
             }
             if (s5 !== peg$FAILED) {
               s6 = peg$parsenumber();
               if (s6 === peg$FAILED) {
                 s6 = peg$parseidentifier();
                 if (s6 === peg$FAILED) {
                   s6 = peg$parseinline();
                 }
               }
               if (s6 !== peg$FAILED) {
-                peg$reportedPos = s2;
-                s3 = peg$c23(s4, s6);
+                peg$savedPos = s2;
+                s3 = peg$c19(s4, s6);
                 s2 = s3;
               } else {
                 peg$currPos = s2;
-                s2 = peg$c3;
+                s2 = peg$FAILED;
               }
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c24(s1);
+        peg$savedPos = s0;
+        s1 = peg$c20(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c20); }
+        if (peg$silentFails === 0) { peg$fail(peg$c16); }
       }
 
       return s0;
     }
 
@@ -1986,98 +2067,98 @@
       s1 = [];
       s2 = peg$currPos;
       s3 = peg$parseld();
       if (s3 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 58) {
-          s4 = peg$c16;
+          s4 = peg$c12;
           peg$currPos++;
         } else {
           s4 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c17); }
+          if (peg$silentFails === 0) { peg$fail(peg$c13); }
         }
         if (s4 !== peg$FAILED) {
           s5 = peg$parsekey();
           if (s5 !== peg$FAILED) {
             s6 = peg$parserd();
             if (s6 !== peg$FAILED) {
               s7 = peg$parsebody();
               if (s7 !== peg$FAILED) {
-                peg$reportedPos = s2;
-                s3 = peg$c23(s5, s7);
+                peg$savedPos = s2;
+                s3 = peg$c19(s5, s7);
                 s2 = s3;
               } else {
                 peg$currPos = s2;
-                s2 = peg$c3;
+                s2 = peg$FAILED;
               }
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       } else {
         peg$currPos = s2;
-        s2 = peg$c3;
+        s2 = peg$FAILED;
       }
       while (s2 !== peg$FAILED) {
         s1.push(s2);
         s2 = peg$currPos;
         s3 = peg$parseld();
         if (s3 !== peg$FAILED) {
           if (input.charCodeAt(peg$currPos) === 58) {
-            s4 = peg$c16;
+            s4 = peg$c12;
             peg$currPos++;
           } else {
             s4 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c17); }
+            if (peg$silentFails === 0) { peg$fail(peg$c13); }
           }
           if (s4 !== peg$FAILED) {
             s5 = peg$parsekey();
             if (s5 !== peg$FAILED) {
               s6 = peg$parserd();
               if (s6 !== peg$FAILED) {
                 s7 = peg$parsebody();
                 if (s7 !== peg$FAILED) {
-                  peg$reportedPos = s2;
-                  s3 = peg$c23(s5, s7);
+                  peg$savedPos = s2;
+                  s3 = peg$c19(s5, s7);
                   s2 = s3;
                 } else {
                   peg$currPos = s2;
-                  s2 = peg$c3;
+                  s2 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s2;
-                s2 = peg$c3;
+                s2 = peg$FAILED;
               }
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c26(s1);
+        peg$savedPos = s0;
+        s1 = peg$c22(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c25); }
+        if (peg$silentFails === 0) { peg$fail(peg$c21); }
       }
 
       return s0;
     }
 
@@ -2092,33 +2173,33 @@
         if (s2 !== peg$FAILED) {
           s3 = peg$parsefilters();
           if (s3 !== peg$FAILED) {
             s4 = peg$parserd();
             if (s4 !== peg$FAILED) {
-              peg$reportedPos = s0;
-              s1 = peg$c28(s2, s3);
+              peg$savedPos = s0;
+              s1 = peg$c24(s2, s3);
               s0 = s1;
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c27); }
+        if (peg$silentFails === 0) { peg$fail(peg$c23); }
       }
 
       return s0;
     }
 
@@ -2128,23 +2209,23 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parseld();
       if (s1 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 62) {
-          s2 = peg$c30;
+          s2 = peg$c26;
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c31); }
+          if (peg$silentFails === 0) { peg$fail(peg$c27); }
         }
         if (s2 === peg$FAILED) {
           if (input.charCodeAt(peg$currPos) === 43) {
-            s2 = peg$c32;
+            s2 = peg$c28;
             peg$currPos++;
           } else {
             s2 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c33); }
+            if (peg$silentFails === 0) { peg$fail(peg$c29); }
           }
         }
         if (s2 !== peg$FAILED) {
           s3 = [];
           s4 = peg$parsews();
@@ -2154,12 +2235,12 @@
           }
           if (s3 !== peg$FAILED) {
             s4 = peg$currPos;
             s5 = peg$parsekey();
             if (s5 !== peg$FAILED) {
-              peg$reportedPos = s4;
-              s5 = peg$c34(s5);
+              peg$savedPos = s4;
+              s5 = peg$c30(s2, s5);
             }
             s4 = s5;
             if (s4 === peg$FAILED) {
               s4 = peg$parseinline();
             }
@@ -2174,62 +2255,62 @@
                     s7.push(s8);
                     s8 = peg$parsews();
                   }
                   if (s7 !== peg$FAILED) {
                     if (input.charCodeAt(peg$currPos) === 47) {
-                      s8 = peg$c8;
+                      s8 = peg$c4;
                       peg$currPos++;
                     } else {
                       s8 = peg$FAILED;
-                      if (peg$silentFails === 0) { peg$fail(peg$c9); }
+                      if (peg$silentFails === 0) { peg$fail(peg$c5); }
                     }
                     if (s8 !== peg$FAILED) {
                       s9 = peg$parserd();
                       if (s9 !== peg$FAILED) {
-                        peg$reportedPos = s0;
-                        s1 = peg$c35(s2, s4, s5, s6);
+                        peg$savedPos = s0;
+                        s1 = peg$c31(s2, s4, s5, s6);
                         s0 = s1;
                       } else {
                         peg$currPos = s0;
-                        s0 = peg$c3;
+                        s0 = peg$FAILED;
                       }
                     } else {
                       peg$currPos = s0;
-                      s0 = peg$c3;
+                      s0 = peg$FAILED;
                     }
                   } else {
                     peg$currPos = s0;
-                    s0 = peg$c3;
+                    s0 = peg$FAILED;
                   }
                 } else {
                   peg$currPos = s0;
-                  s0 = peg$c3;
+                  s0 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c29); }
+        if (peg$silentFails === 0) { peg$fail(peg$c25); }
       }
 
       return s0;
     }
 
@@ -2239,64 +2320,64 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = [];
       s2 = peg$currPos;
       if (input.charCodeAt(peg$currPos) === 124) {
-        s3 = peg$c37;
+        s3 = peg$c33;
         peg$currPos++;
       } else {
         s3 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c38); }
+        if (peg$silentFails === 0) { peg$fail(peg$c34); }
       }
       if (s3 !== peg$FAILED) {
         s4 = peg$parsekey();
         if (s4 !== peg$FAILED) {
-          peg$reportedPos = s2;
-          s3 = peg$c18(s4);
+          peg$savedPos = s2;
+          s3 = peg$c14(s4);
           s2 = s3;
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       } else {
         peg$currPos = s2;
-        s2 = peg$c3;
+        s2 = peg$FAILED;
       }
       while (s2 !== peg$FAILED) {
         s1.push(s2);
         s2 = peg$currPos;
         if (input.charCodeAt(peg$currPos) === 124) {
-          s3 = peg$c37;
+          s3 = peg$c33;
           peg$currPos++;
         } else {
           s3 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c38); }
+          if (peg$silentFails === 0) { peg$fail(peg$c34); }
         }
         if (s3 !== peg$FAILED) {
           s4 = peg$parsekey();
           if (s4 !== peg$FAILED) {
-            peg$reportedPos = s2;
-            s3 = peg$c18(s4);
+            peg$savedPos = s2;
+            s3 = peg$c14(s4);
             s2 = s3;
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c39(s1);
+        peg$savedPos = s0;
+        s1 = peg$c35(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c36); }
+        if (peg$silentFails === 0) { peg$fail(peg$c32); }
       }
 
       return s0;
     }
 
@@ -2306,44 +2387,44 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parseld();
       if (s1 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 126) {
-          s2 = peg$c41;
+          s2 = peg$c37;
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c42); }
+          if (peg$silentFails === 0) { peg$fail(peg$c38); }
         }
         if (s2 !== peg$FAILED) {
           s3 = peg$parsekey();
           if (s3 !== peg$FAILED) {
             s4 = peg$parserd();
             if (s4 !== peg$FAILED) {
-              peg$reportedPos = s0;
-              s1 = peg$c43(s3);
+              peg$savedPos = s0;
+              s1 = peg$c39(s3);
               s0 = s1;
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c40); }
+        if (peg$silentFails === 0) { peg$fail(peg$c36); }
       }
 
       return s0;
     }
 
@@ -2352,27 +2433,27 @@
 
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parsepath();
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c45(s1);
+        peg$savedPos = s0;
+        s1 = peg$c41(s1);
       }
       s0 = s1;
       if (s0 === peg$FAILED) {
         s0 = peg$currPos;
         s1 = peg$parsekey();
         if (s1 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c46(s1);
+          peg$savedPos = s0;
+          s1 = peg$c42(s1);
         }
         s0 = s1;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c44); }
+        if (peg$silentFails === 0) { peg$fail(peg$c40); }
       }
 
       return s0;
     }
 
@@ -2384,18 +2465,18 @@
       s1 = peg$parsefloat();
       if (s1 === peg$FAILED) {
         s1 = peg$parseinteger();
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c48(s1);
+        peg$savedPos = s0;
+        s1 = peg$c44(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c47); }
+        if (peg$silentFails === 0) { peg$fail(peg$c43); }
       }
 
       return s0;
     }
 
@@ -2405,38 +2486,38 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parseinteger();
       if (s1 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 46) {
-          s2 = peg$c50;
+          s2 = peg$c46;
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c51); }
+          if (peg$silentFails === 0) { peg$fail(peg$c47); }
         }
         if (s2 !== peg$FAILED) {
           s3 = peg$parseunsigned_integer();
           if (s3 !== peg$FAILED) {
-            peg$reportedPos = s0;
-            s1 = peg$c52(s1, s3);
+            peg$savedPos = s0;
+            s1 = peg$c48(s1, s3);
             s0 = s1;
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c49); }
+        if (peg$silentFails === 0) { peg$fail(peg$c45); }
       }
 
       return s0;
     }
 
@@ -2444,40 +2525,40 @@
       var s0, s1, s2;
 
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = [];
-      if (peg$c54.test(input.charAt(peg$currPos))) {
+      if (peg$c50.test(input.charAt(peg$currPos))) {
         s2 = input.charAt(peg$currPos);
         peg$currPos++;
       } else {
         s2 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c55); }
+        if (peg$silentFails === 0) { peg$fail(peg$c51); }
       }
       if (s2 !== peg$FAILED) {
         while (s2 !== peg$FAILED) {
           s1.push(s2);
-          if (peg$c54.test(input.charAt(peg$currPos))) {
+          if (peg$c50.test(input.charAt(peg$currPos))) {
             s2 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s2 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c55); }
+            if (peg$silentFails === 0) { peg$fail(peg$c51); }
           }
         }
       } else {
-        s1 = peg$c3;
+        s1 = peg$FAILED;
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c56(s1);
+        peg$savedPos = s0;
+        s1 = peg$c52(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c53); }
+        if (peg$silentFails === 0) { peg$fail(peg$c49); }
       }
 
       return s0;
     }
 
@@ -2485,34 +2566,34 @@
       var s0, s1, s2;
 
       peg$silentFails++;
       s0 = peg$currPos;
       if (input.charCodeAt(peg$currPos) === 45) {
-        s1 = peg$c58;
+        s1 = peg$c54;
         peg$currPos++;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c59); }
+        if (peg$silentFails === 0) { peg$fail(peg$c55); }
       }
       if (s1 !== peg$FAILED) {
         s2 = peg$parseunsigned_integer();
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c60(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c56(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c57); }
+        if (peg$silentFails === 0) { peg$fail(peg$c53); }
       }
 
       return s0;
     }
 
@@ -2525,11 +2606,11 @@
         s0 = peg$parseunsigned_integer();
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c61); }
+        if (peg$silentFails === 0) { peg$fail(peg$c57); }
       }
 
       return s0;
     }
 
@@ -2538,11 +2619,11 @@
 
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = peg$parsekey();
       if (s1 === peg$FAILED) {
-        s1 = peg$c4;
+        s1 = null;
       }
       if (s1 !== peg$FAILED) {
         s2 = [];
         s3 = peg$parsearray_part();
         if (s3 === peg$FAILED) {
@@ -2555,32 +2636,32 @@
             if (s3 === peg$FAILED) {
               s3 = peg$parsearray();
             }
           }
         } else {
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c63(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c59(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       if (s0 === peg$FAILED) {
         s0 = peg$currPos;
         if (input.charCodeAt(peg$currPos) === 46) {
-          s1 = peg$c50;
+          s1 = peg$c46;
           peg$currPos++;
         } else {
           s1 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c51); }
+          if (peg$silentFails === 0) { peg$fail(peg$c47); }
         }
         if (s1 !== peg$FAILED) {
           s2 = [];
           s3 = peg$parsearray_part();
           if (s3 === peg$FAILED) {
@@ -2592,78 +2673,78 @@
             if (s3 === peg$FAILED) {
               s3 = peg$parsearray();
             }
           }
           if (s2 !== peg$FAILED) {
-            peg$reportedPos = s0;
-            s1 = peg$c64(s2);
+            peg$savedPos = s0;
+            s1 = peg$c60(s2);
             s0 = s1;
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c62); }
+        if (peg$silentFails === 0) { peg$fail(peg$c58); }
       }
 
       return s0;
     }
 
     function peg$parsekey() {
       var s0, s1, s2, s3;
 
       peg$silentFails++;
       s0 = peg$currPos;
-      if (peg$c66.test(input.charAt(peg$currPos))) {
+      if (peg$c62.test(input.charAt(peg$currPos))) {
         s1 = input.charAt(peg$currPos);
         peg$currPos++;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c67); }
+        if (peg$silentFails === 0) { peg$fail(peg$c63); }
       }
       if (s1 !== peg$FAILED) {
         s2 = [];
-        if (peg$c68.test(input.charAt(peg$currPos))) {
+        if (peg$c64.test(input.charAt(peg$currPos))) {
           s3 = input.charAt(peg$currPos);
           peg$currPos++;
         } else {
           s3 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c69); }
+          if (peg$silentFails === 0) { peg$fail(peg$c65); }
         }
         while (s3 !== peg$FAILED) {
           s2.push(s3);
-          if (peg$c68.test(input.charAt(peg$currPos))) {
+          if (peg$c64.test(input.charAt(peg$currPos))) {
             s3 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s3 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c69); }
+            if (peg$silentFails === 0) { peg$fail(peg$c65); }
           }
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c70(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c66(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c65); }
+        if (peg$silentFails === 0) { peg$fail(peg$c61); }
       }
 
       return s0;
     }
 
@@ -2675,78 +2756,78 @@
       s1 = peg$currPos;
       s2 = peg$parselb();
       if (s2 !== peg$FAILED) {
         s3 = peg$currPos;
         s4 = [];
-        if (peg$c54.test(input.charAt(peg$currPos))) {
+        if (peg$c50.test(input.charAt(peg$currPos))) {
           s5 = input.charAt(peg$currPos);
           peg$currPos++;
         } else {
           s5 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c55); }
+          if (peg$silentFails === 0) { peg$fail(peg$c51); }
         }
         if (s5 !== peg$FAILED) {
           while (s5 !== peg$FAILED) {
             s4.push(s5);
-            if (peg$c54.test(input.charAt(peg$currPos))) {
+            if (peg$c50.test(input.charAt(peg$currPos))) {
               s5 = input.charAt(peg$currPos);
               peg$currPos++;
             } else {
               s5 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c55); }
+              if (peg$silentFails === 0) { peg$fail(peg$c51); }
             }
           }
         } else {
-          s4 = peg$c3;
+          s4 = peg$FAILED;
         }
         if (s4 !== peg$FAILED) {
-          peg$reportedPos = s3;
-          s4 = peg$c72(s4);
+          peg$savedPos = s3;
+          s4 = peg$c68(s4);
         }
         s3 = s4;
         if (s3 === peg$FAILED) {
           s3 = peg$parseidentifier();
         }
         if (s3 !== peg$FAILED) {
           s4 = peg$parserb();
           if (s4 !== peg$FAILED) {
-            peg$reportedPos = s1;
-            s2 = peg$c73(s3);
+            peg$savedPos = s1;
+            s2 = peg$c69(s3);
             s1 = s2;
           } else {
             peg$currPos = s1;
-            s1 = peg$c3;
+            s1 = peg$FAILED;
           }
         } else {
           peg$currPos = s1;
-          s1 = peg$c3;
+          s1 = peg$FAILED;
         }
       } else {
         peg$currPos = s1;
-        s1 = peg$c3;
+        s1 = peg$FAILED;
       }
       if (s1 !== peg$FAILED) {
         s2 = peg$parsearray_part();
         if (s2 === peg$FAILED) {
-          s2 = peg$c4;
+          s2 = null;
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c74(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c70(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c71); }
+        if (peg$silentFails === 0) { peg$fail(peg$c67); }
       }
 
       return s0;
     }
 
@@ -2756,80 +2837,80 @@
       peg$silentFails++;
       s0 = peg$currPos;
       s1 = [];
       s2 = peg$currPos;
       if (input.charCodeAt(peg$currPos) === 46) {
-        s3 = peg$c50;
+        s3 = peg$c46;
         peg$currPos++;
       } else {
         s3 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c51); }
+        if (peg$silentFails === 0) { peg$fail(peg$c47); }
       }
       if (s3 !== peg$FAILED) {
         s4 = peg$parsekey();
         if (s4 !== peg$FAILED) {
-          peg$reportedPos = s2;
-          s3 = peg$c76(s4);
+          peg$savedPos = s2;
+          s3 = peg$c72(s4);
           s2 = s3;
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       } else {
         peg$currPos = s2;
-        s2 = peg$c3;
+        s2 = peg$FAILED;
       }
       if (s2 !== peg$FAILED) {
         while (s2 !== peg$FAILED) {
           s1.push(s2);
           s2 = peg$currPos;
           if (input.charCodeAt(peg$currPos) === 46) {
-            s3 = peg$c50;
+            s3 = peg$c46;
             peg$currPos++;
           } else {
             s3 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c51); }
+            if (peg$silentFails === 0) { peg$fail(peg$c47); }
           }
           if (s3 !== peg$FAILED) {
             s4 = peg$parsekey();
             if (s4 !== peg$FAILED) {
-              peg$reportedPos = s2;
-              s3 = peg$c76(s4);
+              peg$savedPos = s2;
+              s3 = peg$c72(s4);
               s2 = s3;
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         }
       } else {
-        s1 = peg$c3;
+        s1 = peg$FAILED;
       }
       if (s1 !== peg$FAILED) {
         s2 = peg$parsearray();
         if (s2 === peg$FAILED) {
-          s2 = peg$c4;
+          s2 = null;
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c77(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c73(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c75); }
+        if (peg$silentFails === 0) { peg$fail(peg$c71); }
       }
 
       return s0;
     }
 
@@ -2837,121 +2918,121 @@
       var s0, s1, s2, s3;
 
       peg$silentFails++;
       s0 = peg$currPos;
       if (input.charCodeAt(peg$currPos) === 34) {
-        s1 = peg$c79;
+        s1 = peg$c75;
         peg$currPos++;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c80); }
+        if (peg$silentFails === 0) { peg$fail(peg$c76); }
       }
       if (s1 !== peg$FAILED) {
         if (input.charCodeAt(peg$currPos) === 34) {
-          s2 = peg$c79;
+          s2 = peg$c75;
           peg$currPos++;
         } else {
           s2 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c80); }
+          if (peg$silentFails === 0) { peg$fail(peg$c76); }
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c81();
+          peg$savedPos = s0;
+          s1 = peg$c77();
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       if (s0 === peg$FAILED) {
         s0 = peg$currPos;
         if (input.charCodeAt(peg$currPos) === 34) {
-          s1 = peg$c79;
+          s1 = peg$c75;
           peg$currPos++;
         } else {
           s1 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c80); }
+          if (peg$silentFails === 0) { peg$fail(peg$c76); }
         }
         if (s1 !== peg$FAILED) {
           s2 = peg$parseliteral();
           if (s2 !== peg$FAILED) {
             if (input.charCodeAt(peg$currPos) === 34) {
-              s3 = peg$c79;
+              s3 = peg$c75;
               peg$currPos++;
             } else {
               s3 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c80); }
+              if (peg$silentFails === 0) { peg$fail(peg$c76); }
             }
             if (s3 !== peg$FAILED) {
-              peg$reportedPos = s0;
-              s1 = peg$c82(s2);
+              peg$savedPos = s0;
+              s1 = peg$c78(s2);
               s0 = s1;
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
         if (s0 === peg$FAILED) {
           s0 = peg$currPos;
           if (input.charCodeAt(peg$currPos) === 34) {
-            s1 = peg$c79;
+            s1 = peg$c75;
             peg$currPos++;
           } else {
             s1 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c80); }
+            if (peg$silentFails === 0) { peg$fail(peg$c76); }
           }
           if (s1 !== peg$FAILED) {
             s2 = [];
             s3 = peg$parseinline_part();
             if (s3 !== peg$FAILED) {
               while (s3 !== peg$FAILED) {
                 s2.push(s3);
                 s3 = peg$parseinline_part();
               }
             } else {
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
             if (s2 !== peg$FAILED) {
               if (input.charCodeAt(peg$currPos) === 34) {
-                s3 = peg$c79;
+                s3 = peg$c75;
                 peg$currPos++;
               } else {
                 s3 = peg$FAILED;
-                if (peg$silentFails === 0) { peg$fail(peg$c80); }
+                if (peg$silentFails === 0) { peg$fail(peg$c76); }
               }
               if (s3 !== peg$FAILED) {
-                peg$reportedPos = s0;
-                s1 = peg$c83(s2);
+                peg$savedPos = s0;
+                s1 = peg$c79(s2);
                 s0 = s1;
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         }
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c78); }
+        if (peg$silentFails === 0) { peg$fail(peg$c74); }
       }
 
       return s0;
     }
 
@@ -2963,12 +3044,12 @@
         s0 = peg$parsereference();
         if (s0 === peg$FAILED) {
           s0 = peg$currPos;
           s1 = peg$parseliteral();
           if (s1 !== peg$FAILED) {
-            peg$reportedPos = s0;
-            s1 = peg$c84(s1);
+            peg$savedPos = s0;
+            s1 = peg$c80(s1);
           }
           s0 = s1;
         }
       }
 
@@ -2987,193 +3068,193 @@
         while (s3 !== peg$FAILED) {
           s2.push(s3);
           s3 = peg$parsews();
         }
         if (s2 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c86(s1, s2);
+          peg$savedPos = s0;
+          s1 = peg$c82(s1, s2);
           s0 = s1;
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       if (s0 === peg$FAILED) {
         s0 = peg$currPos;
         s1 = [];
         s2 = peg$currPos;
         s3 = peg$currPos;
         peg$silentFails++;
         s4 = peg$parsetag();
         peg$silentFails--;
         if (s4 === peg$FAILED) {
-          s3 = peg$c6;
+          s3 = void 0;
         } else {
           peg$currPos = s3;
-          s3 = peg$c3;
+          s3 = peg$FAILED;
         }
         if (s3 !== peg$FAILED) {
           s4 = peg$currPos;
           peg$silentFails++;
           s5 = peg$parseraw();
           peg$silentFails--;
           if (s5 === peg$FAILED) {
-            s4 = peg$c6;
+            s4 = void 0;
           } else {
             peg$currPos = s4;
-            s4 = peg$c3;
+            s4 = peg$FAILED;
           }
           if (s4 !== peg$FAILED) {
             s5 = peg$currPos;
             peg$silentFails++;
             s6 = peg$parsecomment();
             peg$silentFails--;
             if (s6 === peg$FAILED) {
-              s5 = peg$c6;
+              s5 = void 0;
             } else {
               peg$currPos = s5;
-              s5 = peg$c3;
+              s5 = peg$FAILED;
             }
             if (s5 !== peg$FAILED) {
               s6 = peg$currPos;
               peg$silentFails++;
               s7 = peg$parseeol();
               peg$silentFails--;
               if (s7 === peg$FAILED) {
-                s6 = peg$c6;
+                s6 = void 0;
               } else {
                 peg$currPos = s6;
-                s6 = peg$c3;
+                s6 = peg$FAILED;
               }
               if (s6 !== peg$FAILED) {
                 if (input.length > peg$currPos) {
                   s7 = input.charAt(peg$currPos);
                   peg$currPos++;
                 } else {
                   s7 = peg$FAILED;
-                  if (peg$silentFails === 0) { peg$fail(peg$c87); }
+                  if (peg$silentFails === 0) { peg$fail(peg$c83); }
                 }
                 if (s7 !== peg$FAILED) {
-                  peg$reportedPos = s2;
-                  s3 = peg$c88(s7);
+                  peg$savedPos = s2;
+                  s3 = peg$c84(s7);
                   s2 = s3;
                 } else {
                   peg$currPos = s2;
-                  s2 = peg$c3;
+                  s2 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s2;
-                s2 = peg$c3;
+                s2 = peg$FAILED;
               }
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
         if (s2 !== peg$FAILED) {
           while (s2 !== peg$FAILED) {
             s1.push(s2);
             s2 = peg$currPos;
             s3 = peg$currPos;
             peg$silentFails++;
             s4 = peg$parsetag();
             peg$silentFails--;
             if (s4 === peg$FAILED) {
-              s3 = peg$c6;
+              s3 = void 0;
             } else {
               peg$currPos = s3;
-              s3 = peg$c3;
+              s3 = peg$FAILED;
             }
             if (s3 !== peg$FAILED) {
               s4 = peg$currPos;
               peg$silentFails++;
               s5 = peg$parseraw();
               peg$silentFails--;
               if (s5 === peg$FAILED) {
-                s4 = peg$c6;
+                s4 = void 0;
               } else {
                 peg$currPos = s4;
-                s4 = peg$c3;
+                s4 = peg$FAILED;
               }
               if (s4 !== peg$FAILED) {
                 s5 = peg$currPos;
                 peg$silentFails++;
                 s6 = peg$parsecomment();
                 peg$silentFails--;
                 if (s6 === peg$FAILED) {
-                  s5 = peg$c6;
+                  s5 = void 0;
                 } else {
                   peg$currPos = s5;
-                  s5 = peg$c3;
+                  s5 = peg$FAILED;
                 }
                 if (s5 !== peg$FAILED) {
                   s6 = peg$currPos;
                   peg$silentFails++;
                   s7 = peg$parseeol();
                   peg$silentFails--;
                   if (s7 === peg$FAILED) {
-                    s6 = peg$c6;
+                    s6 = void 0;
                   } else {
                     peg$currPos = s6;
-                    s6 = peg$c3;
+                    s6 = peg$FAILED;
                   }
                   if (s6 !== peg$FAILED) {
                     if (input.length > peg$currPos) {
                       s7 = input.charAt(peg$currPos);
                       peg$currPos++;
                     } else {
                       s7 = peg$FAILED;
-                      if (peg$silentFails === 0) { peg$fail(peg$c87); }
+                      if (peg$silentFails === 0) { peg$fail(peg$c83); }
                     }
                     if (s7 !== peg$FAILED) {
-                      peg$reportedPos = s2;
-                      s3 = peg$c88(s7);
+                      peg$savedPos = s2;
+                      s3 = peg$c84(s7);
                       s2 = s3;
                     } else {
                       peg$currPos = s2;
-                      s2 = peg$c3;
+                      s2 = peg$FAILED;
                     }
                   } else {
                     peg$currPos = s2;
-                    s2 = peg$c3;
+                    s2 = peg$FAILED;
                   }
                 } else {
                   peg$currPos = s2;
-                  s2 = peg$c3;
+                  s2 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s2;
-                s2 = peg$c3;
+                s2 = peg$FAILED;
               }
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           }
         } else {
-          s1 = peg$c3;
+          s1 = peg$FAILED;
         }
         if (s1 !== peg$FAILED) {
-          peg$reportedPos = s0;
-          s1 = peg$c89(s1);
+          peg$savedPos = s0;
+          s1 = peg$c85(s1);
         }
         s0 = s1;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c85); }
+        if (peg$silentFails === 0) { peg$fail(peg$c81); }
       }
 
       return s0;
     }
 
@@ -3187,107 +3268,107 @@
       s3 = peg$currPos;
       peg$silentFails++;
       s4 = peg$parsetag();
       peg$silentFails--;
       if (s4 === peg$FAILED) {
-        s3 = peg$c6;
+        s3 = void 0;
       } else {
         peg$currPos = s3;
-        s3 = peg$c3;
+        s3 = peg$FAILED;
       }
       if (s3 !== peg$FAILED) {
         s4 = peg$parseesc();
         if (s4 === peg$FAILED) {
-          if (peg$c91.test(input.charAt(peg$currPos))) {
+          if (peg$c87.test(input.charAt(peg$currPos))) {
             s4 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s4 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c92); }
+            if (peg$silentFails === 0) { peg$fail(peg$c88); }
           }
         }
         if (s4 !== peg$FAILED) {
-          peg$reportedPos = s2;
-          s3 = peg$c88(s4);
+          peg$savedPos = s2;
+          s3 = peg$c84(s4);
           s2 = s3;
         } else {
           peg$currPos = s2;
-          s2 = peg$c3;
+          s2 = peg$FAILED;
         }
       } else {
         peg$currPos = s2;
-        s2 = peg$c3;
+        s2 = peg$FAILED;
       }
       if (s2 !== peg$FAILED) {
         while (s2 !== peg$FAILED) {
           s1.push(s2);
           s2 = peg$currPos;
           s3 = peg$currPos;
           peg$silentFails++;
           s4 = peg$parsetag();
           peg$silentFails--;
           if (s4 === peg$FAILED) {
-            s3 = peg$c6;
+            s3 = void 0;
           } else {
             peg$currPos = s3;
-            s3 = peg$c3;
+            s3 = peg$FAILED;
           }
           if (s3 !== peg$FAILED) {
             s4 = peg$parseesc();
             if (s4 === peg$FAILED) {
-              if (peg$c91.test(input.charAt(peg$currPos))) {
+              if (peg$c87.test(input.charAt(peg$currPos))) {
                 s4 = input.charAt(peg$currPos);
                 peg$currPos++;
               } else {
                 s4 = peg$FAILED;
-                if (peg$silentFails === 0) { peg$fail(peg$c92); }
+                if (peg$silentFails === 0) { peg$fail(peg$c88); }
               }
             }
             if (s4 !== peg$FAILED) {
-              peg$reportedPos = s2;
-              s3 = peg$c88(s4);
+              peg$savedPos = s2;
+              s3 = peg$c84(s4);
               s2 = s3;
             } else {
               peg$currPos = s2;
-              s2 = peg$c3;
+              s2 = peg$FAILED;
             }
           } else {
             peg$currPos = s2;
-            s2 = peg$c3;
+            s2 = peg$FAILED;
           }
         }
       } else {
-        s1 = peg$c3;
+        s1 = peg$FAILED;
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c93(s1);
+        peg$savedPos = s0;
+        s1 = peg$c89(s1);
       }
       s0 = s1;
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c90); }
+        if (peg$silentFails === 0) { peg$fail(peg$c86); }
       }
 
       return s0;
     }
 
     function peg$parseesc() {
       var s0, s1;
 
       s0 = peg$currPos;
-      if (input.substr(peg$currPos, 2) === peg$c94) {
-        s1 = peg$c94;
+      if (input.substr(peg$currPos, 2) === peg$c90) {
+        s1 = peg$c90;
         peg$currPos += 2;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c95); }
+        if (peg$silentFails === 0) { peg$fail(peg$c91); }
       }
       if (s1 !== peg$FAILED) {
-        peg$reportedPos = s0;
-        s1 = peg$c96();
+        peg$savedPos = s0;
+        s1 = peg$c92();
       }
       s0 = s1;
 
       return s0;
     }
@@ -3295,248 +3376,248 @@
     function peg$parseraw() {
       var s0, s1, s2, s3, s4, s5;
 
       peg$silentFails++;
       s0 = peg$currPos;
-      if (input.substr(peg$currPos, 2) === peg$c98) {
-        s1 = peg$c98;
+      if (input.substr(peg$currPos, 2) === peg$c94) {
+        s1 = peg$c94;
         peg$currPos += 2;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c99); }
+        if (peg$silentFails === 0) { peg$fail(peg$c95); }
       }
       if (s1 !== peg$FAILED) {
         s2 = [];
         s3 = peg$currPos;
         s4 = peg$currPos;
         peg$silentFails++;
-        if (input.substr(peg$currPos, 2) === peg$c100) {
-          s5 = peg$c100;
+        if (input.substr(peg$currPos, 2) === peg$c96) {
+          s5 = peg$c96;
           peg$currPos += 2;
         } else {
           s5 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c101); }
+          if (peg$silentFails === 0) { peg$fail(peg$c97); }
         }
         peg$silentFails--;
         if (s5 === peg$FAILED) {
-          s4 = peg$c6;
+          s4 = void 0;
         } else {
           peg$currPos = s4;
-          s4 = peg$c3;
+          s4 = peg$FAILED;
         }
         if (s4 !== peg$FAILED) {
           if (input.length > peg$currPos) {
             s5 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s5 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c87); }
+            if (peg$silentFails === 0) { peg$fail(peg$c83); }
           }
           if (s5 !== peg$FAILED) {
-            peg$reportedPos = s3;
-            s4 = peg$c102(s5);
+            peg$savedPos = s3;
+            s4 = peg$c98(s5);
             s3 = s4;
           } else {
             peg$currPos = s3;
-            s3 = peg$c3;
+            s3 = peg$FAILED;
           }
         } else {
           peg$currPos = s3;
-          s3 = peg$c3;
+          s3 = peg$FAILED;
         }
         while (s3 !== peg$FAILED) {
           s2.push(s3);
           s3 = peg$currPos;
           s4 = peg$currPos;
           peg$silentFails++;
-          if (input.substr(peg$currPos, 2) === peg$c100) {
-            s5 = peg$c100;
+          if (input.substr(peg$currPos, 2) === peg$c96) {
+            s5 = peg$c96;
             peg$currPos += 2;
           } else {
             s5 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c101); }
+            if (peg$silentFails === 0) { peg$fail(peg$c97); }
           }
           peg$silentFails--;
           if (s5 === peg$FAILED) {
-            s4 = peg$c6;
+            s4 = void 0;
           } else {
             peg$currPos = s4;
-            s4 = peg$c3;
+            s4 = peg$FAILED;
           }
           if (s4 !== peg$FAILED) {
             if (input.length > peg$currPos) {
               s5 = input.charAt(peg$currPos);
               peg$currPos++;
             } else {
               s5 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c87); }
+              if (peg$silentFails === 0) { peg$fail(peg$c83); }
             }
             if (s5 !== peg$FAILED) {
-              peg$reportedPos = s3;
-              s4 = peg$c102(s5);
+              peg$savedPos = s3;
+              s4 = peg$c98(s5);
               s3 = s4;
             } else {
               peg$currPos = s3;
-              s3 = peg$c3;
+              s3 = peg$FAILED;
             }
           } else {
             peg$currPos = s3;
-            s3 = peg$c3;
+            s3 = peg$FAILED;
           }
         }
         if (s2 !== peg$FAILED) {
-          if (input.substr(peg$currPos, 2) === peg$c100) {
-            s3 = peg$c100;
+          if (input.substr(peg$currPos, 2) === peg$c96) {
+            s3 = peg$c96;
             peg$currPos += 2;
           } else {
             s3 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c101); }
+            if (peg$silentFails === 0) { peg$fail(peg$c97); }
           }
           if (s3 !== peg$FAILED) {
-            peg$reportedPos = s0;
-            s1 = peg$c103(s2);
+            peg$savedPos = s0;
+            s1 = peg$c99(s2);
             s0 = s1;
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c97); }
+        if (peg$silentFails === 0) { peg$fail(peg$c93); }
       }
 
       return s0;
     }
 
     function peg$parsecomment() {
       var s0, s1, s2, s3, s4, s5;
 
       peg$silentFails++;
       s0 = peg$currPos;
-      if (input.substr(peg$currPos, 2) === peg$c105) {
-        s1 = peg$c105;
+      if (input.substr(peg$currPos, 2) === peg$c101) {
+        s1 = peg$c101;
         peg$currPos += 2;
       } else {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c106); }
+        if (peg$silentFails === 0) { peg$fail(peg$c102); }
       }
       if (s1 !== peg$FAILED) {
         s2 = [];
         s3 = peg$currPos;
         s4 = peg$currPos;
         peg$silentFails++;
-        if (input.substr(peg$currPos, 2) === peg$c107) {
-          s5 = peg$c107;
+        if (input.substr(peg$currPos, 2) === peg$c103) {
+          s5 = peg$c103;
           peg$currPos += 2;
         } else {
           s5 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c108); }
+          if (peg$silentFails === 0) { peg$fail(peg$c104); }
         }
         peg$silentFails--;
         if (s5 === peg$FAILED) {
-          s4 = peg$c6;
+          s4 = void 0;
         } else {
           peg$currPos = s4;
-          s4 = peg$c3;
+          s4 = peg$FAILED;
         }
         if (s4 !== peg$FAILED) {
           if (input.length > peg$currPos) {
             s5 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s5 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c87); }
+            if (peg$silentFails === 0) { peg$fail(peg$c83); }
           }
           if (s5 !== peg$FAILED) {
-            peg$reportedPos = s3;
-            s4 = peg$c88(s5);
+            peg$savedPos = s3;
+            s4 = peg$c84(s5);
             s3 = s4;
           } else {
             peg$currPos = s3;
-            s3 = peg$c3;
+            s3 = peg$FAILED;
           }
         } else {
           peg$currPos = s3;
-          s3 = peg$c3;
+          s3 = peg$FAILED;
         }
         while (s3 !== peg$FAILED) {
           s2.push(s3);
           s3 = peg$currPos;
           s4 = peg$currPos;
           peg$silentFails++;
-          if (input.substr(peg$currPos, 2) === peg$c107) {
-            s5 = peg$c107;
+          if (input.substr(peg$currPos, 2) === peg$c103) {
+            s5 = peg$c103;
             peg$currPos += 2;
           } else {
             s5 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c108); }
+            if (peg$silentFails === 0) { peg$fail(peg$c104); }
           }
           peg$silentFails--;
           if (s5 === peg$FAILED) {
-            s4 = peg$c6;
+            s4 = void 0;
           } else {
             peg$currPos = s4;
-            s4 = peg$c3;
+            s4 = peg$FAILED;
           }
           if (s4 !== peg$FAILED) {
             if (input.length > peg$currPos) {
               s5 = input.charAt(peg$currPos);
               peg$currPos++;
             } else {
               s5 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c87); }
+              if (peg$silentFails === 0) { peg$fail(peg$c83); }
             }
             if (s5 !== peg$FAILED) {
-              peg$reportedPos = s3;
-              s4 = peg$c88(s5);
+              peg$savedPos = s3;
+              s4 = peg$c84(s5);
               s3 = s4;
             } else {
               peg$currPos = s3;
-              s3 = peg$c3;
+              s3 = peg$FAILED;
             }
           } else {
             peg$currPos = s3;
-            s3 = peg$c3;
+            s3 = peg$FAILED;
           }
         }
         if (s2 !== peg$FAILED) {
-          if (input.substr(peg$currPos, 2) === peg$c107) {
-            s3 = peg$c107;
+          if (input.substr(peg$currPos, 2) === peg$c103) {
+            s3 = peg$c103;
             peg$currPos += 2;
           } else {
             s3 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c108); }
+            if (peg$silentFails === 0) { peg$fail(peg$c104); }
           }
           if (s3 !== peg$FAILED) {
-            peg$reportedPos = s0;
-            s1 = peg$c109(s2);
+            peg$savedPos = s0;
+            s1 = peg$c105(s2);
             s0 = s1;
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       peg$silentFails--;
       if (s0 === peg$FAILED) {
         s1 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c104); }
+        if (peg$silentFails === 0) { peg$fail(peg$c100); }
       }
 
       return s0;
     }
 
@@ -3551,16 +3632,16 @@
         while (s3 !== peg$FAILED) {
           s2.push(s3);
           s3 = peg$parsews();
         }
         if (s2 !== peg$FAILED) {
-          if (peg$c110.test(input.charAt(peg$currPos))) {
+          if (peg$c106.test(input.charAt(peg$currPos))) {
             s3 = input.charAt(peg$currPos);
             peg$currPos++;
           } else {
             s3 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c111); }
+            if (peg$silentFails === 0) { peg$fail(peg$c107); }
           }
           if (s3 !== peg$FAILED) {
             s4 = [];
             s5 = peg$parsews();
             while (s5 !== peg$FAILED) {
@@ -3573,100 +3654,100 @@
               s7 = peg$currPos;
               peg$silentFails++;
               s8 = peg$parserd();
               peg$silentFails--;
               if (s8 === peg$FAILED) {
-                s7 = peg$c6;
+                s7 = void 0;
               } else {
                 peg$currPos = s7;
-                s7 = peg$c3;
+                s7 = peg$FAILED;
               }
               if (s7 !== peg$FAILED) {
                 s8 = peg$currPos;
                 peg$silentFails++;
                 s9 = peg$parseeol();
                 peg$silentFails--;
                 if (s9 === peg$FAILED) {
-                  s8 = peg$c6;
+                  s8 = void 0;
                 } else {
                   peg$currPos = s8;
-                  s8 = peg$c3;
+                  s8 = peg$FAILED;
                 }
                 if (s8 !== peg$FAILED) {
                   if (input.length > peg$currPos) {
                     s9 = input.charAt(peg$currPos);
                     peg$currPos++;
                   } else {
                     s9 = peg$FAILED;
-                    if (peg$silentFails === 0) { peg$fail(peg$c87); }
+                    if (peg$silentFails === 0) { peg$fail(peg$c83); }
                   }
                   if (s9 !== peg$FAILED) {
                     s7 = [s7, s8, s9];
                     s6 = s7;
                   } else {
                     peg$currPos = s6;
-                    s6 = peg$c3;
+                    s6 = peg$FAILED;
                   }
                 } else {
                   peg$currPos = s6;
-                  s6 = peg$c3;
+                  s6 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s6;
-                s6 = peg$c3;
+                s6 = peg$FAILED;
               }
               if (s6 !== peg$FAILED) {
                 while (s6 !== peg$FAILED) {
                   s5.push(s6);
                   s6 = peg$currPos;
                   s7 = peg$currPos;
                   peg$silentFails++;
                   s8 = peg$parserd();
                   peg$silentFails--;
                   if (s8 === peg$FAILED) {
-                    s7 = peg$c6;
+                    s7 = void 0;
                   } else {
                     peg$currPos = s7;
-                    s7 = peg$c3;
+                    s7 = peg$FAILED;
                   }
                   if (s7 !== peg$FAILED) {
                     s8 = peg$currPos;
                     peg$silentFails++;
                     s9 = peg$parseeol();
                     peg$silentFails--;
                     if (s9 === peg$FAILED) {
-                      s8 = peg$c6;
+                      s8 = void 0;
                     } else {
                       peg$currPos = s8;
-                      s8 = peg$c3;
+                      s8 = peg$FAILED;
                     }
                     if (s8 !== peg$FAILED) {
                       if (input.length > peg$currPos) {
                         s9 = input.charAt(peg$currPos);
                         peg$currPos++;
                       } else {
                         s9 = peg$FAILED;
-                        if (peg$silentFails === 0) { peg$fail(peg$c87); }
+                        if (peg$silentFails === 0) { peg$fail(peg$c83); }
                       }
                       if (s9 !== peg$FAILED) {
                         s7 = [s7, s8, s9];
                         s6 = s7;
                       } else {
                         peg$currPos = s6;
-                        s6 = peg$c3;
+                        s6 = peg$FAILED;
                       }
                     } else {
                       peg$currPos = s6;
-                      s6 = peg$c3;
+                      s6 = peg$FAILED;
                     }
                   } else {
                     peg$currPos = s6;
-                    s6 = peg$c3;
+                    s6 = peg$FAILED;
                   }
                 }
               } else {
-                s5 = peg$c3;
+                s5 = peg$FAILED;
               }
               if (s5 !== peg$FAILED) {
                 s6 = [];
                 s7 = peg$parsews();
                 while (s7 !== peg$FAILED) {
@@ -3678,35 +3759,35 @@
                   if (s7 !== peg$FAILED) {
                     s1 = [s1, s2, s3, s4, s5, s6, s7];
                     s0 = s1;
                   } else {
                     peg$currPos = s0;
-                    s0 = peg$c3;
+                    s0 = peg$FAILED;
                   }
                 } else {
                   peg$currPos = s0;
-                  s0 = peg$c3;
+                  s0 = peg$FAILED;
                 }
               } else {
                 peg$currPos = s0;
-                s0 = peg$c3;
+                s0 = peg$FAILED;
               }
             } else {
               peg$currPos = s0;
-              s0 = peg$c3;
+              s0 = peg$FAILED;
             }
           } else {
             peg$currPos = s0;
-            s0 = peg$c3;
+            s0 = peg$FAILED;
           }
         } else {
           peg$currPos = s0;
-          s0 = peg$c3;
+          s0 = peg$FAILED;
         }
       } else {
         peg$currPos = s0;
-        s0 = peg$c3;
+        s0 = peg$FAILED;
       }
       if (s0 === peg$FAILED) {
         s0 = peg$parsereference();
       }
 
@@ -3715,103 +3796,103 @@
 
     function peg$parseld() {
       var s0;
 
       if (input.charCodeAt(peg$currPos) === 123) {
-        s0 = peg$c112;
+        s0 = peg$c108;
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c113); }
+        if (peg$silentFails === 0) { peg$fail(peg$c109); }
       }
 
       return s0;
     }
 
     function peg$parserd() {
       var s0;
 
       if (input.charCodeAt(peg$currPos) === 125) {
-        s0 = peg$c114;
+        s0 = peg$c110;
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c115); }
+        if (peg$silentFails === 0) { peg$fail(peg$c111); }
       }
 
       return s0;
     }
 
     function peg$parselb() {
       var s0;
 
       if (input.charCodeAt(peg$currPos) === 91) {
-        s0 = peg$c116;
+        s0 = peg$c112;
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c117); }
+        if (peg$silentFails === 0) { peg$fail(peg$c113); }
       }
 
       return s0;
     }
 
     function peg$parserb() {
       var s0;
 
       if (input.charCodeAt(peg$currPos) === 93) {
-        s0 = peg$c118;
+        s0 = peg$c114;
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c119); }
+        if (peg$silentFails === 0) { peg$fail(peg$c115); }
       }
 
       return s0;
     }
 
     function peg$parseeol() {
       var s0;
 
       if (input.charCodeAt(peg$currPos) === 10) {
-        s0 = peg$c120;
+        s0 = peg$c116;
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c121); }
+        if (peg$silentFails === 0) { peg$fail(peg$c117); }
       }
       if (s0 === peg$FAILED) {
-        if (input.substr(peg$currPos, 2) === peg$c122) {
-          s0 = peg$c122;
+        if (input.substr(peg$currPos, 2) === peg$c118) {
+          s0 = peg$c118;
           peg$currPos += 2;
         } else {
           s0 = peg$FAILED;
-          if (peg$silentFails === 0) { peg$fail(peg$c123); }
+          if (peg$silentFails === 0) { peg$fail(peg$c119); }
         }
         if (s0 === peg$FAILED) {
           if (input.charCodeAt(peg$currPos) === 13) {
-            s0 = peg$c124;
+            s0 = peg$c120;
             peg$currPos++;
           } else {
             s0 = peg$FAILED;
-            if (peg$silentFails === 0) { peg$fail(peg$c125); }
+            if (peg$silentFails === 0) { peg$fail(peg$c121); }
           }
           if (s0 === peg$FAILED) {
             if (input.charCodeAt(peg$currPos) === 8232) {
-              s0 = peg$c126;
+              s0 = peg$c122;
               peg$currPos++;
             } else {
               s0 = peg$FAILED;
-              if (peg$silentFails === 0) { peg$fail(peg$c127); }
+              if (peg$silentFails === 0) { peg$fail(peg$c123); }
             }
             if (s0 === peg$FAILED) {
               if (input.charCodeAt(peg$currPos) === 8233) {
-                s0 = peg$c128;
+                s0 = peg$c124;
                 peg$currPos++;
               } else {
                 s0 = peg$FAILED;
-                if (peg$silentFails === 0) { peg$fail(peg$c129); }
+                if (peg$silentFails === 0) { peg$fail(peg$c125); }
               }
             }
           }
         }
       }
@@ -3820,16 +3901,16 @@
     }
 
     function peg$parsews() {
       var s0;
 
-      if (peg$c130.test(input.charAt(peg$currPos))) {
+      if (peg$c126.test(input.charAt(peg$currPos))) {
         s0 = input.charAt(peg$currPos);
         peg$currPos++;
       } else {
         s0 = peg$FAILED;
-        if (peg$silentFails === 0) { peg$fail(peg$c131); }
+        if (peg$silentFails === 0) { peg$fail(peg$c127); }
       }
       if (s0 === peg$FAILED) {
         s0 = peg$parseeol();
       }
 
@@ -3839,11 +3920,12 @@
 
       function makeInteger(arr) {
         return parseInt(arr.join(''), 10);
       }
       function withPosition(arr) {
-        return arr.concat([['line', line()], ['col', column()]]);
+        arr.location = location();
+        return arr;
       }
 
 
     peg$result = peg$startRuleFunction();
 
@@ -3852,17 +3934,24 @@
     } else {
       if (peg$result !== peg$FAILED && peg$currPos < input.length) {
         peg$fail({ type: "end", description: "end of input" });
       }
 
-      throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
+      throw peg$buildException(
+        null,
+        peg$maxFailExpected,
+        peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
+        peg$maxFailPos < input.length
+          ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
+          : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
+      );
     }
   }
 
   return {
-    SyntaxError: SyntaxError,
-    parse:       parse
+    SyntaxError: peg$SyntaxError,
+    parse:       peg$parse
   };
 })();
 
   // expose parser methods
   dust.parse = parser.parse;
@@ -3884,10 +3973,13 @@
   }
 }(this, function(parse, dust) {
   var compiler = {},
       isArray = dust.isArray;
 
+  var escape = (typeof JSON === 'undefined') ?
+                  function(str) { return '"' + escapeToJsSafeString(str) + '"';} :
+                  JSON.stringify;
 
   compiler.compile = function(source, name) {
     // the name parameter is optional.
     // this can happen for templates that are rendered immediately (renderSource which calls compileFn) or
     // for templates that are compiled as a callable (compileFn)
@@ -3895,17 +3987,15 @@
     // for the common case (using compile and render) a name is required so that templates will be cached by name and rendered later, by name.
 
     try {
       var ast = filterAST(parse(source));
       return compile(ast, name);
-    }
-    catch (err)
-    {
-      if (!err.line || !err.column) {
+    } catch (err) {
+      if (!err.location) {
         throw err;
       }
-      throw new SyntaxError(err.message + ' At line : ' + err.line + ', column : ' + err.column);
+      throw new SyntaxError(err.message + ' [' + name + ':' + err.location.start.line + ':' + err.location.start.column + ']');
     }
   };
 
   function filterAST(ast) {
     var context = {};
@@ -3937,13 +4027,11 @@
     filters:   noop,
     key:       noop,
     path:      noop,
     literal:   noop,
     raw:       noop,
-    comment:   nullify,
-    line:      nullify,
-    col:       nullify
+    comment:   nullify
   };
 
   compiler.pragmas = {
     esc: function(compiler, context, bodies) {
       var old = compiler.auto,
@@ -3978,11 +4066,11 @@
       res = compiler.filterNode(context, node[i]);
       if (res) {
         if (res[0] === 'buffer' || res[0] === 'format') {
           if (memo) {
             memo[0] = (res[0] === 'buffer') ? 'buffer' : memo[0];
-            memo[1] += res.slice(1, -2).join('');
+            memo[1] += res.slice(1).join('');
           } else {
             memo = res;
             out.push(res);
           }
         } else {
@@ -4012,14 +4100,14 @@
 
   function nullify(){}
 
   function format(context, node) {
     if(dust.config.whitespace) {
-      // Format nodes are in the form ['format', eol, whitespace, line, col],
+      // Format nodes are in the form ['format', eol, whitespace],
       // which is unlike other nodes in that there are two pieces of content
       // Join eol and whitespace together to normalize the node format
-      node.splice(1, 2, node.slice(1, -2).join(''));
+      node.splice(1, 2, node.slice(1).join(''));
       return node;
     }
     return null;
   }
 
@@ -4063,11 +4151,13 @@
     var out = [],
         blocks = context.blocks,
         name;
 
     for (name in blocks) {
-      out.push('"' + name + '":' + blocks[name]);
+      if (Object.prototype.hasOwnProperty.call(blocks, name)) {
+        out.push('"' + name + '":' + blocks[name]);
+      }
     }
     if (out.length) {
       context.blocks = 'ctx=ctx.shiftBlocks(blocks);';
       return 'var blocks={' + out.join(',') + '};';
     } else {
@@ -4302,14 +4392,10 @@
               .replace(NL, '\\n')
               .replace(CR, '\\r')
               .replace(TB, '\\t');
   }
 
-  var escape = (typeof JSON === 'undefined') ?
-                  function(str) { return '"' + escapeToJsSafeString(str) + '"';} :
-                  JSON.stringify;
-
   function renderSource(source, context, callback) {
     var tmpl = dust.loadSource(dust.compile(source));
     return loaderFor(tmpl)(context, callback);
   }
 
@@ -4343,12 +4429,12 @@
 }));
 
 if (typeof define === "function" && define.amd && define.amd.dust === true) {
     define(["require", "dust.core", "dust.compile"], function(require, dust) {
         dust.onLoad = function(name, cb) {
-            require([name], function() {
-                cb();
+            require([name], function(tmpl) {
+                cb(null, tmpl);
             });
         };
         return dust;
     });
 }
diff --git a/dist/dust-full.min.js b/dist/dust-full.min.js
index 5643b87..756307c 100644
--- a/dist/dust-full.min.js
+++ b/dist/dust-full.min.js
@@ -1,5 +1,5 @@
 /*! dustjs-linkedin - v2.7.2
 * http://dustjs.com/
-* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
-!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){return a?"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&b("[DUST:"+d+"]",a)},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},dust.isArray=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0===a?!1:dust.isArray(a)&&!a.length?!0:!a},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&"object"==typeof a&&"function"==typeof a.then},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;f>e;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context(void 0,a,b)},Context.wrap=function(a,b){return a instanceof Context?a:new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&e>i;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return"function"==typeof h?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;d>c;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return this.taps=b?b.push(a):new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return"function"==typeof a?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if("function"==typeof a&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;f>e;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){c.templateName=a,load(a,b,c).end()}):(c.templateName=a,load(a,this,c))},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return this.map(function(f){a.then(function(a){f=c?f.section(a,b,c):f.reference(a,b,d,e),f.end()},function(a){var d=c&&c.error;d?f.render(d,b.push(a)).end():(dust.log("Unhandled promise rejection in `"+b.getTemplateName()+"`",INFO),f.end())})})},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block,g=c&&c.error;return this.map(function(h){var i=!1;a.on("data",function(a){i||(f?h=h.map(function(c){c.render(f,b.push(a)).end()}):c||(h=h.reference(a,b,d,e)))}).on("error",function(a){i||(g?h.render(g,b.push(a)):dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),i||(i=!0,h.end()))}).on("end",function(){i||(i=!0,h.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.parse",["dust.core"],function(dust){return b(dust).parse}):"object"==typeof exports?module.exports=b(require("./dust")):b(a.dust)}(this,function(dust){var a=function(){function a(a,b){function c(){this.constructor=a}c.prototype=b.prototype,a.prototype=new c}function b(a,b,c,d,e,f){this.message=a,this.expected=b,this.found=c,this.offset=d,this.line=e,this.column=f,this.name="SyntaxError"}function c(a){function c(){return f(wc).line}function d(){return f(wc).column}function e(a){throw h(a,null,wc)}function f(b){function c(b,c,d){var e,f;for(e=c;d>e;e++)f=a.charAt(e),"\n"===f?(b.seenCR||b.line++,b.column=1,b.seenCR=!1):"\r"===f||"\u2028"===f||"\u2029"===f?(b.line++,b.column=1,b.seenCR=!0):(b.column++,b.seenCR=!1)}return xc!==b&&(xc>b&&(xc=0,yc={line:1,column:1,seenCR:!1}),c(yc,xc,b),xc=b),yc}function g(a){zc>vc||(vc>zc&&(zc=vc,Ac=[]),Ac.push(a))}function h(c,d,e){function g(a){var b=1;for(a.sort(function(a,b){return a.description<b.description?-1:a.description>b.description?1:0});b<a.length;)a[b-1]===a[b]?a.splice(b,1):b++}function h(a,b){function c(a){function b(a){return a.charCodeAt(0).toString(16).toUpperCase()}return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(a){return"\\x0"+b(a)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(a){return"\\x"+b(a)}).replace(/[\u0180-\u0FFF]/g,function(a){return"\\u0"+b(a)}).replace(/[\u1080-\uFFFF]/g,function(a){return"\\u"+b(a)})}var d,e,f,g=new Array(a.length);for(f=0;f<a.length;f++)g[f]=a[f].description;return d=a.length>1?g.slice(0,-1).join(", ")+" or "+g[a.length-1]:g[0],e=b?'"'+c(b)+'"':"end of input","Expected "+d+" but "+e+" found."}var i=f(e),j=e<a.length?a.charAt(e):null;return null!==d&&g(d),new b(null!==c?c:h(d,j),d,j,e,i.line,i.column)}function i(){var a;return a=j()}function j(){var a,b,c;for(a=vc,b=[],c=k();c!==X;)b.push(c),c=k();return b!==X&&(wc=a,b=$(b)),a=b}function k(){var a;return a=K(),a===X&&(a=L(),a===X&&(a=l(),a===X&&(a=s(),a===X&&(a=u(),a===X&&(a=r(),a===X&&(a=H())))))),a}function l(){var b,c,d,e,f,h,i,k;if(Bc++,b=vc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(e=O(),e!==X?(f=j(),f!==X?(h=q(),h!==X?(i=n(),i===X&&(i=ba),i!==X?(wc=vc,k=ca(c,f,h,i),k=k?da:aa,k!==X?(wc=b,c=ea(c,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;if(b===X)if(b=vc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(47===a.charCodeAt(vc)?(e=fa,vc++):(e=X,0===Bc&&g(ga)),e!==X?(f=O(),f!==X?(wc=b,c=ha(c),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(_)),b}function m(){var b,c,d,e,f,h,i;if(b=vc,c=N(),c!==X)if(ia.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g(ja)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();e!==X?(f=v(),f!==X?(h=o(),h!==X?(i=p(),i!==X?(wc=b,c=ka(d,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa;return b}function n(){var b,c,d,e,f,h,i;if(Bc++,b=vc,c=N(),c!==X)if(47===a.charCodeAt(vc)?(d=fa,vc++):(d=X,0===Bc&&g(ga)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=v(),f!==X){for(h=[],i=S();i!==X;)h.push(i),i=S();h!==X?(i=O(),i!==X?(wc=b,c=ma(f),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(la)),b}function o(){var b,c,d,e;return b=vc,c=vc,58===a.charCodeAt(vc)?(d=na,vc++):(d=X,0===Bc&&g(oa)),d!==X?(e=v(),e!==X?(wc=c,d=pa(e),c=d):(vc=c,c=aa)):(vc=c,c=aa),c===X&&(c=ba),c!==X&&(wc=b,c=qa(c)),b=c}function p(){var b,c,d,e,f,h,i;if(Bc++,b=vc,c=[],d=vc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=aa;for(e!==X?(f=C(),f!==X?(61===a.charCodeAt(vc)?(h=sa,vc++):(h=X,0===Bc&&g(ta)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(wc=d,e=ua(f,i),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);d!==X;){if(c.push(d),d=vc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=aa;e!==X?(f=C(),f!==X?(61===a.charCodeAt(vc)?(h=sa,vc++):(h=X,0===Bc&&g(ta)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(wc=d,e=ua(f,i),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)}return c!==X&&(wc=b,c=va(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(ra)),b}function q(){var b,c,d,e,f,h,i,k;for(Bc++,b=vc,c=[],d=vc,e=N(),e!==X?(58===a.charCodeAt(vc)?(f=na,vc++):(f=X,0===Bc&&g(oa)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(wc=d,e=ua(h,k),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);d!==X;)c.push(d),d=vc,e=N(),e!==X?(58===a.charCodeAt(vc)?(f=na,vc++):(f=X,0===Bc&&g(oa)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(wc=d,e=ua(h,k),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);return c!==X&&(wc=b,c=xa(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(wa)),b}function r(){var a,b,c,d,e;return Bc++,a=vc,b=N(),b!==X?(c=v(),c!==X?(d=t(),d!==X?(e=O(),e!==X?(wc=a,b=za(c,d),a=b):(vc=a,a=aa)):(vc=a,a=aa)):(vc=a,a=aa)):(vc=a,a=aa),Bc--,a===X&&(b=X,0===Bc&&g(ya)),a}function s(){var b,c,d,e,f,h,i,j,k,l;if(Bc++,b=vc,c=N(),c!==X)if(62===a.charCodeAt(vc)?(d=Ba,vc++):(d=X,0===Bc&&g(Ca)),d===X&&(43===a.charCodeAt(vc)?(d=Da,vc++):(d=X,0===Bc&&g(Ea))),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=vc,h=C(),h!==X&&(wc=f,h=Fa(h)),f=h,f===X&&(f=F()),f!==X)if(h=o(),h!==X)if(i=p(),i!==X){for(j=[],k=S();k!==X;)j.push(k),k=S();j!==X?(47===a.charCodeAt(vc)?(k=fa,vc++):(k=X,0===Bc&&g(ga)),k!==X?(l=O(),l!==X?(wc=b,c=Ga(d,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa;else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Aa)),b}function t(){var b,c,d,e,f;for(Bc++,b=vc,c=[],d=vc,124===a.charCodeAt(vc)?(e=Ia,vc++):(e=X,0===Bc&&g(Ja)),e!==X?(f=C(),f!==X?(wc=d,e=pa(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);d!==X;)c.push(d),d=vc,124===a.charCodeAt(vc)?(e=Ia,vc++):(e=X,0===Bc&&g(Ja)),e!==X?(f=C(),f!==X?(wc=d,e=pa(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);return c!==X&&(wc=b,c=Ka(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Ha)),b}function u(){var b,c,d,e,f;return Bc++,b=vc,c=N(),c!==X?(126===a.charCodeAt(vc)?(d=Ma,vc++):(d=X,0===Bc&&g(Na)),d!==X?(e=C(),e!==X?(f=O(),f!==X?(wc=b,c=Oa(e),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(La)),b}function v(){var a,b;return Bc++,a=vc,b=B(),b!==X&&(wc=a,b=Qa(b)),a=b,a===X&&(a=vc,b=C(),b!==X&&(wc=a,b=Ra(b)),a=b),Bc--,a===X&&(b=X,0===Bc&&g(Pa)),a}function w(){var a,b;return Bc++,a=vc,b=x(),b===X&&(b=A()),b!==X&&(wc=a,b=Ta(b)),a=b,Bc--,a===X&&(b=X,0===Bc&&g(Sa)),a}function x(){var b,c,d,e;return Bc++,b=vc,c=A(),c!==X?(46===a.charCodeAt(vc)?(d=Va,vc++):(d=X,0===Bc&&g(Wa)),d!==X?(e=y(),e!==X?(wc=b,c=Xa(c,e),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(Ua)),b}function y(){var b,c,d;if(Bc++,b=vc,c=[],Za.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g($a)),d!==X)for(;d!==X;)c.push(d),Za.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g($a));else c=aa;return c!==X&&(wc=b,c=_a(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Ya)),b}function z(){var b,c,d;return Bc++,b=vc,45===a.charCodeAt(vc)?(c=bb,vc++):(c=X,0===Bc&&g(cb)),c!==X?(d=y(),d!==X?(wc=b,c=db(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(ab)),b}function A(){var a,b;return Bc++,a=z(),a===X&&(a=y()),Bc--,a===X&&(b=X,0===Bc&&g(eb)),a}function B(){var b,c,d,e;if(Bc++,b=vc,c=C(),c===X&&(c=ba),c!==X){if(d=[],e=E(),e===X&&(e=D()),e!==X)for(;e!==X;)d.push(e),e=E(),e===X&&(e=D());else d=aa;d!==X?(wc=b,c=gb(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;if(b===X)if(b=vc,46===a.charCodeAt(vc)?(c=Va,vc++):(c=X,0===Bc&&g(Wa)),c!==X){for(d=[],e=E(),e===X&&(e=D());e!==X;)d.push(e),e=E(),e===X&&(e=D());d!==X?(wc=b,c=hb(d),b=c):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(fb)),b}function C(){var b,c,d,e;if(Bc++,b=vc,jb.test(a.charAt(vc))?(c=a.charAt(vc),vc++):(c=X,0===Bc&&g(kb)),c!==X){for(d=[],lb.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(mb));e!==X;)d.push(e),lb.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(mb));d!==X?(wc=b,c=nb(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(ib)),b}function D(){var b,c,d,e,f,h;if(Bc++,b=vc,c=vc,d=P(),d!==X){if(e=vc,f=[],Za.test(a.charAt(vc))?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g($a)),h!==X)for(;h!==X;)f.push(h),Za.test(a.charAt(vc))?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g($a));else f=aa;f!==X&&(wc=e,f=pb(f)),e=f,e===X&&(e=v()),e!==X?(f=Q(),f!==X?(wc=c,d=qb(e),c=d):(vc=c,c=aa)):(vc=c,c=aa)}else vc=c,c=aa;return c!==X?(d=E(),d===X&&(d=ba),d!==X?(wc=b,c=rb(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(ob)),b}function E(){var b,c,d,e,f;if(Bc++,b=vc,c=[],d=vc,46===a.charCodeAt(vc)?(e=Va,vc++):(e=X,0===Bc&&g(Wa)),e!==X?(f=C(),f!==X?(wc=d,e=tb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,46===a.charCodeAt(vc)?(e=Va,vc++):(e=X,0===Bc&&g(Wa)),e!==X?(f=C(),f!==X?(wc=d,e=tb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;return c!==X?(d=D(),d===X&&(d=ba),d!==X?(wc=b,c=ub(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(sb)),b}function F(){var b,c,d,e;if(Bc++,b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X?(34===a.charCodeAt(vc)?(d=wb,vc++):(d=X,0===Bc&&g(xb)),d!==X?(wc=b,c=yb(),b=c):(vc=b,b=aa)):(vc=b,b=aa),b===X&&(b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X?(d=I(),d!==X?(34===a.charCodeAt(vc)?(e=wb,vc++):(e=X,0===Bc&&g(xb)),e!==X?(wc=b,c=zb(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),b===X))if(b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X){if(d=[],e=G(),e!==X)for(;e!==X;)d.push(e),e=G();else d=aa;d!==X?(34===a.charCodeAt(vc)?(e=wb,vc++):(e=X,0===Bc&&g(xb)),e!==X?(wc=b,c=Ab(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(vb)),b}function G(){var a,b;return a=u(),a===X&&(a=r(),a===X&&(a=vc,b=I(),b!==X&&(wc=a,b=Bb(b)),a=b)),a}function H(){var b,c,d,e,f,h,i,j;if(Bc++,b=vc,c=R(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(wc=b,c=Db(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;if(b===X){if(b=vc,c=[],d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=vc,Bc++,h=K(),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(h=vc,Bc++,i=L(),Bc--,i===X?h=da:(vc=h,h=aa),h!==X?(i=vc,Bc++,j=R(),Bc--,j===X?i=da:(vc=i,i=aa),i!==X?(a.length>vc?(j=a.charAt(vc),vc++):(j=X,0===Bc&&g(Eb)),j!==X?(wc=d,e=Fb(j),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=vc,Bc++,h=K(),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(h=vc,Bc++,i=L(),Bc--,i===X?h=da:(vc=h,h=aa),h!==X?(i=vc,Bc++,j=R(),Bc--,j===X?i=da:(vc=i,i=aa),i!==X?(a.length>vc?(j=a.charAt(vc),vc++):(j=X,0===Bc&&g(Eb)),j!==X?(wc=d,e=Fb(j),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;c!==X&&(wc=b,c=Gb(c)),b=c}return Bc--,b===X&&(c=X,0===Bc&&g(Cb)),b}function I(){var b,c,d,e,f;if(Bc++,b=vc,c=[],d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=J(),f===X&&(Ib.test(a.charAt(vc))?(f=a.charAt(vc),vc++):(f=X,0===Bc&&g(Jb))),f!==X?(wc=d,e=Fb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=J(),f===X&&(Ib.test(a.charAt(vc))?(f=a.charAt(vc),vc++):(f=X,0===Bc&&g(Jb))),f!==X?(wc=d,e=Fb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;return c!==X&&(wc=b,c=Kb(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Hb)),b}function J(){var b,c;return b=vc,a.substr(vc,2)===Lb?(c=Lb,vc+=2):(c=X,0===Bc&&g(Mb)),c!==X&&(wc=b,c=Nb()),b=c}function K(){var b,c,d,e,f,h;if(Bc++,b=vc,a.substr(vc,2)===Pb?(c=Pb,vc+=2):(c=X,0===Bc&&g(Qb)),c!==X){for(d=[],e=vc,f=vc,Bc++,a.substr(vc,2)===Rb?(h=Rb,vc+=2):(h=X,0===Bc&&g(Sb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Tb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);e!==X;)d.push(e),e=vc,f=vc,Bc++,a.substr(vc,2)===Rb?(h=Rb,vc+=2):(h=X,0===Bc&&g(Sb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Tb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);d!==X?(a.substr(vc,2)===Rb?(e=Rb,vc+=2):(e=X,0===Bc&&g(Sb)),e!==X?(wc=b,c=Ub(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Ob)),b}function L(){var b,c,d,e,f,h;if(Bc++,b=vc,a.substr(vc,2)===Wb?(c=Wb,vc+=2):(c=X,0===Bc&&g(Xb)),c!==X){for(d=[],e=vc,f=vc,Bc++,a.substr(vc,2)===Yb?(h=Yb,vc+=2):(h=X,0===Bc&&g(Zb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Fb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);e!==X;)d.push(e),e=vc,f=vc,Bc++,a.substr(vc,2)===Yb?(h=Yb,vc+=2):(h=X,0===Bc&&g(Zb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Fb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);d!==X?(a.substr(vc,2)===Yb?(e=Yb,vc+=2):(e=X,0===Bc&&g(Zb)),e!==X?(wc=b,c=$b(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Vb)),b}function M(){var b,c,d,e,f,h,i,j,k,l;if(b=vc,c=N(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();if(d!==X)if(_b.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(ac)),e!==X){for(f=[],h=S();h!==X;)f.push(h),h=S();if(f!==X){if(h=[],i=vc,j=vc,Bc++,k=O(),Bc--,k===X?j=da:(vc=j,j=aa),j!==X?(k=vc,Bc++,l=R(),Bc--,l===X?k=da:(vc=k,k=aa),k!==X?(a.length>vc?(l=a.charAt(vc),vc++):(l=X,0===Bc&&g(Eb)),l!==X?(j=[j,k,l],i=j):(vc=i,i=aa)):(vc=i,i=aa)):(vc=i,i=aa),i!==X)for(;i!==X;)h.push(i),i=vc,j=vc,Bc++,k=O(),Bc--,k===X?j=da:(vc=j,j=aa),j!==X?(k=vc,Bc++,l=R(),Bc--,l===X?k=da:(vc=k,k=aa),k!==X?(a.length>vc?(l=a.charAt(vc),vc++):(l=X,0===Bc&&g(Eb)),l!==X?(j=[j,k,l],i=j):(vc=i,i=aa)):(vc=i,i=aa)):(vc=i,i=aa);else h=aa;if(h!==X){for(i=[],j=S();j!==X;)i.push(j),j=S();i!==X?(j=O(),j!==X?(c=[c,d,e,f,h,i,j],b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa}else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;return b===X&&(b=r()),b}function N(){var b;return 123===a.charCodeAt(vc)?(b=bc,vc++):(b=X,0===Bc&&g(cc)),b}function O(){var b;return 125===a.charCodeAt(vc)?(b=dc,vc++):(b=X,0===Bc&&g(ec)),b}function P(){var b;return 91===a.charCodeAt(vc)?(b=fc,vc++):(b=X,0===Bc&&g(gc)),b}function Q(){var b;return 93===a.charCodeAt(vc)?(b=hc,vc++):(b=X,0===Bc&&g(ic)),b}function R(){var b;return 10===a.charCodeAt(vc)?(b=jc,vc++):(b=X,0===Bc&&g(kc)),b===X&&(a.substr(vc,2)===lc?(b=lc,vc+=2):(b=X,0===Bc&&g(mc)),b===X&&(13===a.charCodeAt(vc)?(b=nc,vc++):(b=X,0===Bc&&g(oc)),b===X&&(8232===a.charCodeAt(vc)?(b=pc,vc++):(b=X,0===Bc&&g(qc)),b===X&&(8233===a.charCodeAt(vc)?(b=rc,vc++):(b=X,0===Bc&&g(sc)))))),b}function S(){var b;return tc.test(a.charAt(vc))?(b=a.charAt(vc),vc++):(b=X,0===Bc&&g(uc)),b===X&&(b=R()),b}function T(a){return parseInt(a.join(""),10)}function U(a){return a.concat([["line",c()],["col",d()]])}var V,W=arguments.length>1?arguments[1]:{},X={},Y={start:i},Z=i,$=function(a){var b=["body"].concat(a);return U(b)},_={type:"other",description:"section"},aa=X,ba=null,ca=function(a,b,c,d){return d&&a[1].text===d.text||e("Expected end tag for "+a[1].text+" but it was not found."),!0},da=void 0,ea=function(a,b,c){return c.push(["param",["literal","block"],b]),a.push(c,["filters"]),U(a)},fa="/",ga={type:"literal",value:"/",description:'"/"'},ha=function(a){return a.push(["bodies"],["filters"]),U(a)},ia=/^[#?\^<+@%]/,ja={type:"class",value:"[#?\\^<+@%]",description:"[#?\\^<+@%]"},ka=function(a,b,c,d){return[a,b,c,d]},la={type:"other",description:"end tag"},ma=function(a){return a},na=":",oa={type:"literal",value:":",description:'":"'},pa=function(a){return a},qa=function(a){return a?["context",a]:["context"]},ra={type:"other",description:"params"},sa="=",ta={type:"literal",value:"=",description:'"="'},ua=function(a,b){return["param",["literal",a],b]},va=function(a){return["params"].concat(a)},wa={type:"other",description:"bodies"},xa=function(a){return["bodies"].concat(a)},ya={type:"other",description:"reference"},za=function(a,b){return U(["reference",a,b])},Aa={type:"other",description:"partial"},Ba=">",Ca={type:"literal",value:">",description:'">"'},Da="+",Ea={type:"literal",value:"+",description:'"+"'},Fa=function(a){return["literal",a]},Ga=function(a,b,c,d){var e=">"===a?"partial":a;return U([e,b,c,d])},Ha={type:"other",description:"filters"},Ia="|",Ja={type:"literal",value:"|",description:'"|"'},Ka=function(a){return["filters"].concat(a)},La={type:"other",description:"special"},Ma="~",Na={type:"literal",value:"~",description:'"~"'},Oa=function(a){return U(["special",a])},Pa={type:"other",description:"identifier"},Qa=function(a){var b=["path"].concat(a);return b.text=a[1].join(".").replace(/,line,\d+,col,\d+/g,""),b},Ra=function(a){var b=["key",a];return b.text=a,b},Sa={type:"other",description:"number"},Ta=function(a){return["literal",a]},Ua={type:"other",description:"float"},Va=".",Wa={type:"literal",value:".",description:'"."'},Xa=function(a,b){return parseFloat(a+"."+b)},Ya={type:"other",description:"unsigned_integer"},Za=/^[0-9]/,$a={type:"class",value:"[0-9]",description:"[0-9]"},_a=function(a){return T(a)},ab={type:"other",description:"signed_integer"},bb="-",cb={type:"literal",value:"-",description:'"-"'},db=function(a,b){return-1*b},eb={type:"other",description:"integer"},fb={type:"other",description:"path"},gb=function(a,b){return b=b[0],a&&b?(b.unshift(a),U([!1,b])):U([!0,b])},hb=function(a){return U(a.length>0?[!0,a[0]]:[!0,[]])},ib={type:"other",description:"key"},jb=/^[a-zA-Z_$]/,kb={type:"class",value:"[a-zA-Z_$]",description:"[a-zA-Z_$]"},lb=/^[0-9a-zA-Z_$\-]/,mb={type:"class",value:"[0-9a-zA-Z_$\\-]",description:"[0-9a-zA-Z_$\\-]"},nb=function(a,b){return a+b.join("")},ob={type:"other",description:"array"},pb=function(a){return a.join("")},qb=function(a){return a},rb=function(a,b){return b?b.unshift(a):b=[a],b},sb={type:"other",description:"array_part"},tb=function(a){return a},ub=function(a,b){return b?a.concat(b):a},vb={type:"other",description:"inline"},wb='"',xb={type:"literal",value:'"',description:'"\\""'},yb=function(){return U(["literal",""])},zb=function(a){return U(["literal",a])},Ab=function(a){return U(["body"].concat(a))},Bb=function(a){return["buffer",a]},Cb={type:"other",description:"buffer"},Db=function(a,b){return U(["format",a,b.join("")])},Eb={type:"any",description:"any character"},Fb=function(a){return a},Gb=function(a){return U(["buffer",a.join("")])},Hb={type:"other",description:"literal"},Ib=/^[^"]/,Jb={type:"class",value:'[^"]',description:'[^"]'},Kb=function(a){return a.join("")},Lb='\\"',Mb={type:"literal",value:'\\"',description:'"\\\\\\""'},Nb=function(){return'"'},Ob={type:"other",description:"raw"},Pb="{`",Qb={type:"literal",value:"{`",description:'"{`"'},Rb="`}",Sb={type:"literal",value:"`}",description:'"`}"'},Tb=function(a){return a},Ub=function(a){return U(["raw",a.join("")])},Vb={type:"other",description:"comment"},Wb="{!",Xb={type:"literal",value:"{!",description:'"{!"'},Yb="!}",Zb={type:"literal",value:"!}",description:'"!}"'},$b=function(a){return U(["comment",a.join("")])},_b=/^[#?\^><+%:@\/~%]/,ac={type:"class",value:"[#?\\^><+%:@\\/~%]",description:"[#?\\^><+%:@\\/~%]"},bc="{",cc={type:"literal",value:"{",description:'"{"'},dc="}",ec={type:"literal",value:"}",description:'"}"'},fc="[",gc={type:"literal",value:"[",description:'"["'},hc="]",ic={type:"literal",value:"]",description:'"]"'},jc="\n",kc={type:"literal",value:"\n",description:'"\\n"'},lc="\r\n",mc={type:"literal",
-value:"\r\n",description:'"\\r\\n"'},nc="\r",oc={type:"literal",value:"\r",description:'"\\r"'},pc="\u2028",qc={type:"literal",value:"\u2028",description:'"\\u2028"'},rc="\u2029",sc={type:"literal",value:"\u2029",description:'"\\u2029"'},tc=/^[\t\x0B\f \xA0\uFEFF]/,uc={type:"class",value:"[\\t\\x0B\\f \\xA0\\uFEFF]",description:"[\\t\\x0B\\f \\xA0\\uFEFF]"},vc=0,wc=0,xc=0,yc={line:1,column:1,seenCR:!1},zc=0,Ac=[],Bc=0;if("startRule"in W){if(!(W.startRule in Y))throw new Error("Can't start parsing from rule \""+W.startRule+'".');Z=Y[W.startRule]}if(V=Z(),V!==X&&vc===a.length)return V;throw V!==X&&vc<a.length&&g({type:"end",description:"end of input"}),h(null,Ac,zc)}return a(b,Error),{SyntaxError:b,parse:c}}();return dust.parse=a.parse,a}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.compile",["dust.core","dust.parse"],function(dust,a){return b(a,dust).compile}):"object"==typeof exports?module.exports=b(require("./parser").parse,require("./dust")):b(a.dust.parse,a.dust)}(this,function(a,dust){function b(a){var b={};return r.filterNode(b,a)}function c(a,b){var c,d,e,f=[b[0]];for(c=1,d=b.length;d>c;c++)e=r.filterNode(a,b[c]),e&&f.push(e);return f}function d(a,b){var c,d,e,f,g=[b[0]];for(d=1,e=b.length;e>d;d++)f=r.filterNode(a,b[d]),f&&("buffer"===f[0]||"format"===f[0]?c?(c[0]="buffer"===f[0]?"buffer":c[0],c[1]+=f.slice(1,-2).join("")):(c=f,g.push(f)):(c=null,g.push(f)));return g}function e(a,b){return["buffer",t[b[1]],b[2],b[3]]}function f(a,b){return b}function g(){}function h(a,b){return dust.config.whitespace?(b.splice(1,2,b.slice(1,-2).join("")),b):null}function i(a,b){var c,d={name:b,bodies:[],blocks:{},index:0,auto:"h"},e=dust.escapeJs(b),f=b?'"'+e+'",':"",g="function(dust){",h=r.compileNode(d,a);return b&&(g+='dust.register("'+e+'",'+h+");"),g+=j(d)+k(d)+"return "+h+"}",c="("+g+"(dust));",dust.config.amd?"define("+f+'["dust.core"],'+g+");":dust.config.cjs?"module.exports=function(dust){var tmpl="+c+"var f="+q().toString()+";f.template=tmpl;return f}":c}function j(a){var b,c=[],d=a.blocks;for(b in d)c.push('"'+b+'":'+d[b]);return c.length?(a.blocks="ctx=ctx.shiftBlocks(blocks);","var blocks={"+c.join(",")+"};"):(a.blocks="",a.blocks)}function k(a){var b,c,d=[],e=a.bodies,f=a.blocks;for(b=0,c=e.length;c>b;b++)d[b]="function body_"+b+"(chk,ctx){"+f+"return chk"+e[b]+";}body_"+b+".__dustBody=!0;";return d.join("")}function l(a,b){var c,d,e="";for(c=1,d=b.length;d>c;c++)e+=r.compileNode(a,b[c]);return e}function m(a,b,c){return"."+(dust._aliases[c]||c)+"("+r.compileNode(a,b[1])+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"}function n(a){return a.replace(u,"\\\\").replace(v,'\\"').replace(w,"\\f").replace(x,"\\n").replace(y,"\\r").replace(z,"\\t")}function o(a,b,c){var d=dust.loadSource(dust.compile(a));return q(d)(b,c)}function p(a,b){var c=dust.loadSource(dust.compile(a,b));return q(c)}function q(a){return function(b,c){var d=c?"render":"stream";return dust[d](a,b,c)}}var r={},s=dust.isArray;r.compile=function(c,d){try{var e=b(a(c));return i(e,d)}catch(f){if(!f.line||!f.column)throw f;throw new SyntaxError(f.message+" At line : "+f.line+", column : "+f.column)}},r.filterNode=function(a,b){return r.optimizers[b[0]](a,b)},r.optimizers={body:d,buffer:f,special:e,format:h,reference:c,"#":c,"?":c,"^":c,"<":c,"+":c,"@":c,"%":c,partial:c,context:c,params:c,bodies:c,param:c,filters:f,key:f,path:f,literal:f,raw:f,comment:g,line:g,col:g},r.pragmas={esc:function(a,b,c){var d,e=a.auto;return b||(b="h"),a.auto="s"===b?"":b,d=l(a,c.block),a.auto=e,d}};var t={s:" ",n:"\n",r:"\r",lb:"{",rb:"}"};r.compileNode=function(a,b){return r.nodes[b[0]](a,b)},r.nodes={body:function(a,b){var c=a.index++,d="body_"+c;return a.bodies[c]=l(a,b),d},buffer:function(a,b){return".w("+A(b[1])+")"},format:function(a,b){return".w("+A(b[1])+")"},reference:function(a,b){return".f("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+")"},"#":function(a,b){return m(a,b,"section")},"?":function(a,b){return m(a,b,"exists")},"^":function(a,b){return m(a,b,"notexists")},"<":function(a,b){for(var c=b[4],d=1,e=c.length;e>d;d++){var f=c[d],g=f[1][1];if("block"===g)return a.blocks[b[1].text]=r.compileNode(a,f[2]),""}return""},"+":function(a,b){return"undefined"==typeof b[1].text&&"undefined"==typeof b[4]?".b(ctx.getBlock("+r.compileNode(a,b[1])+",chk, ctx),"+r.compileNode(a,b[2])+", {},"+r.compileNode(a,b[3])+")":".b(ctx.getBlock("+A(b[1].text)+"),"+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"},"@":function(a,b){return".h("+A(b[1].text)+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+","+r.compileNode(a,b[5])+")"},"%":function(a,b){var c,d,e,f,g,h,i,j,k,l=b[1][1];if(!r.pragmas[l])return"";for(c=b[4],d={},j=1,k=c.length;k>j;j++)h=c[j],d[h[1][1]]=h[2];for(e=b[3],f={},j=1,k=e.length;k>j;j++)i=e[j],f[i[1][1]]=i[2][1];return g=b[2][1]?b[2][1].text:null,r.pragmas[l](a,g,d,f)},partial:function(a,b){return".p("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+","+r.compileNode(a,b[3])+")"},context:function(a,b){return b[1]?"ctx.rebase("+r.compileNode(a,b[1])+")":"ctx"},params:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++)c.push(r.compileNode(a,b[d]));return c.length?"{"+c.join(",")+"}":"{}"},bodies:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++)c.push(r.compileNode(a,b[d]));return"{"+c.join(",")+"}"},param:function(a,b){return r.compileNode(a,b[1])+":"+r.compileNode(a,b[2])},filters:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++){var f=b[d];c.push('"'+f+'"')}return'"'+a.auto+'"'+(c.length?",["+c.join(",")+"]":"")},key:function(a,b){return'ctx.get(["'+b[1]+'"], false)'},path:function(a,b){for(var c=b[1],d=b[2],e=[],f=0,g=d.length;g>f;f++)e.push(s(d[f])?r.compileNode(a,d[f]):'"'+d[f]+'"');return"ctx.getPath("+c+", ["+e.join(",")+"])"},literal:function(a,b){return A(b[1])},raw:function(a,b){return".w("+A(b[1])+")"}};var u=/\\/g,v=/"/g,w=/\f/g,x=/\n/g,y=/\r/g,z=/\t/g,A="undefined"==typeof JSON?function(a){return'"'+n(a)+'"'}:JSON.stringify;return dust.compiler=r,dust.compile=dust.compiler.compile,dust.renderSource=o,dust.compileFn=p,dust.filterNode=r.filterNode,dust.optimizers=r.optimizers,dust.pragmas=r.pragmas,dust.compileNode=r.compileNode,dust.nodes=r.nodes,r}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core","dust.compile"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(){b()})},dust});
\ No newline at end of file
+* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
+!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){if(a)return"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e,this._isContext=!0}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function mapThenable(a,b,c,d,e){return a.map(function(a){b.then(function(b){try{e(a,b)}catch(c){dust.log(c,ERROR),a.setError(c)}},function(b){dust.log("Unhandled promise rejection in `"+c.getTemplateName()+"`",INFO),a.renderError(b,c,d).end()})})}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&(b("[DUST:"+d+"]",a),d===ERROR&&dust.debugLevel===DEBUG&&a instanceof Error&&a.stack&&b("[DUST:"+d+"]",a.stack))},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},Array.isArray?dust.isArray=Array.isArray:dust.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0!==a&&(!(!dust.isArray(a)||a.length)||!a)},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&("object"==typeof a||"function"==typeof a)&&"function"==typeof a.then},dust.isNonThenableFunction=function(a){return"function"==typeof a&&!dust.isThenable(a)},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;e<f;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context((void 0),a,b)},dust.isContext=function(a){return"object"==typeof a&&a._isContext===!0},Context.wrap=function(a,b){return dust.isContext(a)?(a.templateName=b,a):new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&i<e;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return dust.isNonThenableFunction(h)?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;c<d;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return b?this.taps=b.push(a):this.taps=new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return dust.isNonThenableFunction(a)?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if(dust.isNonThenableFunction(a)&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;e<f;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.exists(d,b,c).end()});if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.notexists(d,b,c).end()});if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){load(a,b,c).end()}):load(a,this,c)},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return mapThenable(this,a,b,c,function(a,f){c?a.section(f,b,c).end():a.reference(f,b,d,e).end()})},Chunk.prototype.renderError=function(a,b,c){var d=c&&c.error;return d?this.render(d,b.push(a)):this},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block;return this.map(function(g){var h=!1;a.on("data",function(a){h||(f?g=g.map(function(c){c.render(f,b.push(a)).end()}):c||(g=g.reference(a,b,d,e)))}).on("error",function(a){h||(g.renderError(a,b,c),dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),h||(h=!0,g.end()))}).on("end",function(){h||(h=!0,g.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.parse",["dust.core"],function(dust){return b(dust).parse}):"object"==typeof exports?module.exports=b(require("./dust")):b(a.dust)}(this,function(dust){var a=function(){"use strict";function a(a,b){function c(){this.constructor=a}c.prototype=b.prototype,a.prototype=new c}function b(a,c,d,e){this.message=a,this.expected=c,this.found=d,this.location=e,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,b)}function c(a){function c(){return f(tc,sc)}function d(b){throw h(b,null,a.substring(tc,sc),f(tc,sc))}function e(b){var c,d,e=uc[b];if(e)return e;for(c=b-1;!uc[c];)c--;for(e=uc[c],e={line:e.line,column:e.column,seenCR:e.seenCR};c<b;)d=a.charAt(c),"\n"===d?(e.seenCR||e.line++,e.column=1,e.seenCR=!1):"\r"===d||"\u2028"===d||"\u2029"===d?(e.line++,e.column=1,e.seenCR=!0):(e.column++,e.seenCR=!1),c++;return uc[b]=e,e}function f(a,b){var c=e(a),d=e(b);return{start:{offset:a,line:c.line,column:c.column},end:{offset:b,line:d.line,column:d.column}}}function g(a){sc<vc||(sc>vc&&(vc=sc,wc=[]),wc.push(a))}function h(a,c,d,e){function f(a){var b=1;for(a.sort(function(a,b){return a.description<b.description?-1:a.description>b.description?1:0});b<a.length;)a[b-1]===a[b]?a.splice(b,1):b++}function g(a,b){function c(a){function b(a){return a.charCodeAt(0).toString(16).toUpperCase()}return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(a){return"\\x0"+b(a)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(a){return"\\x"+b(a)}).replace(/[\u0100-\u0FFF]/g,function(a){return"\\u0"+b(a)}).replace(/[\u1000-\uFFFF]/g,function(a){return"\\u"+b(a)})}var d,e,f,g=new Array(a.length);for(f=0;f<a.length;f++)g[f]=a[f].description;return d=a.length>1?g.slice(0,-1).join(", ")+" or "+g[a.length-1]:g[0],e=b?'"'+c(b)+'"':"end of input","Expected "+d+" but "+e+" found."}return null!==c&&f(c),new b(null!==a?a:g(c,d),c,d,e)}function i(){var a;return a=j()}function j(){var a,b,c;for(a=sc,b=[],c=k();c!==X;)b.push(c),c=k();return b!==X&&(tc=a,b=$(b)),a=b}function k(){var a;return a=K(),a===X&&(a=L(),a===X&&(a=l(),a===X&&(a=s(),a===X&&(a=u(),a===X&&(a=r(),a===X&&(a=H())))))),a}function l(){var b,c,d,e,f,h,i,k;if(xc++,b=sc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(e=O(),e!==X?(f=j(),f!==X?(h=q(),h!==X?(i=n(),i===X&&(i=null),i!==X?(tc=sc,k=aa(c,f,h,i),k=k?void 0:X,k!==X?(tc=b,c=ba(c,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;if(b===X)if(b=sc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(47===a.charCodeAt(sc)?(e=ca,sc++):(e=X,0===xc&&g(da)),e!==X?(f=O(),f!==X?(tc=b,c=ea(c),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(_)),b}function m(){var b,c,d,e,f,h,i;if(b=sc,c=N(),c!==X)if(fa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(ga)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();e!==X?(f=v(),f!==X?(h=o(),h!==X?(i=p(),i!==X?(tc=b,c=ha(d,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X;return b}function n(){var b,c,d,e,f,h,i;if(xc++,b=sc,c=N(),c!==X)if(47===a.charCodeAt(sc)?(d=ca,sc++):(d=X,0===xc&&g(da)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=v(),f!==X){for(h=[],i=S();i!==X;)h.push(i),i=S();h!==X?(i=O(),i!==X?(tc=b,c=ja(f),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(ia)),b}function o(){var b,c,d,e;return b=sc,c=sc,58===a.charCodeAt(sc)?(d=ka,sc++):(d=X,0===xc&&g(la)),d!==X?(e=v(),e!==X?(tc=c,d=ma(e),c=d):(sc=c,c=X)):(sc=c,c=X),c===X&&(c=null),c!==X&&(tc=b,c=na(c)),b=c}function p(){var b,c,d,e,f,h,i;if(xc++,b=sc,c=[],d=sc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=X;for(e!==X?(f=C(),f!==X?(61===a.charCodeAt(sc)?(h=pa,sc++):(h=X,0===xc&&g(qa)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(tc=d,e=ra(f,i),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);d!==X;){if(c.push(d),d=sc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=X;e!==X?(f=C(),f!==X?(61===a.charCodeAt(sc)?(h=pa,sc++):(h=X,0===xc&&g(qa)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(tc=d,e=ra(f,i),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)}return c!==X&&(tc=b,c=sa(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(oa)),b}function q(){var b,c,d,e,f,h,i,k;for(xc++,b=sc,c=[],d=sc,e=N(),e!==X?(58===a.charCodeAt(sc)?(f=ka,sc++):(f=X,0===xc&&g(la)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(tc=d,e=ra(h,k),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);d!==X;)c.push(d),d=sc,e=N(),e!==X?(58===a.charCodeAt(sc)?(f=ka,sc++):(f=X,0===xc&&g(la)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(tc=d,e=ra(h,k),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);return c!==X&&(tc=b,c=ua(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(ta)),b}function r(){var a,b,c,d,e;return xc++,a=sc,b=N(),b!==X?(c=v(),c!==X?(d=t(),d!==X?(e=O(),e!==X?(tc=a,b=wa(c,d),a=b):(sc=a,a=X)):(sc=a,a=X)):(sc=a,a=X)):(sc=a,a=X),xc--,a===X&&(b=X,0===xc&&g(va)),a}function s(){var b,c,d,e,f,h,i,j,k,l;if(xc++,b=sc,c=N(),c!==X)if(62===a.charCodeAt(sc)?(d=ya,sc++):(d=X,0===xc&&g(za)),d===X&&(43===a.charCodeAt(sc)?(d=Aa,sc++):(d=X,0===xc&&g(Ba))),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=sc,h=C(),h!==X&&(tc=f,h=Ca(d,h)),f=h,f===X&&(f=F()),f!==X)if(h=o(),h!==X)if(i=p(),i!==X){for(j=[],k=S();k!==X;)j.push(k),k=S();j!==X?(47===a.charCodeAt(sc)?(k=ca,sc++):(k=X,0===xc&&g(da)),k!==X?(l=O(),l!==X?(tc=b,c=Da(d,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X;else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(xa)),b}function t(){var b,c,d,e,f;for(xc++,b=sc,c=[],d=sc,124===a.charCodeAt(sc)?(e=Fa,sc++):(e=X,0===xc&&g(Ga)),e!==X?(f=C(),f!==X?(tc=d,e=ma(f),d=e):(sc=d,d=X)):(sc=d,d=X);d!==X;)c.push(d),d=sc,124===a.charCodeAt(sc)?(e=Fa,sc++):(e=X,0===xc&&g(Ga)),e!==X?(f=C(),f!==X?(tc=d,e=ma(f),d=e):(sc=d,d=X)):(sc=d,d=X);return c!==X&&(tc=b,c=Ha(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Ea)),b}function u(){var b,c,d,e,f;return xc++,b=sc,c=N(),c!==X?(126===a.charCodeAt(sc)?(d=Ja,sc++):(d=X,0===xc&&g(Ka)),d!==X?(e=C(),e!==X?(f=O(),f!==X?(tc=b,c=La(e),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Ia)),b}function v(){var a,b;return xc++,a=sc,b=B(),b!==X&&(tc=a,b=Na(b)),a=b,a===X&&(a=sc,b=C(),b!==X&&(tc=a,b=Oa(b)),a=b),xc--,a===X&&(b=X,0===xc&&g(Ma)),a}function w(){var a,b;return xc++,a=sc,b=x(),b===X&&(b=A()),b!==X&&(tc=a,b=Qa(b)),a=b,xc--,a===X&&(b=X,0===xc&&g(Pa)),a}function x(){var b,c,d,e;return xc++,b=sc,c=A(),c!==X?(46===a.charCodeAt(sc)?(d=Sa,sc++):(d=X,0===xc&&g(Ta)),d!==X?(e=y(),e!==X?(tc=b,c=Ua(c,e),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Ra)),b}function y(){var b,c,d;if(xc++,b=sc,c=[],Wa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(Xa)),d!==X)for(;d!==X;)c.push(d),Wa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(Xa));else c=X;return c!==X&&(tc=b,c=Ya(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Va)),b}function z(){var b,c,d;return xc++,b=sc,45===a.charCodeAt(sc)?(c=$a,sc++):(c=X,0===xc&&g(_a)),c!==X?(d=y(),d!==X?(tc=b,c=ab(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Za)),b}function A(){var a,b;return xc++,a=z(),a===X&&(a=y()),xc--,a===X&&(b=X,0===xc&&g(bb)),a}function B(){var b,c,d,e;if(xc++,b=sc,c=C(),c===X&&(c=null),c!==X){if(d=[],e=E(),e===X&&(e=D()),e!==X)for(;e!==X;)d.push(e),e=E(),e===X&&(e=D());else d=X;d!==X?(tc=b,c=db(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;if(b===X)if(b=sc,46===a.charCodeAt(sc)?(c=Sa,sc++):(c=X,0===xc&&g(Ta)),c!==X){for(d=[],e=E(),e===X&&(e=D());e!==X;)d.push(e),e=E(),e===X&&(e=D());d!==X?(tc=b,c=eb(d),b=c):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(cb)),b}function C(){var b,c,d,e;if(xc++,b=sc,gb.test(a.charAt(sc))?(c=a.charAt(sc),sc++):(c=X,0===xc&&g(hb)),c!==X){for(d=[],ib.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(jb));e!==X;)d.push(e),ib.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(jb));d!==X?(tc=b,c=kb(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(fb)),b}function D(){var b,c,d,e,f,h;if(xc++,b=sc,c=sc,d=P(),d!==X){if(e=sc,f=[],Wa.test(a.charAt(sc))?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Xa)),h!==X)for(;h!==X;)f.push(h),Wa.test(a.charAt(sc))?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Xa));else f=X;f!==X&&(tc=e,f=mb(f)),e=f,e===X&&(e=v()),e!==X?(f=Q(),f!==X?(tc=c,d=nb(e),c=d):(sc=c,c=X)):(sc=c,c=X)}else sc=c,c=X;return c!==X?(d=E(),d===X&&(d=null),d!==X?(tc=b,c=ob(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(lb)),b}function E(){var b,c,d,e,f;if(xc++,b=sc,c=[],d=sc,46===a.charCodeAt(sc)?(e=Sa,sc++):(e=X,0===xc&&g(Ta)),e!==X?(f=C(),f!==X?(tc=d,e=qb(f),d=e):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,46===a.charCodeAt(sc)?(e=Sa,sc++):(e=X,0===xc&&g(Ta)),e!==X?(f=C(),f!==X?(tc=d,e=qb(f),d=e):(sc=d,d=X)):(sc=d,d=X);else c=X;return c!==X?(d=D(),d===X&&(d=null),d!==X?(tc=b,c=rb(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(pb)),b}function F(){var b,c,d,e;if(xc++,b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X?(34===a.charCodeAt(sc)?(d=tb,sc++):(d=X,0===xc&&g(ub)),d!==X?(tc=b,c=vb(),b=c):(sc=b,b=X)):(sc=b,b=X),b===X&&(b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X?(d=I(),d!==X?(34===a.charCodeAt(sc)?(e=tb,sc++):(e=X,0===xc&&g(ub)),e!==X?(tc=b,c=wb(d),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),b===X))if(b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X){if(d=[],e=G(),e!==X)for(;e!==X;)d.push(e),e=G();else d=X;d!==X?(34===a.charCodeAt(sc)?(e=tb,sc++):(e=X,0===xc&&g(ub)),e!==X?(tc=b,c=xb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(sb)),b}function G(){var a,b;return a=u(),a===X&&(a=r(),a===X&&(a=sc,b=I(),b!==X&&(tc=a,b=yb(b)),a=b)),a}function H(){var b,c,d,e,f,h,i,j;if(xc++,b=sc,c=R(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(tc=b,c=Ab(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;if(b===X){if(b=sc,c=[],d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=sc,xc++,h=K(),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(h=sc,xc++,i=L(),xc--,i===X?h=void 0:(sc=h,h=X),h!==X?(i=sc,xc++,j=R(),xc--,j===X?i=void 0:(sc=i,i=X),i!==X?(a.length>sc?(j=a.charAt(sc),sc++):(j=X,0===xc&&g(Bb)),j!==X?(tc=d,e=Cb(j),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=sc,xc++,h=K(),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(h=sc,xc++,i=L(),xc--,i===X?h=void 0:(sc=h,h=X),h!==X?(i=sc,xc++,j=R(),xc--,j===X?i=void 0:(sc=i,i=X),i!==X?(a.length>sc?(j=a.charAt(sc),sc++):(j=X,0===xc&&g(Bb)),j!==X?(tc=d,e=Cb(j),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);else c=X;c!==X&&(tc=b,c=Db(c)),b=c}return xc--,b===X&&(c=X,0===xc&&g(zb)),b}function I(){var b,c,d,e,f;if(xc++,b=sc,c=[],d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=J(),f===X&&(Fb.test(a.charAt(sc))?(f=a.charAt(sc),sc++):(f=X,0===xc&&g(Gb))),f!==X?(tc=d,e=Cb(f),d=e):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=J(),f===X&&(Fb.test(a.charAt(sc))?(f=a.charAt(sc),sc++):(f=X,0===xc&&g(Gb))),f!==X?(tc=d,e=Cb(f),d=e):(sc=d,d=X)):(sc=d,d=X);else c=X;return c!==X&&(tc=b,c=Hb(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Eb)),b}function J(){var b,c;return b=sc,a.substr(sc,2)===Ib?(c=Ib,sc+=2):(c=X,0===xc&&g(Jb)),c!==X&&(tc=b,c=Kb()),b=c}function K(){var b,c,d,e,f,h;if(xc++,b=sc,a.substr(sc,2)===Mb?(c=Mb,sc+=2):(c=X,0===xc&&g(Nb)),c!==X){for(d=[],e=sc,f=sc,xc++,a.substr(sc,2)===Ob?(h=Ob,sc+=2):(h=X,0===xc&&g(Pb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Qb(h),e=f):(sc=e,e=X)):(sc=e,e=X);e!==X;)d.push(e),e=sc,f=sc,xc++,a.substr(sc,2)===Ob?(h=Ob,sc+=2):(h=X,0===xc&&g(Pb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Qb(h),e=f):(sc=e,e=X)):(sc=e,e=X);d!==X?(a.substr(sc,2)===Ob?(e=Ob,sc+=2):(e=X,0===xc&&g(Pb)),e!==X?(tc=b,c=Rb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(Lb)),b}function L(){var b,c,d,e,f,h;if(xc++,b=sc,a.substr(sc,2)===Tb?(c=Tb,sc+=2):(c=X,0===xc&&g(Ub)),c!==X){for(d=[],e=sc,f=sc,xc++,a.substr(sc,2)===Vb?(h=Vb,sc+=2):(h=X,0===xc&&g(Wb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Cb(h),e=f):(sc=e,e=X)):(sc=e,e=X);e!==X;)d.push(e),e=sc,f=sc,xc++,a.substr(sc,2)===Vb?(h=Vb,sc+=2):(h=X,0===xc&&g(Wb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Cb(h),e=f):(sc=e,e=X)):(sc=e,e=X);d!==X?(a.substr(sc,2)===Vb?(e=Vb,sc+=2):(e=X,0===xc&&g(Wb)),e!==X?(tc=b,c=Xb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(Sb)),b}function M(){var b,c,d,e,f,h,i,j,k,l;if(b=sc,c=N(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();if(d!==X)if(Yb.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(Zb)),e!==X){for(f=[],h=S();h!==X;)f.push(h),h=S();if(f!==X){if(h=[],i=sc,j=sc,xc++,k=O(),xc--,k===X?j=void 0:(sc=j,j=X),j!==X?(k=sc,xc++,l=R(),xc--,l===X?k=void 0:(sc=k,k=X),k!==X?(a.length>sc?(l=a.charAt(sc),sc++):(l=X,0===xc&&g(Bb)),l!==X?(j=[j,k,l],i=j):(sc=i,i=X)):(sc=i,i=X)):(sc=i,i=X),i!==X)for(;i!==X;)h.push(i),i=sc,j=sc,xc++,k=O(),xc--,k===X?j=void 0:(sc=j,j=X),j!==X?(k=sc,xc++,l=R(),xc--,l===X?k=void 0:(sc=k,k=X),k!==X?(a.length>sc?(l=a.charAt(sc),sc++):(l=X,0===xc&&g(Bb)),l!==X?(j=[j,k,l],i=j):(sc=i,i=X)):(sc=i,i=X)):(sc=i,i=X);else h=X;if(h!==X){for(i=[],j=S();j!==X;)i.push(j),j=S();i!==X?(j=O(),j!==X?(c=[c,d,e,f,h,i,j],b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X}else sc=b,b=X}else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;return b===X&&(b=r()),b}function N(){var b;return 123===a.charCodeAt(sc)?(b=$b,sc++):(b=X,0===xc&&g(_b)),b}function O(){var b;return 125===a.charCodeAt(sc)?(b=ac,sc++):(b=X,0===xc&&g(bc)),b}function P(){var b;return 91===a.charCodeAt(sc)?(b=cc,sc++):(b=X,0===xc&&g(dc)),b}function Q(){var b;return 93===a.charCodeAt(sc)?(b=ec,sc++):(b=X,0===xc&&g(fc)),b}function R(){var b;return 10===a.charCodeAt(sc)?(b=gc,sc++):(b=X,0===xc&&g(hc)),b===X&&(a.substr(sc,2)===ic?(b=ic,sc+=2):(b=X,0===xc&&g(jc)),b===X&&(13===a.charCodeAt(sc)?(b=kc,sc++):(b=X,0===xc&&g(lc)),b===X&&(8232===a.charCodeAt(sc)?(b=mc,sc++):(b=X,0===xc&&g(nc)),b===X&&(8233===a.charCodeAt(sc)?(b=oc,sc++):(b=X,0===xc&&g(pc)))))),b}function S(){var b;return qc.test(a.charAt(sc))?(b=a.charAt(sc),sc++):(b=X,0===xc&&g(rc)),b===X&&(b=R()),b}function T(a){return parseInt(a.join(""),10)}function U(a){return a.location=c(),a}var V,W=arguments.length>1?arguments[1]:{},X={},Y={start:i},Z=i,$=function(a){var b=["body"].concat(a);return U(b)},_={type:"other",description:"section"},aa=function(a,b,c,e){return e&&a[1].text===e.text||d("Expected end tag for "+a[1].text+" but it was not found."),!0},ba=function(a,b,c,d){return c.push(["param",["literal","block"],b]),a.push(c,["filters"]),U(a)},ca="/",da={type:"literal",value:"/",description:'"/"'},ea=function(a){return a.push(["bodies"],["filters"]),U(a)},fa=/^[#?\^<+@%]/,ga={type:"class",value:"[#?^<+@%]",description:"[#?^<+@%]"},ha=function(a,b,c,d){return[a,b,c,d]},ia={type:"other",description:"end tag"},ja=function(a){return a},ka=":",la={type:"literal",value:":",description:'":"'},ma=function(a){return a},na=function(a){return a?["context",a]:["context"]},oa={type:"other",description:"params"},pa="=",qa={type:"literal",value:"=",description:'"="'},ra=function(a,b){return["param",["literal",a],b]},sa=function(a){return["params"].concat(a)},ta={type:"other",description:"bodies"},ua=function(a){return["bodies"].concat(a)},va={type:"other",description:"reference"},wa=function(a,b){return U(["reference",a,b])},xa={type:"other",description:"partial"},ya=">",za={type:"literal",value:">",description:'">"'},Aa="+",Ba={type:"literal",value:"+",description:'"+"'},Ca=function(a,b){return["literal",b]},Da=function(a,b,c,d){var e=">"===a?"partial":a;return U([e,b,c,d])},Ea={type:"other",description:"filters"},Fa="|",Ga={type:"literal",value:"|",description:'"|"'},Ha=function(a){return["filters"].concat(a)},Ia={type:"other",description:"special"},Ja="~",Ka={type:"literal",value:"~",description:'"~"'},La=function(a){return U(["special",a])},Ma={type:"other",description:"identifier"},Na=function(a){var b=["path"].concat(a);return b.text=a[1].join("."),b},Oa=function(a){var b=["key",a];return b.text=a,b},Pa={type:"other",description:"number"},Qa=function(a){return["literal",a]},Ra={type:"other",description:"float"},Sa=".",Ta={type:"literal",value:".",description:'"."'},Ua=function(a,b){return parseFloat(a+"."+b)},Va={type:"other",description:"unsigned_integer"},Wa=/^[0-9]/,Xa={type:"class",value:"[0-9]",description:"[0-9]"},Ya=function(a){return T(a)},Za={type:"other",description:"signed_integer"},$a="-",_a={type:"literal",value:"-",description:'"-"'},ab=function(a,b){return b*-1},bb={type:"other",description:"integer"},cb={type:"other",description:"path"},db=function(a,b){return b=b[0],a&&b?(b.unshift(a),U([!1,b])):U([!0,b])},eb=function(a){return U(a.length>0?[!0,a[0]]:[!0,[]])},fb={type:"other",description:"key"},gb=/^[a-zA-Z_$]/,hb={type:"class",value:"[a-zA-Z_$]",description:"[a-zA-Z_$]"},ib=/^[0-9a-zA-Z_$\-]/,jb={type:"class",value:"[0-9a-zA-Z_$-]",description:"[0-9a-zA-Z_$-]"},kb=function(a,b){return a+b.join("")},lb={type:"other",description:"array"},mb=function(a){return a.join("")},nb=function(a){return a},ob=function(a,b){return b?b.unshift(a):b=[a],b},pb={type:"other",description:"array_part"},qb=function(a){return a},rb=function(a,b){return b?a.concat(b):a},sb={type:"other",description:"inline"},tb='"',ub={type:"literal",value:'"',description:'"\\""'},vb=function(){return U(["literal",""])},wb=function(a){return U(["literal",a])},xb=function(a){return U(["body"].concat(a))},yb=function(a){return["buffer",a]},zb={type:"other",description:"buffer"},Ab=function(a,b){return U(["format",a,b.join("")])},Bb={type:"any",description:"any character"},Cb=function(a){return a},Db=function(a){return U(["buffer",a.join("")])},Eb={type:"other",description:"literal"},Fb=/^[^"]/,Gb={type:"class",value:'[^"]',description:'[^"]'},Hb=function(a){return a.join("")},Ib='\\"',Jb={type:"literal",value:'\\"',description:'"\\\\\\""'},Kb=function(){return'"'},Lb={type:"other",description:"raw"},Mb="{`",Nb={type:"literal",value:"{`",description:'"{`"'},Ob="`}",Pb={type:"literal",value:"`}",description:'"`}"'
+},Qb=function(a){return a},Rb=function(a){return U(["raw",a.join("")])},Sb={type:"other",description:"comment"},Tb="{!",Ub={type:"literal",value:"{!",description:'"{!"'},Vb="!}",Wb={type:"literal",value:"!}",description:'"!}"'},Xb=function(a){return U(["comment",a.join("")])},Yb=/^[#?\^><+%:@\/~%]/,Zb={type:"class",value:"[#?^><+%:@/~%]",description:"[#?^><+%:@/~%]"},$b="{",_b={type:"literal",value:"{",description:'"{"'},ac="}",bc={type:"literal",value:"}",description:'"}"'},cc="[",dc={type:"literal",value:"[",description:'"["'},ec="]",fc={type:"literal",value:"]",description:'"]"'},gc="\n",hc={type:"literal",value:"\n",description:'"\\n"'},ic="\r\n",jc={type:"literal",value:"\r\n",description:'"\\r\\n"'},kc="\r",lc={type:"literal",value:"\r",description:'"\\r"'},mc="\u2028",nc={type:"literal",value:"\u2028",description:'"\\u2028"'},oc="\u2029",pc={type:"literal",value:"\u2029",description:'"\\u2029"'},qc=/^[\t\x0B\f \xA0\uFEFF]/,rc={type:"class",value:"[\\t\\v\\f \\u00A0\\uFEFF]",description:"[\\t\\v\\f \\u00A0\\uFEFF]"},sc=0,tc=0,uc=[{line:1,column:1,seenCR:!1}],vc=0,wc=[],xc=0;if("startRule"in W){if(!(W.startRule in Y))throw new Error("Can't start parsing from rule \""+W.startRule+'".');Z=Y[W.startRule]}if(V=Z(),V!==X&&sc===a.length)return V;throw V!==X&&sc<a.length&&g({type:"end",description:"end of input"}),h(null,wc,vc<a.length?a.charAt(vc):null,vc<a.length?f(vc,vc+1):f(vc,vc))}return a(b,Error),{SyntaxError:b,parse:c}}();return dust.parse=a.parse,a}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.compile",["dust.core","dust.parse"],function(dust,a){return b(a,dust).compile}):"object"==typeof exports?module.exports=b(require("./parser").parse,require("./dust")):b(a.dust.parse,a.dust)}(this,function(a,dust){function b(a){var b={};return r.filterNode(b,a)}function c(a,b){var c,d,e,f=[b[0]];for(c=1,d=b.length;c<d;c++)e=r.filterNode(a,b[c]),e&&f.push(e);return f}function d(a,b){var c,d,e,f,g=[b[0]];for(d=1,e=b.length;d<e;d++)f=r.filterNode(a,b[d]),f&&("buffer"===f[0]||"format"===f[0]?c?(c[0]="buffer"===f[0]?"buffer":c[0],c[1]+=f.slice(1).join("")):(c=f,g.push(f)):(c=null,g.push(f)));return g}function e(a,b){return["buffer",u[b[1]],b[2],b[3]]}function f(a,b){return b}function g(){}function h(a,b){return dust.config.whitespace?(b.splice(1,2,b.slice(1).join("")),b):null}function i(a,b){var c,d={name:b,bodies:[],blocks:{},index:0,auto:"h"},e=dust.escapeJs(b),f=b?'"'+e+'",':"",g="function(dust){",h=r.compileNode(d,a);return b&&(g+='dust.register("'+e+'",'+h+");"),g+=j(d)+k(d)+"return "+h+"}",c="("+g+"(dust));",dust.config.amd?"define("+f+'["dust.core"],'+g+");":dust.config.cjs?"module.exports=function(dust){var tmpl="+c+"var f="+q().toString()+";f.template=tmpl;return f}":c}function j(a){var b,c=[],d=a.blocks;for(b in d)Object.prototype.hasOwnProperty.call(d,b)&&c.push('"'+b+'":'+d[b]);return c.length?(a.blocks="ctx=ctx.shiftBlocks(blocks);","var blocks={"+c.join(",")+"};"):(a.blocks="",a.blocks)}function k(a){var b,c,d=[],e=a.bodies,f=a.blocks;for(b=0,c=e.length;b<c;b++)d[b]="function body_"+b+"(chk,ctx){"+f+"return chk"+e[b]+";}body_"+b+".__dustBody=!0;";return d.join("")}function l(a,b){var c,d,e="";for(c=1,d=b.length;c<d;c++)e+=r.compileNode(a,b[c]);return e}function m(a,b,c){return"."+(dust._aliases[c]||c)+"("+r.compileNode(a,b[1])+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"}function n(a){return a.replace(v,"\\\\").replace(w,'\\"').replace(x,"\\f").replace(y,"\\n").replace(z,"\\r").replace(A,"\\t")}function o(a,b,c){var d=dust.loadSource(dust.compile(a));return q(d)(b,c)}function p(a,b){var c=dust.loadSource(dust.compile(a,b));return q(c)}function q(a){return function(b,c){var d=c?"render":"stream";return dust[d](a,b,c)}}var r={},s=dust.isArray,t="undefined"==typeof JSON?function(a){return'"'+n(a)+'"'}:JSON.stringify;r.compile=function(c,d){try{var e=b(a(c));return i(e,d)}catch(f){if(!f.location)throw f;throw new SyntaxError(f.message+" ["+d+":"+f.location.start.line+":"+f.location.start.column+"]")}},r.filterNode=function(a,b){return r.optimizers[b[0]](a,b)},r.optimizers={body:d,buffer:f,special:e,format:h,reference:c,"#":c,"?":c,"^":c,"<":c,"+":c,"@":c,"%":c,partial:c,context:c,params:c,bodies:c,param:c,filters:f,key:f,path:f,literal:f,raw:f,comment:g},r.pragmas={esc:function(a,b,c){var d,e=a.auto;return b||(b="h"),a.auto="s"===b?"":b,d=l(a,c.block),a.auto=e,d}};var u={s:" ",n:"\n",r:"\r",lb:"{",rb:"}"};r.compileNode=function(a,b){return r.nodes[b[0]](a,b)},r.nodes={body:function(a,b){var c=a.index++,d="body_"+c;return a.bodies[c]=l(a,b),d},buffer:function(a,b){return".w("+t(b[1])+")"},format:function(a,b){return".w("+t(b[1])+")"},reference:function(a,b){return".f("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+")"},"#":function(a,b){return m(a,b,"section")},"?":function(a,b){return m(a,b,"exists")},"^":function(a,b){return m(a,b,"notexists")},"<":function(a,b){for(var c=b[4],d=1,e=c.length;d<e;d++){var f=c[d],g=f[1][1];if("block"===g)return a.blocks[b[1].text]=r.compileNode(a,f[2]),""}return""},"+":function(a,b){return"undefined"==typeof b[1].text&&"undefined"==typeof b[4]?".b(ctx.getBlock("+r.compileNode(a,b[1])+",chk, ctx),"+r.compileNode(a,b[2])+", {},"+r.compileNode(a,b[3])+")":".b(ctx.getBlock("+t(b[1].text)+"),"+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"},"@":function(a,b){return".h("+t(b[1].text)+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+","+r.compileNode(a,b[5])+")"},"%":function(a,b){var c,d,e,f,g,h,i,j,k,l=b[1][1];if(!r.pragmas[l])return"";for(c=b[4],d={},j=1,k=c.length;j<k;j++)h=c[j],d[h[1][1]]=h[2];for(e=b[3],f={},j=1,k=e.length;j<k;j++)i=e[j],f[i[1][1]]=i[2][1];return g=b[2][1]?b[2][1].text:null,r.pragmas[l](a,g,d,f)},partial:function(a,b){return".p("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+","+r.compileNode(a,b[3])+")"},context:function(a,b){return b[1]?"ctx.rebase("+r.compileNode(a,b[1])+")":"ctx"},params:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++)c.push(r.compileNode(a,b[d]));return c.length?"{"+c.join(",")+"}":"{}"},bodies:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++)c.push(r.compileNode(a,b[d]));return"{"+c.join(",")+"}"},param:function(a,b){return r.compileNode(a,b[1])+":"+r.compileNode(a,b[2])},filters:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++){var f=b[d];c.push('"'+f+'"')}return'"'+a.auto+'"'+(c.length?",["+c.join(",")+"]":"")},key:function(a,b){return'ctx.get(["'+b[1]+'"], false)'},path:function(a,b){for(var c=b[1],d=b[2],e=[],f=0,g=d.length;f<g;f++)s(d[f])?e.push(r.compileNode(a,d[f])):e.push('"'+d[f]+'"');return"ctx.getPath("+c+", ["+e.join(",")+"])"},literal:function(a,b){return t(b[1])},raw:function(a,b){return".w("+t(b[1])+")"}};var v=/\\/g,w=/"/g,x=/\f/g,y=/\n/g,z=/\r/g,A=/\t/g;return dust.compiler=r,dust.compile=dust.compiler.compile,dust.renderSource=o,dust.compileFn=p,dust.filterNode=r.filterNode,dust.optimizers=r.optimizers,dust.pragmas=r.pragmas,dust.compileNode=r.compileNode,dust.nodes=r.nodes,r}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core","dust.compile"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(a){b(null,a)})},dust});
\ No newline at end of file
diff --git a/lib/compiler.js b/lib/compiler.js
index 15dc825..f2fa6a3 100644
--- a/lib/compiler.js
+++ b/lib/compiler.js
@@ -190,11 +190,13 @@
     var out = [],
         blocks = context.blocks,
         name;
 
     for (name in blocks) {
-      out.push('"' + name + '":' + blocks[name]);
+      if (Object.prototype.hasOwnProperty.call(blocks, name)) {
+        out.push('"' + name + '":' + blocks[name]);
+      }
     }
     if (out.length) {
       context.blocks = 'ctx=ctx.shiftBlocks(blocks);';
       return 'var blocks={' + out.join(',') + '};';
     } else {
diff --git a/package.json b/package.json
index 10d4e18..db1dec2 100644
--- a/package.json
+++ b/package.json
@@ -42,24 +42,24 @@
     "chokidar": "~1.5.1",
     "cli": "^1.0.1"
   },
   "devDependencies": {
     "ayepromise": "~1.1.1",
-    "grunt": "~1.0.1",
+    "grunt": "~1.4.1",
     "grunt-bump": "~0.8.0",
-    "grunt-cli": "~1.2.0",
-    "grunt-contrib-clean": "~1.0.0",
+    "grunt-cli": "~1.4.3",
+    "grunt-contrib-clean": "~2.0.0",
     "grunt-contrib-concat": "~1.0.1",
-    "grunt-contrib-connect": "~1.0.2",
+    "grunt-contrib-connect": "~3.0.0",
     "grunt-contrib-copy": "~1.0.0",
-    "grunt-contrib-jasmine": "~1.0.3",
-    "grunt-contrib-jshint": "~1.0.0",
+    "grunt-contrib-jasmine": "~1.2.0",
+    "grunt-contrib-jshint": "~3.0.0",
     "grunt-contrib-uglify": "~1.0.1",
-    "grunt-contrib-watch": "~1.0.0",
+    "grunt-contrib-watch": "~1.1.0",
     "grunt-execute": "~0.2.2",
     "grunt-github-changes": "~0.1.0",
-    "grunt-jasmine-nodejs": "~1.5.3",
+    "grunt-jasmine-nodejs": "~1.6.1",
     "grunt-peg": "~2.0.0",
     "grunt-saucelabs": "~8.6.1",
     "grunt-shell": "~1.3.0",
     "grunt-template-jasmine-istanbul": "~0.4.0",
     "highland": "2.8.1",
diff --git a/test/core.spec.js b/test/core.spec.js
index fcfaa3c..532dba0 100644
--- a/test/core.spec.js
+++ b/test/core.spec.js
@@ -80,11 +80,11 @@
       var context = extend({}, base);
       renderIt('survives having its prototype destroyed', '{sayHello} {foo}', context, 'Hello! bar');
     });
   });
 
-  it("valid keys", function() {
+  describe("valid keys", function() {
     renderIt("Renders all valid keys", "{_foo}{$bar}{baz1}", {_foo: 1, $bar: 2, baz1: 3}, "123");
   });
 
   describe('dust.onLoad', function() {
     beforeEach(function() {
@@ -230,6 +230,20 @@
         done();
       });
     });
   });
 
+  describe('vulnerabilities', function() {
+    it('has no prototype pollution vulnerability', function() {
+      const malicious = `this.constructor.constructor('return process')().mainModule.require('child_process').execSync('curl 127.0.0.1')`;
+      Object.prototype.MAL_CODE= [ malicious ];
+      const compiled = dust.compile('{username} is an important person.{~n}');
+      const tmpl = dust.loadSource(compiled);
+      dust.render(tmpl, { username: 'Jane Doe' }, (err, output) => {
+        delete Object.prototype.MAL_CODE;
+        expect(err).toBe(null);
+        expect(output).toEqual('Jane Doe is an important person.\n');
+      });
+    });
+  });
+
 }));

Vulnerable code:   - "0.12"
  - "5"
  - "6"
    - node_js: "0.10"
  - npm install -g npm@3
* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
   * Decide somewhat-naively if something is a Thenable.
    return elem &&
           typeof elem === 'object' &&
    if (context instanceof Context) {
    if (typeof ctx === 'function') {
    if (typeof elem === 'function') {
    if (typeof elem === 'function' && !dust.isTemplateFn(elem)) {
        partialContext.templateName = name;
      partialContext.templateName = elem;
    return this.map(function(chunk) {
      thenable.then(function(data) {
        if (bodies) {
          chunk = chunk.section(data, context, bodies);
        } else {
          // Actually a reference. Self-closing sections don't render
          chunk = chunk.reference(data, context, auto, filters);
        }
        chunk.end();
      }, function(err) {
        var errorBody = bodies && bodies.error;
        if(errorBody) {
          chunk.render(errorBody, context.push(err)).end();
        } else {
          dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
          chunk.end();
        }
      });
    var body = bodies && bodies.block,
        errorBody = bodies && bodies.error;
          if(errorBody) {
            chunk.render(errorBody, context.push(err));
          } else {
            dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
          }
            require([name], function() {
                cb();
* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){return a?"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&b("[DUST:"+d+"]",a)},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},dust.isArray=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0===a?!1:dust.isArray(a)&&!a.length?!0:!a},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&"object"==typeof a&&"function"==typeof a.then},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;f>e;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context(void 0,a,b)},Context.wrap=function(a,b){return a instanceof Context?a:new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&e>i;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return"function"==typeof h?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;d>c;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return this.taps=b?b.push(a):new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return"function"==typeof a?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if("function"==typeof a&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;f>e;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){c.templateName=a,load(a,b,c).end()}):(c.templateName=a,load(a,this,c))},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return this.map(function(f){a.then(function(a){f=c?f.section(a,b,c):f.reference(a,b,d,e),f.end()},function(a){var d=c&&c.error;d?f.render(d,b.push(a)).end():(dust.log("Unhandled promise rejection in `"+b.getTemplateName()+"`",INFO),f.end())})})},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block,g=c&&c.error;return this.map(function(h){var i=!1;a.on("data",function(a){i||(f?h=h.map(function(c){c.render(f,b.push(a)).end()}):c||(h=h.reference(a,b,d,e)))}).on("error",function(a){i||(g?h.render(g,b.push(a)):dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),i||(i=!0,h.end()))}).on("end",function(){i||(i=!0,h.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(){b()})},dust});
* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
   * Decide somewhat-naively if something is a Thenable.
    return elem &&
           typeof elem === 'object' &&
    if (context instanceof Context) {
    if (typeof ctx === 'function') {
    if (typeof elem === 'function') {
    if (typeof elem === 'function' && !dust.isTemplateFn(elem)) {
        partialContext.templateName = name;
      partialContext.templateName = elem;
    return this.map(function(chunk) {
      thenable.then(function(data) {
        if (bodies) {
          chunk = chunk.section(data, context, bodies);
        } else {
          // Actually a reference. Self-closing sections don't render
          chunk = chunk.reference(data, context, auto, filters);
        }
        chunk.end();
      }, function(err) {
        var errorBody = bodies && bodies.error;
        if(errorBody) {
          chunk.render(errorBody, context.push(err)).end();
        } else {
          dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
          chunk.end();
        }
      });
    var body = bodies && bodies.block,
        errorBody = bodies && bodies.error;
          if(errorBody) {
            chunk.render(errorBody, context.push(err));
          } else {
            dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
          }
   * Generated by PEG.js 0.8.0.
   * http://pegjs.majda.cz/
  function SyntaxError(message, expected, found, offset, line, column) {
    this.offset   = offset;
    this.line     = line;
    this.column   = column;

  peg$subclass(SyntaxError, Error);
  function parse(input) {
        peg$c0 = [],
        peg$c1 = function(p) {
        peg$c2 = { type: "other", description: "section" },
        peg$c3 = peg$FAILED,
        peg$c4 = null,
        peg$c5 = function(t, b, e, n) {
        peg$c6 = void 0,
        peg$c7 = function(t, b, e, n) {
        peg$c8 = "/",
        peg$c9 = { type: "literal", value: "/", description: "\"/\"" },
        peg$c10 = function(t) {
        peg$c11 = /^[#?\^<+@%]/,
        peg$c12 = { type: "class", value: "[#?\\^<+@%]", description: "[#?\\^<+@%]" },
        peg$c13 = function(t, n, c, p) { return [t, n, c, p] },
        peg$c14 = { type: "other", description: "end tag" },
        peg$c15 = function(n) { return n },
        peg$c16 = ":",
        peg$c17 = { type: "literal", value: ":", description: "\":\"" },
        peg$c18 = function(n) {return n},
        peg$c19 = function(n) { return n ? ["context", n] : ["context"] },
        peg$c20 = { type: "other", description: "params" },
        peg$c21 = "=",
        peg$c22 = { type: "literal", value: "=", description: "\"=\"" },
        peg$c23 = function(k, v) {return ["param", ["literal", k], v]},
        peg$c24 = function(p) { return ["params"].concat(p) },
        peg$c25 = { type: "other", description: "bodies" },
        peg$c26 = function(p) { return ["bodies"].concat(p) },
        peg$c27 = { type: "other", description: "reference" },
        peg$c28 = function(n, f) { return withPosition(["reference", n, f]) },
        peg$c29 = { type: "other", description: "partial" },
        peg$c30 = ">",
        peg$c31 = { type: "literal", value: ">", description: "\">\"" },
        peg$c32 = "+",
        peg$c33 = { type: "literal", value: "+", description: "\"+\"" },
        peg$c34 = function(k) {return ["literal", k]},
        peg$c35 = function(s, n, c, p) {
        peg$c36 = { type: "other", description: "filters" },
        peg$c37 = "|",
        peg$c38 = { type: "literal", value: "|", description: "\"|\"" },
        peg$c39 = function(f) { return ["filters"].concat(f) },
        peg$c40 = { type: "other", description: "special" },
        peg$c41 = "~",
        peg$c42 = { type: "literal", value: "~", description: "\"~\"" },
        peg$c43 = function(k) { return withPosition(["special", k]) },
        peg$c44 = { type: "other", description: "identifier" },
        peg$c45 = function(p) {
            arr.text = p[1].join('.').replace(/,line,\d+,col,\d+/g,'');
        peg$c46 = function(k) {
        peg$c47 = { type: "other", description: "number" },
        peg$c48 = function(n) { return ['literal', n]; },
        peg$c49 = { type: "other", description: "float" },
        peg$c50 = ".",
        peg$c51 = { type: "literal", value: ".", description: "\".\"" },
        peg$c52 = function(l, r) { return parseFloat(l + "." + r); },
        peg$c53 = { type: "other", description: "unsigned_integer" },
        peg$c54 = /^[0-9]/,
        peg$c55 = { type: "class", value: "[0-9]", description: "[0-9]" },
        peg$c56 = function(digits) { return makeInteger(digits); },
        peg$c57 = { type: "other", description: "signed_integer" },
        peg$c58 = "-",
        peg$c59 = { type: "literal", value: "-", description: "\"-\"" },
        peg$c60 = function(sign, n) { return n * -1; },
        peg$c61 = { type: "other", description: "integer" },
        peg$c62 = { type: "other", description: "path" },
        peg$c63 = function(k, d) {
        peg$c64 = function(d) {
        peg$c65 = { type: "other", description: "key" },
        peg$c66 = /^[a-zA-Z_$]/,
        peg$c67 = { type: "class", value: "[a-zA-Z_$]", description: "[a-zA-Z_$]" },
        peg$c68 = /^[0-9a-zA-Z_$\-]/,
        peg$c69 = { type: "class", value: "[0-9a-zA-Z_$\\-]", description: "[0-9a-zA-Z_$\\-]" },
        peg$c70 = function(h, t) { return h + t.join('') },
        peg$c71 = { type: "other", description: "array" },
        peg$c72 = function(n) {return n.join('')},
        peg$c73 = function(a) {return a; },
        peg$c74 = function(i, nk) { if(nk) { nk.unshift(i); } else {nk = [i] } return nk; },
        peg$c75 = { type: "other", description: "array_part" },
        peg$c76 = function(k) {return k},
        peg$c77 = function(d, a) { if (a) { return d.concat(a); } else { return d; } },
        peg$c78 = { type: "other", description: "inline" },
        peg$c79 = "\"",
        peg$c80 = { type: "literal", value: "\"", description: "\"\\\"\"" },
        peg$c81 = function() { return withPosition(["literal", ""]) },
        peg$c82 = function(l) { return withPosition(["literal", l]) },
        peg$c83 = function(p) { return withPosition(["body"].concat(p)) },
        peg$c84 = function(l) { return ["buffer", l] },
        peg$c85 = { type: "other", description: "buffer" },
        peg$c86 = function(e, w) { return withPosition(["format", e, w.join('')]) },
        peg$c87 = { type: "any", description: "any character" },
        peg$c88 = function(c) {return c},
        peg$c89 = function(b) { return withPosition(["buffer", b.join('')]) },
        peg$c90 = { type: "other", description: "literal" },
        peg$c91 = /^[^"]/,
        peg$c92 = { type: "class", value: "[^\"]", description: "[^\"]" },
        peg$c93 = function(b) { return b.join('') },
        peg$c94 = "\\\"",
        peg$c95 = { type: "literal", value: "\\\"", description: "\"\\\\\\\"\"" },
        peg$c96 = function() { return '"' },
        peg$c97 = { type: "other", description: "raw" },
        peg$c98 = "{`",
        peg$c99 = { type: "literal", value: "{`", description: "\"{`\"" },
        peg$c100 = "`}",
        peg$c101 = { type: "literal", value: "`}", description: "\"`}\"" },
        peg$c102 = function(character) {return character},
        peg$c103 = function(rawText) { return withPosition(["raw", rawText.join('')]) },
        peg$c104 = { type: "other", description: "comment" },
        peg$c105 = "{!",
        peg$c106 = { type: "literal", value: "{!", description: "\"{!\"" },
        peg$c107 = "!}",
        peg$c108 = { type: "literal", value: "!}", description: "\"!}\"" },
        peg$c109 = function(c) { return withPosition(["comment", c.join('')]) },
        peg$c110 = /^[#?\^><+%:@\/~%]/,
        peg$c111 = { type: "class", value: "[#?\\^><+%:@\\/~%]", description: "[#?\\^><+%:@\\/~%]" },
        peg$c112 = "{",
        peg$c113 = { type: "literal", value: "{", description: "\"{\"" },
        peg$c114 = "}",
        peg$c115 = { type: "literal", value: "}", description: "\"}\"" },
        peg$c116 = "[",
        peg$c117 = { type: "literal", value: "[", description: "\"[\"" },
        peg$c118 = "]",
        peg$c119 = { type: "literal", value: "]", description: "\"]\"" },
        peg$c120 = "\n",
        peg$c121 = { type: "literal", value: "\n", description: "\"\\n\"" },
        peg$c122 = "\r\n",
        peg$c123 = { type: "literal", value: "\r\n", description: "\"\\r\\n\"" },
        peg$c124 = "\r",
        peg$c125 = { type: "literal", value: "\r", description: "\"\\r\"" },
        peg$c126 = "\u2028",
        peg$c127 = { type: "literal", value: "\u2028", description: "\"\\u2028\"" },
        peg$c128 = "\u2029",
        peg$c129 = { type: "literal", value: "\u2029", description: "\"\\u2029\"" },
        peg$c130 = /^[\t\x0B\f \xA0\uFEFF]/,
        peg$c131 = { type: "class", value: "[\\t\\x0B\\f \\xA0\\uFEFF]", description: "[\\t\\x0B\\f \\xA0\\uFEFF]" },
        peg$reportedPos      = 0,
        peg$cachedPos        = 0,
        peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
      return input.substring(peg$reportedPos, peg$currPos);
    }

    function offset() {
      return peg$reportedPos;
    }

    function line() {
      return peg$computePosDetails(peg$reportedPos).line;
    function column() {
      return peg$computePosDetails(peg$reportedPos).column;
        peg$reportedPos
      throw peg$buildException(message, null, peg$reportedPos);
      function advance(details, startPos, endPos) {
        var p, ch;
        for (p = startPos; p < endPos; p++) {
        }
      }
      if (peg$cachedPos !== pos) {
        if (peg$cachedPos > pos) {
          peg$cachedPos = 0;
          peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
        advance(peg$cachedPosDetails, peg$cachedPos, pos);
        peg$cachedPos = pos;
      return peg$cachedPosDetails;
    function peg$buildException(message, expected, pos) {
            .replace(/[\u0180-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
            .replace(/[\u1080-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
      var posDetails = peg$computePosDetails(pos),
          found      = pos < input.length ? input.charAt(pos) : null;

      return new SyntaxError(
        pos,
        posDetails.line,
        posDetails.column
        peg$reportedPos = s0;
        s1 = peg$c1(s1);
                  s6 = peg$c4;
                  peg$reportedPos = peg$currPos;
                  s7 = peg$c5(s1, s4, s5, s6);
                    s7 = peg$c6;
                    s7 = peg$c3;
                    peg$reportedPos = s0;
                    s1 = peg$c7(s1, s4, s5, s6);
                    s0 = peg$c3;
                  s0 = peg$c3;
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
              s3 = peg$c8;
              if (peg$silentFails === 0) { peg$fail(peg$c9); }
                peg$reportedPos = s0;
                s1 = peg$c10(s1);
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c2); }
        if (peg$c11.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c12); }
                  peg$reportedPos = s0;
                  s1 = peg$c13(s2, s4, s5, s6);
                  s0 = peg$c3;
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
          s2 = peg$c8;
          if (peg$silentFails === 0) { peg$fail(peg$c9); }
                  peg$reportedPos = s0;
                  s1 = peg$c15(s4);
                  s0 = peg$c3;
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c14); }
        s2 = peg$c16;
        if (peg$silentFails === 0) { peg$fail(peg$c17); }
          peg$reportedPos = s1;
          s2 = peg$c18(s3);
          s1 = peg$c3;
        s1 = peg$c3;
        s1 = peg$c4;
        peg$reportedPos = s0;
        s1 = peg$c19(s1);
        s3 = peg$c3;
            s5 = peg$c21;
            if (peg$silentFails === 0) { peg$fail(peg$c22); }
              peg$reportedPos = s2;
              s3 = peg$c23(s4, s6);
              s2 = peg$c3;
            s2 = peg$c3;
          s2 = peg$c3;
        s2 = peg$c3;
          s3 = peg$c3;
              s5 = peg$c21;
              if (peg$silentFails === 0) { peg$fail(peg$c22); }
                peg$reportedPos = s2;
                s3 = peg$c23(s4, s6);
                s2 = peg$c3;
              s2 = peg$c3;
            s2 = peg$c3;
          s2 = peg$c3;
        peg$reportedPos = s0;
        s1 = peg$c24(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c20); }
          s4 = peg$c16;
          if (peg$silentFails === 0) { peg$fail(peg$c17); }
                peg$reportedPos = s2;
                s3 = peg$c23(s5, s7);
                s2 = peg$c3;
              s2 = peg$c3;
            s2 = peg$c3;
          s2 = peg$c3;
        s2 = peg$c3;
            s4 = peg$c16;
            if (peg$silentFails === 0) { peg$fail(peg$c17); }
                  peg$reportedPos = s2;
                  s3 = peg$c23(s5, s7);
                  s2 = peg$c3;
                s2 = peg$c3;
              s2 = peg$c3;
            s2 = peg$c3;
          s2 = peg$c3;
        peg$reportedPos = s0;
        s1 = peg$c26(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c25); }
              peg$reportedPos = s0;
              s1 = peg$c28(s2, s3);
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c27); }
          s2 = peg$c30;
          if (peg$silentFails === 0) { peg$fail(peg$c31); }
            s2 = peg$c32;
            if (peg$silentFails === 0) { peg$fail(peg$c33); }
              peg$reportedPos = s4;
              s5 = peg$c34(s5);
                      s8 = peg$c8;
                      if (peg$silentFails === 0) { peg$fail(peg$c9); }
                        peg$reportedPos = s0;
                        s1 = peg$c35(s2, s4, s5, s6);
                        s0 = peg$c3;
                      s0 = peg$c3;
                    s0 = peg$c3;
                  s0 = peg$c3;
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c29); }
        s3 = peg$c37;
        if (peg$silentFails === 0) { peg$fail(peg$c38); }
          peg$reportedPos = s2;
          s3 = peg$c18(s4);
          s2 = peg$c3;
        s2 = peg$c3;
          s3 = peg$c37;
          if (peg$silentFails === 0) { peg$fail(peg$c38); }
            peg$reportedPos = s2;
            s3 = peg$c18(s4);
            s2 = peg$c3;
          s2 = peg$c3;
        peg$reportedPos = s0;
        s1 = peg$c39(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c36); }
          s2 = peg$c41;
          if (peg$silentFails === 0) { peg$fail(peg$c42); }
              peg$reportedPos = s0;
              s1 = peg$c43(s3);
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c40); }
        peg$reportedPos = s0;
        s1 = peg$c45(s1);
          peg$reportedPos = s0;
          s1 = peg$c46(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c44); }
        peg$reportedPos = s0;
        s1 = peg$c48(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c47); }
          s2 = peg$c50;
          if (peg$silentFails === 0) { peg$fail(peg$c51); }
            peg$reportedPos = s0;
            s1 = peg$c52(s1, s3);
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c49); }
      if (peg$c54.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c55); }
          if (peg$c54.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c55); }
        s1 = peg$c3;
        peg$reportedPos = s0;
        s1 = peg$c56(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c53); }
        s1 = peg$c58;
        if (peg$silentFails === 0) { peg$fail(peg$c59); }
          peg$reportedPos = s0;
          s1 = peg$c60(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c57); }
        if (peg$silentFails === 0) { peg$fail(peg$c61); }
        s1 = peg$c4;
          s2 = peg$c3;
          peg$reportedPos = s0;
          s1 = peg$c63(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
          s1 = peg$c50;
          if (peg$silentFails === 0) { peg$fail(peg$c51); }
            peg$reportedPos = s0;
            s1 = peg$c64(s2);
            s0 = peg$c3;
          s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c62); }
      if (peg$c66.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c67); }
        if (peg$c68.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c69); }
          if (peg$c68.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c69); }
          peg$reportedPos = s0;
          s1 = peg$c70(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c65); }
        if (peg$c54.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c55); }
            if (peg$c54.test(input.charAt(peg$currPos))) {
              if (peg$silentFails === 0) { peg$fail(peg$c55); }
          s4 = peg$c3;
          peg$reportedPos = s3;
          s4 = peg$c72(s4);
            peg$reportedPos = s1;
            s2 = peg$c73(s3);
            s1 = peg$c3;
          s1 = peg$c3;
        s1 = peg$c3;
          s2 = peg$c4;
          peg$reportedPos = s0;
          s1 = peg$c74(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c71); }
        s3 = peg$c50;
        if (peg$silentFails === 0) { peg$fail(peg$c51); }
          peg$reportedPos = s2;
          s3 = peg$c76(s4);
          s2 = peg$c3;
        s2 = peg$c3;
            s3 = peg$c50;
            if (peg$silentFails === 0) { peg$fail(peg$c51); }
              peg$reportedPos = s2;
              s3 = peg$c76(s4);
              s2 = peg$c3;
            s2 = peg$c3;
        s1 = peg$c3;
          s2 = peg$c4;
          peg$reportedPos = s0;
          s1 = peg$c77(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c75); }
        s1 = peg$c79;
        if (peg$silentFails === 0) { peg$fail(peg$c80); }
          s2 = peg$c79;
          if (peg$silentFails === 0) { peg$fail(peg$c80); }
          peg$reportedPos = s0;
          s1 = peg$c81();
          s0 = peg$c3;
        s0 = peg$c3;
          s1 = peg$c79;
          if (peg$silentFails === 0) { peg$fail(peg$c80); }
              s3 = peg$c79;
              if (peg$silentFails === 0) { peg$fail(peg$c80); }
              peg$reportedPos = s0;
              s1 = peg$c82(s2);
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
            s1 = peg$c79;
            if (peg$silentFails === 0) { peg$fail(peg$c80); }
              s2 = peg$c3;
                s3 = peg$c79;
                if (peg$silentFails === 0) { peg$fail(peg$c80); }
                peg$reportedPos = s0;
                s1 = peg$c83(s2);
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c78); }
            peg$reportedPos = s0;
            s1 = peg$c84(s1);
          peg$reportedPos = s0;
          s1 = peg$c86(s1, s2);
          s0 = peg$c3;
        s0 = peg$c3;
          s3 = peg$c6;
          s3 = peg$c3;
            s4 = peg$c6;
            s4 = peg$c3;
              s5 = peg$c6;
              s5 = peg$c3;
                s6 = peg$c6;
                s6 = peg$c3;
                  if (peg$silentFails === 0) { peg$fail(peg$c87); }
                  peg$reportedPos = s2;
                  s3 = peg$c88(s7);
                  s2 = peg$c3;
                s2 = peg$c3;
              s2 = peg$c3;
            s2 = peg$c3;
          s2 = peg$c3;
              s3 = peg$c6;
              s3 = peg$c3;
                s4 = peg$c6;
                s4 = peg$c3;
                  s5 = peg$c6;
                  s5 = peg$c3;
                    s6 = peg$c6;
                    s6 = peg$c3;
                      if (peg$silentFails === 0) { peg$fail(peg$c87); }
                      peg$reportedPos = s2;
                      s3 = peg$c88(s7);
                      s2 = peg$c3;
                    s2 = peg$c3;
                  s2 = peg$c3;
                s2 = peg$c3;
              s2 = peg$c3;
          s1 = peg$c3;
          peg$reportedPos = s0;
          s1 = peg$c89(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c85); }
        s3 = peg$c6;
        s3 = peg$c3;
          if (peg$c91.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c92); }
          peg$reportedPos = s2;
          s3 = peg$c88(s4);
          s2 = peg$c3;
        s2 = peg$c3;
            s3 = peg$c6;
            s3 = peg$c3;
              if (peg$c91.test(input.charAt(peg$currPos))) {
                if (peg$silentFails === 0) { peg$fail(peg$c92); }
              peg$reportedPos = s2;
              s3 = peg$c88(s4);
              s2 = peg$c3;
            s2 = peg$c3;
        s1 = peg$c3;
        peg$reportedPos = s0;
        s1 = peg$c93(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c90); }
      if (input.substr(peg$currPos, 2) === peg$c94) {
        s1 = peg$c94;
        if (peg$silentFails === 0) { peg$fail(peg$c95); }
        peg$reportedPos = s0;
        s1 = peg$c96();
      if (input.substr(peg$currPos, 2) === peg$c98) {
        s1 = peg$c98;
        if (peg$silentFails === 0) { peg$fail(peg$c99); }
        if (input.substr(peg$currPos, 2) === peg$c100) {
          s5 = peg$c100;
          if (peg$silentFails === 0) { peg$fail(peg$c101); }
          s4 = peg$c6;
          s4 = peg$c3;
            if (peg$silentFails === 0) { peg$fail(peg$c87); }
            peg$reportedPos = s3;
            s4 = peg$c102(s5);
            s3 = peg$c3;
          s3 = peg$c3;
          if (input.substr(peg$currPos, 2) === peg$c100) {
            s5 = peg$c100;
            if (peg$silentFails === 0) { peg$fail(peg$c101); }
            s4 = peg$c6;
            s4 = peg$c3;
              if (peg$silentFails === 0) { peg$fail(peg$c87); }
              peg$reportedPos = s3;
              s4 = peg$c102(s5);
              s3 = peg$c3;
            s3 = peg$c3;
          if (input.substr(peg$currPos, 2) === peg$c100) {
            s3 = peg$c100;
            if (peg$silentFails === 0) { peg$fail(peg$c101); }
            peg$reportedPos = s0;
            s1 = peg$c103(s2);
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c97); }
      if (input.substr(peg$currPos, 2) === peg$c105) {
        s1 = peg$c105;
        if (peg$silentFails === 0) { peg$fail(peg$c106); }
        if (input.substr(peg$currPos, 2) === peg$c107) {
          s5 = peg$c107;
          if (peg$silentFails === 0) { peg$fail(peg$c108); }
          s4 = peg$c6;
          s4 = peg$c3;
            if (peg$silentFails === 0) { peg$fail(peg$c87); }
            peg$reportedPos = s3;
            s4 = peg$c88(s5);
            s3 = peg$c3;
          s3 = peg$c3;
          if (input.substr(peg$currPos, 2) === peg$c107) {
            s5 = peg$c107;
            if (peg$silentFails === 0) { peg$fail(peg$c108); }
            s4 = peg$c6;
            s4 = peg$c3;
              if (peg$silentFails === 0) { peg$fail(peg$c87); }
              peg$reportedPos = s3;
              s4 = peg$c88(s5);
              s3 = peg$c3;
            s3 = peg$c3;
          if (input.substr(peg$currPos, 2) === peg$c107) {
            s3 = peg$c107;
            if (peg$silentFails === 0) { peg$fail(peg$c108); }
            peg$reportedPos = s0;
            s1 = peg$c109(s2);
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        if (peg$silentFails === 0) { peg$fail(peg$c104); }
          if (peg$c110.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c111); }
                s7 = peg$c6;
                s7 = peg$c3;
                  s8 = peg$c6;
                  s8 = peg$c3;
                    if (peg$silentFails === 0) { peg$fail(peg$c87); }
                    s6 = peg$c3;
                  s6 = peg$c3;
                s6 = peg$c3;
                    s7 = peg$c6;
                    s7 = peg$c3;
                      s8 = peg$c6;
                      s8 = peg$c3;
                        if (peg$silentFails === 0) { peg$fail(peg$c87); }
                        s6 = peg$c3;
                      s6 = peg$c3;
                    s6 = peg$c3;
                s5 = peg$c3;
                    s0 = peg$c3;
                  s0 = peg$c3;
                s0 = peg$c3;
              s0 = peg$c3;
            s0 = peg$c3;
          s0 = peg$c3;
        s0 = peg$c3;
        s0 = peg$c112;
        if (peg$silentFails === 0) { peg$fail(peg$c113); }
        s0 = peg$c114;
        if (peg$silentFails === 0) { peg$fail(peg$c115); }
        s0 = peg$c116;
        if (peg$silentFails === 0) { peg$fail(peg$c117); }
        s0 = peg$c118;
        if (peg$silentFails === 0) { peg$fail(peg$c119); }
        s0 = peg$c120;
        if (peg$silentFails === 0) { peg$fail(peg$c121); }
        if (input.substr(peg$currPos, 2) === peg$c122) {
          s0 = peg$c122;
          if (peg$silentFails === 0) { peg$fail(peg$c123); }
            s0 = peg$c124;
            if (peg$silentFails === 0) { peg$fail(peg$c125); }
              s0 = peg$c126;
              if (peg$silentFails === 0) { peg$fail(peg$c127); }
                s0 = peg$c128;
                if (peg$silentFails === 0) { peg$fail(peg$c129); }
      if (peg$c130.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c131); }
        return arr.concat([['line', line()], ['col', column()]]);
      throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
    SyntaxError: SyntaxError,
    parse:       parse
    }
    catch (err)
    {
      if (!err.line || !err.column) {
      throw new SyntaxError(err.message + ' At line : ' + err.line + ', column : ' + err.column);
    comment:   nullify,
    line:      nullify,
    col:       nullify
            memo[1] += res.slice(1, -2).join('');
      // Format nodes are in the form ['format', eol, whitespace, line, col],
      node.splice(1, 2, node.slice(1, -2).join(''));
      out.push('"' + name + '":' + blocks[name]);
  var escape = (typeof JSON === 'undefined') ?
                  function(str) { return '"' + escapeToJsSafeString(str) + '"';} :
                  JSON.stringify;

            require([name], function() {
                cb();
* Copyright (c) 2015 Aleksander Williams; Released under the MIT License */
!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){return a?"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&b("[DUST:"+d+"]",a)},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},dust.isArray=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0===a?!1:dust.isArray(a)&&!a.length?!0:!a},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&"object"==typeof a&&"function"==typeof a.then},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;f>e;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context(void 0,a,b)},Context.wrap=function(a,b){return a instanceof Context?a:new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&e>i;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return"function"==typeof h?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;d>c;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return this.taps=b?b.push(a):new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return"function"==typeof a?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if("function"==typeof a&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;f>e;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){c.templateName=a,load(a,b,c).end()}):(c.templateName=a,load(a,this,c))},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return this.map(function(f){a.then(function(a){f=c?f.section(a,b,c):f.reference(a,b,d,e),f.end()},function(a){var d=c&&c.error;d?f.render(d,b.push(a)).end():(dust.log("Unhandled promise rejection in `"+b.getTemplateName()+"`",INFO),f.end())})})},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block,g=c&&c.error;return this.map(function(h){var i=!1;a.on("data",function(a){i||(f?h=h.map(function(c){c.render(f,b.push(a)).end()}):c||(h=h.reference(a,b,d,e)))}).on("error",function(a){i||(g?h.render(g,b.push(a)):dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),i||(i=!0,h.end()))}).on("end",function(){i||(i=!0,h.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.parse",["dust.core"],function(dust){return b(dust).parse}):"object"==typeof exports?module.exports=b(require("./dust")):b(a.dust)}(this,function(dust){var a=function(){function a(a,b){function c(){this.constructor=a}c.prototype=b.prototype,a.prototype=new c}function b(a,b,c,d,e,f){this.message=a,this.expected=b,this.found=c,this.offset=d,this.line=e,this.column=f,this.name="SyntaxError"}function c(a){function c(){return f(wc).line}function d(){return f(wc).column}function e(a){throw h(a,null,wc)}function f(b){function c(b,c,d){var e,f;for(e=c;d>e;e++)f=a.charAt(e),"\n"===f?(b.seenCR||b.line++,b.column=1,b.seenCR=!1):"\r"===f||"\u2028"===f||"\u2029"===f?(b.line++,b.column=1,b.seenCR=!0):(b.column++,b.seenCR=!1)}return xc!==b&&(xc>b&&(xc=0,yc={line:1,column:1,seenCR:!1}),c(yc,xc,b),xc=b),yc}function g(a){zc>vc||(vc>zc&&(zc=vc,Ac=[]),Ac.push(a))}function h(c,d,e){function g(a){var b=1;for(a.sort(function(a,b){return a.description<b.description?-1:a.description>b.description?1:0});b<a.length;)a[b-1]===a[b]?a.splice(b,1):b++}function h(a,b){function c(a){function b(a){return a.charCodeAt(0).toString(16).toUpperCase()}return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(a){return"\\x0"+b(a)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(a){return"\\x"+b(a)}).replace(/[\u0180-\u0FFF]/g,function(a){return"\\u0"+b(a)}).replace(/[\u1080-\uFFFF]/g,function(a){return"\\u"+b(a)})}var d,e,f,g=new Array(a.length);for(f=0;f<a.length;f++)g[f]=a[f].description;return d=a.length>1?g.slice(0,-1).join(", ")+" or "+g[a.length-1]:g[0],e=b?'"'+c(b)+'"':"end of input","Expected "+d+" but "+e+" found."}var i=f(e),j=e<a.length?a.charAt(e):null;return null!==d&&g(d),new b(null!==c?c:h(d,j),d,j,e,i.line,i.column)}function i(){var a;return a=j()}function j(){var a,b,c;for(a=vc,b=[],c=k();c!==X;)b.push(c),c=k();return b!==X&&(wc=a,b=$(b)),a=b}function k(){var a;return a=K(),a===X&&(a=L(),a===X&&(a=l(),a===X&&(a=s(),a===X&&(a=u(),a===X&&(a=r(),a===X&&(a=H())))))),a}function l(){var b,c,d,e,f,h,i,k;if(Bc++,b=vc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(e=O(),e!==X?(f=j(),f!==X?(h=q(),h!==X?(i=n(),i===X&&(i=ba),i!==X?(wc=vc,k=ca(c,f,h,i),k=k?da:aa,k!==X?(wc=b,c=ea(c,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;if(b===X)if(b=vc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(47===a.charCodeAt(vc)?(e=fa,vc++):(e=X,0===Bc&&g(ga)),e!==X?(f=O(),f!==X?(wc=b,c=ha(c),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(_)),b}function m(){var b,c,d,e,f,h,i;if(b=vc,c=N(),c!==X)if(ia.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g(ja)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();e!==X?(f=v(),f!==X?(h=o(),h!==X?(i=p(),i!==X?(wc=b,c=ka(d,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa;return b}function n(){var b,c,d,e,f,h,i;if(Bc++,b=vc,c=N(),c!==X)if(47===a.charCodeAt(vc)?(d=fa,vc++):(d=X,0===Bc&&g(ga)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=v(),f!==X){for(h=[],i=S();i!==X;)h.push(i),i=S();h!==X?(i=O(),i!==X?(wc=b,c=ma(f),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(la)),b}function o(){var b,c,d,e;return b=vc,c=vc,58===a.charCodeAt(vc)?(d=na,vc++):(d=X,0===Bc&&g(oa)),d!==X?(e=v(),e!==X?(wc=c,d=pa(e),c=d):(vc=c,c=aa)):(vc=c,c=aa),c===X&&(c=ba),c!==X&&(wc=b,c=qa(c)),b=c}function p(){var b,c,d,e,f,h,i;if(Bc++,b=vc,c=[],d=vc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=aa;for(e!==X?(f=C(),f!==X?(61===a.charCodeAt(vc)?(h=sa,vc++):(h=X,0===Bc&&g(ta)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(wc=d,e=ua(f,i),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);d!==X;){if(c.push(d),d=vc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=aa;e!==X?(f=C(),f!==X?(61===a.charCodeAt(vc)?(h=sa,vc++):(h=X,0===Bc&&g(ta)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(wc=d,e=ua(f,i),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)}return c!==X&&(wc=b,c=va(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(ra)),b}function q(){var b,c,d,e,f,h,i,k;for(Bc++,b=vc,c=[],d=vc,e=N(),e!==X?(58===a.charCodeAt(vc)?(f=na,vc++):(f=X,0===Bc&&g(oa)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(wc=d,e=ua(h,k),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);d!==X;)c.push(d),d=vc,e=N(),e!==X?(58===a.charCodeAt(vc)?(f=na,vc++):(f=X,0===Bc&&g(oa)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(wc=d,e=ua(h,k),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);return c!==X&&(wc=b,c=xa(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(wa)),b}function r(){var a,b,c,d,e;return Bc++,a=vc,b=N(),b!==X?(c=v(),c!==X?(d=t(),d!==X?(e=O(),e!==X?(wc=a,b=za(c,d),a=b):(vc=a,a=aa)):(vc=a,a=aa)):(vc=a,a=aa)):(vc=a,a=aa),Bc--,a===X&&(b=X,0===Bc&&g(ya)),a}function s(){var b,c,d,e,f,h,i,j,k,l;if(Bc++,b=vc,c=N(),c!==X)if(62===a.charCodeAt(vc)?(d=Ba,vc++):(d=X,0===Bc&&g(Ca)),d===X&&(43===a.charCodeAt(vc)?(d=Da,vc++):(d=X,0===Bc&&g(Ea))),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=vc,h=C(),h!==X&&(wc=f,h=Fa(h)),f=h,f===X&&(f=F()),f!==X)if(h=o(),h!==X)if(i=p(),i!==X){for(j=[],k=S();k!==X;)j.push(k),k=S();j!==X?(47===a.charCodeAt(vc)?(k=fa,vc++):(k=X,0===Bc&&g(ga)),k!==X?(l=O(),l!==X?(wc=b,c=Ga(d,f,h,i),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;else vc=b,b=aa;else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Aa)),b}function t(){var b,c,d,e,f;for(Bc++,b=vc,c=[],d=vc,124===a.charCodeAt(vc)?(e=Ia,vc++):(e=X,0===Bc&&g(Ja)),e!==X?(f=C(),f!==X?(wc=d,e=pa(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);d!==X;)c.push(d),d=vc,124===a.charCodeAt(vc)?(e=Ia,vc++):(e=X,0===Bc&&g(Ja)),e!==X?(f=C(),f!==X?(wc=d,e=pa(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);return c!==X&&(wc=b,c=Ka(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Ha)),b}function u(){var b,c,d,e,f;return Bc++,b=vc,c=N(),c!==X?(126===a.charCodeAt(vc)?(d=Ma,vc++):(d=X,0===Bc&&g(Na)),d!==X?(e=C(),e!==X?(f=O(),f!==X?(wc=b,c=Oa(e),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(La)),b}function v(){var a,b;return Bc++,a=vc,b=B(),b!==X&&(wc=a,b=Qa(b)),a=b,a===X&&(a=vc,b=C(),b!==X&&(wc=a,b=Ra(b)),a=b),Bc--,a===X&&(b=X,0===Bc&&g(Pa)),a}function w(){var a,b;return Bc++,a=vc,b=x(),b===X&&(b=A()),b!==X&&(wc=a,b=Ta(b)),a=b,Bc--,a===X&&(b=X,0===Bc&&g(Sa)),a}function x(){var b,c,d,e;return Bc++,b=vc,c=A(),c!==X?(46===a.charCodeAt(vc)?(d=Va,vc++):(d=X,0===Bc&&g(Wa)),d!==X?(e=y(),e!==X?(wc=b,c=Xa(c,e),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(Ua)),b}function y(){var b,c,d;if(Bc++,b=vc,c=[],Za.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g($a)),d!==X)for(;d!==X;)c.push(d),Za.test(a.charAt(vc))?(d=a.charAt(vc),vc++):(d=X,0===Bc&&g($a));else c=aa;return c!==X&&(wc=b,c=_a(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Ya)),b}function z(){var b,c,d;return Bc++,b=vc,45===a.charCodeAt(vc)?(c=bb,vc++):(c=X,0===Bc&&g(cb)),c!==X?(d=y(),d!==X?(wc=b,c=db(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(ab)),b}function A(){var a,b;return Bc++,a=z(),a===X&&(a=y()),Bc--,a===X&&(b=X,0===Bc&&g(eb)),a}function B(){var b,c,d,e;if(Bc++,b=vc,c=C(),c===X&&(c=ba),c!==X){if(d=[],e=E(),e===X&&(e=D()),e!==X)for(;e!==X;)d.push(e),e=E(),e===X&&(e=D());else d=aa;d!==X?(wc=b,c=gb(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;if(b===X)if(b=vc,46===a.charCodeAt(vc)?(c=Va,vc++):(c=X,0===Bc&&g(Wa)),c!==X){for(d=[],e=E(),e===X&&(e=D());e!==X;)d.push(e),e=E(),e===X&&(e=D());d!==X?(wc=b,c=hb(d),b=c):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(fb)),b}function C(){var b,c,d,e;if(Bc++,b=vc,jb.test(a.charAt(vc))?(c=a.charAt(vc),vc++):(c=X,0===Bc&&g(kb)),c!==X){for(d=[],lb.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(mb));e!==X;)d.push(e),lb.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(mb));d!==X?(wc=b,c=nb(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(ib)),b}function D(){var b,c,d,e,f,h;if(Bc++,b=vc,c=vc,d=P(),d!==X){if(e=vc,f=[],Za.test(a.charAt(vc))?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g($a)),h!==X)for(;h!==X;)f.push(h),Za.test(a.charAt(vc))?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g($a));else f=aa;f!==X&&(wc=e,f=pb(f)),e=f,e===X&&(e=v()),e!==X?(f=Q(),f!==X?(wc=c,d=qb(e),c=d):(vc=c,c=aa)):(vc=c,c=aa)}else vc=c,c=aa;return c!==X?(d=E(),d===X&&(d=ba),d!==X?(wc=b,c=rb(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(ob)),b}function E(){var b,c,d,e,f;if(Bc++,b=vc,c=[],d=vc,46===a.charCodeAt(vc)?(e=Va,vc++):(e=X,0===Bc&&g(Wa)),e!==X?(f=C(),f!==X?(wc=d,e=tb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,46===a.charCodeAt(vc)?(e=Va,vc++):(e=X,0===Bc&&g(Wa)),e!==X?(f=C(),f!==X?(wc=d,e=tb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;return c!==X?(d=D(),d===X&&(d=ba),d!==X?(wc=b,c=ub(c,d),b=c):(vc=b,b=aa)):(vc=b,b=aa),Bc--,b===X&&(c=X,0===Bc&&g(sb)),b}function F(){var b,c,d,e;if(Bc++,b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X?(34===a.charCodeAt(vc)?(d=wb,vc++):(d=X,0===Bc&&g(xb)),d!==X?(wc=b,c=yb(),b=c):(vc=b,b=aa)):(vc=b,b=aa),b===X&&(b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X?(d=I(),d!==X?(34===a.charCodeAt(vc)?(e=wb,vc++):(e=X,0===Bc&&g(xb)),e!==X?(wc=b,c=zb(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)):(vc=b,b=aa),b===X))if(b=vc,34===a.charCodeAt(vc)?(c=wb,vc++):(c=X,0===Bc&&g(xb)),c!==X){if(d=[],e=G(),e!==X)for(;e!==X;)d.push(e),e=G();else d=aa;d!==X?(34===a.charCodeAt(vc)?(e=wb,vc++):(e=X,0===Bc&&g(xb)),e!==X?(wc=b,c=Ab(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(vb)),b}function G(){var a,b;return a=u(),a===X&&(a=r(),a===X&&(a=vc,b=I(),b!==X&&(wc=a,b=Bb(b)),a=b)),a}function H(){var b,c,d,e,f,h,i,j;if(Bc++,b=vc,c=R(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(wc=b,c=Db(c,d),b=c):(vc=b,b=aa)}else vc=b,b=aa;if(b===X){if(b=vc,c=[],d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=vc,Bc++,h=K(),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(h=vc,Bc++,i=L(),Bc--,i===X?h=da:(vc=h,h=aa),h!==X?(i=vc,Bc++,j=R(),Bc--,j===X?i=da:(vc=i,i=aa),i!==X?(a.length>vc?(j=a.charAt(vc),vc++):(j=X,0===Bc&&g(Eb)),j!==X?(wc=d,e=Fb(j),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=vc,Bc++,h=K(),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(h=vc,Bc++,i=L(),Bc--,i===X?h=da:(vc=h,h=aa),h!==X?(i=vc,Bc++,j=R(),Bc--,j===X?i=da:(vc=i,i=aa),i!==X?(a.length>vc?(j=a.charAt(vc),vc++):(j=X,0===Bc&&g(Eb)),j!==X?(wc=d,e=Fb(j),d=e):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;c!==X&&(wc=b,c=Gb(c)),b=c}return Bc--,b===X&&(c=X,0===Bc&&g(Cb)),b}function I(){var b,c,d,e,f;if(Bc++,b=vc,c=[],d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=J(),f===X&&(Ib.test(a.charAt(vc))?(f=a.charAt(vc),vc++):(f=X,0===Bc&&g(Jb))),f!==X?(wc=d,e=Fb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa),d!==X)for(;d!==X;)c.push(d),d=vc,e=vc,Bc++,f=M(),Bc--,f===X?e=da:(vc=e,e=aa),e!==X?(f=J(),f===X&&(Ib.test(a.charAt(vc))?(f=a.charAt(vc),vc++):(f=X,0===Bc&&g(Jb))),f!==X?(wc=d,e=Fb(f),d=e):(vc=d,d=aa)):(vc=d,d=aa);else c=aa;return c!==X&&(wc=b,c=Kb(c)),b=c,Bc--,b===X&&(c=X,0===Bc&&g(Hb)),b}function J(){var b,c;return b=vc,a.substr(vc,2)===Lb?(c=Lb,vc+=2):(c=X,0===Bc&&g(Mb)),c!==X&&(wc=b,c=Nb()),b=c}function K(){var b,c,d,e,f,h;if(Bc++,b=vc,a.substr(vc,2)===Pb?(c=Pb,vc+=2):(c=X,0===Bc&&g(Qb)),c!==X){for(d=[],e=vc,f=vc,Bc++,a.substr(vc,2)===Rb?(h=Rb,vc+=2):(h=X,0===Bc&&g(Sb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Tb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);e!==X;)d.push(e),e=vc,f=vc,Bc++,a.substr(vc,2)===Rb?(h=Rb,vc+=2):(h=X,0===Bc&&g(Sb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Tb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);d!==X?(a.substr(vc,2)===Rb?(e=Rb,vc+=2):(e=X,0===Bc&&g(Sb)),e!==X?(wc=b,c=Ub(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Ob)),b}function L(){var b,c,d,e,f,h;if(Bc++,b=vc,a.substr(vc,2)===Wb?(c=Wb,vc+=2):(c=X,0===Bc&&g(Xb)),c!==X){for(d=[],e=vc,f=vc,Bc++,a.substr(vc,2)===Yb?(h=Yb,vc+=2):(h=X,0===Bc&&g(Zb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Fb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);e!==X;)d.push(e),e=vc,f=vc,Bc++,a.substr(vc,2)===Yb?(h=Yb,vc+=2):(h=X,0===Bc&&g(Zb)),Bc--,h===X?f=da:(vc=f,f=aa),f!==X?(a.length>vc?(h=a.charAt(vc),vc++):(h=X,0===Bc&&g(Eb)),h!==X?(wc=e,f=Fb(h),e=f):(vc=e,e=aa)):(vc=e,e=aa);d!==X?(a.substr(vc,2)===Yb?(e=Yb,vc+=2):(e=X,0===Bc&&g(Zb)),e!==X?(wc=b,c=$b(d),b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa;return Bc--,b===X&&(c=X,0===Bc&&g(Vb)),b}function M(){var b,c,d,e,f,h,i,j,k,l;if(b=vc,c=N(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();if(d!==X)if(_b.test(a.charAt(vc))?(e=a.charAt(vc),vc++):(e=X,0===Bc&&g(ac)),e!==X){for(f=[],h=S();h!==X;)f.push(h),h=S();if(f!==X){if(h=[],i=vc,j=vc,Bc++,k=O(),Bc--,k===X?j=da:(vc=j,j=aa),j!==X?(k=vc,Bc++,l=R(),Bc--,l===X?k=da:(vc=k,k=aa),k!==X?(a.length>vc?(l=a.charAt(vc),vc++):(l=X,0===Bc&&g(Eb)),l!==X?(j=[j,k,l],i=j):(vc=i,i=aa)):(vc=i,i=aa)):(vc=i,i=aa),i!==X)for(;i!==X;)h.push(i),i=vc,j=vc,Bc++,k=O(),Bc--,k===X?j=da:(vc=j,j=aa),j!==X?(k=vc,Bc++,l=R(),Bc--,l===X?k=da:(vc=k,k=aa),k!==X?(a.length>vc?(l=a.charAt(vc),vc++):(l=X,0===Bc&&g(Eb)),l!==X?(j=[j,k,l],i=j):(vc=i,i=aa)):(vc=i,i=aa)):(vc=i,i=aa);else h=aa;if(h!==X){for(i=[],j=S();j!==X;)i.push(j),j=S();i!==X?(j=O(),j!==X?(c=[c,d,e,f,h,i,j],b=c):(vc=b,b=aa)):(vc=b,b=aa)}else vc=b,b=aa}else vc=b,b=aa}else vc=b,b=aa;else vc=b,b=aa}else vc=b,b=aa;return b===X&&(b=r()),b}function N(){var b;return 123===a.charCodeAt(vc)?(b=bc,vc++):(b=X,0===Bc&&g(cc)),b}function O(){var b;return 125===a.charCodeAt(vc)?(b=dc,vc++):(b=X,0===Bc&&g(ec)),b}function P(){var b;return 91===a.charCodeAt(vc)?(b=fc,vc++):(b=X,0===Bc&&g(gc)),b}function Q(){var b;return 93===a.charCodeAt(vc)?(b=hc,vc++):(b=X,0===Bc&&g(ic)),b}function R(){var b;return 10===a.charCodeAt(vc)?(b=jc,vc++):(b=X,0===Bc&&g(kc)),b===X&&(a.substr(vc,2)===lc?(b=lc,vc+=2):(b=X,0===Bc&&g(mc)),b===X&&(13===a.charCodeAt(vc)?(b=nc,vc++):(b=X,0===Bc&&g(oc)),b===X&&(8232===a.charCodeAt(vc)?(b=pc,vc++):(b=X,0===Bc&&g(qc)),b===X&&(8233===a.charCodeAt(vc)?(b=rc,vc++):(b=X,0===Bc&&g(sc)))))),b}function S(){var b;return tc.test(a.charAt(vc))?(b=a.charAt(vc),vc++):(b=X,0===Bc&&g(uc)),b===X&&(b=R()),b}function T(a){return parseInt(a.join(""),10)}function U(a){return a.concat([["line",c()],["col",d()]])}var V,W=arguments.length>1?arguments[1]:{},X={},Y={start:i},Z=i,$=function(a){var b=["body"].concat(a);return U(b)},_={type:"other",description:"section"},aa=X,ba=null,ca=function(a,b,c,d){return d&&a[1].text===d.text||e("Expected end tag for "+a[1].text+" but it was not found."),!0},da=void 0,ea=function(a,b,c){return c.push(["param",["literal","block"],b]),a.push(c,["filters"]),U(a)},fa="/",ga={type:"literal",value:"/",description:'"/"'},ha=function(a){return a.push(["bodies"],["filters"]),U(a)},ia=/^[#?\^<+@%]/,ja={type:"class",value:"[#?\\^<+@%]",description:"[#?\\^<+@%]"},ka=function(a,b,c,d){return[a,b,c,d]},la={type:"other",description:"end tag"},ma=function(a){return a},na=":",oa={type:"literal",value:":",description:'":"'},pa=function(a){return a},qa=function(a){return a?["context",a]:["context"]},ra={type:"other",description:"params"},sa="=",ta={type:"literal",value:"=",description:'"="'},ua=function(a,b){return["param",["literal",a],b]},va=function(a){return["params"].concat(a)},wa={type:"other",description:"bodies"},xa=function(a){return["bodies"].concat(a)},ya={type:"other",description:"reference"},za=function(a,b){return U(["reference",a,b])},Aa={type:"other",description:"partial"},Ba=">",Ca={type:"literal",value:">",description:'">"'},Da="+",Ea={type:"literal",value:"+",description:'"+"'},Fa=function(a){return["literal",a]},Ga=function(a,b,c,d){var e=">"===a?"partial":a;return U([e,b,c,d])},Ha={type:"other",description:"filters"},Ia="|",Ja={type:"literal",value:"|",description:'"|"'},Ka=function(a){return["filters"].concat(a)},La={type:"other",description:"special"},Ma="~",Na={type:"literal",value:"~",description:'"~"'},Oa=function(a){return U(["special",a])},Pa={type:"other",description:"identifier"},Qa=function(a){var b=["path"].concat(a);return b.text=a[1].join(".").replace(/,line,\d+,col,\d+/g,""),b},Ra=function(a){var b=["key",a];return b.text=a,b},Sa={type:"other",description:"number"},Ta=function(a){return["literal",a]},Ua={type:"other",description:"float"},Va=".",Wa={type:"literal",value:".",description:'"."'},Xa=function(a,b){return parseFloat(a+"."+b)},Ya={type:"other",description:"unsigned_integer"},Za=/^[0-9]/,$a={type:"class",value:"[0-9]",description:"[0-9]"},_a=function(a){return T(a)},ab={type:"other",description:"signed_integer"},bb="-",cb={type:"literal",value:"-",description:'"-"'},db=function(a,b){return-1*b},eb={type:"other",description:"integer"},fb={type:"other",description:"path"},gb=function(a,b){return b=b[0],a&&b?(b.unshift(a),U([!1,b])):U([!0,b])},hb=function(a){return U(a.length>0?[!0,a[0]]:[!0,[]])},ib={type:"other",description:"key"},jb=/^[a-zA-Z_$]/,kb={type:"class",value:"[a-zA-Z_$]",description:"[a-zA-Z_$]"},lb=/^[0-9a-zA-Z_$\-]/,mb={type:"class",value:"[0-9a-zA-Z_$\\-]",description:"[0-9a-zA-Z_$\\-]"},nb=function(a,b){return a+b.join("")},ob={type:"other",description:"array"},pb=function(a){return a.join("")},qb=function(a){return a},rb=function(a,b){return b?b.unshift(a):b=[a],b},sb={type:"other",description:"array_part"},tb=function(a){return a},ub=function(a,b){return b?a.concat(b):a},vb={type:"other",description:"inline"},wb='"',xb={type:"literal",value:'"',description:'"\\""'},yb=function(){return U(["literal",""])},zb=function(a){return U(["literal",a])},Ab=function(a){return U(["body"].concat(a))},Bb=function(a){return["buffer",a]},Cb={type:"other",description:"buffer"},Db=function(a,b){return U(["format",a,b.join("")])},Eb={type:"any",description:"any character"},Fb=function(a){return a},Gb=function(a){return U(["buffer",a.join("")])},Hb={type:"other",description:"literal"},Ib=/^[^"]/,Jb={type:"class",value:'[^"]',description:'[^"]'},Kb=function(a){return a.join("")},Lb='\\"',Mb={type:"literal",value:'\\"',description:'"\\\\\\""'},Nb=function(){return'"'},Ob={type:"other",description:"raw"},Pb="{`",Qb={type:"literal",value:"{`",description:'"{`"'},Rb="`}",Sb={type:"literal",value:"`}",description:'"`}"'},Tb=function(a){return a},Ub=function(a){return U(["raw",a.join("")])},Vb={type:"other",description:"comment"},Wb="{!",Xb={type:"literal",value:"{!",description:'"{!"'},Yb="!}",Zb={type:"literal",value:"!}",description:'"!}"'},$b=function(a){return U(["comment",a.join("")])},_b=/^[#?\^><+%:@\/~%]/,ac={type:"class",value:"[#?\\^><+%:@\\/~%]",description:"[#?\\^><+%:@\\/~%]"},bc="{",cc={type:"literal",value:"{",description:'"{"'},dc="}",ec={type:"literal",value:"}",description:'"}"'},fc="[",gc={type:"literal",value:"[",description:'"["'},hc="]",ic={type:"literal",value:"]",description:'"]"'},jc="\n",kc={type:"literal",value:"\n",description:'"\\n"'},lc="\r\n",mc={type:"literal",
value:"\r\n",description:'"\\r\\n"'},nc="\r",oc={type:"literal",value:"\r",description:'"\\r"'},pc="\u2028",qc={type:"literal",value:"\u2028",description:'"\\u2028"'},rc="\u2029",sc={type:"literal",value:"\u2029",description:'"\\u2029"'},tc=/^[\t\x0B\f \xA0\uFEFF]/,uc={type:"class",value:"[\\t\\x0B\\f \\xA0\\uFEFF]",description:"[\\t\\x0B\\f \\xA0\\uFEFF]"},vc=0,wc=0,xc=0,yc={line:1,column:1,seenCR:!1},zc=0,Ac=[],Bc=0;if("startRule"in W){if(!(W.startRule in Y))throw new Error("Can't start parsing from rule \""+W.startRule+'".');Z=Y[W.startRule]}if(V=Z(),V!==X&&vc===a.length)return V;throw V!==X&&vc<a.length&&g({type:"end",description:"end of input"}),h(null,Ac,zc)}return a(b,Error),{SyntaxError:b,parse:c}}();return dust.parse=a.parse,a}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.compile",["dust.core","dust.parse"],function(dust,a){return b(a,dust).compile}):"object"==typeof exports?module.exports=b(require("./parser").parse,require("./dust")):b(a.dust.parse,a.dust)}(this,function(a,dust){function b(a){var b={};return r.filterNode(b,a)}function c(a,b){var c,d,e,f=[b[0]];for(c=1,d=b.length;d>c;c++)e=r.filterNode(a,b[c]),e&&f.push(e);return f}function d(a,b){var c,d,e,f,g=[b[0]];for(d=1,e=b.length;e>d;d++)f=r.filterNode(a,b[d]),f&&("buffer"===f[0]||"format"===f[0]?c?(c[0]="buffer"===f[0]?"buffer":c[0],c[1]+=f.slice(1,-2).join("")):(c=f,g.push(f)):(c=null,g.push(f)));return g}function e(a,b){return["buffer",t[b[1]],b[2],b[3]]}function f(a,b){return b}function g(){}function h(a,b){return dust.config.whitespace?(b.splice(1,2,b.slice(1,-2).join("")),b):null}function i(a,b){var c,d={name:b,bodies:[],blocks:{},index:0,auto:"h"},e=dust.escapeJs(b),f=b?'"'+e+'",':"",g="function(dust){",h=r.compileNode(d,a);return b&&(g+='dust.register("'+e+'",'+h+");"),g+=j(d)+k(d)+"return "+h+"}",c="("+g+"(dust));",dust.config.amd?"define("+f+'["dust.core"],'+g+");":dust.config.cjs?"module.exports=function(dust){var tmpl="+c+"var f="+q().toString()+";f.template=tmpl;return f}":c}function j(a){var b,c=[],d=a.blocks;for(b in d)c.push('"'+b+'":'+d[b]);return c.length?(a.blocks="ctx=ctx.shiftBlocks(blocks);","var blocks={"+c.join(",")+"};"):(a.blocks="",a.blocks)}function k(a){var b,c,d=[],e=a.bodies,f=a.blocks;for(b=0,c=e.length;c>b;b++)d[b]="function body_"+b+"(chk,ctx){"+f+"return chk"+e[b]+";}body_"+b+".__dustBody=!0;";return d.join("")}function l(a,b){var c,d,e="";for(c=1,d=b.length;d>c;c++)e+=r.compileNode(a,b[c]);return e}function m(a,b,c){return"."+(dust._aliases[c]||c)+"("+r.compileNode(a,b[1])+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"}function n(a){return a.replace(u,"\\\\").replace(v,'\\"').replace(w,"\\f").replace(x,"\\n").replace(y,"\\r").replace(z,"\\t")}function o(a,b,c){var d=dust.loadSource(dust.compile(a));return q(d)(b,c)}function p(a,b){var c=dust.loadSource(dust.compile(a,b));return q(c)}function q(a){return function(b,c){var d=c?"render":"stream";return dust[d](a,b,c)}}var r={},s=dust.isArray;r.compile=function(c,d){try{var e=b(a(c));return i(e,d)}catch(f){if(!f.line||!f.column)throw f;throw new SyntaxError(f.message+" At line : "+f.line+", column : "+f.column)}},r.filterNode=function(a,b){return r.optimizers[b[0]](a,b)},r.optimizers={body:d,buffer:f,special:e,format:h,reference:c,"#":c,"?":c,"^":c,"<":c,"+":c,"@":c,"%":c,partial:c,context:c,params:c,bodies:c,param:c,filters:f,key:f,path:f,literal:f,raw:f,comment:g,line:g,col:g},r.pragmas={esc:function(a,b,c){var d,e=a.auto;return b||(b="h"),a.auto="s"===b?"":b,d=l(a,c.block),a.auto=e,d}};var t={s:" ",n:"\n",r:"\r",lb:"{",rb:"}"};r.compileNode=function(a,b){return r.nodes[b[0]](a,b)},r.nodes={body:function(a,b){var c=a.index++,d="body_"+c;return a.bodies[c]=l(a,b),d},buffer:function(a,b){return".w("+A(b[1])+")"},format:function(a,b){return".w("+A(b[1])+")"},reference:function(a,b){return".f("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+")"},"#":function(a,b){return m(a,b,"section")},"?":function(a,b){return m(a,b,"exists")},"^":function(a,b){return m(a,b,"notexists")},"<":function(a,b){for(var c=b[4],d=1,e=c.length;e>d;d++){var f=c[d],g=f[1][1];if("block"===g)return a.blocks[b[1].text]=r.compileNode(a,f[2]),""}return""},"+":function(a,b){return"undefined"==typeof b[1].text&&"undefined"==typeof b[4]?".b(ctx.getBlock("+r.compileNode(a,b[1])+",chk, ctx),"+r.compileNode(a,b[2])+", {},"+r.compileNode(a,b[3])+")":".b(ctx.getBlock("+A(b[1].text)+"),"+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"},"@":function(a,b){return".h("+A(b[1].text)+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+","+r.compileNode(a,b[5])+")"},"%":function(a,b){var c,d,e,f,g,h,i,j,k,l=b[1][1];if(!r.pragmas[l])return"";for(c=b[4],d={},j=1,k=c.length;k>j;j++)h=c[j],d[h[1][1]]=h[2];for(e=b[3],f={},j=1,k=e.length;k>j;j++)i=e[j],f[i[1][1]]=i[2][1];return g=b[2][1]?b[2][1].text:null,r.pragmas[l](a,g,d,f)},partial:function(a,b){return".p("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+","+r.compileNode(a,b[3])+")"},context:function(a,b){return b[1]?"ctx.rebase("+r.compileNode(a,b[1])+")":"ctx"},params:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++)c.push(r.compileNode(a,b[d]));return c.length?"{"+c.join(",")+"}":"{}"},bodies:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++)c.push(r.compileNode(a,b[d]));return"{"+c.join(",")+"}"},param:function(a,b){return r.compileNode(a,b[1])+":"+r.compileNode(a,b[2])},filters:function(a,b){for(var c=[],d=1,e=b.length;e>d;d++){var f=b[d];c.push('"'+f+'"')}return'"'+a.auto+'"'+(c.length?",["+c.join(",")+"]":"")},key:function(a,b){return'ctx.get(["'+b[1]+'"], false)'},path:function(a,b){for(var c=b[1],d=b[2],e=[],f=0,g=d.length;g>f;f++)e.push(s(d[f])?r.compileNode(a,d[f]):'"'+d[f]+'"');return"ctx.getPath("+c+", ["+e.join(",")+"])"},literal:function(a,b){return A(b[1])},raw:function(a,b){return".w("+A(b[1])+")"}};var u=/\\/g,v=/"/g,w=/\f/g,x=/\n/g,y=/\r/g,z=/\t/g,A="undefined"==typeof JSON?function(a){return'"'+n(a)+'"'}:JSON.stringify;return dust.compiler=r,dust.compile=dust.compiler.compile,dust.renderSource=o,dust.compileFn=p,dust.filterNode=r.filterNode,dust.optimizers=r.optimizers,dust.pragmas=r.pragmas,dust.compileNode=r.compileNode,dust.nodes=r.nodes,r}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core","dust.compile"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(){b()})},dust});
      out.push('"' + name + '":' + blocks[name]);
    "grunt": "~1.0.1",
    "grunt-cli": "~1.2.0",
    "grunt-contrib-clean": "~1.0.0",
    "grunt-contrib-connect": "~1.0.2",
    "grunt-contrib-jasmine": "~1.0.3",
    "grunt-contrib-jshint": "~1.0.0",
    "grunt-contrib-watch": "~1.0.0",
    "grunt-jasmine-nodejs": "~1.5.3",
  it("valid keys", function() {
Fixed code: .vscode
package-lock.json
  - "12"
  - "14"
  - "16"
    - node_js: "12"
  - npm install -g npm@6
* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
        if (type === ERROR && dust.debugLevel === DEBUG && message instanceof Error && message.stack) {
          log('[DUST:' + type + ']', message.stack);
        }
   * Decide somewhat-naively if something is a Thenable.  Matches Promises A+ Spec, section 1.2 “thenable” is an object or function that defines a then method."
    return elem &&  /* Beware: `typeof null` is `object` */
           (typeof elem === 'object' || typeof elem === 'function') &&
  /**
   * Decide if an element is a function but not Thenable; it is prefereable to resolve a thenable function by its `.then` method.
   * @param elem {*} target of inspection
   * @return {Boolean} is `elem` a function without a `.then` property?
   */
  dust.isNonThenableFunction = function(elem) {
    return typeof elem === 'function' && !dust.isThenable(elem);
  };

    this._isContext = true;
  dust.isContext = function(obj) {
    return typeof obj === "object" && obj._isContext === true;
  };

    if (dust.isContext(context)) {
      context.templateName = name;
    if (dust.isNonThenableFunction(ctx)) {
  /**
   * Inserts a new chunk that can be used to asynchronously render or write to it
   * @param callback {Function} The function that will be called with the new chunk
   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
   */
  /**
   * Like Chunk#map but additionally resolves a thenable.  If the thenable succeeds the callback is invoked with
   * a new chunk that can be used to asynchronously render or write to it, otherwise if the thenable is rejected 
   * then the error body is rendered if available, an error is logged, and the callback is never invoked.
   * @param {Chunk} The current chunk to insert a new chunk
   * @param thenable {Thenable} the target thenable to await
   * @param context {Context} context to use to render the deferred chunk
   * @param bodies {Object} may optionally contain an "error" for when the thenable is rejected
   * @param callback {Function} The function that will be called with the new chunk
   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
   */
  function mapThenable(chunk, thenable, context, bodies, callback) {
    return chunk.map(function(asyncChunk) {
      thenable.then(function(data) {
        try {
          callback(asyncChunk, data);
        } catch (err) {
          // handle errors the same way Chunk#map would.  This logic is only here since the thenable defers 
          // logic such that the try / catch in Chunk#map would not capture it. 
          dust.log(err, ERROR);
          asyncChunk.setError(err);
        }
      }, function(err) {
        dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
        asyncChunk.renderError(err, context, bodies).end();
      });
    });
  }

    if (dust.isNonThenableFunction(elem)) {
    if (dust.isNonThenableFunction(elem) && !dust.isTemplateFn(elem)) {
    if (dust.isThenable(elem)) {
      return mapThenable(this, elem, context, bodies, function(chunk, data) {
        chunk.exists(data, context, bodies).end();
      });
    }

    if (dust.isThenable(elem)) {
      return mapThenable(this, elem, context, bodies, function(chunk, data) {
        chunk.notexists(data, context, bodies).end();
      });
    }

    return mapThenable(this, thenable, context, bodies, function(chunk, data) {
      if (bodies) {
        chunk.section(data, context, bodies).end();
      } else {
        // Actually a reference. Self-closing sections don't render
        chunk.reference(data, context, auto, filters).end();
      }
  /**
   * Render an error body if available
   * @param err {Error} error that occurred
   * @param context {Context} context to use to render the error
   * @param bodies {Object} may optionally contain an "error" which will be rendered
   * @return {Chunk}
   */
  Chunk.prototype.renderError = function(err, context, bodies) {
    var errorBody = bodies && bodies.error;
    if (errorBody) {
      return this.render(errorBody, context.push(err));
    }
    return this;
  };

    var body = bodies && bodies.block;
          chunk.renderError(err, context, bodies);
          dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
            require([name], function(tmpl) {
                cb(null, tmpl);
* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){if(a)return"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e,this._isContext=!0}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function mapThenable(a,b,c,d,e){return a.map(function(a){b.then(function(b){try{e(a,b)}catch(c){dust.log(c,ERROR),a.setError(c)}},function(b){dust.log("Unhandled promise rejection in `"+c.getTemplateName()+"`",INFO),a.renderError(b,c,d).end()})})}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&(b("[DUST:"+d+"]",a),d===ERROR&&dust.debugLevel===DEBUG&&a instanceof Error&&a.stack&&b("[DUST:"+d+"]",a.stack))},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},Array.isArray?dust.isArray=Array.isArray:dust.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0!==a&&(!(!dust.isArray(a)||a.length)||!a)},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&("object"==typeof a||"function"==typeof a)&&"function"==typeof a.then},dust.isNonThenableFunction=function(a){return"function"==typeof a&&!dust.isThenable(a)},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;e<f;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context((void 0),a,b)},dust.isContext=function(a){return"object"==typeof a&&a._isContext===!0},Context.wrap=function(a,b){return dust.isContext(a)?(a.templateName=b,a):new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&i<e;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return dust.isNonThenableFunction(h)?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;c<d;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return b?this.taps=b.push(a):this.taps=new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return dust.isNonThenableFunction(a)?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if(dust.isNonThenableFunction(a)&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;e<f;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.exists(d,b,c).end()});if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.notexists(d,b,c).end()});if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){load(a,b,c).end()}):load(a,this,c)},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return mapThenable(this,a,b,c,function(a,f){c?a.section(f,b,c).end():a.reference(f,b,d,e).end()})},Chunk.prototype.renderError=function(a,b,c){var d=c&&c.error;return d?this.render(d,b.push(a)):this},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block;return this.map(function(g){var h=!1;a.on("data",function(a){h||(f?g=g.map(function(c){c.render(f,b.push(a)).end()}):c||(g=g.reference(a,b,d,e)))}).on("error",function(a){h||(g.renderError(a,b,c),dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),h||(h=!0,g.end()))}).on("end",function(){h||(h=!0,g.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(a){b(null,a)})},dust});
* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
        if (type === ERROR && dust.debugLevel === DEBUG && message instanceof Error && message.stack) {
          log('[DUST:' + type + ']', message.stack);
        }
   * Decide somewhat-naively if something is a Thenable.  Matches Promises A+ Spec, section 1.2 “thenable” is an object or function that defines a then method."
    return elem &&  /* Beware: `typeof null` is `object` */
           (typeof elem === 'object' || typeof elem === 'function') &&
  /**
   * Decide if an element is a function but not Thenable; it is prefereable to resolve a thenable function by its `.then` method.
   * @param elem {*} target of inspection
   * @return {Boolean} is `elem` a function without a `.then` property?
   */
  dust.isNonThenableFunction = function(elem) {
    return typeof elem === 'function' && !dust.isThenable(elem);
  };

    this._isContext = true;
  dust.isContext = function(obj) {
    return typeof obj === "object" && obj._isContext === true;
  };

    if (dust.isContext(context)) {
      context.templateName = name;
    if (dust.isNonThenableFunction(ctx)) {
  /**
   * Inserts a new chunk that can be used to asynchronously render or write to it
   * @param callback {Function} The function that will be called with the new chunk
   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
   */
  /**
   * Like Chunk#map but additionally resolves a thenable.  If the thenable succeeds the callback is invoked with
   * a new chunk that can be used to asynchronously render or write to it, otherwise if the thenable is rejected 
   * then the error body is rendered if available, an error is logged, and the callback is never invoked.
   * @param {Chunk} The current chunk to insert a new chunk
   * @param thenable {Thenable} the target thenable to await
   * @param context {Context} context to use to render the deferred chunk
   * @param bodies {Object} may optionally contain an "error" for when the thenable is rejected
   * @param callback {Function} The function that will be called with the new chunk
   * @returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk
   */
  function mapThenable(chunk, thenable, context, bodies, callback) {
    return chunk.map(function(asyncChunk) {
      thenable.then(function(data) {
        try {
          callback(asyncChunk, data);
        } catch (err) {
          // handle errors the same way Chunk#map would.  This logic is only here since the thenable defers 
          // logic such that the try / catch in Chunk#map would not capture it. 
          dust.log(err, ERROR);
          asyncChunk.setError(err);
        }
      }, function(err) {
        dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
        asyncChunk.renderError(err, context, bodies).end();
      });
    });
  }

    if (dust.isNonThenableFunction(elem)) {
    if (dust.isNonThenableFunction(elem) && !dust.isTemplateFn(elem)) {
    if (dust.isThenable(elem)) {
      return mapThenable(this, elem, context, bodies, function(chunk, data) {
        chunk.exists(data, context, bodies).end();
      });
    }

    if (dust.isThenable(elem)) {
      return mapThenable(this, elem, context, bodies, function(chunk, data) {
        chunk.notexists(data, context, bodies).end();
      });
    }

    return mapThenable(this, thenable, context, bodies, function(chunk, data) {
      if (bodies) {
        chunk.section(data, context, bodies).end();
      } else {
        // Actually a reference. Self-closing sections don't render
        chunk.reference(data, context, auto, filters).end();
      }
  /**
   * Render an error body if available
   * @param err {Error} error that occurred
   * @param context {Context} context to use to render the error
   * @param bodies {Object} may optionally contain an "error" which will be rendered
   * @return {Chunk}
   */
  Chunk.prototype.renderError = function(err, context, bodies) {
    var errorBody = bodies && bodies.error;
    if (errorBody) {
      return this.render(errorBody, context.push(err));
    }
    return this;
  };

    var body = bodies && bodies.block;
          chunk.renderError(err, context, bodies);
          dust.log('Unhandled stream error in `' + context.getTemplateName() + '`', INFO);
  "use strict";

   * Generated by PEG.js 0.9.0.
   * http://pegjs.org/
  function peg$SyntaxError(message, expected, found, location) {
    this.location = location;

    if (typeof Error.captureStackTrace === "function") {
      Error.captureStackTrace(this, peg$SyntaxError);
    }
  peg$subclass(peg$SyntaxError, Error);
  function peg$parse(input) {
        parser  = this,
        peg$c0 = function(p) {
        peg$c1 = { type: "other", description: "section" },
        peg$c2 = function(t, b, e, n) {
        peg$c3 = function(t, b, e, n) {
        peg$c4 = "/",
        peg$c5 = { type: "literal", value: "/", description: "\"/\"" },
        peg$c6 = function(t) {
        peg$c7 = /^[#?\^<+@%]/,
        peg$c8 = { type: "class", value: "[#?^<+@%]", description: "[#?^<+@%]" },
        peg$c9 = function(t, n, c, p) { return [t, n, c, p] },
        peg$c10 = { type: "other", description: "end tag" },
        peg$c11 = function(n) { return n },
        peg$c12 = ":",
        peg$c13 = { type: "literal", value: ":", description: "\":\"" },
        peg$c14 = function(n) {return n},
        peg$c15 = function(n) { return n ? ["context", n] : ["context"] },
        peg$c16 = { type: "other", description: "params" },
        peg$c17 = "=",
        peg$c18 = { type: "literal", value: "=", description: "\"=\"" },
        peg$c19 = function(k, v) {return ["param", ["literal", k], v]},
        peg$c20 = function(p) { return ["params"].concat(p) },
        peg$c21 = { type: "other", description: "bodies" },
        peg$c22 = function(p) { return ["bodies"].concat(p) },
        peg$c23 = { type: "other", description: "reference" },
        peg$c24 = function(n, f) { return withPosition(["reference", n, f]) },
        peg$c25 = { type: "other", description: "partial" },
        peg$c26 = ">",
        peg$c27 = { type: "literal", value: ">", description: "\">\"" },
        peg$c28 = "+",
        peg$c29 = { type: "literal", value: "+", description: "\"+\"" },
        peg$c30 = function(s, k) {return ["literal", k]},
        peg$c31 = function(s, n, c, p) {
        peg$c32 = { type: "other", description: "filters" },
        peg$c33 = "|",
        peg$c34 = { type: "literal", value: "|", description: "\"|\"" },
        peg$c35 = function(f) { return ["filters"].concat(f) },
        peg$c36 = { type: "other", description: "special" },
        peg$c37 = "~",
        peg$c38 = { type: "literal", value: "~", description: "\"~\"" },
        peg$c39 = function(k) { return withPosition(["special", k]) },
        peg$c40 = { type: "other", description: "identifier" },
        peg$c41 = function(p) {
            arr.text = p[1].join('.');
        peg$c42 = function(k) {
        peg$c43 = { type: "other", description: "number" },
        peg$c44 = function(n) { return ['literal', n]; },
        peg$c45 = { type: "other", description: "float" },
        peg$c46 = ".",
        peg$c47 = { type: "literal", value: ".", description: "\".\"" },
        peg$c48 = function(l, r) { return parseFloat(l + "." + r); },
        peg$c49 = { type: "other", description: "unsigned_integer" },
        peg$c50 = /^[0-9]/,
        peg$c51 = { type: "class", value: "[0-9]", description: "[0-9]" },
        peg$c52 = function(digits) { return makeInteger(digits); },
        peg$c53 = { type: "other", description: "signed_integer" },
        peg$c54 = "-",
        peg$c55 = { type: "literal", value: "-", description: "\"-\"" },
        peg$c56 = function(sign, n) { return n * -1; },
        peg$c57 = { type: "other", description: "integer" },
        peg$c58 = { type: "other", description: "path" },
        peg$c59 = function(k, d) {
        peg$c60 = function(d) {
        peg$c61 = { type: "other", description: "key" },
        peg$c62 = /^[a-zA-Z_$]/,
        peg$c63 = { type: "class", value: "[a-zA-Z_$]", description: "[a-zA-Z_$]" },
        peg$c64 = /^[0-9a-zA-Z_$\-]/,
        peg$c65 = { type: "class", value: "[0-9a-zA-Z_$-]", description: "[0-9a-zA-Z_$-]" },
        peg$c66 = function(h, t) { return h + t.join('') },
        peg$c67 = { type: "other", description: "array" },
        peg$c68 = function(n) {return n.join('')},
        peg$c69 = function(a) {return a; },
        peg$c70 = function(i, nk) { if(nk) { nk.unshift(i); } else {nk = [i] } return nk; },
        peg$c71 = { type: "other", description: "array_part" },
        peg$c72 = function(k) {return k},
        peg$c73 = function(d, a) { if (a) { return d.concat(a); } else { return d; } },
        peg$c74 = { type: "other", description: "inline" },
        peg$c75 = "\"",
        peg$c76 = { type: "literal", value: "\"", description: "\"\\\"\"" },
        peg$c77 = function() { return withPosition(["literal", ""]) },
        peg$c78 = function(l) { return withPosition(["literal", l]) },
        peg$c79 = function(p) { return withPosition(["body"].concat(p)) },
        peg$c80 = function(l) { return ["buffer", l] },
        peg$c81 = { type: "other", description: "buffer" },
        peg$c82 = function(e, w) { return withPosition(["format", e, w.join('')]) },
        peg$c83 = { type: "any", description: "any character" },
        peg$c84 = function(c) {return c},
        peg$c85 = function(b) { return withPosition(["buffer", b.join('')]) },
        peg$c86 = { type: "other", description: "literal" },
        peg$c87 = /^[^"]/,
        peg$c88 = { type: "class", value: "[^\"]", description: "[^\"]" },
        peg$c89 = function(b) { return b.join('') },
        peg$c90 = "\\\"",
        peg$c91 = { type: "literal", value: "\\\"", description: "\"\\\\\\\"\"" },
        peg$c92 = function() { return '"' },
        peg$c93 = { type: "other", description: "raw" },
        peg$c94 = "{`",
        peg$c95 = { type: "literal", value: "{`", description: "\"{`\"" },
        peg$c96 = "`}",
        peg$c97 = { type: "literal", value: "`}", description: "\"`}\"" },
        peg$c98 = function(character) {return character},
        peg$c99 = function(rawText) { return withPosition(["raw", rawText.join('')]) },
        peg$c100 = { type: "other", description: "comment" },
        peg$c101 = "{!",
        peg$c102 = { type: "literal", value: "{!", description: "\"{!\"" },
        peg$c103 = "!}",
        peg$c104 = { type: "literal", value: "!}", description: "\"!}\"" },
        peg$c105 = function(c) { return withPosition(["comment", c.join('')]) },
        peg$c106 = /^[#?\^><+%:@\/~%]/,
        peg$c107 = { type: "class", value: "[#?^><+%:@/~%]", description: "[#?^><+%:@/~%]" },
        peg$c108 = "{",
        peg$c109 = { type: "literal", value: "{", description: "\"{\"" },
        peg$c110 = "}",
        peg$c111 = { type: "literal", value: "}", description: "\"}\"" },
        peg$c112 = "[",
        peg$c113 = { type: "literal", value: "[", description: "\"[\"" },
        peg$c114 = "]",
        peg$c115 = { type: "literal", value: "]", description: "\"]\"" },
        peg$c116 = "\n",
        peg$c117 = { type: "literal", value: "\n", description: "\"\\n\"" },
        peg$c118 = "\r\n",
        peg$c119 = { type: "literal", value: "\r\n", description: "\"\\r\\n\"" },
        peg$c120 = "\r",
        peg$c121 = { type: "literal", value: "\r", description: "\"\\r\"" },
        peg$c122 = "\u2028",
        peg$c123 = { type: "literal", value: "\u2028", description: "\"\\u2028\"" },
        peg$c124 = "\u2029",
        peg$c125 = { type: "literal", value: "\u2029", description: "\"\\u2029\"" },
        peg$c126 = /^[\t\x0B\f \xA0\uFEFF]/,
        peg$c127 = { type: "class", value: "[\\t\\v\\f \\u00A0\\uFEFF]", description: "[\\t\\v\\f \\u00A0\\uFEFF]" },
        peg$savedPos         = 0,
        peg$posDetailsCache  = [{ line: 1, column: 1, seenCR: false }],
      return input.substring(peg$savedPos, peg$currPos);
    function location() {
      return peg$computeLocation(peg$savedPos, peg$currPos);
        input.substring(peg$savedPos, peg$currPos),
        peg$computeLocation(peg$savedPos, peg$currPos)
      throw peg$buildException(
        message,
        null,
        input.substring(peg$savedPos, peg$currPos),
        peg$computeLocation(peg$savedPos, peg$currPos)
      );
      var details = peg$posDetailsCache[pos],
          p, ch;

      if (details) {
        return details;
      } else {
        p = pos - 1;
        while (!peg$posDetailsCache[p]) {
          p--;
        }

        details = peg$posDetailsCache[p];
        details = {
          line:   details.line,
          column: details.column,
          seenCR: details.seenCR
        };
        while (p < pos) {
          p++;

        peg$posDetailsCache[pos] = details;
        return details;
    }
    function peg$computeLocation(startPos, endPos) {
      var startPosDetails = peg$computePosDetails(startPos),
          endPosDetails   = peg$computePosDetails(endPos);

      return {
        start: {
          offset: startPos,
          line:   startPosDetails.line,
          column: startPosDetails.column
        },
        end: {
          offset: endPos,
          line:   endPosDetails.line,
          column: endPosDetails.column
        }
      };
    function peg$buildException(message, expected, found, location) {
            .replace(/[\u0100-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
            .replace(/[\u1000-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
      return new peg$SyntaxError(
        location
        peg$savedPos = s0;
        s1 = peg$c0(s1);
                  s6 = null;
                  peg$savedPos = peg$currPos;
                  s7 = peg$c2(s1, s4, s5, s6);
                    s7 = void 0;
                    s7 = peg$FAILED;
                    peg$savedPos = s0;
                    s1 = peg$c3(s1, s4, s5, s6);
                    s0 = peg$FAILED;
                  s0 = peg$FAILED;
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
              s3 = peg$c4;
              if (peg$silentFails === 0) { peg$fail(peg$c5); }
                peg$savedPos = s0;
                s1 = peg$c6(s1);
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c1); }
        if (peg$c7.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c8); }
                  peg$savedPos = s0;
                  s1 = peg$c9(s2, s4, s5, s6);
                  s0 = peg$FAILED;
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
          s2 = peg$c4;
          if (peg$silentFails === 0) { peg$fail(peg$c5); }
                  peg$savedPos = s0;
                  s1 = peg$c11(s4);
                  s0 = peg$FAILED;
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c10); }
        s2 = peg$c12;
        if (peg$silentFails === 0) { peg$fail(peg$c13); }
          peg$savedPos = s1;
          s2 = peg$c14(s3);
          s1 = peg$FAILED;
        s1 = peg$FAILED;
        s1 = null;
        peg$savedPos = s0;
        s1 = peg$c15(s1);
        s3 = peg$FAILED;
            s5 = peg$c17;
            if (peg$silentFails === 0) { peg$fail(peg$c18); }
              peg$savedPos = s2;
              s3 = peg$c19(s4, s6);
              s2 = peg$FAILED;
            s2 = peg$FAILED;
          s2 = peg$FAILED;
        s2 = peg$FAILED;
          s3 = peg$FAILED;
              s5 = peg$c17;
              if (peg$silentFails === 0) { peg$fail(peg$c18); }
                peg$savedPos = s2;
                s3 = peg$c19(s4, s6);
                s2 = peg$FAILED;
              s2 = peg$FAILED;
            s2 = peg$FAILED;
          s2 = peg$FAILED;
        peg$savedPos = s0;
        s1 = peg$c20(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c16); }
          s4 = peg$c12;
          if (peg$silentFails === 0) { peg$fail(peg$c13); }
                peg$savedPos = s2;
                s3 = peg$c19(s5, s7);
                s2 = peg$FAILED;
              s2 = peg$FAILED;
            s2 = peg$FAILED;
          s2 = peg$FAILED;
        s2 = peg$FAILED;
            s4 = peg$c12;
            if (peg$silentFails === 0) { peg$fail(peg$c13); }
                  peg$savedPos = s2;
                  s3 = peg$c19(s5, s7);
                  s2 = peg$FAILED;
                s2 = peg$FAILED;
              s2 = peg$FAILED;
            s2 = peg$FAILED;
          s2 = peg$FAILED;
        peg$savedPos = s0;
        s1 = peg$c22(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c21); }
              peg$savedPos = s0;
              s1 = peg$c24(s2, s3);
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c23); }
          s2 = peg$c26;
          if (peg$silentFails === 0) { peg$fail(peg$c27); }
            s2 = peg$c28;
            if (peg$silentFails === 0) { peg$fail(peg$c29); }
              peg$savedPos = s4;
              s5 = peg$c30(s2, s5);
                      s8 = peg$c4;
                      if (peg$silentFails === 0) { peg$fail(peg$c5); }
                        peg$savedPos = s0;
                        s1 = peg$c31(s2, s4, s5, s6);
                        s0 = peg$FAILED;
                      s0 = peg$FAILED;
                    s0 = peg$FAILED;
                  s0 = peg$FAILED;
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c25); }
        s3 = peg$c33;
        if (peg$silentFails === 0) { peg$fail(peg$c34); }
          peg$savedPos = s2;
          s3 = peg$c14(s4);
          s2 = peg$FAILED;
        s2 = peg$FAILED;
          s3 = peg$c33;
          if (peg$silentFails === 0) { peg$fail(peg$c34); }
            peg$savedPos = s2;
            s3 = peg$c14(s4);
            s2 = peg$FAILED;
          s2 = peg$FAILED;
        peg$savedPos = s0;
        s1 = peg$c35(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c32); }
          s2 = peg$c37;
          if (peg$silentFails === 0) { peg$fail(peg$c38); }
              peg$savedPos = s0;
              s1 = peg$c39(s3);
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c36); }
        peg$savedPos = s0;
        s1 = peg$c41(s1);
          peg$savedPos = s0;
          s1 = peg$c42(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c40); }
        peg$savedPos = s0;
        s1 = peg$c44(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c43); }
          s2 = peg$c46;
          if (peg$silentFails === 0) { peg$fail(peg$c47); }
            peg$savedPos = s0;
            s1 = peg$c48(s1, s3);
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c45); }
      if (peg$c50.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c51); }
          if (peg$c50.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c51); }
        s1 = peg$FAILED;
        peg$savedPos = s0;
        s1 = peg$c52(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c49); }
        s1 = peg$c54;
        if (peg$silentFails === 0) { peg$fail(peg$c55); }
          peg$savedPos = s0;
          s1 = peg$c56(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c53); }
        if (peg$silentFails === 0) { peg$fail(peg$c57); }
        s1 = null;
          s2 = peg$FAILED;
          peg$savedPos = s0;
          s1 = peg$c59(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
          s1 = peg$c46;
          if (peg$silentFails === 0) { peg$fail(peg$c47); }
            peg$savedPos = s0;
            s1 = peg$c60(s2);
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c58); }
      if (peg$c62.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c63); }
        if (peg$c64.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c65); }
          if (peg$c64.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c65); }
          peg$savedPos = s0;
          s1 = peg$c66(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c61); }
        if (peg$c50.test(input.charAt(peg$currPos))) {
          if (peg$silentFails === 0) { peg$fail(peg$c51); }
            if (peg$c50.test(input.charAt(peg$currPos))) {
              if (peg$silentFails === 0) { peg$fail(peg$c51); }
          s4 = peg$FAILED;
          peg$savedPos = s3;
          s4 = peg$c68(s4);
            peg$savedPos = s1;
            s2 = peg$c69(s3);
            s1 = peg$FAILED;
          s1 = peg$FAILED;
        s1 = peg$FAILED;
          s2 = null;
          peg$savedPos = s0;
          s1 = peg$c70(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c67); }
        s3 = peg$c46;
        if (peg$silentFails === 0) { peg$fail(peg$c47); }
          peg$savedPos = s2;
          s3 = peg$c72(s4);
          s2 = peg$FAILED;
        s2 = peg$FAILED;
            s3 = peg$c46;
            if (peg$silentFails === 0) { peg$fail(peg$c47); }
              peg$savedPos = s2;
              s3 = peg$c72(s4);
              s2 = peg$FAILED;
            s2 = peg$FAILED;
        s1 = peg$FAILED;
          s2 = null;
          peg$savedPos = s0;
          s1 = peg$c73(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c71); }
        s1 = peg$c75;
        if (peg$silentFails === 0) { peg$fail(peg$c76); }
          s2 = peg$c75;
          if (peg$silentFails === 0) { peg$fail(peg$c76); }
          peg$savedPos = s0;
          s1 = peg$c77();
          s0 = peg$FAILED;
        s0 = peg$FAILED;
          s1 = peg$c75;
          if (peg$silentFails === 0) { peg$fail(peg$c76); }
              s3 = peg$c75;
              if (peg$silentFails === 0) { peg$fail(peg$c76); }
              peg$savedPos = s0;
              s1 = peg$c78(s2);
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
            s1 = peg$c75;
            if (peg$silentFails === 0) { peg$fail(peg$c76); }
              s2 = peg$FAILED;
                s3 = peg$c75;
                if (peg$silentFails === 0) { peg$fail(peg$c76); }
                peg$savedPos = s0;
                s1 = peg$c79(s2);
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c74); }
            peg$savedPos = s0;
            s1 = peg$c80(s1);
          peg$savedPos = s0;
          s1 = peg$c82(s1, s2);
          s0 = peg$FAILED;
        s0 = peg$FAILED;
          s3 = void 0;
          s3 = peg$FAILED;
            s4 = void 0;
            s4 = peg$FAILED;
              s5 = void 0;
              s5 = peg$FAILED;
                s6 = void 0;
                s6 = peg$FAILED;
                  if (peg$silentFails === 0) { peg$fail(peg$c83); }
                  peg$savedPos = s2;
                  s3 = peg$c84(s7);
                  s2 = peg$FAILED;
                s2 = peg$FAILED;
              s2 = peg$FAILED;
            s2 = peg$FAILED;
          s2 = peg$FAILED;
              s3 = void 0;
              s3 = peg$FAILED;
                s4 = void 0;
                s4 = peg$FAILED;
                  s5 = void 0;
                  s5 = peg$FAILED;
                    s6 = void 0;
                    s6 = peg$FAILED;
                      if (peg$silentFails === 0) { peg$fail(peg$c83); }
                      peg$savedPos = s2;
                      s3 = peg$c84(s7);
                      s2 = peg$FAILED;
                    s2 = peg$FAILED;
                  s2 = peg$FAILED;
                s2 = peg$FAILED;
              s2 = peg$FAILED;
          s1 = peg$FAILED;
          peg$savedPos = s0;
          s1 = peg$c85(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c81); }
        s3 = void 0;
        s3 = peg$FAILED;
          if (peg$c87.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c88); }
          peg$savedPos = s2;
          s3 = peg$c84(s4);
          s2 = peg$FAILED;
        s2 = peg$FAILED;
            s3 = void 0;
            s3 = peg$FAILED;
              if (peg$c87.test(input.charAt(peg$currPos))) {
                if (peg$silentFails === 0) { peg$fail(peg$c88); }
              peg$savedPos = s2;
              s3 = peg$c84(s4);
              s2 = peg$FAILED;
            s2 = peg$FAILED;
        s1 = peg$FAILED;
        peg$savedPos = s0;
        s1 = peg$c89(s1);
        if (peg$silentFails === 0) { peg$fail(peg$c86); }
      if (input.substr(peg$currPos, 2) === peg$c90) {
        s1 = peg$c90;
        if (peg$silentFails === 0) { peg$fail(peg$c91); }
        peg$savedPos = s0;
        s1 = peg$c92();
      if (input.substr(peg$currPos, 2) === peg$c94) {
        s1 = peg$c94;
        if (peg$silentFails === 0) { peg$fail(peg$c95); }
        if (input.substr(peg$currPos, 2) === peg$c96) {
          s5 = peg$c96;
          if (peg$silentFails === 0) { peg$fail(peg$c97); }
          s4 = void 0;
          s4 = peg$FAILED;
            if (peg$silentFails === 0) { peg$fail(peg$c83); }
            peg$savedPos = s3;
            s4 = peg$c98(s5);
            s3 = peg$FAILED;
          s3 = peg$FAILED;
          if (input.substr(peg$currPos, 2) === peg$c96) {
            s5 = peg$c96;
            if (peg$silentFails === 0) { peg$fail(peg$c97); }
            s4 = void 0;
            s4 = peg$FAILED;
              if (peg$silentFails === 0) { peg$fail(peg$c83); }
              peg$savedPos = s3;
              s4 = peg$c98(s5);
              s3 = peg$FAILED;
            s3 = peg$FAILED;
          if (input.substr(peg$currPos, 2) === peg$c96) {
            s3 = peg$c96;
            if (peg$silentFails === 0) { peg$fail(peg$c97); }
            peg$savedPos = s0;
            s1 = peg$c99(s2);
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c93); }
      if (input.substr(peg$currPos, 2) === peg$c101) {
        s1 = peg$c101;
        if (peg$silentFails === 0) { peg$fail(peg$c102); }
        if (input.substr(peg$currPos, 2) === peg$c103) {
          s5 = peg$c103;
          if (peg$silentFails === 0) { peg$fail(peg$c104); }
          s4 = void 0;
          s4 = peg$FAILED;
            if (peg$silentFails === 0) { peg$fail(peg$c83); }
            peg$savedPos = s3;
            s4 = peg$c84(s5);
            s3 = peg$FAILED;
          s3 = peg$FAILED;
          if (input.substr(peg$currPos, 2) === peg$c103) {
            s5 = peg$c103;
            if (peg$silentFails === 0) { peg$fail(peg$c104); }
            s4 = void 0;
            s4 = peg$FAILED;
              if (peg$silentFails === 0) { peg$fail(peg$c83); }
              peg$savedPos = s3;
              s4 = peg$c84(s5);
              s3 = peg$FAILED;
            s3 = peg$FAILED;
          if (input.substr(peg$currPos, 2) === peg$c103) {
            s3 = peg$c103;
            if (peg$silentFails === 0) { peg$fail(peg$c104); }
            peg$savedPos = s0;
            s1 = peg$c105(s2);
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        if (peg$silentFails === 0) { peg$fail(peg$c100); }
          if (peg$c106.test(input.charAt(peg$currPos))) {
            if (peg$silentFails === 0) { peg$fail(peg$c107); }
                s7 = void 0;
                s7 = peg$FAILED;
                  s8 = void 0;
                  s8 = peg$FAILED;
                    if (peg$silentFails === 0) { peg$fail(peg$c83); }
                    s6 = peg$FAILED;
                  s6 = peg$FAILED;
                s6 = peg$FAILED;
                    s7 = void 0;
                    s7 = peg$FAILED;
                      s8 = void 0;
                      s8 = peg$FAILED;
                        if (peg$silentFails === 0) { peg$fail(peg$c83); }
                        s6 = peg$FAILED;
                      s6 = peg$FAILED;
                    s6 = peg$FAILED;
                s5 = peg$FAILED;
                    s0 = peg$FAILED;
                  s0 = peg$FAILED;
                s0 = peg$FAILED;
              s0 = peg$FAILED;
            s0 = peg$FAILED;
          s0 = peg$FAILED;
        s0 = peg$FAILED;
        s0 = peg$c108;
        if (peg$silentFails === 0) { peg$fail(peg$c109); }
        s0 = peg$c110;
        if (peg$silentFails === 0) { peg$fail(peg$c111); }
        s0 = peg$c112;
        if (peg$silentFails === 0) { peg$fail(peg$c113); }
        s0 = peg$c114;
        if (peg$silentFails === 0) { peg$fail(peg$c115); }
        s0 = peg$c116;
        if (peg$silentFails === 0) { peg$fail(peg$c117); }
        if (input.substr(peg$currPos, 2) === peg$c118) {
          s0 = peg$c118;
          if (peg$silentFails === 0) { peg$fail(peg$c119); }
            s0 = peg$c120;
            if (peg$silentFails === 0) { peg$fail(peg$c121); }
              s0 = peg$c122;
              if (peg$silentFails === 0) { peg$fail(peg$c123); }
                s0 = peg$c124;
                if (peg$silentFails === 0) { peg$fail(peg$c125); }
      if (peg$c126.test(input.charAt(peg$currPos))) {
        if (peg$silentFails === 0) { peg$fail(peg$c127); }
        arr.location = location();
        return arr;
      throw peg$buildException(
        null,
        peg$maxFailExpected,
        peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
        peg$maxFailPos < input.length
          ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
          : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
      );
    SyntaxError: peg$SyntaxError,
    parse:       peg$parse
  var escape = (typeof JSON === 'undefined') ?
                  function(str) { return '"' + escapeToJsSafeString(str) + '"';} :
                  JSON.stringify;
    } catch (err) {
      if (!err.location) {
      throw new SyntaxError(err.message + ' [' + name + ':' + err.location.start.line + ':' + err.location.start.column + ']');
    comment:   nullify
            memo[1] += res.slice(1).join('');
      // Format nodes are in the form ['format', eol, whitespace],
      node.splice(1, 2, node.slice(1).join(''));
      if (Object.prototype.hasOwnProperty.call(blocks, name)) {
        out.push('"' + name + '":' + blocks[name]);
      }
            require([name], function(tmpl) {
                cb(null, tmpl);
* Copyright (c) 2021 Aleksander Williams; Released under the MIT License */
!function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.core",[],b):"object"==typeof exports?module.exports=b():a.dust=b()}(this,function(){function getTemplate(a,b){if(a)return"function"==typeof a&&a.template?a.template:dust.isTemplateFn(a)?a:b!==!1?dust.cache[a]:void 0}function load(a,b,c){if(!a)return b.setError(new Error("No template or template name provided to render"));var d=getTemplate(a,dust.config.cache);return d?d(b,Context.wrap(c,d.templateName)):dust.onLoad?b.map(function(b){function d(a,d){var f;if(a)return b.setError(a);if(f=getTemplate(d,!1)||getTemplate(e,dust.config.cache),!f){if(!dust.compile)return b.setError(new Error("Dust compiler not available"));f=dust.loadSource(dust.compile(d,e))}f(b,Context.wrap(c,f.templateName)).end()}var e=a;3===dust.onLoad.length?dust.onLoad(e,c.options,d):dust.onLoad(e,d)}):b.setError(new Error("Template Not Found: "+a))}function Context(a,b,c,d,e){void 0===a||a instanceof Stack||(a=new Stack(a)),this.stack=a,this.global=b,this.options=c,this.blocks=d,this.templateName=e,this._isContext=!0}function getWithResolvedData(a,b,c){return function(d){return a.push(d)._get(b,c)}}function Stack(a,b,c,d){this.tail=b,this.isObject=a&&"object"==typeof a,this.head=a,this.index=c,this.of=d}function Stub(a){this.head=new Chunk(this),this.callback=a,this.out=""}function Stream(){this.head=new Chunk(this)}function Chunk(a,b,c){this.root=a,this.next=b,this.data=[],this.flushable=!1,this.taps=c}function mapThenable(a,b,c,d,e){return a.map(function(a){b.then(function(b){try{e(a,b)}catch(c){dust.log(c,ERROR),a.setError(c)}},function(b){dust.log("Unhandled promise rejection in `"+c.getTemplateName()+"`",INFO),a.renderError(b,c,d).end()})})}function Tap(a,b){this.head=a,this.tail=b}var dust={version:"2.7.2"},NONE="NONE",ERROR="ERROR",WARN="WARN",INFO="INFO",DEBUG="DEBUG",EMPTY_FUNC=function(){};dust.config={whitespace:!1,amd:!1,cjs:!1,cache:!0},dust._aliases={write:"w",end:"e",map:"m",render:"r",reference:"f",section:"s",exists:"x",notexists:"nx",block:"b",partial:"p",helper:"h"},function(){var a,b,c={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};"undefined"!=typeof console&&console.log?(a=console.log,b="function"==typeof a?function(){a.apply(console,arguments)}:function(){a(Array.prototype.slice.apply(arguments).join(" "))}):b=EMPTY_FUNC,dust.log=function(a,d){d=d||INFO,c[d]>=c[dust.debugLevel]&&(b("[DUST:"+d+"]",a),d===ERROR&&dust.debugLevel===DEBUG&&a instanceof Error&&a.stack&&b("[DUST:"+d+"]",a.stack))},dust.debugLevel=NONE,"undefined"!=typeof process&&process.env&&/\bdust\b/.test(process.env.DEBUG)&&(dust.debugLevel=DEBUG)}(),dust.helpers={},dust.cache={},dust.register=function(a,b){a&&(b.templateName=a,dust.config.cache!==!1&&(dust.cache[a]=b))},dust.render=function(a,b,c){var d=new Stub(c).head;try{load(a,d,b).end()}catch(e){d.setError(e)}},dust.stream=function(a,b){var c=new Stream,d=c.head;return dust.nextTick(function(){try{load(a,d,b).end()}catch(c){d.setError(c)}}),c},dust.loadSource=function(source){return eval(source)},Array.isArray?dust.isArray=Array.isArray:dust.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},dust.nextTick=function(){return function(a){setTimeout(a,0)}}(),dust.isEmpty=function(a){return 0!==a&&(!(!dust.isArray(a)||a.length)||!a)},dust.isEmptyObject=function(a){var b;if(null===a)return!1;if(void 0===a)return!1;if(a.length>0)return!1;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b))return!1;return!0},dust.isTemplateFn=function(a){return"function"==typeof a&&a.__dustBody},dust.isThenable=function(a){return a&&("object"==typeof a||"function"==typeof a)&&"function"==typeof a.then},dust.isNonThenableFunction=function(a){return"function"==typeof a&&!dust.isThenable(a)},dust.isStreamable=function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pipe},dust.filter=function(a,b,c,d){var e,f,g,h;if(c)for(e=0,f=c.length;e<f;e++)g=c[e],g.length&&(h=dust.filters[g],"s"===g?b=null:"function"==typeof h?a=h(a,d):dust.log("Invalid filter `"+g+"`",WARN));return b&&(a=dust.filters[b](a,d)),a},dust.filters={h:function(a){return dust.escapeHtml(a)},j:function(a){return dust.escapeJs(a)},u:encodeURI,uc:encodeURIComponent,js:function(a){return dust.escapeJSON(a)},jp:function(a){return JSON?JSON.parse(a):(dust.log("JSON is undefined; could not parse `"+a+"`",WARN),a)}},dust.makeBase=dust.context=function(a,b){return new Context((void 0),a,b)},dust.isContext=function(a){return"object"==typeof a&&a._isContext===!0},Context.wrap=function(a,b){return dust.isContext(a)?(a.templateName=b,a):new Context(a,{},{},null,b)},Context.prototype.get=function(a,b){return"string"==typeof a&&("."===a[0]&&(b=!0,a=a.substr(1)),a=a.split(".")),this._get(b,a)},Context.prototype._get=function(a,b){var c,d,e,f,g,h=this.stack||{},i=1;if(d=b[0],e=b.length,a&&0===e)f=h,h=h.head;else{if(a)h&&(h=h.head?h.head[d]:void 0);else{for(;h&&(!h.isObject||(f=h.head,c=h.head[d],void 0===c));)h=h.tail;h=void 0!==c?c:this.global&&this.global[d]}for(;h&&i<e;){if(dust.isThenable(h))return h.then(getWithResolvedData(this,a,b.slice(i)));f=h,h=h[b[i]],i++}}return dust.isNonThenableFunction(h)?(g=function(){try{return h.apply(f,arguments)}catch(a){throw dust.log(a,ERROR),a}},g.__dustBody=!!h.__dustBody,g):(void 0===h&&dust.log("Cannot find reference `{"+b.join(".")+"}` in template `"+this.getTemplateName()+"`",INFO),h)},Context.prototype.getPath=function(a,b){return this._get(a,b)},Context.prototype.push=function(a,b,c){return void 0===a?(dust.log("Not pushing an undefined variable onto the context",INFO),this):this.rebase(new Stack(a,this.stack,b,c))},Context.prototype.pop=function(){var a=this.current();return this.stack=this.stack&&this.stack.tail,a},Context.prototype.rebase=function(a){return new Context(a,this.global,this.options,this.blocks,this.getTemplateName())},Context.prototype.clone=function(){var a=this.rebase();return a.stack=this.stack,a},Context.prototype.current=function(){return this.stack&&this.stack.head},Context.prototype.getBlock=function(a){var b,c,d;if("function"==typeof a&&(a=a(new Chunk,this).data.join("")),b=this.blocks,!b)return dust.log("No blocks for context `"+a+"` in template `"+this.getTemplateName()+"`",DEBUG),!1;for(c=b.length;c--;)if(d=b[c][a])return d;return dust.log("Malformed template `"+this.getTemplateName()+"` was missing one or more blocks."),!1},Context.prototype.shiftBlocks=function(a){var b,c=this.blocks;return a?(b=c?c.concat([a]):[a],new Context(this.stack,this.global,this.options,b,this.getTemplateName())):this},Context.prototype.resolve=function(a){var b;return"function"!=typeof a?a:(b=(new Chunk).render(a,this),b instanceof Chunk?b.data.join(""):b)},Context.prototype.getTemplateName=function(){return this.templateName},Stub.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.callback(a.error),dust.log("Rendering failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.out+=a.data.join(""),a=a.next,this.head=a}this.callback(null,this.out)},Stream.prototype.flush=function(){for(var a=this.head;a;){if(!a.flushable)return a.error?(this.emit("error",a.error),this.emit("end"),dust.log("Streaming failed with error `"+a.error+"`",ERROR),void(this.flush=EMPTY_FUNC)):void 0;this.emit("data",a.data.join("")),a=a.next,this.head=a}this.emit("end")},Stream.prototype.emit=function(a,b){var c,d,e=this.events||{},f=e[a]||[];if(!f.length)return dust.log("Stream broadcasting, but no listeners for `"+a+"`",DEBUG),!1;for(f=f.slice(0),c=0,d=f.length;c<d;c++)f[c](b);return!0},Stream.prototype.on=function(a,b){var c=this.events=this.events||{},d=c[a]=c[a]||[];return"function"!=typeof b?dust.log("No callback function provided for `"+a+"` event listener",WARN):d.push(b),this},Stream.prototype.pipe=function(a){if("function"!=typeof a.write||"function"!=typeof a.end)return dust.log("Incompatible stream passed to `pipe`",WARN),this;var b=!1;return"function"==typeof a.emit&&a.emit("pipe",this),"function"==typeof a.on&&a.on("error",function(){b=!0}),this.on("data",function(c){if(!b)try{a.write(c,"utf8")}catch(d){dust.log(d,ERROR)}}).on("end",function(){if(!b)try{a.end(),b=!0}catch(c){dust.log(c,ERROR)}})},Chunk.prototype.write=function(a){var b=this.taps;return b&&(a=b.go(a)),this.data.push(a),this},Chunk.prototype.end=function(a){return a&&this.write(a),this.flushable=!0,this.root.flush(),this},Chunk.prototype.map=function(a){var b=new Chunk(this.root,this.next,this.taps),c=new Chunk(this.root,b,this.taps);this.next=c,this.flushable=!0;try{a(c)}catch(d){dust.log(d,ERROR),c.setError(d)}return b},Chunk.prototype.tap=function(a){var b=this.taps;return b?this.taps=b.push(a):this.taps=new Tap(a),this},Chunk.prototype.untap=function(){return this.taps=this.taps.tail,this},Chunk.prototype.render=function(a,b){return a(this,b)},Chunk.prototype.reference=function(a,b,c,d){return dust.isNonThenableFunction(a)?(a=a.apply(b.current(),[this,b,null,{auto:c,filters:d}]),a instanceof Chunk?a:this.reference(a,b,c,d)):dust.isThenable(a)?this.await(a,b,null,c,d):dust.isStreamable(a)?this.stream(a,b,null,c,d):dust.isEmpty(a)?this:this.write(dust.filter(a,c,d,b))},Chunk.prototype.section=function(a,b,c,d){var e,f,g,h=c.block,i=c["else"],j=this;if(dust.isNonThenableFunction(a)&&!dust.isTemplateFn(a)){try{a=a.apply(b.current(),[this,b,c,d])}catch(k){return dust.log(k,ERROR),this.setError(k)}if(a instanceof Chunk)return a}if(dust.isEmptyObject(c))return j;if(dust.isEmptyObject(d)||(b=b.push(d)),dust.isArray(a)){if(h){if(f=a.length,f>0){for(g=b.stack&&b.stack.head||{},g.$len=f,e=0;e<f;e++)g.$idx=e,j=h(j,b.push(a[e],e,f));return g.$idx=void 0,g.$len=void 0,j}if(i)return i(this,b)}}else{if(dust.isThenable(a))return this.await(a,b,c);if(dust.isStreamable(a))return this.stream(a,b,c);if(a===!0){if(h)return h(this,b)}else if(a||0===a){if(h)return h(this,b.push(a))}else if(i)return i(this,b)}return dust.log("Section without corresponding key in template `"+b.getTemplateName()+"`",DEBUG),this},Chunk.prototype.exists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.exists(d,b,c).end()});if(dust.isEmpty(a)){if(e)return e(this,b)}else{if(d)return d(this,b);dust.log("No block for exists check in template `"+b.getTemplateName()+"`",DEBUG)}return this},Chunk.prototype.notexists=function(a,b,c){var d=c.block,e=c["else"];if(dust.isThenable(a))return mapThenable(this,a,b,c,function(a,d){a.notexists(d,b,c).end()});if(dust.isEmpty(a)){if(d)return d(this,b);dust.log("No block for not-exists check in template `"+b.getTemplateName()+"`",DEBUG)}else if(e)return e(this,b);return this},Chunk.prototype.block=function(a,b,c){var d=a||c.block;return d?d(this,b):this},Chunk.prototype.partial=function(a,b,c,d){var e;return void 0===d&&(d=c,c=b),dust.isEmptyObject(d)||(c=c.clone(),e=c.pop(),c=c.push(d).push(e)),dust.isTemplateFn(a)?this.capture(a,b,function(a,b){load(a,b,c).end()}):load(a,this,c)},Chunk.prototype.helper=function(a,b,c,d,e){var f,g=this,h=d.filters;if(void 0===e&&(e="h"),!dust.helpers[a])return dust.log("Helper `"+a+"` does not exist",WARN),g;try{return f=dust.helpers[a](g,b,c,d),f instanceof Chunk?f:("string"==typeof h&&(h=h.split("|")),dust.isEmptyObject(c)?g.reference(f,b,e,h):g.section(f,b,c,d))}catch(i){return dust.log("Error in helper `"+a+"`: "+i.message,ERROR),g.setError(i)}},Chunk.prototype.await=function(a,b,c,d,e){return mapThenable(this,a,b,c,function(a,f){c?a.section(f,b,c).end():a.reference(f,b,d,e).end()})},Chunk.prototype.renderError=function(a,b,c){var d=c&&c.error;return d?this.render(d,b.push(a)):this},Chunk.prototype.stream=function(a,b,c,d,e){var f=c&&c.block;return this.map(function(g){var h=!1;a.on("data",function(a){h||(f?g=g.map(function(c){c.render(f,b.push(a)).end()}):c||(g=g.reference(a,b,d,e)))}).on("error",function(a){h||(g.renderError(a,b,c),dust.log("Unhandled stream error in `"+b.getTemplateName()+"`",INFO),h||(h=!0,g.end()))}).on("end",function(){h||(h=!0,g.end())})})},Chunk.prototype.capture=function(a,b,c){return this.map(function(d){var e=new Stub(function(a,b){a?d.setError(a):c(b,d)});a(e.head,b).end()})},Chunk.prototype.setError=function(a){return this.error=a,this.root.flush(),this};for(var f in Chunk.prototype)dust._aliases[f]&&(Chunk.prototype[dust._aliases[f]]=Chunk.prototype[f]);Tap.prototype.push=function(a){return new Tap(a,this)},Tap.prototype.go=function(a){for(var b=this;b;)a=b.head(a),b=b.tail;return a};var HCHARS=/[&<>"']/,AMP=/&/g,LT=/</g,GT=/>/g,QUOT=/\"/g,SQUOT=/\'/g;dust.escapeHtml=function(a){return"string"==typeof a||a&&"function"==typeof a.toString?("string"!=typeof a&&(a=a.toString()),HCHARS.test(a)?a.replace(AMP,"&amp;").replace(LT,"&lt;").replace(GT,"&gt;").replace(QUOT,"&quot;").replace(SQUOT,"&#39;"):a):a};var BS=/\\/g,FS=/\//g,CR=/\r/g,LS=/\u2028/g,PS=/\u2029/g,NL=/\n/g,LF=/\f/g,SQ=/'/g,DQ=/"/g,TB=/\t/g;return dust.escapeJs=function(a){return"string"==typeof a?a.replace(BS,"\\\\").replace(FS,"\\/").replace(DQ,'\\"').replace(SQ,"\\'").replace(CR,"\\r").replace(LS,"\\u2028").replace(PS,"\\u2029").replace(NL,"\\n").replace(LF,"\\f").replace(TB,"\\t"):a},dust.escapeJSON=function(a){return JSON?JSON.stringify(a).replace(LS,"\\u2028").replace(PS,"\\u2029").replace(LT,"\\u003c"):(dust.log("JSON is undefined; could not escape `"+a+"`",WARN),a)},dust}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.parse",["dust.core"],function(dust){return b(dust).parse}):"object"==typeof exports?module.exports=b(require("./dust")):b(a.dust)}(this,function(dust){var a=function(){"use strict";function a(a,b){function c(){this.constructor=a}c.prototype=b.prototype,a.prototype=new c}function b(a,c,d,e){this.message=a,this.expected=c,this.found=d,this.location=e,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,b)}function c(a){function c(){return f(tc,sc)}function d(b){throw h(b,null,a.substring(tc,sc),f(tc,sc))}function e(b){var c,d,e=uc[b];if(e)return e;for(c=b-1;!uc[c];)c--;for(e=uc[c],e={line:e.line,column:e.column,seenCR:e.seenCR};c<b;)d=a.charAt(c),"\n"===d?(e.seenCR||e.line++,e.column=1,e.seenCR=!1):"\r"===d||"\u2028"===d||"\u2029"===d?(e.line++,e.column=1,e.seenCR=!0):(e.column++,e.seenCR=!1),c++;return uc[b]=e,e}function f(a,b){var c=e(a),d=e(b);return{start:{offset:a,line:c.line,column:c.column},end:{offset:b,line:d.line,column:d.column}}}function g(a){sc<vc||(sc>vc&&(vc=sc,wc=[]),wc.push(a))}function h(a,c,d,e){function f(a){var b=1;for(a.sort(function(a,b){return a.description<b.description?-1:a.description>b.description?1:0});b<a.length;)a[b-1]===a[b]?a.splice(b,1):b++}function g(a,b){function c(a){function b(a){return a.charCodeAt(0).toString(16).toUpperCase()}return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(a){return"\\x0"+b(a)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(a){return"\\x"+b(a)}).replace(/[\u0100-\u0FFF]/g,function(a){return"\\u0"+b(a)}).replace(/[\u1000-\uFFFF]/g,function(a){return"\\u"+b(a)})}var d,e,f,g=new Array(a.length);for(f=0;f<a.length;f++)g[f]=a[f].description;return d=a.length>1?g.slice(0,-1).join(", ")+" or "+g[a.length-1]:g[0],e=b?'"'+c(b)+'"':"end of input","Expected "+d+" but "+e+" found."}return null!==c&&f(c),new b(null!==a?a:g(c,d),c,d,e)}function i(){var a;return a=j()}function j(){var a,b,c;for(a=sc,b=[],c=k();c!==X;)b.push(c),c=k();return b!==X&&(tc=a,b=$(b)),a=b}function k(){var a;return a=K(),a===X&&(a=L(),a===X&&(a=l(),a===X&&(a=s(),a===X&&(a=u(),a===X&&(a=r(),a===X&&(a=H())))))),a}function l(){var b,c,d,e,f,h,i,k;if(xc++,b=sc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(e=O(),e!==X?(f=j(),f!==X?(h=q(),h!==X?(i=n(),i===X&&(i=null),i!==X?(tc=sc,k=aa(c,f,h,i),k=k?void 0:X,k!==X?(tc=b,c=ba(c,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;if(b===X)if(b=sc,c=m(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(47===a.charCodeAt(sc)?(e=ca,sc++):(e=X,0===xc&&g(da)),e!==X?(f=O(),f!==X?(tc=b,c=ea(c),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(_)),b}function m(){var b,c,d,e,f,h,i;if(b=sc,c=N(),c!==X)if(fa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(ga)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();e!==X?(f=v(),f!==X?(h=o(),h!==X?(i=p(),i!==X?(tc=b,c=ha(d,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X;return b}function n(){var b,c,d,e,f,h,i;if(xc++,b=sc,c=N(),c!==X)if(47===a.charCodeAt(sc)?(d=ca,sc++):(d=X,0===xc&&g(da)),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=v(),f!==X){for(h=[],i=S();i!==X;)h.push(i),i=S();h!==X?(i=O(),i!==X?(tc=b,c=ja(f),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(ia)),b}function o(){var b,c,d,e;return b=sc,c=sc,58===a.charCodeAt(sc)?(d=ka,sc++):(d=X,0===xc&&g(la)),d!==X?(e=v(),e!==X?(tc=c,d=ma(e),c=d):(sc=c,c=X)):(sc=c,c=X),c===X&&(c=null),c!==X&&(tc=b,c=na(c)),b=c}function p(){var b,c,d,e,f,h,i;if(xc++,b=sc,c=[],d=sc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=X;for(e!==X?(f=C(),f!==X?(61===a.charCodeAt(sc)?(h=pa,sc++):(h=X,0===xc&&g(qa)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(tc=d,e=ra(f,i),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);d!==X;){if(c.push(d),d=sc,e=[],f=S(),f!==X)for(;f!==X;)e.push(f),f=S();else e=X;e!==X?(f=C(),f!==X?(61===a.charCodeAt(sc)?(h=pa,sc++):(h=X,0===xc&&g(qa)),h!==X?(i=w(),i===X&&(i=v(),i===X&&(i=F())),i!==X?(tc=d,e=ra(f,i),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)}return c!==X&&(tc=b,c=sa(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(oa)),b}function q(){var b,c,d,e,f,h,i,k;for(xc++,b=sc,c=[],d=sc,e=N(),e!==X?(58===a.charCodeAt(sc)?(f=ka,sc++):(f=X,0===xc&&g(la)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(tc=d,e=ra(h,k),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);d!==X;)c.push(d),d=sc,e=N(),e!==X?(58===a.charCodeAt(sc)?(f=ka,sc++):(f=X,0===xc&&g(la)),f!==X?(h=C(),h!==X?(i=O(),i!==X?(k=j(),k!==X?(tc=d,e=ra(h,k),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);return c!==X&&(tc=b,c=ua(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(ta)),b}function r(){var a,b,c,d,e;return xc++,a=sc,b=N(),b!==X?(c=v(),c!==X?(d=t(),d!==X?(e=O(),e!==X?(tc=a,b=wa(c,d),a=b):(sc=a,a=X)):(sc=a,a=X)):(sc=a,a=X)):(sc=a,a=X),xc--,a===X&&(b=X,0===xc&&g(va)),a}function s(){var b,c,d,e,f,h,i,j,k,l;if(xc++,b=sc,c=N(),c!==X)if(62===a.charCodeAt(sc)?(d=ya,sc++):(d=X,0===xc&&g(za)),d===X&&(43===a.charCodeAt(sc)?(d=Aa,sc++):(d=X,0===xc&&g(Ba))),d!==X){for(e=[],f=S();f!==X;)e.push(f),f=S();if(e!==X)if(f=sc,h=C(),h!==X&&(tc=f,h=Ca(d,h)),f=h,f===X&&(f=F()),f!==X)if(h=o(),h!==X)if(i=p(),i!==X){for(j=[],k=S();k!==X;)j.push(k),k=S();j!==X?(47===a.charCodeAt(sc)?(k=ca,sc++):(k=X,0===xc&&g(da)),k!==X?(l=O(),l!==X?(tc=b,c=Da(d,f,h,i),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;else sc=b,b=X;else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(xa)),b}function t(){var b,c,d,e,f;for(xc++,b=sc,c=[],d=sc,124===a.charCodeAt(sc)?(e=Fa,sc++):(e=X,0===xc&&g(Ga)),e!==X?(f=C(),f!==X?(tc=d,e=ma(f),d=e):(sc=d,d=X)):(sc=d,d=X);d!==X;)c.push(d),d=sc,124===a.charCodeAt(sc)?(e=Fa,sc++):(e=X,0===xc&&g(Ga)),e!==X?(f=C(),f!==X?(tc=d,e=ma(f),d=e):(sc=d,d=X)):(sc=d,d=X);return c!==X&&(tc=b,c=Ha(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Ea)),b}function u(){var b,c,d,e,f;return xc++,b=sc,c=N(),c!==X?(126===a.charCodeAt(sc)?(d=Ja,sc++):(d=X,0===xc&&g(Ka)),d!==X?(e=C(),e!==X?(f=O(),f!==X?(tc=b,c=La(e),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Ia)),b}function v(){var a,b;return xc++,a=sc,b=B(),b!==X&&(tc=a,b=Na(b)),a=b,a===X&&(a=sc,b=C(),b!==X&&(tc=a,b=Oa(b)),a=b),xc--,a===X&&(b=X,0===xc&&g(Ma)),a}function w(){var a,b;return xc++,a=sc,b=x(),b===X&&(b=A()),b!==X&&(tc=a,b=Qa(b)),a=b,xc--,a===X&&(b=X,0===xc&&g(Pa)),a}function x(){var b,c,d,e;return xc++,b=sc,c=A(),c!==X?(46===a.charCodeAt(sc)?(d=Sa,sc++):(d=X,0===xc&&g(Ta)),d!==X?(e=y(),e!==X?(tc=b,c=Ua(c,e),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Ra)),b}function y(){var b,c,d;if(xc++,b=sc,c=[],Wa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(Xa)),d!==X)for(;d!==X;)c.push(d),Wa.test(a.charAt(sc))?(d=a.charAt(sc),sc++):(d=X,0===xc&&g(Xa));else c=X;return c!==X&&(tc=b,c=Ya(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Va)),b}function z(){var b,c,d;return xc++,b=sc,45===a.charCodeAt(sc)?(c=$a,sc++):(c=X,0===xc&&g(_a)),c!==X?(d=y(),d!==X?(tc=b,c=ab(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(Za)),b}function A(){var a,b;return xc++,a=z(),a===X&&(a=y()),xc--,a===X&&(b=X,0===xc&&g(bb)),a}function B(){var b,c,d,e;if(xc++,b=sc,c=C(),c===X&&(c=null),c!==X){if(d=[],e=E(),e===X&&(e=D()),e!==X)for(;e!==X;)d.push(e),e=E(),e===X&&(e=D());else d=X;d!==X?(tc=b,c=db(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;if(b===X)if(b=sc,46===a.charCodeAt(sc)?(c=Sa,sc++):(c=X,0===xc&&g(Ta)),c!==X){for(d=[],e=E(),e===X&&(e=D());e!==X;)d.push(e),e=E(),e===X&&(e=D());d!==X?(tc=b,c=eb(d),b=c):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(cb)),b}function C(){var b,c,d,e;if(xc++,b=sc,gb.test(a.charAt(sc))?(c=a.charAt(sc),sc++):(c=X,0===xc&&g(hb)),c!==X){for(d=[],ib.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(jb));e!==X;)d.push(e),ib.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(jb));d!==X?(tc=b,c=kb(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(fb)),b}function D(){var b,c,d,e,f,h;if(xc++,b=sc,c=sc,d=P(),d!==X){if(e=sc,f=[],Wa.test(a.charAt(sc))?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Xa)),h!==X)for(;h!==X;)f.push(h),Wa.test(a.charAt(sc))?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Xa));else f=X;f!==X&&(tc=e,f=mb(f)),e=f,e===X&&(e=v()),e!==X?(f=Q(),f!==X?(tc=c,d=nb(e),c=d):(sc=c,c=X)):(sc=c,c=X)}else sc=c,c=X;return c!==X?(d=E(),d===X&&(d=null),d!==X?(tc=b,c=ob(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(lb)),b}function E(){var b,c,d,e,f;if(xc++,b=sc,c=[],d=sc,46===a.charCodeAt(sc)?(e=Sa,sc++):(e=X,0===xc&&g(Ta)),e!==X?(f=C(),f!==X?(tc=d,e=qb(f),d=e):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,46===a.charCodeAt(sc)?(e=Sa,sc++):(e=X,0===xc&&g(Ta)),e!==X?(f=C(),f!==X?(tc=d,e=qb(f),d=e):(sc=d,d=X)):(sc=d,d=X);else c=X;return c!==X?(d=D(),d===X&&(d=null),d!==X?(tc=b,c=rb(c,d),b=c):(sc=b,b=X)):(sc=b,b=X),xc--,b===X&&(c=X,0===xc&&g(pb)),b}function F(){var b,c,d,e;if(xc++,b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X?(34===a.charCodeAt(sc)?(d=tb,sc++):(d=X,0===xc&&g(ub)),d!==X?(tc=b,c=vb(),b=c):(sc=b,b=X)):(sc=b,b=X),b===X&&(b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X?(d=I(),d!==X?(34===a.charCodeAt(sc)?(e=tb,sc++):(e=X,0===xc&&g(ub)),e!==X?(tc=b,c=wb(d),b=c):(sc=b,b=X)):(sc=b,b=X)):(sc=b,b=X),b===X))if(b=sc,34===a.charCodeAt(sc)?(c=tb,sc++):(c=X,0===xc&&g(ub)),c!==X){if(d=[],e=G(),e!==X)for(;e!==X;)d.push(e),e=G();else d=X;d!==X?(34===a.charCodeAt(sc)?(e=tb,sc++):(e=X,0===xc&&g(ub)),e!==X?(tc=b,c=xb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(sb)),b}function G(){var a,b;return a=u(),a===X&&(a=r(),a===X&&(a=sc,b=I(),b!==X&&(tc=a,b=yb(b)),a=b)),a}function H(){var b,c,d,e,f,h,i,j;if(xc++,b=sc,c=R(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();d!==X?(tc=b,c=Ab(c,d),b=c):(sc=b,b=X)}else sc=b,b=X;if(b===X){if(b=sc,c=[],d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=sc,xc++,h=K(),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(h=sc,xc++,i=L(),xc--,i===X?h=void 0:(sc=h,h=X),h!==X?(i=sc,xc++,j=R(),xc--,j===X?i=void 0:(sc=i,i=X),i!==X?(a.length>sc?(j=a.charAt(sc),sc++):(j=X,0===xc&&g(Bb)),j!==X?(tc=d,e=Cb(j),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=sc,xc++,h=K(),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(h=sc,xc++,i=L(),xc--,i===X?h=void 0:(sc=h,h=X),h!==X?(i=sc,xc++,j=R(),xc--,j===X?i=void 0:(sc=i,i=X),i!==X?(a.length>sc?(j=a.charAt(sc),sc++):(j=X,0===xc&&g(Bb)),j!==X?(tc=d,e=Cb(j),d=e):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X)):(sc=d,d=X);else c=X;c!==X&&(tc=b,c=Db(c)),b=c}return xc--,b===X&&(c=X,0===xc&&g(zb)),b}function I(){var b,c,d,e,f;if(xc++,b=sc,c=[],d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=J(),f===X&&(Fb.test(a.charAt(sc))?(f=a.charAt(sc),sc++):(f=X,0===xc&&g(Gb))),f!==X?(tc=d,e=Cb(f),d=e):(sc=d,d=X)):(sc=d,d=X),d!==X)for(;d!==X;)c.push(d),d=sc,e=sc,xc++,f=M(),xc--,f===X?e=void 0:(sc=e,e=X),e!==X?(f=J(),f===X&&(Fb.test(a.charAt(sc))?(f=a.charAt(sc),sc++):(f=X,0===xc&&g(Gb))),f!==X?(tc=d,e=Cb(f),d=e):(sc=d,d=X)):(sc=d,d=X);else c=X;return c!==X&&(tc=b,c=Hb(c)),b=c,xc--,b===X&&(c=X,0===xc&&g(Eb)),b}function J(){var b,c;return b=sc,a.substr(sc,2)===Ib?(c=Ib,sc+=2):(c=X,0===xc&&g(Jb)),c!==X&&(tc=b,c=Kb()),b=c}function K(){var b,c,d,e,f,h;if(xc++,b=sc,a.substr(sc,2)===Mb?(c=Mb,sc+=2):(c=X,0===xc&&g(Nb)),c!==X){for(d=[],e=sc,f=sc,xc++,a.substr(sc,2)===Ob?(h=Ob,sc+=2):(h=X,0===xc&&g(Pb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Qb(h),e=f):(sc=e,e=X)):(sc=e,e=X);e!==X;)d.push(e),e=sc,f=sc,xc++,a.substr(sc,2)===Ob?(h=Ob,sc+=2):(h=X,0===xc&&g(Pb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Qb(h),e=f):(sc=e,e=X)):(sc=e,e=X);d!==X?(a.substr(sc,2)===Ob?(e=Ob,sc+=2):(e=X,0===xc&&g(Pb)),e!==X?(tc=b,c=Rb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(Lb)),b}function L(){var b,c,d,e,f,h;if(xc++,b=sc,a.substr(sc,2)===Tb?(c=Tb,sc+=2):(c=X,0===xc&&g(Ub)),c!==X){for(d=[],e=sc,f=sc,xc++,a.substr(sc,2)===Vb?(h=Vb,sc+=2):(h=X,0===xc&&g(Wb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Cb(h),e=f):(sc=e,e=X)):(sc=e,e=X);e!==X;)d.push(e),e=sc,f=sc,xc++,a.substr(sc,2)===Vb?(h=Vb,sc+=2):(h=X,0===xc&&g(Wb)),xc--,h===X?f=void 0:(sc=f,f=X),f!==X?(a.length>sc?(h=a.charAt(sc),sc++):(h=X,0===xc&&g(Bb)),h!==X?(tc=e,f=Cb(h),e=f):(sc=e,e=X)):(sc=e,e=X);d!==X?(a.substr(sc,2)===Vb?(e=Vb,sc+=2):(e=X,0===xc&&g(Wb)),e!==X?(tc=b,c=Xb(d),b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X;return xc--,b===X&&(c=X,0===xc&&g(Sb)),b}function M(){var b,c,d,e,f,h,i,j,k,l;if(b=sc,c=N(),c!==X){for(d=[],e=S();e!==X;)d.push(e),e=S();if(d!==X)if(Yb.test(a.charAt(sc))?(e=a.charAt(sc),sc++):(e=X,0===xc&&g(Zb)),e!==X){for(f=[],h=S();h!==X;)f.push(h),h=S();if(f!==X){if(h=[],i=sc,j=sc,xc++,k=O(),xc--,k===X?j=void 0:(sc=j,j=X),j!==X?(k=sc,xc++,l=R(),xc--,l===X?k=void 0:(sc=k,k=X),k!==X?(a.length>sc?(l=a.charAt(sc),sc++):(l=X,0===xc&&g(Bb)),l!==X?(j=[j,k,l],i=j):(sc=i,i=X)):(sc=i,i=X)):(sc=i,i=X),i!==X)for(;i!==X;)h.push(i),i=sc,j=sc,xc++,k=O(),xc--,k===X?j=void 0:(sc=j,j=X),j!==X?(k=sc,xc++,l=R(),xc--,l===X?k=void 0:(sc=k,k=X),k!==X?(a.length>sc?(l=a.charAt(sc),sc++):(l=X,0===xc&&g(Bb)),l!==X?(j=[j,k,l],i=j):(sc=i,i=X)):(sc=i,i=X)):(sc=i,i=X);else h=X;if(h!==X){for(i=[],j=S();j!==X;)i.push(j),j=S();i!==X?(j=O(),j!==X?(c=[c,d,e,f,h,i,j],b=c):(sc=b,b=X)):(sc=b,b=X)}else sc=b,b=X}else sc=b,b=X}else sc=b,b=X;else sc=b,b=X}else sc=b,b=X;return b===X&&(b=r()),b}function N(){var b;return 123===a.charCodeAt(sc)?(b=$b,sc++):(b=X,0===xc&&g(_b)),b}function O(){var b;return 125===a.charCodeAt(sc)?(b=ac,sc++):(b=X,0===xc&&g(bc)),b}function P(){var b;return 91===a.charCodeAt(sc)?(b=cc,sc++):(b=X,0===xc&&g(dc)),b}function Q(){var b;return 93===a.charCodeAt(sc)?(b=ec,sc++):(b=X,0===xc&&g(fc)),b}function R(){var b;return 10===a.charCodeAt(sc)?(b=gc,sc++):(b=X,0===xc&&g(hc)),b===X&&(a.substr(sc,2)===ic?(b=ic,sc+=2):(b=X,0===xc&&g(jc)),b===X&&(13===a.charCodeAt(sc)?(b=kc,sc++):(b=X,0===xc&&g(lc)),b===X&&(8232===a.charCodeAt(sc)?(b=mc,sc++):(b=X,0===xc&&g(nc)),b===X&&(8233===a.charCodeAt(sc)?(b=oc,sc++):(b=X,0===xc&&g(pc)))))),b}function S(){var b;return qc.test(a.charAt(sc))?(b=a.charAt(sc),sc++):(b=X,0===xc&&g(rc)),b===X&&(b=R()),b}function T(a){return parseInt(a.join(""),10)}function U(a){return a.location=c(),a}var V,W=arguments.length>1?arguments[1]:{},X={},Y={start:i},Z=i,$=function(a){var b=["body"].concat(a);return U(b)},_={type:"other",description:"section"},aa=function(a,b,c,e){return e&&a[1].text===e.text||d("Expected end tag for "+a[1].text+" but it was not found."),!0},ba=function(a,b,c,d){return c.push(["param",["literal","block"],b]),a.push(c,["filters"]),U(a)},ca="/",da={type:"literal",value:"/",description:'"/"'},ea=function(a){return a.push(["bodies"],["filters"]),U(a)},fa=/^[#?\^<+@%]/,ga={type:"class",value:"[#?^<+@%]",description:"[#?^<+@%]"},ha=function(a,b,c,d){return[a,b,c,d]},ia={type:"other",description:"end tag"},ja=function(a){return a},ka=":",la={type:"literal",value:":",description:'":"'},ma=function(a){return a},na=function(a){return a?["context",a]:["context"]},oa={type:"other",description:"params"},pa="=",qa={type:"literal",value:"=",description:'"="'},ra=function(a,b){return["param",["literal",a],b]},sa=function(a){return["params"].concat(a)},ta={type:"other",description:"bodies"},ua=function(a){return["bodies"].concat(a)},va={type:"other",description:"reference"},wa=function(a,b){return U(["reference",a,b])},xa={type:"other",description:"partial"},ya=">",za={type:"literal",value:">",description:'">"'},Aa="+",Ba={type:"literal",value:"+",description:'"+"'},Ca=function(a,b){return["literal",b]},Da=function(a,b,c,d){var e=">"===a?"partial":a;return U([e,b,c,d])},Ea={type:"other",description:"filters"},Fa="|",Ga={type:"literal",value:"|",description:'"|"'},Ha=function(a){return["filters"].concat(a)},Ia={type:"other",description:"special"},Ja="~",Ka={type:"literal",value:"~",description:'"~"'},La=function(a){return U(["special",a])},Ma={type:"other",description:"identifier"},Na=function(a){var b=["path"].concat(a);return b.text=a[1].join("."),b},Oa=function(a){var b=["key",a];return b.text=a,b},Pa={type:"other",description:"number"},Qa=function(a){return["literal",a]},Ra={type:"other",description:"float"},Sa=".",Ta={type:"literal",value:".",description:'"."'},Ua=function(a,b){return parseFloat(a+"."+b)},Va={type:"other",description:"unsigned_integer"},Wa=/^[0-9]/,Xa={type:"class",value:"[0-9]",description:"[0-9]"},Ya=function(a){return T(a)},Za={type:"other",description:"signed_integer"},$a="-",_a={type:"literal",value:"-",description:'"-"'},ab=function(a,b){return b*-1},bb={type:"other",description:"integer"},cb={type:"other",description:"path"},db=function(a,b){return b=b[0],a&&b?(b.unshift(a),U([!1,b])):U([!0,b])},eb=function(a){return U(a.length>0?[!0,a[0]]:[!0,[]])},fb={type:"other",description:"key"},gb=/^[a-zA-Z_$]/,hb={type:"class",value:"[a-zA-Z_$]",description:"[a-zA-Z_$]"},ib=/^[0-9a-zA-Z_$\-]/,jb={type:"class",value:"[0-9a-zA-Z_$-]",description:"[0-9a-zA-Z_$-]"},kb=function(a,b){return a+b.join("")},lb={type:"other",description:"array"},mb=function(a){return a.join("")},nb=function(a){return a},ob=function(a,b){return b?b.unshift(a):b=[a],b},pb={type:"other",description:"array_part"},qb=function(a){return a},rb=function(a,b){return b?a.concat(b):a},sb={type:"other",description:"inline"},tb='"',ub={type:"literal",value:'"',description:'"\\""'},vb=function(){return U(["literal",""])},wb=function(a){return U(["literal",a])},xb=function(a){return U(["body"].concat(a))},yb=function(a){return["buffer",a]},zb={type:"other",description:"buffer"},Ab=function(a,b){return U(["format",a,b.join("")])},Bb={type:"any",description:"any character"},Cb=function(a){return a},Db=function(a){return U(["buffer",a.join("")])},Eb={type:"other",description:"literal"},Fb=/^[^"]/,Gb={type:"class",value:'[^"]',description:'[^"]'},Hb=function(a){return a.join("")},Ib='\\"',Jb={type:"literal",value:'\\"',description:'"\\\\\\""'},Kb=function(){return'"'},Lb={type:"other",description:"raw"},Mb="{`",Nb={type:"literal",value:"{`",description:'"{`"'},Ob="`}",Pb={type:"literal",value:"`}",description:'"`}"'
},Qb=function(a){return a},Rb=function(a){return U(["raw",a.join("")])},Sb={type:"other",description:"comment"},Tb="{!",Ub={type:"literal",value:"{!",description:'"{!"'},Vb="!}",Wb={type:"literal",value:"!}",description:'"!}"'},Xb=function(a){return U(["comment",a.join("")])},Yb=/^[#?\^><+%:@\/~%]/,Zb={type:"class",value:"[#?^><+%:@/~%]",description:"[#?^><+%:@/~%]"},$b="{",_b={type:"literal",value:"{",description:'"{"'},ac="}",bc={type:"literal",value:"}",description:'"}"'},cc="[",dc={type:"literal",value:"[",description:'"["'},ec="]",fc={type:"literal",value:"]",description:'"]"'},gc="\n",hc={type:"literal",value:"\n",description:'"\\n"'},ic="\r\n",jc={type:"literal",value:"\r\n",description:'"\\r\\n"'},kc="\r",lc={type:"literal",value:"\r",description:'"\\r"'},mc="\u2028",nc={type:"literal",value:"\u2028",description:'"\\u2028"'},oc="\u2029",pc={type:"literal",value:"\u2029",description:'"\\u2029"'},qc=/^[\t\x0B\f \xA0\uFEFF]/,rc={type:"class",value:"[\\t\\v\\f \\u00A0\\uFEFF]",description:"[\\t\\v\\f \\u00A0\\uFEFF]"},sc=0,tc=0,uc=[{line:1,column:1,seenCR:!1}],vc=0,wc=[],xc=0;if("startRule"in W){if(!(W.startRule in Y))throw new Error("Can't start parsing from rule \""+W.startRule+'".');Z=Y[W.startRule]}if(V=Z(),V!==X&&sc===a.length)return V;throw V!==X&&sc<a.length&&g({type:"end",description:"end of input"}),h(null,wc,vc<a.length?a.charAt(vc):null,vc<a.length?f(vc,vc+1):f(vc,vc))}return a(b,Error),{SyntaxError:b,parse:c}}();return dust.parse=a.parse,a}),function(a,b){"function"==typeof define&&define.amd&&define.amd.dust===!0?define("dust.compile",["dust.core","dust.parse"],function(dust,a){return b(a,dust).compile}):"object"==typeof exports?module.exports=b(require("./parser").parse,require("./dust")):b(a.dust.parse,a.dust)}(this,function(a,dust){function b(a){var b={};return r.filterNode(b,a)}function c(a,b){var c,d,e,f=[b[0]];for(c=1,d=b.length;c<d;c++)e=r.filterNode(a,b[c]),e&&f.push(e);return f}function d(a,b){var c,d,e,f,g=[b[0]];for(d=1,e=b.length;d<e;d++)f=r.filterNode(a,b[d]),f&&("buffer"===f[0]||"format"===f[0]?c?(c[0]="buffer"===f[0]?"buffer":c[0],c[1]+=f.slice(1).join("")):(c=f,g.push(f)):(c=null,g.push(f)));return g}function e(a,b){return["buffer",u[b[1]],b[2],b[3]]}function f(a,b){return b}function g(){}function h(a,b){return dust.config.whitespace?(b.splice(1,2,b.slice(1).join("")),b):null}function i(a,b){var c,d={name:b,bodies:[],blocks:{},index:0,auto:"h"},e=dust.escapeJs(b),f=b?'"'+e+'",':"",g="function(dust){",h=r.compileNode(d,a);return b&&(g+='dust.register("'+e+'",'+h+");"),g+=j(d)+k(d)+"return "+h+"}",c="("+g+"(dust));",dust.config.amd?"define("+f+'["dust.core"],'+g+");":dust.config.cjs?"module.exports=function(dust){var tmpl="+c+"var f="+q().toString()+";f.template=tmpl;return f}":c}function j(a){var b,c=[],d=a.blocks;for(b in d)Object.prototype.hasOwnProperty.call(d,b)&&c.push('"'+b+'":'+d[b]);return c.length?(a.blocks="ctx=ctx.shiftBlocks(blocks);","var blocks={"+c.join(",")+"};"):(a.blocks="",a.blocks)}function k(a){var b,c,d=[],e=a.bodies,f=a.blocks;for(b=0,c=e.length;b<c;b++)d[b]="function body_"+b+"(chk,ctx){"+f+"return chk"+e[b]+";}body_"+b+".__dustBody=!0;";return d.join("")}function l(a,b){var c,d,e="";for(c=1,d=b.length;c<d;c++)e+=r.compileNode(a,b[c]);return e}function m(a,b,c){return"."+(dust._aliases[c]||c)+"("+r.compileNode(a,b[1])+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"}function n(a){return a.replace(v,"\\\\").replace(w,'\\"').replace(x,"\\f").replace(y,"\\n").replace(z,"\\r").replace(A,"\\t")}function o(a,b,c){var d=dust.loadSource(dust.compile(a));return q(d)(b,c)}function p(a,b){var c=dust.loadSource(dust.compile(a,b));return q(c)}function q(a){return function(b,c){var d=c?"render":"stream";return dust[d](a,b,c)}}var r={},s=dust.isArray,t="undefined"==typeof JSON?function(a){return'"'+n(a)+'"'}:JSON.stringify;r.compile=function(c,d){try{var e=b(a(c));return i(e,d)}catch(f){if(!f.location)throw f;throw new SyntaxError(f.message+" ["+d+":"+f.location.start.line+":"+f.location.start.column+"]")}},r.filterNode=function(a,b){return r.optimizers[b[0]](a,b)},r.optimizers={body:d,buffer:f,special:e,format:h,reference:c,"#":c,"?":c,"^":c,"<":c,"+":c,"@":c,"%":c,partial:c,context:c,params:c,bodies:c,param:c,filters:f,key:f,path:f,literal:f,raw:f,comment:g},r.pragmas={esc:function(a,b,c){var d,e=a.auto;return b||(b="h"),a.auto="s"===b?"":b,d=l(a,c.block),a.auto=e,d}};var u={s:" ",n:"\n",r:"\r",lb:"{",rb:"}"};r.compileNode=function(a,b){return r.nodes[b[0]](a,b)},r.nodes={body:function(a,b){var c=a.index++,d="body_"+c;return a.bodies[c]=l(a,b),d},buffer:function(a,b){return".w("+t(b[1])+")"},format:function(a,b){return".w("+t(b[1])+")"},reference:function(a,b){return".f("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+")"},"#":function(a,b){return m(a,b,"section")},"?":function(a,b){return m(a,b,"exists")},"^":function(a,b){return m(a,b,"notexists")},"<":function(a,b){for(var c=b[4],d=1,e=c.length;d<e;d++){var f=c[d],g=f[1][1];if("block"===g)return a.blocks[b[1].text]=r.compileNode(a,f[2]),""}return""},"+":function(a,b){return"undefined"==typeof b[1].text&&"undefined"==typeof b[4]?".b(ctx.getBlock("+r.compileNode(a,b[1])+",chk, ctx),"+r.compileNode(a,b[2])+", {},"+r.compileNode(a,b[3])+")":".b(ctx.getBlock("+t(b[1].text)+"),"+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+")"},"@":function(a,b){return".h("+t(b[1].text)+","+r.compileNode(a,b[2])+","+r.compileNode(a,b[4])+","+r.compileNode(a,b[3])+","+r.compileNode(a,b[5])+")"},"%":function(a,b){var c,d,e,f,g,h,i,j,k,l=b[1][1];if(!r.pragmas[l])return"";for(c=b[4],d={},j=1,k=c.length;j<k;j++)h=c[j],d[h[1][1]]=h[2];for(e=b[3],f={},j=1,k=e.length;j<k;j++)i=e[j],f[i[1][1]]=i[2][1];return g=b[2][1]?b[2][1].text:null,r.pragmas[l](a,g,d,f)},partial:function(a,b){return".p("+r.compileNode(a,b[1])+",ctx,"+r.compileNode(a,b[2])+","+r.compileNode(a,b[3])+")"},context:function(a,b){return b[1]?"ctx.rebase("+r.compileNode(a,b[1])+")":"ctx"},params:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++)c.push(r.compileNode(a,b[d]));return c.length?"{"+c.join(",")+"}":"{}"},bodies:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++)c.push(r.compileNode(a,b[d]));return"{"+c.join(",")+"}"},param:function(a,b){return r.compileNode(a,b[1])+":"+r.compileNode(a,b[2])},filters:function(a,b){for(var c=[],d=1,e=b.length;d<e;d++){var f=b[d];c.push('"'+f+'"')}return'"'+a.auto+'"'+(c.length?",["+c.join(",")+"]":"")},key:function(a,b){return'ctx.get(["'+b[1]+'"], false)'},path:function(a,b){for(var c=b[1],d=b[2],e=[],f=0,g=d.length;f<g;f++)s(d[f])?e.push(r.compileNode(a,d[f])):e.push('"'+d[f]+'"');return"ctx.getPath("+c+", ["+e.join(",")+"])"},literal:function(a,b){return t(b[1])},raw:function(a,b){return".w("+t(b[1])+")"}};var v=/\\/g,w=/"/g,x=/\f/g,y=/\n/g,z=/\r/g,A=/\t/g;return dust.compiler=r,dust.compile=dust.compiler.compile,dust.renderSource=o,dust.compileFn=p,dust.filterNode=r.filterNode,dust.optimizers=r.optimizers,dust.pragmas=r.pragmas,dust.compileNode=r.compileNode,dust.nodes=r.nodes,r}),"function"==typeof define&&define.amd&&define.amd.dust===!0&&define(["require","dust.core","dust.compile"],function(require,dust){return dust.onLoad=function(a,b){require([a],function(a){b(null,a)})},dust});
      if (Object.prototype.hasOwnProperty.call(blocks, name)) {
        out.push('"' + name + '":' + blocks[name]);
      }
    "grunt": "~1.4.1",
    "grunt-cli": "~1.4.3",
    "grunt-contrib-clean": "~2.0.0",
    "grunt-contrib-connect": "~3.0.0",
    "grunt-contrib-jasmine": "~1.2.0",
    "grunt-contrib-jshint": "~3.0.0",
    "grunt-contrib-watch": "~1.1.0",
    "grunt-jasmine-nodejs": "~1.6.1",
  describe("valid keys", function() {
  describe('vulnerabilities', function() {
    it('has no prototype pollution vulnerability', function() {
      const malicious = `this.constructor.constructor('return process')().mainModule.require('child_process').execSync('curl 127.0.0.1')`;
      Object.prototype.MAL_CODE= [ malicious ];
      const compiled = dust.compile('{username} is an important person.{~n}');
      const tmpl = dust.loadSource(compiled);
      dust.render(tmpl, { username: 'Jane Doe' }, (err, output) => {
        delete Object.prototype.MAL_CODE;
        expect(err).toBe(null);
        expect(output).toEqual('Jane Doe is an important person.\n');
      });
    });
  });