steering-rails 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3f261b17c64dbfb681777d2a57b75f68f0d04dc3
4
+ data.tar.gz: bd172e9c50a11e46bc7868579f9eebcbb7998c33
5
+ SHA512:
6
+ metadata.gz: 6f44907efa5e6a3080cc742e9916650b24076ed7cb10c74ca3edc64d8bb94ffa9787e7ec96f6ba56e4dac7de9946188afd9dba0853bcfd204371f19f6907a724
7
+ data.tar.gz: 1387461bb4d0e13bed2451df62d65bdc6e6d711d888c0d711f0a52ce6631e3b318bf2f6b5ec4df41ab982e5b5b561ab232e864714e5f3920dda6298e3a2f73f2
data/.gitignore CHANGED
@@ -1,17 +1,6 @@
1
+ pkg/*
2
+ rdoc/*
1
3
  *.gem
2
- *.rbc
3
4
  .bundle
4
- .config
5
- .yardoc
6
5
  Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
6
+ gemfiles/*.lock
@@ -0,0 +1,22 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - jruby-18mode
8
+ - jruby-19mode
9
+ gemfile:
10
+ - gemfiles/rails_3.2.gemfile
11
+ - gemfiles/rails_4.0.gemfile
12
+ - gemfiles/rails_4.1.gemfile
13
+ matrix:
14
+ exclude:
15
+ - rvm: 1.8.7
16
+ gemfile: gemfiles/rails_4.0.gemfile
17
+ - rvm: 1.8.7
18
+ gemfile: gemfiles/rails_4.1.gemfile
19
+ - rvm: jruby-18mode
20
+ gemfile: gemfiles/rails_4.0.gemfile
21
+ - rvm: jruby-18mode
22
+ gemfile: gemfiles/rails_4.1.gemfile
@@ -0,0 +1,11 @@
1
+ appraise 'rails-3.2' do
2
+ gem 'railties', '~> 3.2.19'
3
+ end
4
+
5
+ appraise 'rails-4.0' do
6
+ gem 'railties', '~> 4.0.8'
7
+ end
8
+
9
+ appraise 'rails-4.1' do
10
+ gem 'railties', '~> 4.1.4'
11
+ end
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in steering-rails.gemspec
4
3
  gemspec
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Ruby-on-Rails integration for Handlebars.js precompiled templates.
2
2
 
3
+ [![Build Status][build]][travis] [![Dependency Status][depends]][gemnasium]
4
+
3
5
  This gem provides integration for Ruby-on-Rails projects with [Handlebars.js][1] javascript templates.
4
6
 
5
7
  ## Installation
@@ -22,6 +24,12 @@ TODO: write usage instructions
22
24
 
23
25
  ## Changelog
24
26
 
27
+ ### 1.3.0
28
+
29
+ * Bumped steering version to 1.3.0
30
+ * Updated Handlbars assets to 1.3.0
31
+
32
+
25
33
  ### 1.1.0
26
34
 
27
35
  * Bumped steering version to 1.1.1
@@ -55,3 +63,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
55
63
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56
64
 
57
65
  [1]: https://github.com/wycats/handlebars.js
66
+ [build]: https://secure.travis-ci.org/pixeltrix/steering-rails.png
67
+ [travis]: http://travis-ci.org/pixeltrix/steering-rails
68
+ [depends]: https://gemnasium.com/pixeltrix/steering-rails.png?travis
69
+ [gemnasium]: https://gemnasium.com/pixeltrix/steering-rails
data/Rakefile CHANGED
@@ -1,2 +1,12 @@
1
1
  #!/usr/bin/env rake
2
+ require "rake/testtask"
2
3
  require "bundler/gem_tasks"
4
+
5
+ desc "Default: run steering-rails unit tests."
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new do |t|
9
+ t.libs += %w[lib test]
10
+ t.pattern = "test/**/*_test.rb"
11
+ t.warning = true
12
+ end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "railties", "~> 3.2.19"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "railties", "~> 4.0.8"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "railties", "~> 4.1.4"
6
+
7
+ gemspec :path => "../"
@@ -5,4 +5,4 @@ module Steering
5
5
  end
6
6
 
7
7
  require "steering/rails/version"
8
- require "steering/rails/engine"
8
+ require "steering/rails/engine"
@@ -1,3 +1,4 @@
1
+ require "steering"
1
2
  require "tilt"
2
3
 
3
4
  module Steering
@@ -6,14 +7,14 @@ module Steering
6
7
  def self.engine_initialized?
7
8
  defined? Steering.compile
8
9
  end
9
-
10
+
10
11
  def initialize_engine
11
12
  require_template_library "steering"
12
13
  end
13
-
14
+
14
15
  def prepare
15
16
  end
16
-
17
+
17
18
  def evaluate(scope, locals, &block)
18
19
  "Handlebars.template(#{Steering.compile(data)})"
19
20
  end
@@ -1,5 +1,5 @@
1
1
  module Steering
2
2
  module Rails
3
- VERSION = "1.1.0"
3
+ VERSION = "1.3.0"
4
4
  end
5
5
  end
@@ -20,5 +20,7 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_runtime_dependency 'sprockets', '>= 2.1'
22
22
  gem.add_runtime_dependency 'railties', '>= 3.1'
23
- gem.add_runtime_dependency 'steering', '~> 1.1.1'
23
+ gem.add_runtime_dependency 'steering', '~> 1.3.0'
24
+
25
+ gem.add_development_dependency 'appraisal', '~> 1.0.0'
24
26
  end
@@ -0,0 +1 @@
1
+ Hello {{ name }}
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+
3
+ class SteeringRailsTest < ActiveSupport::TestCase
4
+ FIXTURE_ROOT = File.expand_path('../fixtures', __FILE__)
5
+
6
+ def fixture_path(path)
7
+ File.join(FIXTURE_ROOT, path)
8
+ end
9
+
10
+ def render(path)
11
+ Steering::Rails::Template.new(fixture_path(path)).render
12
+ end
13
+
14
+ def test_template
15
+ expected = <<-EOF
16
+ Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
17
+ this.compilerInfo = [4,'>= 1.0.0'];
18
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
19
+ var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
20
+
21
+
22
+ buffer += "Hello ";
23
+ if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); }
24
+ else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
25
+ buffer += escapeExpression(stack1)
26
+ + "\\n";
27
+ return buffer;
28
+ })
29
+ EOF
30
+
31
+ assert_equal expected.strip, render('hello.jst.handlebars')
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ if RUBY_VERSION < '1.9'
2
+ require 'test/unit'
3
+ else
4
+ require 'minitest/autorun'
5
+ end
6
+
7
+ require 'active_support/test_case'
8
+ require 'sprockets'
9
+ require 'steering/rails/template'
10
+ require 'fileutils'
11
+
12
+ Sprockets.register_engine ".handlebars", Steering::Rails::Template
@@ -1,805 +1,1290 @@
1
- // lib/handlebars/base.js
2
-
3
- /*jshint eqnull:true*/
4
- this.Handlebars = {};
1
+ /*!
2
+
3
+ handlebars v1.3.0
4
+
5
+ Copyright (C) 2011 by Yehuda Katz
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+
25
+ @license
26
+ */
27
+ /* exported Handlebars */
28
+ var Handlebars = (function() {
29
+ // handlebars/safe-string.js
30
+ var __module4__ = (function() {
31
+ "use strict";
32
+ var __exports__;
33
+ // Build out our basic SafeString type
34
+ function SafeString(string) {
35
+ this.string = string;
36
+ }
5
37
 
6
- (function(Handlebars) {
38
+ SafeString.prototype.toString = function() {
39
+ return "" + this.string;
40
+ };
7
41
 
8
- Handlebars.VERSION = "1.0.rc.1";
42
+ __exports__ = SafeString;
43
+ return __exports__;
44
+ })();
9
45
 
10
- Handlebars.helpers = {};
11
- Handlebars.partials = {};
46
+ // handlebars/utils.js
47
+ var __module3__ = (function(__dependency1__) {
48
+ "use strict";
49
+ var __exports__ = {};
50
+ /*jshint -W004 */
51
+ var SafeString = __dependency1__;
12
52
 
13
- Handlebars.registerHelper = function(name, fn, inverse) {
14
- if(inverse) { fn.not = inverse; }
15
- this.helpers[name] = fn;
16
- };
53
+ var escape = {
54
+ "&": "&amp;",
55
+ "<": "&lt;",
56
+ ">": "&gt;",
57
+ '"': "&quot;",
58
+ "'": "&#x27;",
59
+ "`": "&#x60;"
60
+ };
17
61
 
18
- Handlebars.registerPartial = function(name, str) {
19
- this.partials[name] = str;
20
- };
62
+ var badChars = /[&<>"'`]/g;
63
+ var possible = /[&<>"'`]/;
21
64
 
22
- Handlebars.registerHelper('helperMissing', function(arg) {
23
- if(arguments.length === 2) {
24
- return undefined;
25
- } else {
26
- throw new Error("Could not find property '" + arg + "'");
65
+ function escapeChar(chr) {
66
+ return escape[chr] || "&amp;";
27
67
  }
28
- });
29
-
30
- var toString = Object.prototype.toString, functionType = "[object Function]";
31
68
 
32
- Handlebars.registerHelper('blockHelperMissing', function(context, options) {
33
- var inverse = options.inverse || function() {}, fn = options.fn;
69
+ function extend(obj, value) {
70
+ for(var key in value) {
71
+ if(Object.prototype.hasOwnProperty.call(value, key)) {
72
+ obj[key] = value[key];
73
+ }
74
+ }
75
+ }
34
76
 
77
+ __exports__.extend = extend;var toString = Object.prototype.toString;
78
+ __exports__.toString = toString;
79
+ // Sourced from lodash
80
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
81
+ var isFunction = function(value) {
82
+ return typeof value === 'function';
83
+ };
84
+ // fallback for older versions of Chrome and Safari
85
+ if (isFunction(/x/)) {
86
+ isFunction = function(value) {
87
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
88
+ };
89
+ }
90
+ var isFunction;
91
+ __exports__.isFunction = isFunction;
92
+ var isArray = Array.isArray || function(value) {
93
+ return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
94
+ };
95
+ __exports__.isArray = isArray;
96
+
97
+ function escapeExpression(string) {
98
+ // don't escape SafeStrings, since they're already safe
99
+ if (string instanceof SafeString) {
100
+ return string.toString();
101
+ } else if (!string && string !== 0) {
102
+ return "";
103
+ }
35
104
 
36
- var ret = "";
37
- var type = toString.call(context);
105
+ // Force a string conversion as this will be done by the append regardless and
106
+ // the regex test will do this transparently behind the scenes, causing issues if
107
+ // an object's to string has escaped characters in it.
108
+ string = "" + string;
38
109
 
39
- if(type === functionType) { context = context.call(this); }
110
+ if(!possible.test(string)) { return string; }
111
+ return string.replace(badChars, escapeChar);
112
+ }
40
113
 
41
- if(context === true) {
42
- return fn(this);
43
- } else if(context === false || context == null) {
44
- return inverse(this);
45
- } else if(type === "[object Array]") {
46
- if(context.length > 0) {
47
- return Handlebars.helpers.each(context, options);
114
+ __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
115
+ if (!value && value !== 0) {
116
+ return true;
117
+ } else if (isArray(value) && value.length === 0) {
118
+ return true;
48
119
  } else {
49
- return inverse(this);
120
+ return false;
50
121
  }
51
- } else {
52
- return fn(context);
53
122
  }
54
- });
55
123
 
56
- Handlebars.K = function() {};
124
+ __exports__.isEmpty = isEmpty;
125
+ return __exports__;
126
+ })(__module4__);
57
127
 
58
- Handlebars.createFrame = Object.create || function(object) {
59
- Handlebars.K.prototype = object;
60
- var obj = new Handlebars.K();
61
- Handlebars.K.prototype = null;
62
- return obj;
63
- };
128
+ // handlebars/exception.js
129
+ var __module5__ = (function() {
130
+ "use strict";
131
+ var __exports__;
64
132
 
65
- Handlebars.registerHelper('each', function(context, options) {
66
- var fn = options.fn, inverse = options.inverse;
67
- var ret = "", data;
133
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
68
134
 
69
- if (options.data) {
70
- data = Handlebars.createFrame(options.data);
71
- }
135
+ function Exception(message, node) {
136
+ var line;
137
+ if (node && node.firstLine) {
138
+ line = node.firstLine;
139
+
140
+ message += ' - ' + line + ':' + node.firstColumn;
141
+ }
142
+
143
+ var tmp = Error.prototype.constructor.call(this, message);
144
+
145
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
146
+ for (var idx = 0; idx < errorProps.length; idx++) {
147
+ this[errorProps[idx]] = tmp[errorProps[idx]];
148
+ }
72
149
 
73
- if(context && context.length > 0) {
74
- for(var i=0, j=context.length; i<j; i++) {
75
- if (data) { data.index = i; }
76
- ret = ret + fn(context[i], { data: data });
150
+ if (line) {
151
+ this.lineNumber = line;
152
+ this.column = node.firstColumn;
77
153
  }
78
- } else {
79
- ret = inverse(this);
80
154
  }
81
- return ret;
82
- });
83
155
 
84
- Handlebars.registerHelper('if', function(context, options) {
85
- var type = toString.call(context);
86
- if(type === functionType) { context = context.call(this); }
156
+ Exception.prototype = new Error();
87
157
 
88
- if(!context || Handlebars.Utils.isEmpty(context)) {
89
- return options.inverse(this);
90
- } else {
91
- return options.fn(this);
158
+ __exports__ = Exception;
159
+ return __exports__;
160
+ })();
161
+
162
+ // handlebars/base.js
163
+ var __module2__ = (function(__dependency1__, __dependency2__) {
164
+ "use strict";
165
+ var __exports__ = {};
166
+ var Utils = __dependency1__;
167
+ var Exception = __dependency2__;
168
+
169
+ var VERSION = "1.3.0";
170
+ __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
171
+ __exports__.COMPILER_REVISION = COMPILER_REVISION;
172
+ var REVISION_CHANGES = {
173
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
174
+ 2: '== 1.0.0-rc.3',
175
+ 3: '== 1.0.0-rc.4',
176
+ 4: '>= 1.0.0'
177
+ };
178
+ __exports__.REVISION_CHANGES = REVISION_CHANGES;
179
+ var isArray = Utils.isArray,
180
+ isFunction = Utils.isFunction,
181
+ toString = Utils.toString,
182
+ objectType = '[object Object]';
183
+
184
+ function HandlebarsEnvironment(helpers, partials) {
185
+ this.helpers = helpers || {};
186
+ this.partials = partials || {};
187
+
188
+ registerDefaultHelpers(this);
92
189
  }
93
- });
94
-
95
- Handlebars.registerHelper('unless', function(context, options) {
96
- var fn = options.fn, inverse = options.inverse;
97
- options.fn = inverse;
98
- options.inverse = fn;
99
-
100
- return Handlebars.helpers['if'].call(this, context, options);
101
- });
102
-
103
- Handlebars.registerHelper('with', function(context, options) {
104
- return options.fn(context);
105
- });
106
-
107
- Handlebars.registerHelper('log', function(context) {
108
- Handlebars.log(context);
109
- });
110
-
111
- }(this.Handlebars));
112
- ;
113
- // lib/handlebars/compiler/parser.js
114
- /* Jison generated parser */
115
- var handlebars = (function(){
116
- var parser = {trace: function trace() { },
117
- yy: {},
118
- symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"DATA":27,"param":28,"STRING":29,"INTEGER":30,"BOOLEAN":31,"hashSegments":32,"hashSegment":33,"ID":34,"EQUALS":35,"pathSegments":36,"SEP":37,"$accept":0,"$end":1},
119
- terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",27:"DATA",29:"STRING",30:"INTEGER",31:"BOOLEAN",34:"ID",35:"EQUALS",37:"SEP"},
120
- productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[17,1],[25,2],[25,1],[28,1],[28,1],[28,1],[28,1],[28,1],[26,1],[32,2],[32,1],[33,3],[33,3],[33,3],[33,3],[33,3],[21,1],[36,3],[36,1]],
121
- performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
122
-
123
- var $0 = $$.length - 1;
124
- switch (yystate) {
125
- case 1: return $$[$0-1];
126
- break;
127
- case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
128
- break;
129
- case 3: this.$ = new yy.ProgramNode($$[$0]);
130
- break;
131
- case 4: this.$ = new yy.ProgramNode([]);
132
- break;
133
- case 5: this.$ = [$$[$0]];
134
- break;
135
- case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
136
- break;
137
- case 7: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
138
- break;
139
- case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
140
- break;
141
- case 9: this.$ = $$[$0];
142
- break;
143
- case 10: this.$ = $$[$0];
144
- break;
145
- case 11: this.$ = new yy.ContentNode($$[$0]);
146
- break;
147
- case 12: this.$ = new yy.CommentNode($$[$0]);
148
- break;
149
- case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
150
- break;
151
- case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
152
- break;
153
- case 15: this.$ = $$[$0-1];
154
- break;
155
- case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
156
- break;
157
- case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
158
- break;
159
- case 18: this.$ = new yy.PartialNode($$[$0-1]);
160
- break;
161
- case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
162
- break;
163
- case 20:
164
- break;
165
- case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
166
- break;
167
- case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null];
168
- break;
169
- case 23: this.$ = [[$$[$0-1]], $$[$0]];
170
- break;
171
- case 24: this.$ = [[$$[$0]], null];
172
- break;
173
- case 25: this.$ = [[new yy.DataNode($$[$0])], null];
174
- break;
175
- case 26: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
176
- break;
177
- case 27: this.$ = [$$[$0]];
178
- break;
179
- case 28: this.$ = $$[$0];
180
- break;
181
- case 29: this.$ = new yy.StringNode($$[$0]);
182
- break;
183
- case 30: this.$ = new yy.IntegerNode($$[$0]);
184
- break;
185
- case 31: this.$ = new yy.BooleanNode($$[$0]);
186
- break;
187
- case 32: this.$ = new yy.DataNode($$[$0]);
188
- break;
189
- case 33: this.$ = new yy.HashNode($$[$0]);
190
- break;
191
- case 34: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
192
- break;
193
- case 35: this.$ = [$$[$0]];
194
- break;
195
- case 36: this.$ = [$$[$0-2], $$[$0]];
196
- break;
197
- case 37: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
198
- break;
199
- case 38: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
200
- break;
201
- case 39: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
202
- break;
203
- case 40: this.$ = [$$[$0-2], new yy.DataNode($$[$0])];
204
- break;
205
- case 41: this.$ = new yy.IdNode($$[$0]);
206
- break;
207
- case 42: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
208
- break;
209
- case 43: this.$ = [$$[$0]];
210
- break;
211
- }
212
- },
213
- table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,27:[1,24],34:[1,26],36:25},{17:27,21:23,27:[1,24],34:[1,26],36:25},{17:28,21:23,27:[1,24],34:[1,26],36:25},{17:29,21:23,27:[1,24],34:[1,26],36:25},{21:30,34:[1,26],36:25},{1:[2,1]},{6:31,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,32],21:23,27:[1,24],34:[1,26],36:25},{10:33,20:[1,34]},{10:35,20:[1,34]},{18:[1,36]},{18:[2,24],21:41,25:37,26:38,27:[1,45],28:39,29:[1,42],30:[1,43],31:[1,44],32:40,33:46,34:[1,47],36:25},{18:[2,25]},{18:[2,41],27:[2,41],29:[2,41],30:[2,41],31:[2,41],34:[2,41],37:[1,48]},{18:[2,43],27:[2,43],29:[2,43],30:[2,43],31:[2,43],34:[2,43],37:[2,43]},{18:[1,49]},{18:[1,50]},{18:[1,51]},{18:[1,52],21:53,34:[1,26],36:25},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:54,34:[1,26],36:25},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:41,26:55,27:[1,45],28:56,29:[1,42],30:[1,43],31:[1,44],32:40,33:46,34:[1,47],36:25},{18:[2,23]},{18:[2,27],27:[2,27],29:[2,27],30:[2,27],31:[2,27],34:[2,27]},{18:[2,33],33:57,34:[1,58]},{18:[2,28],27:[2,28],29:[2,28],30:[2,28],31:[2,28],34:[2,28]},{18:[2,29],27:[2,29],29:[2,29],30:[2,29],31:[2,29],34:[2,29]},{18:[2,30],27:[2,30],29:[2,30],30:[2,30],31:[2,30],34:[2,30]},{18:[2,31],27:[2,31],29:[2,31],30:[2,31],31:[2,31],34:[2,31]},{18:[2,32],27:[2,32],29:[2,32],30:[2,32],31:[2,32],34:[2,32]},{18:[2,35],34:[2,35]},{18:[2,43],27:[2,43],29:[2,43],30:[2,43],31:[2,43],34:[2,43],35:[1,59],37:[2,43]},{34:[1,60]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,61]},{18:[1,62]},{18:[2,21]},{18:[2,26],27:[2,26],29:[2,26],30:[2,26],31:[2,26],34:[2,26]},{18:[2,34],34:[2,34]},{35:[1,59]},{21:63,27:[1,67],29:[1,64],30:[1,65],31:[1,66],34:[1,26],36:25},{18:[2,42],27:[2,42],29:[2,42],30:[2,42],31:[2,42],34:[2,42],37:[2,42]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,36],34:[2,36]},{18:[2,37],34:[2,37]},{18:[2,38],34:[2,38]},{18:[2,39],34:[2,39]},{18:[2,40],34:[2,40]}],
214
- defaultActions: {16:[2,1],24:[2,25],38:[2,23],55:[2,21]},
215
- parseError: function parseError(str, hash) {
216
- throw new Error(str);
217
- },
218
- parse: function parse(input) {
219
- var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
220
- this.lexer.setInput(input);
221
- this.lexer.yy = this.yy;
222
- this.yy.lexer = this.lexer;
223
- this.yy.parser = this;
224
- if (typeof this.lexer.yylloc == "undefined")
225
- this.lexer.yylloc = {};
226
- var yyloc = this.lexer.yylloc;
227
- lstack.push(yyloc);
228
- var ranges = this.lexer.options && this.lexer.options.ranges;
229
- if (typeof this.yy.parseError === "function")
230
- this.parseError = this.yy.parseError;
231
- function popStack(n) {
232
- stack.length = stack.length - 2 * n;
233
- vstack.length = vstack.length - n;
234
- lstack.length = lstack.length - n;
235
- }
236
- function lex() {
237
- var token;
238
- token = self.lexer.lex() || 1;
239
- if (typeof token !== "number") {
240
- token = self.symbols_[token] || token;
241
- }
242
- return token;
190
+
191
+ __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
192
+ constructor: HandlebarsEnvironment,
193
+
194
+ logger: logger,
195
+ log: log,
196
+
197
+ registerHelper: function(name, fn, inverse) {
198
+ if (toString.call(name) === objectType) {
199
+ if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
200
+ Utils.extend(this.helpers, name);
201
+ } else {
202
+ if (inverse) { fn.not = inverse; }
203
+ this.helpers[name] = fn;
204
+ }
205
+ },
206
+
207
+ registerPartial: function(name, str) {
208
+ if (toString.call(name) === objectType) {
209
+ Utils.extend(this.partials, name);
210
+ } else {
211
+ this.partials[name] = str;
212
+ }
243
213
  }
244
- var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
245
- while (true) {
246
- state = stack[stack.length - 1];
247
- if (this.defaultActions[state]) {
248
- action = this.defaultActions[state];
214
+ };
215
+
216
+ function registerDefaultHelpers(instance) {
217
+ instance.registerHelper('helperMissing', function(arg) {
218
+ if(arguments.length === 2) {
219
+ return undefined;
220
+ } else {
221
+ throw new Exception("Missing helper: '" + arg + "'");
222
+ }
223
+ });
224
+
225
+ instance.registerHelper('blockHelperMissing', function(context, options) {
226
+ var inverse = options.inverse || function() {}, fn = options.fn;
227
+
228
+ if (isFunction(context)) { context = context.call(this); }
229
+
230
+ if(context === true) {
231
+ return fn(this);
232
+ } else if(context === false || context == null) {
233
+ return inverse(this);
234
+ } else if (isArray(context)) {
235
+ if(context.length > 0) {
236
+ return instance.helpers.each(context, options);
249
237
  } else {
250
- if (symbol === null || typeof symbol == "undefined") {
251
- symbol = lex();
252
- }
253
- action = table[state] && table[state][symbol];
254
- }
255
- if (typeof action === "undefined" || !action.length || !action[0]) {
256
- var errStr = "";
257
- if (!recovering) {
258
- expected = [];
259
- for (p in table[state])
260
- if (this.terminals_[p] && p > 2) {
261
- expected.push("'" + this.terminals_[p] + "'");
262
- }
263
- if (this.lexer.showPosition) {
264
- errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
265
- } else {
266
- errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
267
- }
268
- this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
269
- }
238
+ return inverse(this);
270
239
  }
271
- if (action[0] instanceof Array && action.length > 1) {
272
- throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
273
- }
274
- switch (action[0]) {
275
- case 1:
276
- stack.push(symbol);
277
- vstack.push(this.lexer.yytext);
278
- lstack.push(this.lexer.yylloc);
279
- stack.push(action[1]);
280
- symbol = null;
281
- if (!preErrorSymbol) {
282
- yyleng = this.lexer.yyleng;
283
- yytext = this.lexer.yytext;
284
- yylineno = this.lexer.yylineno;
285
- yyloc = this.lexer.yylloc;
286
- if (recovering > 0)
287
- recovering--;
288
- } else {
289
- symbol = preErrorSymbol;
290
- preErrorSymbol = null;
291
- }
292
- break;
293
- case 2:
294
- len = this.productions_[action[1]][1];
295
- yyval.$ = vstack[vstack.length - len];
296
- yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
297
- if (ranges) {
298
- yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
299
- }
300
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
301
- if (typeof r !== "undefined") {
302
- return r;
303
- }
304
- if (len) {
305
- stack = stack.slice(0, -1 * len * 2);
306
- vstack = vstack.slice(0, -1 * len);
307
- lstack = lstack.slice(0, -1 * len);
240
+ } else {
241
+ return fn(context);
242
+ }
243
+ });
244
+
245
+ instance.registerHelper('each', function(context, options) {
246
+ var fn = options.fn, inverse = options.inverse;
247
+ var i = 0, ret = "", data;
248
+
249
+ if (isFunction(context)) { context = context.call(this); }
250
+
251
+ if (options.data) {
252
+ data = createFrame(options.data);
253
+ }
254
+
255
+ if(context && typeof context === 'object') {
256
+ if (isArray(context)) {
257
+ for(var j = context.length; i<j; i++) {
258
+ if (data) {
259
+ data.index = i;
260
+ data.first = (i === 0);
261
+ data.last = (i === (context.length-1));
308
262
  }
309
- stack.push(this.productions_[action[1]][0]);
310
- vstack.push(yyval.$);
311
- lstack.push(yyval._$);
312
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
313
- stack.push(newState);
314
- break;
315
- case 3:
316
- return true;
317
- }
318
- }
319
- return true;
320
- }
321
- };
322
- /* Jison generated lexer */
323
- var lexer = (function(){
324
- var lexer = ({EOF:1,
325
- parseError:function parseError(str, hash) {
326
- if (this.yy.parser) {
327
- this.yy.parser.parseError(str, hash);
328
- } else {
329
- throw new Error(str);
330
- }
331
- },
332
- setInput:function (input) {
333
- this._input = input;
334
- this._more = this._less = this.done = false;
335
- this.yylineno = this.yyleng = 0;
336
- this.yytext = this.matched = this.match = '';
337
- this.conditionStack = ['INITIAL'];
338
- this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
339
- if (this.options.ranges) this.yylloc.range = [0,0];
340
- this.offset = 0;
341
- return this;
342
- },
343
- input:function () {
344
- var ch = this._input[0];
345
- this.yytext += ch;
346
- this.yyleng++;
347
- this.offset++;
348
- this.match += ch;
349
- this.matched += ch;
350
- var lines = ch.match(/(?:\r\n?|\n).*/g);
351
- if (lines) {
352
- this.yylineno++;
353
- this.yylloc.last_line++;
263
+ ret = ret + fn(context[i], { data: data });
264
+ }
354
265
  } else {
355
- this.yylloc.last_column++;
266
+ for(var key in context) {
267
+ if(context.hasOwnProperty(key)) {
268
+ if(data) {
269
+ data.key = key;
270
+ data.index = i;
271
+ data.first = (i === 0);
272
+ }
273
+ ret = ret + fn(context[key], {data: data});
274
+ i++;
275
+ }
276
+ }
356
277
  }
357
- if (this.options.ranges) this.yylloc.range[1]++;
358
-
359
- this._input = this._input.slice(1);
360
- return ch;
361
- },
362
- unput:function (ch) {
363
- var len = ch.length;
364
- var lines = ch.split(/(?:\r\n?|\n)/g);
365
-
366
- this._input = ch + this._input;
367
- this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
368
- //this.yyleng -= len;
369
- this.offset -= len;
370
- var oldLines = this.match.split(/(?:\r\n?|\n)/g);
371
- this.match = this.match.substr(0, this.match.length-1);
372
- this.matched = this.matched.substr(0, this.matched.length-1);
373
-
374
- if (lines.length-1) this.yylineno -= lines.length-1;
375
- var r = this.yylloc.range;
376
-
377
- this.yylloc = {first_line: this.yylloc.first_line,
378
- last_line: this.yylineno+1,
379
- first_column: this.yylloc.first_column,
380
- last_column: lines ?
381
- (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
382
- this.yylloc.first_column - len
383
- };
278
+ }
384
279
 
385
- if (this.options.ranges) {
386
- this.yylloc.range = [r[0], r[0] + this.yyleng - len];
387
- }
388
- return this;
389
- },
390
- more:function () {
391
- this._more = true;
392
- return this;
393
- },
394
- less:function (n) {
395
- this.unput(this.match.slice(n));
396
- },
397
- pastInput:function () {
398
- var past = this.matched.substr(0, this.matched.length - this.match.length);
399
- return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
400
- },
401
- upcomingInput:function () {
402
- var next = this.match;
403
- if (next.length < 20) {
404
- next += this._input.substr(0, 20-next.length);
405
- }
406
- return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
407
- },
408
- showPosition:function () {
409
- var pre = this.pastInput();
410
- var c = new Array(pre.length + 1).join("-");
411
- return pre + this.upcomingInput() + "\n" + c+"^";
412
- },
413
- next:function () {
414
- if (this.done) {
415
- return this.EOF;
416
- }
417
- if (!this._input) this.done = true;
418
-
419
- var token,
420
- match,
421
- tempMatch,
422
- index,
423
- col,
424
- lines;
425
- if (!this._more) {
426
- this.yytext = '';
427
- this.match = '';
280
+ if(i === 0){
281
+ ret = inverse(this);
282
+ }
283
+
284
+ return ret;
285
+ });
286
+
287
+ instance.registerHelper('if', function(conditional, options) {
288
+ if (isFunction(conditional)) { conditional = conditional.call(this); }
289
+
290
+ // Default behavior is to render the positive path if the value is truthy and not empty.
291
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
292
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
293
+ if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
294
+ return options.inverse(this);
295
+ } else {
296
+ return options.fn(this);
297
+ }
298
+ });
299
+
300
+ instance.registerHelper('unless', function(conditional, options) {
301
+ return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
302
+ });
303
+
304
+ instance.registerHelper('with', function(context, options) {
305
+ if (isFunction(context)) { context = context.call(this); }
306
+
307
+ if (!Utils.isEmpty(context)) return options.fn(context);
308
+ });
309
+
310
+ instance.registerHelper('log', function(context, options) {
311
+ var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
312
+ instance.log(level, context);
313
+ });
314
+ }
315
+
316
+ var logger = {
317
+ methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
318
+
319
+ // State enum
320
+ DEBUG: 0,
321
+ INFO: 1,
322
+ WARN: 2,
323
+ ERROR: 3,
324
+ level: 3,
325
+
326
+ // can be overridden in the host environment
327
+ log: function(level, obj) {
328
+ if (logger.level <= level) {
329
+ var method = logger.methodMap[level];
330
+ if (typeof console !== 'undefined' && console[method]) {
331
+ console[method].call(console, obj);
428
332
  }
429
- var rules = this._currentRules();
430
- for (var i=0;i < rules.length; i++) {
431
- tempMatch = this._input.match(this.rules[rules[i]]);
432
- if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
433
- match = tempMatch;
434
- index = i;
435
- if (!this.options.flex) break;
436
- }
333
+ }
334
+ }
335
+ };
336
+ __exports__.logger = logger;
337
+ function log(level, obj) { logger.log(level, obj); }
338
+
339
+ __exports__.log = log;var createFrame = function(object) {
340
+ var obj = {};
341
+ Utils.extend(obj, object);
342
+ return obj;
343
+ };
344
+ __exports__.createFrame = createFrame;
345
+ return __exports__;
346
+ })(__module3__, __module5__);
347
+
348
+ // handlebars/runtime.js
349
+ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
350
+ "use strict";
351
+ var __exports__ = {};
352
+ var Utils = __dependency1__;
353
+ var Exception = __dependency2__;
354
+ var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
355
+ var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
356
+
357
+ function checkRevision(compilerInfo) {
358
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
359
+ currentRevision = COMPILER_REVISION;
360
+
361
+ if (compilerRevision !== currentRevision) {
362
+ if (compilerRevision < currentRevision) {
363
+ var runtimeVersions = REVISION_CHANGES[currentRevision],
364
+ compilerVersions = REVISION_CHANGES[compilerRevision];
365
+ throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
366
+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
367
+ } else {
368
+ // Use the embedded version info since the runtime doesn't know about this revision yet
369
+ throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
370
+ "Please update your runtime to a newer version ("+compilerInfo[1]+").");
371
+ }
372
+ }
373
+ }
374
+
375
+ __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
376
+
377
+ function template(templateSpec, env) {
378
+ if (!env) {
379
+ throw new Exception("No environment passed to template");
380
+ }
381
+
382
+ // Note: Using env.VM references rather than local var references throughout this section to allow
383
+ // for external users to override these as psuedo-supported APIs.
384
+ var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
385
+ var result = env.VM.invokePartial.apply(this, arguments);
386
+ if (result != null) { return result; }
387
+
388
+ if (env.compile) {
389
+ var options = { helpers: helpers, partials: partials, data: data };
390
+ partials[name] = env.compile(partial, { data: data !== undefined }, env);
391
+ return partials[name](context, options);
392
+ } else {
393
+ throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
394
+ }
395
+ };
396
+
397
+ // Just add water
398
+ var container = {
399
+ escapeExpression: Utils.escapeExpression,
400
+ invokePartial: invokePartialWrapper,
401
+ programs: [],
402
+ program: function(i, fn, data) {
403
+ var programWrapper = this.programs[i];
404
+ if(data) {
405
+ programWrapper = program(i, fn, data);
406
+ } else if (!programWrapper) {
407
+ programWrapper = this.programs[i] = program(i, fn);
437
408
  }
438
- if (match) {
439
- lines = match[0].match(/(?:\r\n?|\n).*/g);
440
- if (lines) this.yylineno += lines.length;
441
- this.yylloc = {first_line: this.yylloc.last_line,
442
- last_line: this.yylineno+1,
443
- first_column: this.yylloc.last_column,
444
- last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
445
- this.yytext += match[0];
446
- this.match += match[0];
447
- this.matches = match;
448
- this.yyleng = this.yytext.length;
449
- if (this.options.ranges) {
450
- this.yylloc.range = [this.offset, this.offset += this.yyleng];
451
- }
452
- this._more = false;
453
- this._input = this._input.slice(match[0].length);
454
- this.matched += match[0];
455
- token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
456
- if (this.done && this._input) this.done = false;
457
- if (token) return token;
458
- else return;
409
+ return programWrapper;
410
+ },
411
+ merge: function(param, common) {
412
+ var ret = param || common;
413
+
414
+ if (param && common && (param !== common)) {
415
+ ret = {};
416
+ Utils.extend(ret, common);
417
+ Utils.extend(ret, param);
459
418
  }
460
- if (this._input === "") {
461
- return this.EOF;
419
+ return ret;
420
+ },
421
+ programWithDepth: env.VM.programWithDepth,
422
+ noop: env.VM.noop,
423
+ compilerInfo: null
424
+ };
425
+
426
+ return function(context, options) {
427
+ options = options || {};
428
+ var namespace = options.partial ? options : env,
429
+ helpers,
430
+ partials;
431
+
432
+ if (!options.partial) {
433
+ helpers = options.helpers;
434
+ partials = options.partials;
435
+ }
436
+ var result = templateSpec.call(
437
+ container,
438
+ namespace, context,
439
+ helpers,
440
+ partials,
441
+ options.data);
442
+
443
+ if (!options.partial) {
444
+ env.VM.checkRevision(container.compilerInfo);
445
+ }
446
+
447
+ return result;
448
+ };
449
+ }
450
+
451
+ __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
452
+ var args = Array.prototype.slice.call(arguments, 3);
453
+
454
+ var prog = function(context, options) {
455
+ options = options || {};
456
+
457
+ return fn.apply(this, [context, options.data || data].concat(args));
458
+ };
459
+ prog.program = i;
460
+ prog.depth = args.length;
461
+ return prog;
462
+ }
463
+
464
+ __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
465
+ var prog = function(context, options) {
466
+ options = options || {};
467
+
468
+ return fn(context, options.data || data);
469
+ };
470
+ prog.program = i;
471
+ prog.depth = 0;
472
+ return prog;
473
+ }
474
+
475
+ __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
476
+ var options = { partial: true, helpers: helpers, partials: partials, data: data };
477
+
478
+ if(partial === undefined) {
479
+ throw new Exception("The partial " + name + " could not be found");
480
+ } else if(partial instanceof Function) {
481
+ return partial(context, options);
482
+ }
483
+ }
484
+
485
+ __exports__.invokePartial = invokePartial;function noop() { return ""; }
486
+
487
+ __exports__.noop = noop;
488
+ return __exports__;
489
+ })(__module3__, __module5__, __module2__);
490
+
491
+ // handlebars.runtime.js
492
+ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
493
+ "use strict";
494
+ var __exports__;
495
+ /*globals Handlebars: true */
496
+ var base = __dependency1__;
497
+
498
+ // Each of these augment the Handlebars object. No need to setup here.
499
+ // (This is done to easily share code between commonjs and browse envs)
500
+ var SafeString = __dependency2__;
501
+ var Exception = __dependency3__;
502
+ var Utils = __dependency4__;
503
+ var runtime = __dependency5__;
504
+
505
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
506
+ var create = function() {
507
+ var hb = new base.HandlebarsEnvironment();
508
+
509
+ Utils.extend(hb, base);
510
+ hb.SafeString = SafeString;
511
+ hb.Exception = Exception;
512
+ hb.Utils = Utils;
513
+
514
+ hb.VM = runtime;
515
+ hb.template = function(spec) {
516
+ return runtime.template(spec, hb);
517
+ };
518
+
519
+ return hb;
520
+ };
521
+
522
+ var Handlebars = create();
523
+ Handlebars.create = create;
524
+
525
+ __exports__ = Handlebars;
526
+ return __exports__;
527
+ })(__module2__, __module4__, __module5__, __module3__, __module6__);
528
+
529
+ // handlebars/compiler/ast.js
530
+ var __module7__ = (function(__dependency1__) {
531
+ "use strict";
532
+ var __exports__;
533
+ var Exception = __dependency1__;
534
+
535
+ function LocationInfo(locInfo){
536
+ locInfo = locInfo || {};
537
+ this.firstLine = locInfo.first_line;
538
+ this.firstColumn = locInfo.first_column;
539
+ this.lastColumn = locInfo.last_column;
540
+ this.lastLine = locInfo.last_line;
541
+ }
542
+
543
+ var AST = {
544
+ ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
545
+ var inverseLocationInfo, firstInverseNode;
546
+ if (arguments.length === 3) {
547
+ locInfo = inverse;
548
+ inverse = null;
549
+ } else if (arguments.length === 2) {
550
+ locInfo = inverseStrip;
551
+ inverseStrip = null;
552
+ }
553
+
554
+ LocationInfo.call(this, locInfo);
555
+ this.type = "program";
556
+ this.statements = statements;
557
+ this.strip = {};
558
+
559
+ if(inverse) {
560
+ firstInverseNode = inverse[0];
561
+ if (firstInverseNode) {
562
+ inverseLocationInfo = {
563
+ first_line: firstInverseNode.firstLine,
564
+ last_line: firstInverseNode.lastLine,
565
+ last_column: firstInverseNode.lastColumn,
566
+ first_column: firstInverseNode.firstColumn
567
+ };
568
+ this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
462
569
  } else {
463
- return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
464
- {text: "", token: null, line: this.yylineno});
570
+ this.inverse = new AST.ProgramNode(inverse, inverseStrip);
465
571
  }
572
+ this.strip.right = inverseStrip.left;
573
+ } else if (inverseStrip) {
574
+ this.strip.left = inverseStrip.right;
575
+ }
466
576
  },
467
- lex:function lex() {
468
- var r = this.next();
469
- if (typeof r !== 'undefined') {
470
- return r;
471
- } else {
472
- return this.lex();
473
- }
577
+
578
+ MustacheNode: function(rawParams, hash, open, strip, locInfo) {
579
+ LocationInfo.call(this, locInfo);
580
+ this.type = "mustache";
581
+ this.strip = strip;
582
+
583
+ // Open may be a string parsed from the parser or a passed boolean flag
584
+ if (open != null && open.charAt) {
585
+ // Must use charAt to support IE pre-10
586
+ var escapeFlag = open.charAt(3) || open.charAt(2);
587
+ this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
588
+ } else {
589
+ this.escaped = !!open;
590
+ }
591
+
592
+ if (rawParams instanceof AST.SexprNode) {
593
+ this.sexpr = rawParams;
594
+ } else {
595
+ // Support old AST API
596
+ this.sexpr = new AST.SexprNode(rawParams, hash);
597
+ }
598
+
599
+ this.sexpr.isRoot = true;
600
+
601
+ // Support old AST API that stored this info in MustacheNode
602
+ this.id = this.sexpr.id;
603
+ this.params = this.sexpr.params;
604
+ this.hash = this.sexpr.hash;
605
+ this.eligibleHelper = this.sexpr.eligibleHelper;
606
+ this.isHelper = this.sexpr.isHelper;
474
607
  },
475
- begin:function begin(condition) {
476
- this.conditionStack.push(condition);
477
- },
478
- popState:function popState() {
479
- return this.conditionStack.pop();
480
- },
481
- _currentRules:function _currentRules() {
482
- return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
483
- },
484
- topState:function () {
485
- return this.conditionStack[this.conditionStack.length-2];
486
- },
487
- pushState:function begin(condition) {
488
- this.begin(condition);
489
- }});
490
- lexer.options = {};
491
- lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
492
-
493
- var YYSTATE=YY_START
494
- switch($avoiding_name_collisions) {
495
- case 0:
496
- if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
497
- if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
498
- if(yy_.yytext) return 14;
499
-
500
- break;
501
- case 1: return 14;
502
- break;
503
- case 2:
504
- if(yy_.yytext.slice(-1) !== "\\") this.popState();
505
- if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
506
- return 14;
507
-
508
- break;
509
- case 3: return 24;
510
- break;
511
- case 4: return 16;
512
- break;
513
- case 5: return 20;
514
- break;
515
- case 6: return 19;
516
- break;
517
- case 7: return 19;
518
- break;
519
- case 8: return 23;
520
- break;
521
- case 9: return 23;
522
- break;
523
- case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
524
- break;
525
- case 11: return 22;
526
- break;
527
- case 12: return 35;
528
- break;
529
- case 13: return 34;
530
- break;
531
- case 14: return 34;
532
- break;
533
- case 15: return 37;
534
- break;
535
- case 16: /*ignore whitespace*/
536
- break;
537
- case 17: this.popState(); return 18;
538
- break;
539
- case 18: this.popState(); return 18;
540
- break;
541
- case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 29;
542
- break;
543
- case 20: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 29;
544
- break;
545
- case 21: yy_.yytext = yy_.yytext.substr(1); return 27;
546
- break;
547
- case 22: return 31;
548
- break;
549
- case 23: return 31;
550
- break;
551
- case 24: return 30;
552
- break;
553
- case 25: return 34;
554
- break;
555
- case 26: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 34;
556
- break;
557
- case 27: return 'INVALID';
558
- break;
559
- case 28: return 5;
560
- break;
561
- }
562
- };
563
- lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
564
- lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,28],"inclusive":true}};
565
- return lexer;})()
566
- parser.lexer = lexer;
567
- function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
568
- return new Parser;
569
- })();
570
- if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
571
- exports.parser = handlebars;
572
- exports.Parser = handlebars.Parser;
573
- exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
574
- exports.main = function commonjsMain(args) {
575
- if (!args[1])
576
- throw new Error('Usage: '+args[0]+' FILE');
577
- var source, cwd;
578
- if (typeof process !== 'undefined') {
579
- source = require('fs').readFileSync(require('path').resolve(args[1]), "utf8");
580
- } else {
581
- source = require("file").path(require("file").cwd()).join(args[1]).read({charset: "utf-8"});
582
- }
583
- return exports.parser.parse(source);
584
- }
585
- if (typeof module !== 'undefined' && require.main === module) {
586
- exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
587
- }
588
- };
589
- ;
590
- // lib/handlebars/compiler/base.js
591
- Handlebars.Parser = handlebars;
592
-
593
- Handlebars.parse = function(string) {
594
- Handlebars.Parser.yy = Handlebars.AST;
595
- return Handlebars.Parser.parse(string);
596
- };
597
-
598
- Handlebars.print = function(ast) {
599
- return new Handlebars.PrintVisitor().accept(ast);
600
- };
601
-
602
- Handlebars.logger = {
603
- DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
604
-
605
- // override in the host environment
606
- log: function(level, str) {}
607
- };
608
-
609
- Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
610
- ;
611
- // lib/handlebars/compiler/ast.js
612
- (function() {
613
-
614
- Handlebars.AST = {};
615
-
616
- Handlebars.AST.ProgramNode = function(statements, inverse) {
617
- this.type = "program";
618
- this.statements = statements;
619
- if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
620
- };
621
608
 
622
- Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
623
- this.type = "mustache";
624
- this.escaped = !unescaped;
625
- this.hash = hash;
609
+ SexprNode: function(rawParams, hash, locInfo) {
610
+ LocationInfo.call(this, locInfo);
626
611
 
627
- var id = this.id = rawParams[0];
628
- var params = this.params = rawParams.slice(1);
612
+ this.type = "sexpr";
613
+ this.hash = hash;
629
614
 
630
- // a mustache is an eligible helper if:
631
- // * its id is simple (a single part, not `this` or `..`)
632
- var eligibleHelper = this.eligibleHelper = id.isSimple;
615
+ var id = this.id = rawParams[0];
616
+ var params = this.params = rawParams.slice(1);
633
617
 
634
- // a mustache is definitely a helper if:
635
- // * it is an eligible helper, and
636
- // * it has at least one parameter or hash segment
637
- this.isHelper = eligibleHelper && (params.length || hash);
618
+ // a mustache is an eligible helper if:
619
+ // * its id is simple (a single part, not `this` or `..`)
620
+ var eligibleHelper = this.eligibleHelper = id.isSimple;
638
621
 
639
- // if a mustache is an eligible helper but not a definite
640
- // helper, it is ambiguous, and will be resolved in a later
641
- // pass or at runtime.
642
- };
622
+ // a mustache is definitely a helper if:
623
+ // * it is an eligible helper, and
624
+ // * it has at least one parameter or hash segment
625
+ this.isHelper = eligibleHelper && (params.length || hash);
643
626
 
644
- Handlebars.AST.PartialNode = function(id, context) {
645
- this.type = "partial";
627
+ // if a mustache is an eligible helper but not a definite
628
+ // helper, it is ambiguous, and will be resolved in a later
629
+ // pass or at runtime.
630
+ },
646
631
 
647
- // TODO: disallow complex IDs
632
+ PartialNode: function(partialName, context, strip, locInfo) {
633
+ LocationInfo.call(this, locInfo);
634
+ this.type = "partial";
635
+ this.partialName = partialName;
636
+ this.context = context;
637
+ this.strip = strip;
638
+ },
648
639
 
649
- this.id = id;
650
- this.context = context;
651
- };
640
+ BlockNode: function(mustache, program, inverse, close, locInfo) {
641
+ LocationInfo.call(this, locInfo);
652
642
 
653
- var verifyMatch = function(open, close) {
654
- if(open.original !== close.original) {
655
- throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
656
- }
657
- };
643
+ if(mustache.sexpr.id.original !== close.path.original) {
644
+ throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
645
+ }
658
646
 
659
- Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
660
- verifyMatch(mustache.id, close);
661
- this.type = "block";
662
- this.mustache = mustache;
663
- this.program = program;
664
- this.inverse = inverse;
647
+ this.type = 'block';
648
+ this.mustache = mustache;
649
+ this.program = program;
650
+ this.inverse = inverse;
665
651
 
666
- if (this.inverse && !this.program) {
667
- this.isInverse = true;
668
- }
669
- };
652
+ this.strip = {
653
+ left: mustache.strip.left,
654
+ right: close.strip.right
655
+ };
670
656
 
671
- Handlebars.AST.ContentNode = function(string) {
672
- this.type = "content";
673
- this.string = string;
674
- };
657
+ (program || inverse).strip.left = mustache.strip.right;
658
+ (inverse || program).strip.right = close.strip.left;
675
659
 
676
- Handlebars.AST.HashNode = function(pairs) {
677
- this.type = "hash";
678
- this.pairs = pairs;
679
- };
660
+ if (inverse && !program) {
661
+ this.isInverse = true;
662
+ }
663
+ },
664
+
665
+ ContentNode: function(string, locInfo) {
666
+ LocationInfo.call(this, locInfo);
667
+ this.type = "content";
668
+ this.string = string;
669
+ },
680
670
 
681
- Handlebars.AST.IdNode = function(parts) {
682
- this.type = "ID";
683
- this.original = parts.join(".");
671
+ HashNode: function(pairs, locInfo) {
672
+ LocationInfo.call(this, locInfo);
673
+ this.type = "hash";
674
+ this.pairs = pairs;
675
+ },
684
676
 
685
- var dig = [], depth = 0;
677
+ IdNode: function(parts, locInfo) {
678
+ LocationInfo.call(this, locInfo);
679
+ this.type = "ID";
686
680
 
687
- for(var i=0,l=parts.length; i<l; i++) {
688
- var part = parts[i];
681
+ var original = "",
682
+ dig = [],
683
+ depth = 0;
689
684
 
690
- if(part === "..") { depth++; }
691
- else if(part === "." || part === "this") { this.isScoped = true; }
692
- else { dig.push(part); }
693
- }
685
+ for(var i=0,l=parts.length; i<l; i++) {
686
+ var part = parts[i].part;
687
+ original += (parts[i].separator || '') + part;
694
688
 
695
- this.parts = dig;
696
- this.string = dig.join('.');
697
- this.depth = depth;
689
+ if (part === ".." || part === "." || part === "this") {
690
+ if (dig.length > 0) {
691
+ throw new Exception("Invalid path: " + original, this);
692
+ } else if (part === "..") {
693
+ depth++;
694
+ } else {
695
+ this.isScoped = true;
696
+ }
697
+ } else {
698
+ dig.push(part);
699
+ }
700
+ }
698
701
 
699
- // an ID is simple if it only has one part, and that part is not
700
- // `..` or `this`.
701
- this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
702
- };
702
+ this.original = original;
703
+ this.parts = dig;
704
+ this.string = dig.join('.');
705
+ this.depth = depth;
703
706
 
704
- Handlebars.AST.DataNode = function(id) {
705
- this.type = "DATA";
706
- this.id = id;
707
- };
707
+ // an ID is simple if it only has one part, and that part is not
708
+ // `..` or `this`.
709
+ this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
708
710
 
709
- Handlebars.AST.StringNode = function(string) {
710
- this.type = "STRING";
711
- this.string = string;
712
- };
711
+ this.stringModeValue = this.string;
712
+ },
713
713
 
714
- Handlebars.AST.IntegerNode = function(integer) {
715
- this.type = "INTEGER";
716
- this.integer = integer;
717
- };
714
+ PartialNameNode: function(name, locInfo) {
715
+ LocationInfo.call(this, locInfo);
716
+ this.type = "PARTIAL_NAME";
717
+ this.name = name.original;
718
+ },
719
+
720
+ DataNode: function(id, locInfo) {
721
+ LocationInfo.call(this, locInfo);
722
+ this.type = "DATA";
723
+ this.id = id;
724
+ },
725
+
726
+ StringNode: function(string, locInfo) {
727
+ LocationInfo.call(this, locInfo);
728
+ this.type = "STRING";
729
+ this.original =
730
+ this.string =
731
+ this.stringModeValue = string;
732
+ },
718
733
 
719
- Handlebars.AST.BooleanNode = function(bool) {
720
- this.type = "BOOLEAN";
721
- this.bool = bool;
734
+ IntegerNode: function(integer, locInfo) {
735
+ LocationInfo.call(this, locInfo);
736
+ this.type = "INTEGER";
737
+ this.original =
738
+ this.integer = integer;
739
+ this.stringModeValue = Number(integer);
740
+ },
741
+
742
+ BooleanNode: function(bool, locInfo) {
743
+ LocationInfo.call(this, locInfo);
744
+ this.type = "BOOLEAN";
745
+ this.bool = bool;
746
+ this.stringModeValue = bool === "true";
747
+ },
748
+
749
+ CommentNode: function(comment, locInfo) {
750
+ LocationInfo.call(this, locInfo);
751
+ this.type = "comment";
752
+ this.comment = comment;
753
+ }
722
754
  };
723
755
 
724
- Handlebars.AST.CommentNode = function(comment) {
725
- this.type = "comment";
726
- this.comment = comment;
756
+ // Must be exported as an object rather than the root of the module as the jison lexer
757
+ // most modify the object to operate properly.
758
+ __exports__ = AST;
759
+ return __exports__;
760
+ })(__module5__);
761
+
762
+ // handlebars/compiler/parser.js
763
+ var __module9__ = (function() {
764
+ "use strict";
765
+ var __exports__;
766
+ /* jshint ignore:start */
767
+ /* Jison generated parser */
768
+ var handlebars = (function(){
769
+ var parser = {trace: function trace() { },
770
+ yy: {},
771
+ symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
772
+ terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
773
+ productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
774
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
775
+
776
+ var $0 = $$.length - 1;
777
+ switch (yystate) {
778
+ case 1: return new yy.ProgramNode($$[$0-1], this._$);
779
+ break;
780
+ case 2: return new yy.ProgramNode([], this._$);
781
+ break;
782
+ case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
783
+ break;
784
+ case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
785
+ break;
786
+ case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
787
+ break;
788
+ case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
789
+ break;
790
+ case 7:this.$ = new yy.ProgramNode([], this._$);
791
+ break;
792
+ case 8:this.$ = new yy.ProgramNode([], this._$);
793
+ break;
794
+ case 9:this.$ = [$$[$0]];
795
+ break;
796
+ case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
797
+ break;
798
+ case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
799
+ break;
800
+ case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
801
+ break;
802
+ case 13:this.$ = $$[$0];
803
+ break;
804
+ case 14:this.$ = $$[$0];
805
+ break;
806
+ case 15:this.$ = new yy.ContentNode($$[$0], this._$);
807
+ break;
808
+ case 16:this.$ = new yy.CommentNode($$[$0], this._$);
809
+ break;
810
+ case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
811
+ break;
812
+ case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
813
+ break;
814
+ case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
815
+ break;
816
+ case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
817
+ break;
818
+ case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
819
+ break;
820
+ case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
821
+ break;
822
+ case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
823
+ break;
824
+ case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
825
+ break;
826
+ case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
827
+ break;
828
+ case 26:this.$ = $$[$0];
829
+ break;
830
+ case 27:this.$ = new yy.StringNode($$[$0], this._$);
831
+ break;
832
+ case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
833
+ break;
834
+ case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
835
+ break;
836
+ case 30:this.$ = $$[$0];
837
+ break;
838
+ case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
839
+ break;
840
+ case 32:this.$ = new yy.HashNode($$[$0], this._$);
841
+ break;
842
+ case 33:this.$ = [$$[$0-2], $$[$0]];
843
+ break;
844
+ case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
845
+ break;
846
+ case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
847
+ break;
848
+ case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
849
+ break;
850
+ case 37:this.$ = new yy.DataNode($$[$0], this._$);
851
+ break;
852
+ case 38:this.$ = new yy.IdNode($$[$0], this._$);
853
+ break;
854
+ case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
855
+ break;
856
+ case 40:this.$ = [{part: $$[$0]}];
857
+ break;
858
+ case 43:this.$ = [];
859
+ break;
860
+ case 44:$$[$0-1].push($$[$0]);
861
+ break;
862
+ case 47:this.$ = [$$[$0]];
863
+ break;
864
+ case 48:$$[$0-1].push($$[$0]);
865
+ break;
866
+ }
867
+ },
868
+ table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
869
+ defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
870
+ parseError: function parseError(str, hash) {
871
+ throw new Error(str);
872
+ },
873
+ parse: function parse(input) {
874
+ var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
875
+ this.lexer.setInput(input);
876
+ this.lexer.yy = this.yy;
877
+ this.yy.lexer = this.lexer;
878
+ this.yy.parser = this;
879
+ if (typeof this.lexer.yylloc == "undefined")
880
+ this.lexer.yylloc = {};
881
+ var yyloc = this.lexer.yylloc;
882
+ lstack.push(yyloc);
883
+ var ranges = this.lexer.options && this.lexer.options.ranges;
884
+ if (typeof this.yy.parseError === "function")
885
+ this.parseError = this.yy.parseError;
886
+ function popStack(n) {
887
+ stack.length = stack.length - 2 * n;
888
+ vstack.length = vstack.length - n;
889
+ lstack.length = lstack.length - n;
890
+ }
891
+ function lex() {
892
+ var token;
893
+ token = self.lexer.lex() || 1;
894
+ if (typeof token !== "number") {
895
+ token = self.symbols_[token] || token;
896
+ }
897
+ return token;
898
+ }
899
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
900
+ while (true) {
901
+ state = stack[stack.length - 1];
902
+ if (this.defaultActions[state]) {
903
+ action = this.defaultActions[state];
904
+ } else {
905
+ if (symbol === null || typeof symbol == "undefined") {
906
+ symbol = lex();
907
+ }
908
+ action = table[state] && table[state][symbol];
909
+ }
910
+ if (typeof action === "undefined" || !action.length || !action[0]) {
911
+ var errStr = "";
912
+ if (!recovering) {
913
+ expected = [];
914
+ for (p in table[state])
915
+ if (this.terminals_[p] && p > 2) {
916
+ expected.push("'" + this.terminals_[p] + "'");
917
+ }
918
+ if (this.lexer.showPosition) {
919
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
920
+ } else {
921
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
922
+ }
923
+ this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
924
+ }
925
+ }
926
+ if (action[0] instanceof Array && action.length > 1) {
927
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
928
+ }
929
+ switch (action[0]) {
930
+ case 1:
931
+ stack.push(symbol);
932
+ vstack.push(this.lexer.yytext);
933
+ lstack.push(this.lexer.yylloc);
934
+ stack.push(action[1]);
935
+ symbol = null;
936
+ if (!preErrorSymbol) {
937
+ yyleng = this.lexer.yyleng;
938
+ yytext = this.lexer.yytext;
939
+ yylineno = this.lexer.yylineno;
940
+ yyloc = this.lexer.yylloc;
941
+ if (recovering > 0)
942
+ recovering--;
943
+ } else {
944
+ symbol = preErrorSymbol;
945
+ preErrorSymbol = null;
946
+ }
947
+ break;
948
+ case 2:
949
+ len = this.productions_[action[1]][1];
950
+ yyval.$ = vstack[vstack.length - len];
951
+ yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
952
+ if (ranges) {
953
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
954
+ }
955
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
956
+ if (typeof r !== "undefined") {
957
+ return r;
958
+ }
959
+ if (len) {
960
+ stack = stack.slice(0, -1 * len * 2);
961
+ vstack = vstack.slice(0, -1 * len);
962
+ lstack = lstack.slice(0, -1 * len);
963
+ }
964
+ stack.push(this.productions_[action[1]][0]);
965
+ vstack.push(yyval.$);
966
+ lstack.push(yyval._$);
967
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
968
+ stack.push(newState);
969
+ break;
970
+ case 3:
971
+ return true;
972
+ }
973
+ }
974
+ return true;
975
+ }
727
976
  };
728
977
 
729
- })();;
730
- // lib/handlebars/utils.js
731
- Handlebars.Exception = function(message) {
732
- var tmp = Error.prototype.constructor.apply(this, arguments);
733
978
 
734
- for (var p in tmp) {
735
- if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
979
+ function stripFlags(open, close) {
980
+ return {
981
+ left: open.charAt(2) === '~',
982
+ right: close.charAt(0) === '~' || close.charAt(1) === '~'
983
+ };
736
984
  }
737
985
 
738
- this.message = tmp.message;
739
- };
740
- Handlebars.Exception.prototype = new Error();
741
-
742
- // Build out our basic SafeString type
743
- Handlebars.SafeString = function(string) {
744
- this.string = string;
745
- };
746
- Handlebars.SafeString.prototype.toString = function() {
747
- return this.string.toString();
748
- };
986
+ /* Jison generated lexer */
987
+ var lexer = (function(){
988
+ var lexer = ({EOF:1,
989
+ parseError:function parseError(str, hash) {
990
+ if (this.yy.parser) {
991
+ this.yy.parser.parseError(str, hash);
992
+ } else {
993
+ throw new Error(str);
994
+ }
995
+ },
996
+ setInput:function (input) {
997
+ this._input = input;
998
+ this._more = this._less = this.done = false;
999
+ this.yylineno = this.yyleng = 0;
1000
+ this.yytext = this.matched = this.match = '';
1001
+ this.conditionStack = ['INITIAL'];
1002
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
1003
+ if (this.options.ranges) this.yylloc.range = [0,0];
1004
+ this.offset = 0;
1005
+ return this;
1006
+ },
1007
+ input:function () {
1008
+ var ch = this._input[0];
1009
+ this.yytext += ch;
1010
+ this.yyleng++;
1011
+ this.offset++;
1012
+ this.match += ch;
1013
+ this.matched += ch;
1014
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
1015
+ if (lines) {
1016
+ this.yylineno++;
1017
+ this.yylloc.last_line++;
1018
+ } else {
1019
+ this.yylloc.last_column++;
1020
+ }
1021
+ if (this.options.ranges) this.yylloc.range[1]++;
749
1022
 
750
- (function() {
751
- var escape = {
752
- "&": "&amp;",
753
- "<": "&lt;",
754
- ">": "&gt;",
755
- '"': "&quot;",
756
- "'": "&#x27;",
757
- "`": "&#x60;"
758
- };
1023
+ this._input = this._input.slice(1);
1024
+ return ch;
1025
+ },
1026
+ unput:function (ch) {
1027
+ var len = ch.length;
1028
+ var lines = ch.split(/(?:\r\n?|\n)/g);
1029
+
1030
+ this._input = ch + this._input;
1031
+ this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
1032
+ //this.yyleng -= len;
1033
+ this.offset -= len;
1034
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
1035
+ this.match = this.match.substr(0, this.match.length-1);
1036
+ this.matched = this.matched.substr(0, this.matched.length-1);
1037
+
1038
+ if (lines.length-1) this.yylineno -= lines.length-1;
1039
+ var r = this.yylloc.range;
1040
+
1041
+ this.yylloc = {first_line: this.yylloc.first_line,
1042
+ last_line: this.yylineno+1,
1043
+ first_column: this.yylloc.first_column,
1044
+ last_column: lines ?
1045
+ (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
1046
+ this.yylloc.first_column - len
1047
+ };
1048
+
1049
+ if (this.options.ranges) {
1050
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
1051
+ }
1052
+ return this;
1053
+ },
1054
+ more:function () {
1055
+ this._more = true;
1056
+ return this;
1057
+ },
1058
+ less:function (n) {
1059
+ this.unput(this.match.slice(n));
1060
+ },
1061
+ pastInput:function () {
1062
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
1063
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
1064
+ },
1065
+ upcomingInput:function () {
1066
+ var next = this.match;
1067
+ if (next.length < 20) {
1068
+ next += this._input.substr(0, 20-next.length);
1069
+ }
1070
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
1071
+ },
1072
+ showPosition:function () {
1073
+ var pre = this.pastInput();
1074
+ var c = new Array(pre.length + 1).join("-");
1075
+ return pre + this.upcomingInput() + "\n" + c+"^";
1076
+ },
1077
+ next:function () {
1078
+ if (this.done) {
1079
+ return this.EOF;
1080
+ }
1081
+ if (!this._input) this.done = true;
1082
+
1083
+ var token,
1084
+ match,
1085
+ tempMatch,
1086
+ index,
1087
+ col,
1088
+ lines;
1089
+ if (!this._more) {
1090
+ this.yytext = '';
1091
+ this.match = '';
1092
+ }
1093
+ var rules = this._currentRules();
1094
+ for (var i=0;i < rules.length; i++) {
1095
+ tempMatch = this._input.match(this.rules[rules[i]]);
1096
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1097
+ match = tempMatch;
1098
+ index = i;
1099
+ if (!this.options.flex) break;
1100
+ }
1101
+ }
1102
+ if (match) {
1103
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
1104
+ if (lines) this.yylineno += lines.length;
1105
+ this.yylloc = {first_line: this.yylloc.last_line,
1106
+ last_line: this.yylineno+1,
1107
+ first_column: this.yylloc.last_column,
1108
+ last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1109
+ this.yytext += match[0];
1110
+ this.match += match[0];
1111
+ this.matches = match;
1112
+ this.yyleng = this.yytext.length;
1113
+ if (this.options.ranges) {
1114
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
1115
+ }
1116
+ this._more = false;
1117
+ this._input = this._input.slice(match[0].length);
1118
+ this.matched += match[0];
1119
+ token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1120
+ if (this.done && this._input) this.done = false;
1121
+ if (token) return token;
1122
+ else return;
1123
+ }
1124
+ if (this._input === "") {
1125
+ return this.EOF;
1126
+ } else {
1127
+ return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1128
+ {text: "", token: null, line: this.yylineno});
1129
+ }
1130
+ },
1131
+ lex:function lex() {
1132
+ var r = this.next();
1133
+ if (typeof r !== 'undefined') {
1134
+ return r;
1135
+ } else {
1136
+ return this.lex();
1137
+ }
1138
+ },
1139
+ begin:function begin(condition) {
1140
+ this.conditionStack.push(condition);
1141
+ },
1142
+ popState:function popState() {
1143
+ return this.conditionStack.pop();
1144
+ },
1145
+ _currentRules:function _currentRules() {
1146
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1147
+ },
1148
+ topState:function () {
1149
+ return this.conditionStack[this.conditionStack.length-2];
1150
+ },
1151
+ pushState:function begin(condition) {
1152
+ this.begin(condition);
1153
+ }});
1154
+ lexer.options = {};
1155
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
759
1156
 
760
- var badChars = /[&<>"'`]/g;
761
- var possible = /[&<>"'`]/;
762
1157
 
763
- var escapeChar = function(chr) {
764
- return escape[chr] || "&amp;";
1158
+ function strip(start, end) {
1159
+ return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1160
+ }
1161
+
1162
+
1163
+ var YYSTATE=YY_START
1164
+ switch($avoiding_name_collisions) {
1165
+ case 0:
1166
+ if(yy_.yytext.slice(-2) === "\\\\") {
1167
+ strip(0,1);
1168
+ this.begin("mu");
1169
+ } else if(yy_.yytext.slice(-1) === "\\") {
1170
+ strip(0,1);
1171
+ this.begin("emu");
1172
+ } else {
1173
+ this.begin("mu");
1174
+ }
1175
+ if(yy_.yytext) return 14;
1176
+
1177
+ break;
1178
+ case 1:return 14;
1179
+ break;
1180
+ case 2:
1181
+ this.popState();
1182
+ return 14;
1183
+
1184
+ break;
1185
+ case 3:strip(0,4); this.popState(); return 15;
1186
+ break;
1187
+ case 4:return 35;
1188
+ break;
1189
+ case 5:return 36;
1190
+ break;
1191
+ case 6:return 25;
1192
+ break;
1193
+ case 7:return 16;
1194
+ break;
1195
+ case 8:return 20;
1196
+ break;
1197
+ case 9:return 19;
1198
+ break;
1199
+ case 10:return 19;
1200
+ break;
1201
+ case 11:return 23;
1202
+ break;
1203
+ case 12:return 22;
1204
+ break;
1205
+ case 13:this.popState(); this.begin('com');
1206
+ break;
1207
+ case 14:strip(3,5); this.popState(); return 15;
1208
+ break;
1209
+ case 15:return 22;
1210
+ break;
1211
+ case 16:return 41;
1212
+ break;
1213
+ case 17:return 40;
1214
+ break;
1215
+ case 18:return 40;
1216
+ break;
1217
+ case 19:return 44;
1218
+ break;
1219
+ case 20:// ignore whitespace
1220
+ break;
1221
+ case 21:this.popState(); return 24;
1222
+ break;
1223
+ case 22:this.popState(); return 18;
1224
+ break;
1225
+ case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
1226
+ break;
1227
+ case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
1228
+ break;
1229
+ case 25:return 42;
1230
+ break;
1231
+ case 26:return 34;
1232
+ break;
1233
+ case 27:return 34;
1234
+ break;
1235
+ case 28:return 33;
1236
+ break;
1237
+ case 29:return 40;
1238
+ break;
1239
+ case 30:yy_.yytext = strip(1,2); return 40;
1240
+ break;
1241
+ case 31:return 'INVALID';
1242
+ break;
1243
+ case 32:return 5;
1244
+ break;
1245
+ }
765
1246
  };
1247
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1248
+ lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
1249
+ return lexer;})()
1250
+ parser.lexer = lexer;
1251
+ function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1252
+ return new Parser;
1253
+ })();__exports__ = handlebars;
1254
+ /* jshint ignore:end */
1255
+ return __exports__;
1256
+ })();
766
1257
 
767
- Handlebars.Utils = {
768
- escapeExpression: function(string) {
769
- // don't escape SafeStrings, since they're already safe
770
- if (string instanceof Handlebars.SafeString) {
771
- return string.toString();
772
- } else if (string == null || string === false) {
773
- return "";
774
- }
1258
+ // handlebars/compiler/base.js
1259
+ var __module8__ = (function(__dependency1__, __dependency2__) {
1260
+ "use strict";
1261
+ var __exports__ = {};
1262
+ var parser = __dependency1__;
1263
+ var AST = __dependency2__;
775
1264
 
776
- if(!possible.test(string)) { return string; }
777
- return string.replace(badChars, escapeChar);
778
- },
1265
+ __exports__.parser = parser;
779
1266
 
780
- isEmpty: function(value) {
781
- if (typeof value === "undefined") {
782
- return true;
783
- } else if (value === null) {
784
- return true;
785
- } else if (value === false) {
786
- return true;
787
- } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
788
- return true;
789
- } else {
790
- return false;
791
- }
792
- }
793
- };
794
- })();;
795
- // lib/handlebars/compiler/compiler.js
1267
+ function parse(input) {
1268
+ // Just return if an already-compile AST was passed in.
1269
+ if(input.constructor === AST.ProgramNode) { return input; }
1270
+
1271
+ parser.yy = AST;
1272
+ return parser.parse(input);
1273
+ }
1274
+
1275
+ __exports__.parse = parse;
1276
+ return __exports__;
1277
+ })(__module9__, __module7__);
796
1278
 
797
- /*jshint eqnull:true*/
798
- Handlebars.Compiler = function() {};
799
- Handlebars.JavaScriptCompiler = function() {};
1279
+ // handlebars/compiler/compiler.js
1280
+ var __module10__ = (function(__dependency1__) {
1281
+ "use strict";
1282
+ var __exports__ = {};
1283
+ var Exception = __dependency1__;
800
1284
 
801
- (function(Compiler, JavaScriptCompiler) {
802
- // the foundHelper register will disambiguate helper lookup from finding a
1285
+ function Compiler() {}
1286
+
1287
+ __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
803
1288
  // function in a context. This is necessary for mustache compatibility, which
804
1289
  // requires that context functions in blocks are evaluated by blockHelperMissing,
805
1290
  // and then proceed as if the resulting value was provided to blockHelperMissing.
@@ -831,9 +1316,42 @@ Handlebars.JavaScriptCompiler = function() {};
831
1316
  return out.join("\n");
832
1317
  },
833
1318
 
1319
+ equals: function(other) {
1320
+ var len = this.opcodes.length;
1321
+ if (other.opcodes.length !== len) {
1322
+ return false;
1323
+ }
1324
+
1325
+ for (var i = 0; i < len; i++) {
1326
+ var opcode = this.opcodes[i],
1327
+ otherOpcode = other.opcodes[i];
1328
+ if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
1329
+ return false;
1330
+ }
1331
+ for (var j = 0; j < opcode.args.length; j++) {
1332
+ if (opcode.args[j] !== otherOpcode.args[j]) {
1333
+ return false;
1334
+ }
1335
+ }
1336
+ }
1337
+
1338
+ len = this.children.length;
1339
+ if (other.children.length !== len) {
1340
+ return false;
1341
+ }
1342
+ for (i = 0; i < len; i++) {
1343
+ if (!this.children[i].equals(other.children[i])) {
1344
+ return false;
1345
+ }
1346
+ }
1347
+
1348
+ return true;
1349
+ },
1350
+
834
1351
  guid: 0,
835
1352
 
836
1353
  compile: function(program, options) {
1354
+ this.opcodes = [];
837
1355
  this.children = [];
838
1356
  this.depths = {list: []};
839
1357
  this.options = options;
@@ -855,20 +1373,30 @@ Handlebars.JavaScriptCompiler = function() {};
855
1373
  }
856
1374
  }
857
1375
 
858
- return this.program(program);
1376
+ return this.accept(program);
859
1377
  },
860
1378
 
861
1379
  accept: function(node) {
862
- return this[node.type](node);
1380
+ var strip = node.strip || {},
1381
+ ret;
1382
+ if (strip.left) {
1383
+ this.opcode('strip');
1384
+ }
1385
+
1386
+ ret = this[node.type](node);
1387
+
1388
+ if (strip.right) {
1389
+ this.opcode('strip');
1390
+ }
1391
+
1392
+ return ret;
863
1393
  },
864
1394
 
865
1395
  program: function(program) {
866
- var statements = program.statements, statement;
867
- this.opcodes = [];
1396
+ var statements = program.statements;
868
1397
 
869
1398
  for(var i=0, l=statements.length; i<l; i++) {
870
- statement = statements[i];
871
- this[statement.type](statement);
1399
+ this.accept(statements[i]);
872
1400
  }
873
1401
  this.isSimple = l === 1;
874
1402
 
@@ -910,27 +1438,28 @@ Handlebars.JavaScriptCompiler = function() {};
910
1438
  inverse = this.compileProgram(inverse);
911
1439
  }
912
1440
 
913
- var type = this.classifyMustache(mustache);
1441
+ var sexpr = mustache.sexpr;
1442
+ var type = this.classifySexpr(sexpr);
914
1443
 
915
1444
  if (type === "helper") {
916
- this.helperMustache(mustache, program, inverse);
1445
+ this.helperSexpr(sexpr, program, inverse);
917
1446
  } else if (type === "simple") {
918
- this.simpleMustache(mustache);
1447
+ this.simpleSexpr(sexpr);
919
1448
 
920
1449
  // now that the simple mustache is resolved, we need to
921
1450
  // evaluate it by executing `blockHelperMissing`
922
1451
  this.opcode('pushProgram', program);
923
1452
  this.opcode('pushProgram', inverse);
924
- this.opcode('pushLiteral', '{}');
1453
+ this.opcode('emptyHash');
925
1454
  this.opcode('blockValue');
926
1455
  } else {
927
- this.ambiguousMustache(mustache, program, inverse);
1456
+ this.ambiguousSexpr(sexpr, program, inverse);
928
1457
 
929
1458
  // now that the simple mustache is resolved, we need to
930
1459
  // evaluate it by executing `blockHelperMissing`
931
1460
  this.opcode('pushProgram', program);
932
1461
  this.opcode('pushProgram', inverse);
933
- this.opcode('pushLiteral', '{}');
1462
+ this.opcode('emptyHash');
934
1463
  this.opcode('ambiguousBlockValue');
935
1464
  }
936
1465
 
@@ -940,19 +1469,35 @@ Handlebars.JavaScriptCompiler = function() {};
940
1469
  hash: function(hash) {
941
1470
  var pairs = hash.pairs, pair, val;
942
1471
 
943
- this.opcode('push', '{}');
1472
+ this.opcode('pushHash');
944
1473
 
945
1474
  for(var i=0, l=pairs.length; i<l; i++) {
946
1475
  pair = pairs[i];
947
1476
  val = pair[1];
948
1477
 
949
- this.accept(val);
1478
+ if (this.options.stringParams) {
1479
+ if(val.depth) {
1480
+ this.addDepth(val.depth);
1481
+ }
1482
+ this.opcode('getContext', val.depth || 0);
1483
+ this.opcode('pushStringParam', val.stringModeValue, val.type);
1484
+
1485
+ if (val.type === 'sexpr') {
1486
+ // Subexpressions get evaluated and passed in
1487
+ // in string params mode.
1488
+ this.sexpr(val);
1489
+ }
1490
+ } else {
1491
+ this.accept(val);
1492
+ }
1493
+
950
1494
  this.opcode('assignToHash', pair[0]);
951
1495
  }
1496
+ this.opcode('popHash');
952
1497
  },
953
1498
 
954
1499
  partial: function(partial) {
955
- var id = partial.id;
1500
+ var partialName = partial.partialName;
956
1501
  this.usePartial = true;
957
1502
 
958
1503
  if(partial.context) {
@@ -961,7 +1506,7 @@ Handlebars.JavaScriptCompiler = function() {};
961
1506
  this.opcode('push', 'depth0');
962
1507
  }
963
1508
 
964
- this.opcode('invokePartial', id.original);
1509
+ this.opcode('invokePartial', partialName.name);
965
1510
  this.opcode('append');
966
1511
  },
967
1512
 
@@ -970,37 +1515,30 @@ Handlebars.JavaScriptCompiler = function() {};
970
1515
  },
971
1516
 
972
1517
  mustache: function(mustache) {
973
- var options = this.options;
974
- var type = this.classifyMustache(mustache);
975
-
976
- if (type === "simple") {
977
- this.simpleMustache(mustache);
978
- } else if (type === "helper") {
979
- this.helperMustache(mustache);
980
- } else {
981
- this.ambiguousMustache(mustache);
982
- }
1518
+ this.sexpr(mustache.sexpr);
983
1519
 
984
- if(mustache.escaped && !options.noEscape) {
1520
+ if(mustache.escaped && !this.options.noEscape) {
985
1521
  this.opcode('appendEscaped');
986
1522
  } else {
987
1523
  this.opcode('append');
988
1524
  }
989
1525
  },
990
1526
 
991
- ambiguousMustache: function(mustache, program, inverse) {
992
- var id = mustache.id, name = id.parts[0];
1527
+ ambiguousSexpr: function(sexpr, program, inverse) {
1528
+ var id = sexpr.id,
1529
+ name = id.parts[0],
1530
+ isBlock = program != null || inverse != null;
993
1531
 
994
1532
  this.opcode('getContext', id.depth);
995
1533
 
996
1534
  this.opcode('pushProgram', program);
997
1535
  this.opcode('pushProgram', inverse);
998
1536
 
999
- this.opcode('invokeAmbiguous', name);
1537
+ this.opcode('invokeAmbiguous', name, isBlock);
1000
1538
  },
1001
1539
 
1002
- simpleMustache: function(mustache, program, inverse) {
1003
- var id = mustache.id;
1540
+ simpleSexpr: function(sexpr) {
1541
+ var id = sexpr.id;
1004
1542
 
1005
1543
  if (id.type === 'DATA') {
1006
1544
  this.DATA(id);
@@ -1016,16 +1554,28 @@ Handlebars.JavaScriptCompiler = function() {};
1016
1554
  this.opcode('resolvePossibleLambda');
1017
1555
  },
1018
1556
 
1019
- helperMustache: function(mustache, program, inverse) {
1020
- var params = this.setupFullMustacheParams(mustache, program, inverse),
1021
- name = mustache.id.parts[0];
1557
+ helperSexpr: function(sexpr, program, inverse) {
1558
+ var params = this.setupFullMustacheParams(sexpr, program, inverse),
1559
+ name = sexpr.id.parts[0];
1022
1560
 
1023
1561
  if (this.options.knownHelpers[name]) {
1024
1562
  this.opcode('invokeKnownHelper', params.length, name);
1025
- } else if (this.knownHelpersOnly) {
1026
- throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
1563
+ } else if (this.options.knownHelpersOnly) {
1564
+ throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
1565
+ } else {
1566
+ this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
1567
+ }
1568
+ },
1569
+
1570
+ sexpr: function(sexpr) {
1571
+ var type = this.classifySexpr(sexpr);
1572
+
1573
+ if (type === "simple") {
1574
+ this.simpleSexpr(sexpr);
1575
+ } else if (type === "helper") {
1576
+ this.helperSexpr(sexpr);
1027
1577
  } else {
1028
- this.opcode('invokeHelper', params.length, name);
1578
+ this.ambiguousSexpr(sexpr);
1029
1579
  }
1030
1580
  },
1031
1581
 
@@ -1047,7 +1597,15 @@ Handlebars.JavaScriptCompiler = function() {};
1047
1597
 
1048
1598
  DATA: function(data) {
1049
1599
  this.options.data = true;
1050
- this.opcode('lookupData', data.id);
1600
+ if (data.id.isScoped || data.id.depth) {
1601
+ throw new Exception('Scoped data references are not supported: ' + data.original, data);
1602
+ }
1603
+
1604
+ this.opcode('lookupData');
1605
+ var parts = data.id.parts;
1606
+ for(var i=0, l=parts.length; i<l; i++) {
1607
+ this.opcode('lookup', parts[i]);
1608
+ }
1051
1609
  },
1052
1610
 
1053
1611
  STRING: function(string) {
@@ -1074,7 +1632,6 @@ Handlebars.JavaScriptCompiler = function() {};
1074
1632
  },
1075
1633
 
1076
1634
  addDepth: function(depth) {
1077
- if(isNaN(depth)) { throw new Error("EWOT"); }
1078
1635
  if(depth === 0) { return; }
1079
1636
 
1080
1637
  if(!this.depths[depth]) {
@@ -1083,14 +1640,14 @@ Handlebars.JavaScriptCompiler = function() {};
1083
1640
  }
1084
1641
  },
1085
1642
 
1086
- classifyMustache: function(mustache) {
1087
- var isHelper = mustache.isHelper;
1088
- var isEligible = mustache.eligibleHelper;
1643
+ classifySexpr: function(sexpr) {
1644
+ var isHelper = sexpr.isHelper;
1645
+ var isEligible = sexpr.eligibleHelper;
1089
1646
  var options = this.options;
1090
1647
 
1091
1648
  // if ambiguous, we can possibly resolve the ambiguity now
1092
1649
  if (isEligible && !isHelper) {
1093
- var name = mustache.id.parts[0];
1650
+ var name = sexpr.id.parts[0];
1094
1651
 
1095
1652
  if (options.knownHelpers[name]) {
1096
1653
  isHelper = true;
@@ -1116,67 +1673,140 @@ Handlebars.JavaScriptCompiler = function() {};
1116
1673
  }
1117
1674
 
1118
1675
  this.opcode('getContext', param.depth || 0);
1119
- this.opcode('pushStringParam', param.string);
1676
+ this.opcode('pushStringParam', param.stringModeValue, param.type);
1677
+
1678
+ if (param.type === 'sexpr') {
1679
+ // Subexpressions get evaluated and passed in
1680
+ // in string params mode.
1681
+ this.sexpr(param);
1682
+ }
1120
1683
  } else {
1121
1684
  this[param.type](param);
1122
1685
  }
1123
1686
  }
1124
1687
  },
1125
1688
 
1126
- setupMustacheParams: function(mustache) {
1127
- var params = mustache.params;
1128
- this.pushParams(params);
1129
-
1130
- if(mustache.hash) {
1131
- this.hash(mustache.hash);
1132
- } else {
1133
- this.opcode('pushLiteral', '{}');
1134
- }
1135
-
1136
- return params;
1137
- },
1138
-
1139
- // this will replace setupMustacheParams when we're done
1140
- setupFullMustacheParams: function(mustache, program, inverse) {
1141
- var params = mustache.params;
1689
+ setupFullMustacheParams: function(sexpr, program, inverse) {
1690
+ var params = sexpr.params;
1142
1691
  this.pushParams(params);
1143
1692
 
1144
1693
  this.opcode('pushProgram', program);
1145
1694
  this.opcode('pushProgram', inverse);
1146
1695
 
1147
- if(mustache.hash) {
1148
- this.hash(mustache.hash);
1696
+ if (sexpr.hash) {
1697
+ this.hash(sexpr.hash);
1149
1698
  } else {
1150
- this.opcode('pushLiteral', '{}');
1699
+ this.opcode('emptyHash');
1151
1700
  }
1152
1701
 
1153
1702
  return params;
1154
1703
  }
1155
1704
  };
1156
1705
 
1157
- var Literal = function(value) {
1706
+ function precompile(input, options, env) {
1707
+ if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
1708
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
1709
+ }
1710
+
1711
+ options = options || {};
1712
+ if (!('data' in options)) {
1713
+ options.data = true;
1714
+ }
1715
+
1716
+ var ast = env.parse(input);
1717
+ var environment = new env.Compiler().compile(ast, options);
1718
+ return new env.JavaScriptCompiler().compile(environment, options);
1719
+ }
1720
+
1721
+ __exports__.precompile = precompile;function compile(input, options, env) {
1722
+ if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
1723
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
1724
+ }
1725
+
1726
+ options = options || {};
1727
+
1728
+ if (!('data' in options)) {
1729
+ options.data = true;
1730
+ }
1731
+
1732
+ var compiled;
1733
+
1734
+ function compileInput() {
1735
+ var ast = env.parse(input);
1736
+ var environment = new env.Compiler().compile(ast, options);
1737
+ var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
1738
+ return env.template(templateSpec);
1739
+ }
1740
+
1741
+ // Template is only compiled on first use and cached after that point.
1742
+ return function(context, options) {
1743
+ if (!compiled) {
1744
+ compiled = compileInput();
1745
+ }
1746
+ return compiled.call(this, context, options);
1747
+ };
1748
+ }
1749
+
1750
+ __exports__.compile = compile;
1751
+ return __exports__;
1752
+ })(__module5__);
1753
+
1754
+ // handlebars/compiler/javascript-compiler.js
1755
+ var __module11__ = (function(__dependency1__, __dependency2__) {
1756
+ "use strict";
1757
+ var __exports__;
1758
+ var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
1759
+ var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
1760
+ var log = __dependency1__.log;
1761
+ var Exception = __dependency2__;
1762
+
1763
+ function Literal(value) {
1158
1764
  this.value = value;
1159
- };
1765
+ }
1766
+
1767
+ function JavaScriptCompiler() {}
1160
1768
 
1161
1769
  JavaScriptCompiler.prototype = {
1162
1770
  // PUBLIC API: You can override these methods in a subclass to provide
1163
1771
  // alternative compiled forms for name lookup and buffering semantics
1164
- nameLookup: function(parent, name, type) {
1772
+ nameLookup: function(parent, name /* , type*/) {
1773
+ var wrap,
1774
+ ret;
1775
+ if (parent.indexOf('depth') === 0) {
1776
+ wrap = true;
1777
+ }
1778
+
1165
1779
  if (/^[0-9]+$/.test(name)) {
1166
- return parent + "[" + name + "]";
1780
+ ret = parent + "[" + name + "]";
1167
1781
  } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1168
- return parent + "." + name;
1782
+ ret = parent + "." + name;
1169
1783
  }
1170
1784
  else {
1171
- return parent + "['" + name + "']";
1785
+ ret = parent + "['" + name + "']";
1786
+ }
1787
+
1788
+ if (wrap) {
1789
+ return '(' + parent + ' && ' + ret + ')';
1790
+ } else {
1791
+ return ret;
1172
1792
  }
1173
1793
  },
1174
1794
 
1795
+ compilerInfo: function() {
1796
+ var revision = COMPILER_REVISION,
1797
+ versions = REVISION_CHANGES[revision];
1798
+ return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
1799
+ },
1800
+
1175
1801
  appendToBuffer: function(string) {
1176
1802
  if (this.environment.isSimple) {
1177
1803
  return "return " + string + ";";
1178
1804
  } else {
1179
- return "buffer += " + string + ";";
1805
+ return {
1806
+ appendToBuffer: true,
1807
+ content: string,
1808
+ toString: function() { return "buffer += " + string + ";"; }
1809
+ };
1180
1810
  }
1181
1811
  },
1182
1812
 
@@ -1191,12 +1821,13 @@ Handlebars.JavaScriptCompiler = function() {};
1191
1821
  this.environment = environment;
1192
1822
  this.options = options || {};
1193
1823
 
1194
- Handlebars.log(Handlebars.logger.DEBUG, this.environment.disassemble() + "\n\n");
1824
+ log('debug', this.environment.disassemble() + "\n\n");
1195
1825
 
1196
1826
  this.name = this.environment.name;
1197
1827
  this.isChild = !!context;
1198
1828
  this.context = context || {
1199
1829
  programs: [],
1830
+ environments: [],
1200
1831
  aliases: { }
1201
1832
  };
1202
1833
 
@@ -1205,7 +1836,9 @@ Handlebars.JavaScriptCompiler = function() {};
1205
1836
  this.stackSlot = 0;
1206
1837
  this.stackVars = [];
1207
1838
  this.registers = { list: [] };
1839
+ this.hashes = [];
1208
1840
  this.compileStack = [];
1841
+ this.inlineStack = [];
1209
1842
 
1210
1843
  this.compileChildren(environment, options);
1211
1844
 
@@ -1213,7 +1846,7 @@ Handlebars.JavaScriptCompiler = function() {};
1213
1846
 
1214
1847
  this.i = 0;
1215
1848
 
1216
- for(l=opcodes.length; this.i<l; this.i++) {
1849
+ for(var l=opcodes.length; this.i<l; this.i++) {
1217
1850
  opcode = opcodes[this.i];
1218
1851
 
1219
1852
  if(opcode.opcode === 'DECLARE') {
@@ -1221,18 +1854,21 @@ Handlebars.JavaScriptCompiler = function() {};
1221
1854
  } else {
1222
1855
  this[opcode.opcode].apply(this, opcode.args);
1223
1856
  }
1857
+
1858
+ // Reset the stripNext flag if it was not set by this operation.
1859
+ if (opcode.opcode !== this.stripNext) {
1860
+ this.stripNext = false;
1861
+ }
1224
1862
  }
1225
1863
 
1226
- return this.createFunctionContext(asObject);
1227
- },
1864
+ // Flush any trailing content that might be pending.
1865
+ this.pushSource('');
1228
1866
 
1229
- nextOpcode: function() {
1230
- var opcodes = this.environment.opcodes, opcode = opcodes[this.i + 1];
1231
- return opcodes[this.i + 1];
1232
- },
1867
+ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
1868
+ throw new Exception('Compile completed with content left on stack');
1869
+ }
1233
1870
 
1234
- eat: function(opcode) {
1235
- this.i = this.i + 1;
1871
+ return this.createFunctionContext(asObject);
1236
1872
  },
1237
1873
 
1238
1874
  preamble: function() {
@@ -1240,8 +1876,9 @@ Handlebars.JavaScriptCompiler = function() {};
1240
1876
 
1241
1877
  if (!this.isChild) {
1242
1878
  var namespace = this.namespace;
1243
- var copies = "helpers = helpers || " + namespace + ".helpers;";
1244
- if (this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
1879
+
1880
+ var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1881
+ if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1245
1882
  if (this.options.data) { copies = copies + " data = data || {};"; }
1246
1883
  out.push(copies);
1247
1884
  } else {
@@ -1269,9 +1906,10 @@ Handlebars.JavaScriptCompiler = function() {};
1269
1906
 
1270
1907
  // Generate minimizer alias mappings
1271
1908
  if (!this.isChild) {
1272
- var aliases = [];
1273
1909
  for (var alias in this.context.aliases) {
1274
- this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1910
+ if (this.context.aliases.hasOwnProperty(alias)) {
1911
+ this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1912
+ }
1275
1913
  }
1276
1914
  }
1277
1915
 
@@ -1285,7 +1923,7 @@ Handlebars.JavaScriptCompiler = function() {};
1285
1923
  }
1286
1924
 
1287
1925
  if (!this.environment.isSimple) {
1288
- this.source.push("return buffer;");
1926
+ this.pushSource("return buffer;");
1289
1927
  }
1290
1928
 
1291
1929
  var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
@@ -1294,16 +1932,46 @@ Handlebars.JavaScriptCompiler = function() {};
1294
1932
  params.push("depth" + this.environment.depths.list[i]);
1295
1933
  }
1296
1934
 
1935
+ // Perform a second pass over the output to merge content when possible
1936
+ var source = this.mergeSource();
1937
+
1938
+ if (!this.isChild) {
1939
+ source = this.compilerInfo()+source;
1940
+ }
1941
+
1297
1942
  if (asObject) {
1298
- params.push(this.source.join("\n "));
1943
+ params.push(source);
1299
1944
 
1300
1945
  return Function.apply(this, params);
1301
1946
  } else {
1302
- var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
1303
- Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
1947
+ var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
1948
+ log('debug', functionSource + "\n\n");
1304
1949
  return functionSource;
1305
1950
  }
1306
1951
  },
1952
+ mergeSource: function() {
1953
+ // WARN: We are not handling the case where buffer is still populated as the source should
1954
+ // not have buffer append operations as their final action.
1955
+ var source = '',
1956
+ buffer;
1957
+ for (var i = 0, len = this.source.length; i < len; i++) {
1958
+ var line = this.source[i];
1959
+ if (line.appendToBuffer) {
1960
+ if (buffer) {
1961
+ buffer = buffer + '\n + ' + line.content;
1962
+ } else {
1963
+ buffer = line.content;
1964
+ }
1965
+ } else {
1966
+ if (buffer) {
1967
+ source += 'buffer += ' + buffer + ';\n ';
1968
+ buffer = undefined;
1969
+ }
1970
+ source += line + '\n ';
1971
+ }
1972
+ }
1973
+ return source;
1974
+ },
1307
1975
 
1308
1976
  // [blockValue]
1309
1977
  //
@@ -1322,7 +1990,7 @@ Handlebars.JavaScriptCompiler = function() {};
1322
1990
 
1323
1991
  this.replaceStack(function(current) {
1324
1992
  params.splice(1, 0, current);
1325
- return current + " = blockHelperMissing.call(" + params.join(", ") + ")";
1993
+ return "blockHelperMissing.call(" + params.join(", ") + ")";
1326
1994
  });
1327
1995
  },
1328
1996
 
@@ -1341,7 +2009,7 @@ Handlebars.JavaScriptCompiler = function() {};
1341
2009
  var current = this.topStack();
1342
2010
  params.splice(1, 0, current);
1343
2011
 
1344
- this.source.push("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
2012
+ this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
1345
2013
  },
1346
2014
 
1347
2015
  // [appendContent]
@@ -1351,7 +2019,28 @@ Handlebars.JavaScriptCompiler = function() {};
1351
2019
  //
1352
2020
  // Appends the string value of `content` to the current buffer
1353
2021
  appendContent: function(content) {
1354
- this.source.push(this.appendToBuffer(this.quotedString(content)));
2022
+ if (this.pendingContent) {
2023
+ content = this.pendingContent + content;
2024
+ }
2025
+ if (this.stripNext) {
2026
+ content = content.replace(/^\s+/, '');
2027
+ }
2028
+
2029
+ this.pendingContent = content;
2030
+ },
2031
+
2032
+ // [strip]
2033
+ //
2034
+ // On stack, before: ...
2035
+ // On stack, after: ...
2036
+ //
2037
+ // Removes any trailing whitespace from the prior content node and flags
2038
+ // the next operation for stripping if it is a content node.
2039
+ strip: function() {
2040
+ if (this.pendingContent) {
2041
+ this.pendingContent = this.pendingContent.replace(/\s+$/, '');
2042
+ }
2043
+ this.stripNext = 'strip';
1355
2044
  },
1356
2045
 
1357
2046
  // [append]
@@ -1364,10 +2053,13 @@ Handlebars.JavaScriptCompiler = function() {};
1364
2053
  // If `value` is truthy, or 0, it is coerced into a string and appended
1365
2054
  // Otherwise, the empty string is appended
1366
2055
  append: function() {
2056
+ // Force anything that is inlined onto the stack so we don't have duplication
2057
+ // when we examine local
2058
+ this.flushInline();
1367
2059
  var local = this.popStack();
1368
- this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
2060
+ this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1369
2061
  if (this.environment.isSimple) {
1370
- this.source.push("else { " + this.appendToBuffer("''") + " }");
2062
+ this.pushSource("else { " + this.appendToBuffer("''") + " }");
1371
2063
  }
1372
2064
  },
1373
2065
 
@@ -1378,15 +2070,9 @@ Handlebars.JavaScriptCompiler = function() {};
1378
2070
  //
1379
2071
  // Escape `value` and append it to the buffer
1380
2072
  appendEscaped: function() {
1381
- var opcode = this.nextOpcode(), extra = "";
1382
2073
  this.context.aliases.escapeExpression = 'this.escapeExpression';
1383
2074
 
1384
- if(opcode && opcode.opcode === 'appendContent') {
1385
- extra = " + " + this.quotedString(opcode.args[0]);
1386
- this.eat(opcode);
1387
- }
1388
-
1389
- this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
2075
+ this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
1390
2076
  },
1391
2077
 
1392
2078
  // [getContext]
@@ -1410,7 +2096,7 @@ Handlebars.JavaScriptCompiler = function() {};
1410
2096
  // Looks up the value of `name` on the current context and pushes
1411
2097
  // it onto the stack.
1412
2098
  lookupOnContext: function(name) {
1413
- this.pushStack(this.nameLookup('depth' + this.lastContext, name, 'context'));
2099
+ this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
1414
2100
  },
1415
2101
 
1416
2102
  // [pushContext]
@@ -1434,7 +2120,7 @@ Handlebars.JavaScriptCompiler = function() {};
1434
2120
  this.context.aliases.functionType = '"function"';
1435
2121
 
1436
2122
  this.replaceStack(function(current) {
1437
- return "typeof " + current + " === functionType ? " + current + "() : " + current;
2123
+ return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
1438
2124
  });
1439
2125
  },
1440
2126
 
@@ -1454,11 +2140,11 @@ Handlebars.JavaScriptCompiler = function() {};
1454
2140
  // [lookupData]
1455
2141
  //
1456
2142
  // On stack, before: ...
1457
- // On stack, after: data[id], ...
2143
+ // On stack, after: data, ...
1458
2144
  //
1459
- // Push the result of looking up `id` on the current data
1460
- lookupData: function(id) {
1461
- this.pushStack(this.nameLookup('data', id, 'data'));
2145
+ // Push the data lookup operator
2146
+ lookupData: function() {
2147
+ this.pushStackLiteral('data');
1462
2148
  },
1463
2149
 
1464
2150
  // [pushStringParam]
@@ -1469,9 +2155,46 @@ Handlebars.JavaScriptCompiler = function() {};
1469
2155
  // This opcode is designed for use in string mode, which
1470
2156
  // provides the string value of a parameter along with its
1471
2157
  // depth rather than resolving it immediately.
1472
- pushStringParam: function(string) {
2158
+ pushStringParam: function(string, type) {
1473
2159
  this.pushStackLiteral('depth' + this.lastContext);
1474
- this.pushString(string);
2160
+
2161
+ this.pushString(type);
2162
+
2163
+ // If it's a subexpression, the string result
2164
+ // will be pushed after this opcode.
2165
+ if (type !== 'sexpr') {
2166
+ if (typeof string === 'string') {
2167
+ this.pushString(string);
2168
+ } else {
2169
+ this.pushStackLiteral(string);
2170
+ }
2171
+ }
2172
+ },
2173
+
2174
+ emptyHash: function() {
2175
+ this.pushStackLiteral('{}');
2176
+
2177
+ if (this.options.stringParams) {
2178
+ this.push('{}'); // hashContexts
2179
+ this.push('{}'); // hashTypes
2180
+ }
2181
+ },
2182
+ pushHash: function() {
2183
+ if (this.hash) {
2184
+ this.hashes.push(this.hash);
2185
+ }
2186
+ this.hash = {values: [], types: [], contexts: []};
2187
+ },
2188
+ popHash: function() {
2189
+ var hash = this.hash;
2190
+ this.hash = this.hashes.pop();
2191
+
2192
+ if (this.options.stringParams) {
2193
+ this.push('{' + hash.contexts.join(',') + '}');
2194
+ this.push('{' + hash.types.join(',') + '}');
2195
+ }
2196
+
2197
+ this.push('{\n ' + hash.values.join(',\n ') + '\n }');
1475
2198
  },
1476
2199
 
1477
2200
  // [pushString]
@@ -1491,7 +2214,8 @@ Handlebars.JavaScriptCompiler = function() {};
1491
2214
  //
1492
2215
  // Push an expression onto the stack
1493
2216
  push: function(expr) {
1494
- this.pushStack(expr);
2217
+ this.inlineStack.push(expr);
2218
+ return expr;
1495
2219
  },
1496
2220
 
1497
2221
  // [pushLiteral]
@@ -1531,15 +2255,31 @@ Handlebars.JavaScriptCompiler = function() {};
1531
2255
  // and pushes the helper's return value onto the stack.
1532
2256
  //
1533
2257
  // If the helper is not found, `helperMissing` is called.
1534
- invokeHelper: function(paramSize, name) {
2258
+ invokeHelper: function(paramSize, name, isRoot) {
1535
2259
  this.context.aliases.helperMissing = 'helpers.helperMissing';
2260
+ this.useRegister('helper');
2261
+
2262
+ var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
2263
+ var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1536
2264
 
1537
- var helper = this.lastHelper = this.setupHelper(paramSize, name);
1538
- this.register('foundHelper', helper.name);
2265
+ var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
2266
+ if (helper.paramsInit) {
2267
+ lookup += ',' + helper.paramsInit;
2268
+ }
1539
2269
 
1540
- this.pushStack("foundHelper ? foundHelper.call(" +
1541
- helper.callParams + ") " + ": helperMissing.call(" +
1542
- helper.helperMissingParams + ")");
2270
+ this.push(
2271
+ '('
2272
+ + lookup
2273
+ + ',helper '
2274
+ + '? helper.call(' + helper.callParams + ') '
2275
+ + ': helperMissing.call(' + helper.helperMissingParams + '))');
2276
+
2277
+ // Always flush subexpressions. This is both to prevent the compounding size issue that
2278
+ // occurs when the code has to be duplicated for inlining and also to prevent errors
2279
+ // due to the incorrect options object being passed due to the shared register.
2280
+ if (!isRoot) {
2281
+ this.flushInline();
2282
+ }
1543
2283
  },
1544
2284
 
1545
2285
  // [invokeKnownHelper]
@@ -1551,7 +2291,7 @@ Handlebars.JavaScriptCompiler = function() {};
1551
2291
  // so a `helperMissing` fallback is not required.
1552
2292
  invokeKnownHelper: function(paramSize, name) {
1553
2293
  var helper = this.setupHelper(paramSize, name);
1554
- this.pushStack(helper.name + ".call(" + helper.callParams + ")");
2294
+ this.push(helper.name + ".call(" + helper.callParams + ")");
1555
2295
  },
1556
2296
 
1557
2297
  // [invokeAmbiguous]
@@ -1566,20 +2306,23 @@ Handlebars.JavaScriptCompiler = function() {};
1566
2306
  // This operation emits more code than the other options,
1567
2307
  // and can be avoided by passing the `knownHelpers` and
1568
2308
  // `knownHelpersOnly` flags at compile-time.
1569
- invokeAmbiguous: function(name) {
2309
+ invokeAmbiguous: function(name, helperCall) {
1570
2310
  this.context.aliases.functionType = '"function"';
2311
+ this.useRegister('helper');
1571
2312
 
1572
- this.pushStackLiteral('{}');
1573
- var helper = this.setupHelper(0, name);
2313
+ this.emptyHash();
2314
+ var helper = this.setupHelper(0, name, helperCall);
1574
2315
 
1575
2316
  var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
1576
- this.register('foundHelper', helperName);
1577
2317
 
1578
2318
  var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1579
2319
  var nextStack = this.nextStack();
1580
2320
 
1581
- this.source.push('if (foundHelper) { ' + nextStack + ' = foundHelper.call(' + helper.callParams + '); }');
1582
- this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '() : ' + nextStack + '; }');
2321
+ if (helper.paramsInit) {
2322
+ this.pushSource(helper.paramsInit);
2323
+ }
2324
+ this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
2325
+ this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
1583
2326
  },
1584
2327
 
1585
2328
  // [invokePartial]
@@ -1597,7 +2340,7 @@ Handlebars.JavaScriptCompiler = function() {};
1597
2340
  }
1598
2341
 
1599
2342
  this.context.aliases.self = "this";
1600
- this.pushStack("self.invokePartial(" + params.join(", ") + ");");
2343
+ this.push("self.invokePartial(" + params.join(", ") + ")");
1601
2344
  },
1602
2345
 
1603
2346
  // [assignToHash]
@@ -1608,10 +2351,23 @@ Handlebars.JavaScriptCompiler = function() {};
1608
2351
  // Pops a value and hash off the stack, assigns `hash[key] = value`
1609
2352
  // and pushes the hash back onto the stack.
1610
2353
  assignToHash: function(key) {
1611
- var value = this.popStack();
1612
- var hash = this.topStack();
2354
+ var value = this.popStack(),
2355
+ context,
2356
+ type;
2357
+
2358
+ if (this.options.stringParams) {
2359
+ type = this.popStack();
2360
+ context = this.popStack();
2361
+ }
1613
2362
 
1614
- this.source.push(hash + "['" + key + "'] = " + value + ";");
2363
+ var hash = this.hash;
2364
+ if (context) {
2365
+ hash.contexts.push("'" + key + "': " + context);
2366
+ }
2367
+ if (type) {
2368
+ hash.types.push("'" + key + "': " + type);
2369
+ }
2370
+ hash.values.push("'" + key + "': (" + value + ")");
1615
2371
  },
1616
2372
 
1617
2373
  // HELPERS
@@ -1625,11 +2381,27 @@ Handlebars.JavaScriptCompiler = function() {};
1625
2381
  child = children[i];
1626
2382
  compiler = new this.compiler();
1627
2383
 
1628
- this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
1629
- var index = this.context.programs.length;
1630
- child.index = index;
1631
- child.name = 'program' + index;
1632
- this.context.programs[index] = compiler.compile(child, options, this.context);
2384
+ var index = this.matchExistingProgram(child);
2385
+
2386
+ if (index == null) {
2387
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
2388
+ index = this.context.programs.length;
2389
+ child.index = index;
2390
+ child.name = 'program' + index;
2391
+ this.context.programs[index] = compiler.compile(child, options, this.context);
2392
+ this.context.environments[index] = child;
2393
+ } else {
2394
+ child.index = index;
2395
+ child.name = 'program' + index;
2396
+ }
2397
+ }
2398
+ },
2399
+ matchExistingProgram: function(child) {
2400
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
2401
+ var environment = this.context.environments[i];
2402
+ if (environment && environment.equals(child)) {
2403
+ return i;
2404
+ }
1633
2405
  }
1634
2406
  },
1635
2407
 
@@ -1652,17 +2424,12 @@ Handlebars.JavaScriptCompiler = function() {};
1652
2424
  else { programParams.push("depth" + (depth - 1)); }
1653
2425
  }
1654
2426
 
1655
- if(depths.length === 0) {
1656
- return "self.program(" + programParams.join(", ") + ")";
1657
- } else {
1658
- programParams.shift();
1659
- return "self.programWithDepth(" + programParams.join(", ") + ")";
1660
- }
2427
+ return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
1661
2428
  },
1662
2429
 
1663
2430
  register: function(name, val) {
1664
2431
  this.useRegister(name);
1665
- this.source.push(name + " = " + val + ";");
2432
+ this.pushSource(name + " = " + val + ";");
1666
2433
  },
1667
2434
 
1668
2435
  useRegister: function(name) {
@@ -1673,50 +2440,132 @@ Handlebars.JavaScriptCompiler = function() {};
1673
2440
  },
1674
2441
 
1675
2442
  pushStackLiteral: function(item) {
1676
- this.compileStack.push(new Literal(item));
1677
- return item;
2443
+ return this.push(new Literal(item));
2444
+ },
2445
+
2446
+ pushSource: function(source) {
2447
+ if (this.pendingContent) {
2448
+ this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
2449
+ this.pendingContent = undefined;
2450
+ }
2451
+
2452
+ if (source) {
2453
+ this.source.push(source);
2454
+ }
1678
2455
  },
1679
2456
 
1680
2457
  pushStack: function(item) {
1681
- this.source.push(this.incrStack() + " = " + item + ";");
1682
- this.compileStack.push("stack" + this.stackSlot);
1683
- return "stack" + this.stackSlot;
2458
+ this.flushInline();
2459
+
2460
+ var stack = this.incrStack();
2461
+ if (item) {
2462
+ this.pushSource(stack + " = " + item + ";");
2463
+ }
2464
+ this.compileStack.push(stack);
2465
+ return stack;
1684
2466
  },
1685
2467
 
1686
2468
  replaceStack: function(callback) {
1687
- var item = callback.call(this, this.topStack());
2469
+ var prefix = '',
2470
+ inline = this.isInline(),
2471
+ stack,
2472
+ createdStack,
2473
+ usedLiteral;
2474
+
2475
+ // If we are currently inline then we want to merge the inline statement into the
2476
+ // replacement statement via ','
2477
+ if (inline) {
2478
+ var top = this.popStack(true);
2479
+
2480
+ if (top instanceof Literal) {
2481
+ // Literals do not need to be inlined
2482
+ stack = top.value;
2483
+ usedLiteral = true;
2484
+ } else {
2485
+ // Get or create the current stack name for use by the inline
2486
+ createdStack = !this.stackSlot;
2487
+ var name = !createdStack ? this.topStackName() : this.incrStack();
1688
2488
 
1689
- this.source.push(this.topStack() + " = " + item + ";");
1690
- return "stack" + this.stackSlot;
2489
+ prefix = '(' + this.push(name) + ' = ' + top + '),';
2490
+ stack = this.topStack();
2491
+ }
2492
+ } else {
2493
+ stack = this.topStack();
2494
+ }
2495
+
2496
+ var item = callback.call(this, stack);
2497
+
2498
+ if (inline) {
2499
+ if (!usedLiteral) {
2500
+ this.popStack();
2501
+ }
2502
+ if (createdStack) {
2503
+ this.stackSlot--;
2504
+ }
2505
+ this.push('(' + prefix + item + ')');
2506
+ } else {
2507
+ // Prevent modification of the context depth variable. Through replaceStack
2508
+ if (!/^stack/.test(stack)) {
2509
+ stack = this.nextStack();
2510
+ }
2511
+
2512
+ this.pushSource(stack + " = (" + prefix + item + ");");
2513
+ }
2514
+ return stack;
1691
2515
  },
1692
2516
 
1693
- nextStack: function(skipCompileStack) {
1694
- var name = this.incrStack();
1695
- this.compileStack.push("stack" + this.stackSlot);
1696
- return name;
2517
+ nextStack: function() {
2518
+ return this.pushStack();
1697
2519
  },
1698
2520
 
1699
2521
  incrStack: function() {
1700
2522
  this.stackSlot++;
1701
2523
  if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
2524
+ return this.topStackName();
2525
+ },
2526
+ topStackName: function() {
1702
2527
  return "stack" + this.stackSlot;
1703
2528
  },
2529
+ flushInline: function() {
2530
+ var inlineStack = this.inlineStack;
2531
+ if (inlineStack.length) {
2532
+ this.inlineStack = [];
2533
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
2534
+ var entry = inlineStack[i];
2535
+ if (entry instanceof Literal) {
2536
+ this.compileStack.push(entry);
2537
+ } else {
2538
+ this.pushStack(entry);
2539
+ }
2540
+ }
2541
+ }
2542
+ },
2543
+ isInline: function() {
2544
+ return this.inlineStack.length;
2545
+ },
1704
2546
 
1705
- popStack: function() {
1706
- var item = this.compileStack.pop();
2547
+ popStack: function(wrapped) {
2548
+ var inline = this.isInline(),
2549
+ item = (inline ? this.inlineStack : this.compileStack).pop();
1707
2550
 
1708
- if (item instanceof Literal) {
2551
+ if (!wrapped && (item instanceof Literal)) {
1709
2552
  return item.value;
1710
2553
  } else {
1711
- this.stackSlot--;
2554
+ if (!inline) {
2555
+ if (!this.stackSlot) {
2556
+ throw new Exception('Invalid stack pop');
2557
+ }
2558
+ this.stackSlot--;
2559
+ }
1712
2560
  return item;
1713
2561
  }
1714
2562
  },
1715
2563
 
1716
- topStack: function() {
1717
- var item = this.compileStack[this.compileStack.length - 1];
2564
+ topStack: function(wrapped) {
2565
+ var stack = (this.isInline() ? this.inlineStack : this.compileStack),
2566
+ item = stack[stack.length - 1];
1718
2567
 
1719
- if (item instanceof Literal) {
2568
+ if (!wrapped && (item instanceof Literal)) {
1720
2569
  return item.value;
1721
2570
  } else {
1722
2571
  return item;
@@ -1728,29 +2577,35 @@ Handlebars.JavaScriptCompiler = function() {};
1728
2577
  .replace(/\\/g, '\\\\')
1729
2578
  .replace(/"/g, '\\"')
1730
2579
  .replace(/\n/g, '\\n')
1731
- .replace(/\r/g, '\\r') + '"';
2580
+ .replace(/\r/g, '\\r')
2581
+ .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
2582
+ .replace(/\u2029/g, '\\u2029') + '"';
1732
2583
  },
1733
2584
 
1734
- setupHelper: function(paramSize, name) {
1735
- var params = [];
1736
- this.setupParams(paramSize, params);
2585
+ setupHelper: function(paramSize, name, missingParams) {
2586
+ var params = [],
2587
+ paramsInit = this.setupParams(paramSize, params, missingParams);
1737
2588
  var foundHelper = this.nameLookup('helpers', name, 'helper');
1738
2589
 
1739
2590
  return {
1740
2591
  params: params,
2592
+ paramsInit: paramsInit,
1741
2593
  name: foundHelper,
1742
2594
  callParams: ["depth0"].concat(params).join(", "),
1743
- helperMissingParams: ["depth0", this.quotedString(name)].concat(params).join(", ")
2595
+ helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
1744
2596
  };
1745
2597
  },
1746
2598
 
1747
- // the params and contexts arguments are passed in arrays
1748
- // to fill in
1749
- setupParams: function(paramSize, params) {
1750
- var options = [], contexts = [], param, inverse, program;
2599
+ setupOptions: function(paramSize, params) {
2600
+ var options = [], contexts = [], types = [], param, inverse, program;
1751
2601
 
1752
2602
  options.push("hash:" + this.popStack());
1753
2603
 
2604
+ if (this.options.stringParams) {
2605
+ options.push("hashTypes:" + this.popStack());
2606
+ options.push("hashContexts:" + this.popStack());
2607
+ }
2608
+
1754
2609
  inverse = this.popStack();
1755
2610
  program = this.popStack();
1756
2611
 
@@ -1763,7 +2618,7 @@ Handlebars.JavaScriptCompiler = function() {};
1763
2618
  }
1764
2619
 
1765
2620
  if (!inverse) {
1766
- this.context.aliases.self = "this";
2621
+ this.context.aliases.self = "this";
1767
2622
  inverse = "self.noop";
1768
2623
  }
1769
2624
 
@@ -1776,20 +2631,36 @@ Handlebars.JavaScriptCompiler = function() {};
1776
2631
  params.push(param);
1777
2632
 
1778
2633
  if(this.options.stringParams) {
2634
+ types.push(this.popStack());
1779
2635
  contexts.push(this.popStack());
1780
2636
  }
1781
2637
  }
1782
2638
 
1783
2639
  if (this.options.stringParams) {
1784
2640
  options.push("contexts:[" + contexts.join(",") + "]");
2641
+ options.push("types:[" + types.join(",") + "]");
1785
2642
  }
1786
2643
 
1787
2644
  if(this.options.data) {
1788
2645
  options.push("data:data");
1789
2646
  }
1790
2647
 
1791
- params.push("{" + options.join(",") + "}");
1792
- return params.join(", ");
2648
+ return options;
2649
+ },
2650
+
2651
+ // the params and contexts arguments are passed in arrays
2652
+ // to fill in
2653
+ setupParams: function(paramSize, params, useRegister) {
2654
+ var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
2655
+
2656
+ if (useRegister) {
2657
+ this.useRegister('options');
2658
+ params.push('options');
2659
+ return 'options=' + options;
2660
+ } else {
2661
+ params.push(options);
2662
+ return '';
2663
+ }
1793
2664
  }
1794
2665
  };
1795
2666
 
@@ -1818,103 +2689,58 @@ Handlebars.JavaScriptCompiler = function() {};
1818
2689
  }
1819
2690
 
1820
2691
  JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
1821
- if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
2692
+ if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
1822
2693
  return true;
1823
2694
  }
1824
2695
  return false;
1825
2696
  };
1826
2697
 
1827
- })(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
1828
-
1829
- Handlebars.precompile = function(string, options) {
1830
- options = options || {};
1831
-
1832
- var ast = Handlebars.parse(string);
1833
- var environment = new Handlebars.Compiler().compile(ast, options);
1834
- return new Handlebars.JavaScriptCompiler().compile(environment, options);
1835
- };
1836
-
1837
- Handlebars.compile = function(string, options) {
1838
- options = options || {};
1839
-
1840
- var compiled;
1841
- function compile() {
1842
- var ast = Handlebars.parse(string);
1843
- var environment = new Handlebars.Compiler().compile(ast, options);
1844
- var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
1845
- return Handlebars.template(templateSpec);
1846
- }
1847
-
1848
- // Template is only compiled on first use and cached after that point.
1849
- return function(context, options) {
1850
- if (!compiled) {
1851
- compiled = compile();
1852
- }
1853
- return compiled.call(this, context, options);
1854
- };
1855
- };
1856
- ;
1857
- // lib/handlebars/runtime.js
1858
- Handlebars.VM = {
1859
- template: function(templateSpec) {
1860
- // Just add water
1861
- var container = {
1862
- escapeExpression: Handlebars.Utils.escapeExpression,
1863
- invokePartial: Handlebars.VM.invokePartial,
1864
- programs: [],
1865
- program: function(i, fn, data) {
1866
- var programWrapper = this.programs[i];
1867
- if(data) {
1868
- return Handlebars.VM.program(fn, data);
1869
- } else if(programWrapper) {
1870
- return programWrapper;
1871
- } else {
1872
- programWrapper = this.programs[i] = Handlebars.VM.program(fn);
1873
- return programWrapper;
1874
- }
1875
- },
1876
- programWithDepth: Handlebars.VM.programWithDepth,
1877
- noop: Handlebars.VM.noop
2698
+ __exports__ = JavaScriptCompiler;
2699
+ return __exports__;
2700
+ })(__module2__, __module5__);
2701
+
2702
+ // handlebars.js
2703
+ var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
2704
+ "use strict";
2705
+ var __exports__;
2706
+ /*globals Handlebars: true */
2707
+ var Handlebars = __dependency1__;
2708
+
2709
+ // Compiler imports
2710
+ var AST = __dependency2__;
2711
+ var Parser = __dependency3__.parser;
2712
+ var parse = __dependency3__.parse;
2713
+ var Compiler = __dependency4__.Compiler;
2714
+ var compile = __dependency4__.compile;
2715
+ var precompile = __dependency4__.precompile;
2716
+ var JavaScriptCompiler = __dependency5__;
2717
+
2718
+ var _create = Handlebars.create;
2719
+ var create = function() {
2720
+ var hb = _create();
2721
+
2722
+ hb.compile = function(input, options) {
2723
+ return compile(input, options, hb);
1878
2724
  };
1879
-
1880
- return function(context, options) {
1881
- options = options || {};
1882
- return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
2725
+ hb.precompile = function (input, options) {
2726
+ return precompile(input, options, hb);
1883
2727
  };
1884
- },
1885
-
1886
- programWithDepth: function(fn, data, $depth) {
1887
- var args = Array.prototype.slice.call(arguments, 2);
1888
2728
 
1889
- return function(context, options) {
1890
- options = options || {};
2729
+ hb.AST = AST;
2730
+ hb.Compiler = Compiler;
2731
+ hb.JavaScriptCompiler = JavaScriptCompiler;
2732
+ hb.Parser = Parser;
2733
+ hb.parse = parse;
1891
2734
 
1892
- return fn.apply(this, [context, options.data || data].concat(args));
1893
- };
1894
- },
1895
- program: function(fn, data) {
1896
- return function(context, options) {
1897
- options = options || {};
2735
+ return hb;
2736
+ };
1898
2737
 
1899
- return fn(context, options.data || data);
1900
- };
1901
- },
1902
- noop: function() { return ""; },
1903
- invokePartial: function(partial, name, context, helpers, partials, data) {
1904
- var options = { helpers: helpers, partials: partials, data: data };
2738
+ Handlebars = create();
2739
+ Handlebars.create = create;
1905
2740
 
1906
- if(partial === undefined) {
1907
- throw new Handlebars.Exception("The partial " + name + " could not be found");
1908
- } else if(partial instanceof Function) {
1909
- return partial(context, options);
1910
- } else if (!Handlebars.compile) {
1911
- throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
1912
- } else {
1913
- partials[name] = Handlebars.compile(partial, {data: data !== undefined});
1914
- return partials[name](context, options);
1915
- }
1916
- }
1917
- };
2741
+ __exports__ = Handlebars;
2742
+ return __exports__;
2743
+ })(__module1__, __module7__, __module8__, __module10__, __module11__);
1918
2744
 
1919
- Handlebars.template = Handlebars.VM.template;
1920
- ;
2745
+ return __module0__;
2746
+ })();