biola_wcms_components 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +74 -0
  7. data/Rakefile +1 -0
  8. data/app/assets/images/.gitkeep +0 -0
  9. data/app/assets/javascripts/biola-wcms-components.js.coffee +15 -0
  10. data/app/assets/javascripts/components/forms/json_editor.js.coffee +20 -0
  11. data/app/assets/javascripts/components/forms/person_lookup.js.coffee +29 -0
  12. data/app/assets/javascripts/components/forms/presentation_data_editor.js.coffee +69 -0
  13. data/app/assets/javascripts/components/forms/yaml_editor.js.coffee +39 -0
  14. data/app/assets/javascripts/configuration/file_uploader.js.coffee +55 -0
  15. data/app/assets/javascripts/configuration/setup_redactor.js.coffee +65 -0
  16. data/app/assets/stylesheets/_mixins.scss +43 -0
  17. data/app/assets/stylesheets/_settings.scss +1 -0
  18. data/app/assets/stylesheets/biola-wcms-components.scss +11 -0
  19. data/app/assets/stylesheets/components/alerts/_message_list.scss +3 -0
  20. data/app/assets/stylesheets/components/forms/_person_lookup.scss +72 -0
  21. data/app/assets/stylesheets/components/forms/_presentation_data_editor.scss +38 -0
  22. data/app/assets/stylesheets/components/navigation/_site_nav.scss +24 -0
  23. data/app/helpers/wcms_components/alerts_helper.rb +41 -0
  24. data/app/helpers/wcms_components/component_helper.rb +9 -0
  25. data/app/helpers/wcms_components/navigation_helper.rb +32 -0
  26. data/app/views/wcms_components/alerts/_message_list.html.slim +8 -0
  27. data/app/views/wcms_components/forms/_json_editor.html.slim +13 -0
  28. data/app/views/wcms_components/forms/_person_lookup.html.slim +12 -0
  29. data/app/views/wcms_components/forms/_presentation_data_editor.html.slim +36 -0
  30. data/app/views/wcms_components/forms/_redactor_editor.html.slim +32 -0
  31. data/app/views/wcms_components/forms/_text_area.html.slim +13 -0
  32. data/app/views/wcms_components/forms/_yaml_editor.html.slim +16 -0
  33. data/app/views/wcms_components/navigation/_page_nav.html.slim +33 -0
  34. data/app/views/wcms_components/navigation/_site_nav.html.slim +38 -0
  35. data/app/views/wcms_components/shared/.gitkeep +0 -0
  36. data/app/views/wcms_components/shared/_embedded_image_uploader.html.slim +6 -0
  37. data/biola_wcms_components.gemspec +27 -0
  38. data/config/locales/en.yml +4 -0
  39. data/lib/biola_wcms_components.rb +22 -0
  40. data/lib/biola_wcms_components/configuration.rb +9 -0
  41. data/lib/biola_wcms_components/engine.rb +6 -0
  42. data/lib/biola_wcms_components/version.rb +3 -0
  43. data/lib/components/menu_block.rb +130 -0
  44. data/lib/components/presentation_data_editor.rb +199 -0
  45. data/vendor/assets/javascripts/handlebars.js +3750 -0
  46. data/vendor/assets/javascripts/redactor.js +8312 -0
  47. data/vendor/assets/javascripts/redactor_fullscreen.js +123 -0
  48. data/vendor/assets/javascripts/typeahead.js +11 -0
  49. data/vendor/assets/stylesheets/redactor.css +924 -0
  50. metadata +176 -0
@@ -0,0 +1,6 @@
1
+ ruby:
2
+ embedded_image_url ||= nil # should be the post url for creating new embedded images
3
+
4
+ - if embedded_image_url
5
+ javascript:
6
+ fileUploader.addUploader('embedded_image', "#{embedded_image_url}");
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'biola_wcms_components/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "biola_wcms_components"
8
+ spec.version = BiolaWcmsComponents::VERSION
9
+ spec.authors = ["Ryan Hall"]
10
+ spec.email = ["ryan.hall@biola.edu"]
11
+ spec.description = %q{Reusable UX components for use in or WCMS projects}
12
+ spec.summary = %q{Reusable UX components for use in or WCMS projects}
13
+ spec.homepage = "https://github.com/biola/biola-wcms-components"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "ace-rails-ap", "~> 3.0"
22
+ spec.add_dependency "coffee-rails", ">= 4.0"
23
+ spec.add_dependency "sass-rails", ">= 4.0"
24
+ spec.add_dependency "slim", ">= 2.0"
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ wcms_components:
3
+ hello: World
4
+
@@ -0,0 +1,22 @@
1
+ require "biola_wcms_components/version"
2
+ require "biola_wcms_components/engine" if defined?(::Rails)
3
+ require "ace-rails-ap"
4
+ require "coffee-rails"
5
+ require "sass-rails"
6
+ require "slim"
7
+
8
+ module BiolaWcmsComponents
9
+ require 'biola_wcms_components/configuration'
10
+
11
+ def self.configure
12
+ yield config
13
+ end
14
+
15
+ def self.config
16
+ @config ||= Configuration.new
17
+ end
18
+ end
19
+
20
+
21
+ autoload :MenuBlock, 'components/menu_block'
22
+ autoload :PresentationDataEditor, 'components/presentation_data_editor'
@@ -0,0 +1,9 @@
1
+ module BiolaWcmsComponents
2
+ class Configuration
3
+ attr_accessor :default_redactor_buttons
4
+
5
+ def initialize
6
+ @default_redactor_buttons = ['bold', 'italic', 'orderedlist', 'unorderedlist']
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module BiolaWcmsComponents
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module BiolaWcmsComponents
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,130 @@
1
+ class MenuBlock
2
+ attr_reader :items
3
+ attr_reader :context
4
+ attr_reader :html_options
5
+
6
+ def initialize(view_context, html_options = {})
7
+ @context = view_context
8
+ @html_options = html_options
9
+ @items = []
10
+ end
11
+
12
+ # Adds a menu item to the menu block
13
+ #
14
+ # ==== Options
15
+ # * <tt>default: false</tt> - Whether or not this item is default if nothing else is active.
16
+ # * <tt>match_params: {}</tt> - Pass a hash to compare with params. Leave blank for defaults matchers.
17
+ # To use: <tt>{action: [:new, :create], id: '12345'}</tt>.
18
+ #
19
+ # ==== Examples
20
+ # For a regular default menu item
21
+ #
22
+ # = menu.add_item('Profile', default: true) { edit_person_path(@person, page: 'profile') }
23
+ #
24
+ # For a subitem you can so something like this
25
+ # .subitems
26
+ # = menu.add_item('New Custom Profile', match_params: {action: [:new, :create]}) { new_person_custom_profile_path(@person) }
27
+ #
28
+ def add_item(name, default: false, match_params: {}, &route_block)
29
+ items << MenuItem.new(context, name, default: default, match_params: match_params, &route_block)
30
+
31
+ placeholder(items.length - 1)
32
+ end
33
+
34
+ def render(&block)
35
+ # Grab the HTML from the block so that custom HTML can be injected into the menu
36
+ html = context.capture(self, &block)
37
+
38
+ items.each_with_index do |item, i|
39
+ opts = html_options.dup || {}
40
+ if item.active? || (items.none?(&:active?) && item.default?)
41
+ opts[:class] = [html_options[:class], 'active'].compact.join(' ')
42
+ end
43
+
44
+ html[placeholder(i)] = context.link_to(item.name, item.route, opts)
45
+ end
46
+
47
+ html
48
+ end
49
+
50
+ private
51
+
52
+ def placeholder(number)
53
+ # Placeholder for delayed rendering. We need this so that we can work
54
+ # with all of the menu items so that by the time we render the first one,
55
+ # which could be the default, we know whether or not any others are active.
56
+ "[[menu_block:#{number}]]"
57
+ end
58
+
59
+ class MenuItem
60
+ attr_reader :name
61
+ attr_reader :route_block
62
+ attr_reader :default
63
+ attr_reader :match_params
64
+
65
+ alias :default? :default
66
+
67
+ def initialize(context, name, default: false, match_params: {}, &route_block)
68
+ @context = context
69
+ @name = name
70
+ @route_block = route_block
71
+ @default = default
72
+ @match_params = match_params
73
+ end
74
+
75
+ def route
76
+ @route ||= route_block.call
77
+ end
78
+
79
+ def active?
80
+ matches = []
81
+
82
+ # Set default match_params. For example: This is the default matcher for :controller if :controller isn't specified
83
+ match_params[:controller] ||= recognized_route[:controller]
84
+
85
+ # Make sure everything in match_params is contained in params.
86
+ match_params.each do |key,val|
87
+ # This will handle arrays, strings, numbers, etc. params should always return a string or nil.
88
+ matches << Array(val).compact.map(&:to_s).include?(params[key])
89
+ end
90
+
91
+ # Loop through query parameters to make sure they match
92
+ ::Rack::Utils.parse_query(URI.parse(route).query).each do |param, val|
93
+ matches << (params[param] == val)
94
+ end
95
+
96
+ matches.all?
97
+ end
98
+
99
+ private
100
+
101
+ def request
102
+ @context.request
103
+ end
104
+
105
+ def params
106
+ @context.params
107
+ end
108
+
109
+ def recognized_route
110
+ @recognized_route ||= (
111
+ recognizable_path = without_script_name { route_block.call }
112
+ Rails.application.routes.recognize_path(recognizable_path)
113
+ )
114
+ end
115
+
116
+ # The router won't recognize routes with a script_name
117
+ # So we need to temporarily set the script_name to nil
118
+ # so we can generate a path the router will like.
119
+ def without_script_name(&block)
120
+ script_name = request.script_name
121
+ request.script_name = nil
122
+
123
+ val = block.call
124
+
125
+ request.script_name = script_name
126
+
127
+ val
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,199 @@
1
+ class PresentationDataEditor
2
+ attr_reader :view
3
+ attr_reader :data
4
+ attr_reader :schema
5
+ attr_reader :form
6
+
7
+ # Expects a hash schema definition.
8
+ # will probably come from presentation_data_template.schema
9
+ def initialize(view_context, data, schema, form)
10
+ @view = view_context
11
+ @data = data
12
+ @schema = schema
13
+ @form = form
14
+ end
15
+
16
+ def render
17
+ presentation_data_editor if schema.is_a? Array
18
+ end
19
+
20
+
21
+ private
22
+
23
+ def presentation_data_editor
24
+ view.content_tag :div, array_of_attributes(schema), id: 'presentation_data_editor'
25
+ end
26
+
27
+ def array_of_attributes(attributes, parent_keys=[], wrapper_class: 'nest')
28
+ view.content_tag(:div, class: wrapper_class) do
29
+ Array(attributes).map do |attribute|
30
+ build_form_attribute(ActiveSupport::HashWithIndifferentAccess.new(attribute), parent_keys)
31
+ end.join(" ").html_safe
32
+ end
33
+ end
34
+
35
+ def build_form_attribute(attribute, parent_keys)
36
+ case attribute[:type]
37
+ when 'hash'
38
+ build_hash(attribute, parent_keys)
39
+ when 'array'
40
+ build_array(attribute, parent_keys)
41
+ when 'string', nil # String should be the default value
42
+ build_string(attribute, parent_keys)
43
+ when 'image'
44
+ build_image_uploader(attribute, parent_keys)
45
+ when 'html'
46
+ build_html(attribute, parent_keys)
47
+ end
48
+ end
49
+
50
+
51
+
52
+ ############################
53
+ ### Type specific Builders
54
+ ############################
55
+ def build_hash(attribute, parent_keys)
56
+ view.content_tag(:h4, attribute[:name].titleize) +
57
+ array_of_attributes(attribute[:nested_attributes], parent_keys + Array(attribute[:name]))
58
+ end
59
+
60
+ def build_array(attribute, parent_keys)
61
+ view.content_tag(:div, class: 'array_wrapper') do
62
+ view.content_tag(:h4, attribute[:name].titleize) +
63
+ # build empty form template for creating new items
64
+ build_array_with_data(
65
+ attribute[:nested_attributes],
66
+ parent_keys,
67
+ attribute[:name]
68
+ )
69
+ end
70
+ end
71
+
72
+ def build_array_with_data(attributes, parent_keys, array_name)
73
+ view.content_tag(:div, class: 'nest existing_array') do
74
+ build_array_framework(attributes, parent_keys, array_name) +
75
+ build_array_items(attributes, parent_keys, array_name) +
76
+ view.content_tag(:a, 'Add Item', href:'#', class: 'add_array_item', tabindex: '-1')
77
+ end
78
+ end
79
+
80
+ def build_array_items(attributes, parent_keys, array_name)
81
+ Array(data_grab(parent_keys, array_name)).each_with_index.map do |v,i|
82
+ view.content_tag :div, class: 'array_item' do
83
+ view.content_tag(:a, 'Delete Item', href:'#', class: 'delete_array_item pull-right', tabindex: '-1') +
84
+ array_of_attributes(attributes, parent_keys + Array(array_name) + Array(i), wrapper_class: nil)
85
+ end
86
+ end.join(" ").html_safe
87
+ end
88
+
89
+ def build_array_framework(attributes, parent_keys, array_name)
90
+ view.content_tag(:div, class: 'array_item framework') do
91
+ view.content_tag(:a, 'Delete Item', href:'#', class: 'delete_array_item pull-right', tabindex: '-1') +
92
+ array_of_attributes(attributes, parent_keys + Array(array_name) + Array(0), wrapper_class: nil)
93
+ end
94
+ end
95
+
96
+
97
+ def build_string(attribute, parent_keys)
98
+ view.content_tag :div, class: 'form-group' do
99
+ view.label_tag(attribute[:name]) +
100
+ view.text_field_tag(
101
+ form_name(parent_keys, attribute[:name]),
102
+ data_grab(parent_keys, attribute[:name]),
103
+ {
104
+ class: "form-control #{attribute[:class]}",
105
+ id: attribute_id(parent_keys, attribute[:name]),
106
+ placeholder: attribute[:placeholder]
107
+ }
108
+ )
109
+ end
110
+ end
111
+
112
+ def build_image_uploader(attribute, parent_keys)
113
+ view.content_tag :div, class: 'form-group' do
114
+ view.label_tag(attribute[:name]) +
115
+ view.text_field_tag(
116
+ form_name(parent_keys, attribute[:name]),
117
+ data_grab(parent_keys, attribute[:name]),
118
+ {
119
+ class: "form-control drop-image-uploader #{attribute[:class]}",
120
+ id: attribute_id(parent_keys, attribute[:name]),
121
+ placeholder: "Drop image here"
122
+ }
123
+ )
124
+ end
125
+ end
126
+
127
+ def build_html(attribute, parent_keys)
128
+ view.content_tag :div, class: 'form-group' do
129
+ view.label_tag(attribute[:name]) +
130
+ view.text_area_tag(
131
+ form_name(parent_keys, attribute[:name]),
132
+ data_grab(parent_keys, attribute[:name]),
133
+ {
134
+ class: "redactor #{attribute[:class]}",
135
+ id: attribute_id(parent_keys, attribute[:name]),
136
+ 'data-buttons' => editor_buttons(attribute)
137
+ }
138
+ )
139
+ end
140
+ end
141
+
142
+
143
+
144
+ ############################
145
+ ### helper methods
146
+ ############################
147
+
148
+ # This will create the name parameter for a given form input
149
+ # Example:
150
+ # research(hash) > books(array) > 2(array index) > title(attribute_name)
151
+ # will become
152
+ # "pdata[research][books][][title]"
153
+ def form_name(parent_keys, attr_name)
154
+ p = ['pdata'] + parent_keys + [attr_name]
155
+ p.compact.each_with_index.map do |v,i|
156
+ if i == 0
157
+ v # don't wrap the first key in brackets
158
+ elsif v.is_a?(Integer)
159
+ "[]" # Skip the number, this will be an array...
160
+ else
161
+ "[#{v}]"
162
+ end
163
+ end.join('')
164
+ end
165
+
166
+ # Creates an underscored version of the form_name above.
167
+ # Example:
168
+ # "pdata_research_books_2_title"
169
+ def attribute_id(parent_keys, attr_name)
170
+ p = ['pdata'] + parent_keys + [attr_name]
171
+ p.compact.join('_')
172
+ end
173
+
174
+ # Will look up the data given the correct path
175
+ def data_grab(parent_keys, attr_name)
176
+ path = parent_keys + [attr_name]
177
+
178
+ # I'm using inject here to traverse the data hash with each sequential
179
+ # key or index value. I use `try` just in case the data is not there
180
+ # and `last` is nil.
181
+ path.compact.inject(data) do |last, p|
182
+ if last.is_a? Array
183
+ # Use a number to reference the array element
184
+ last.try(:[], p.to_i)
185
+ elsif last.is_a? Hash
186
+ last.try(:[], p.to_s)
187
+ end
188
+ end
189
+ end
190
+
191
+ def editor_buttons(attribute)
192
+ default_buttons = %w(bold italic unorderedlist orderedlist link)
193
+ buttons = attribute[:editor_buttons].to_s.split(' ').presence || default_buttons
194
+ buttons.push('html') if !buttons.include?('html') && view.current_user.try(:admin?)
195
+ buttons.push('fullscreen') unless buttons.include?('fullscreen')
196
+ buttons.join(' ')
197
+ end
198
+
199
+ end
@@ -0,0 +1,3750 @@
1
+ // Handlebars is being used for the typeahead templates
2
+ // Its a little overkill, the other option looks to be use the Underscore library
3
+ // or some other templating engine.
4
+
5
+ /*!
6
+
7
+ handlebars v3.0.0
8
+
9
+ Copyright (C) 2011-2014 by Yehuda Katz
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ THE SOFTWARE.
28
+
29
+ @license
30
+ */
31
+ /* exported Handlebars */
32
+ (function (root, factory) {
33
+ if (typeof define === 'function' && define.amd) {
34
+ define([], factory);
35
+ } else if (typeof exports === 'object') {
36
+ module.exports = factory();
37
+ } else {
38
+ root.Handlebars = factory();
39
+ }
40
+ }(this, function () {
41
+ // handlebars/utils.js
42
+ var __module3__ = (function() {
43
+ "use strict";
44
+ var __exports__ = {};
45
+ /*jshint -W004 */
46
+ var escape = {
47
+ "&": "&amp;",
48
+ "<": "&lt;",
49
+ ">": "&gt;",
50
+ '"': "&quot;",
51
+ "'": "&#x27;",
52
+ "`": "&#x60;"
53
+ };
54
+
55
+ var badChars = /[&<>"'`]/g;
56
+ var possible = /[&<>"'`]/;
57
+
58
+ function escapeChar(chr) {
59
+ return escape[chr];
60
+ }
61
+
62
+ function extend(obj /* , ...source */) {
63
+ for (var i = 1; i < arguments.length; i++) {
64
+ for (var key in arguments[i]) {
65
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
66
+ obj[key] = arguments[i][key];
67
+ }
68
+ }
69
+ }
70
+
71
+ return obj;
72
+ }
73
+
74
+ __exports__.extend = extend;var toString = Object.prototype.toString;
75
+ __exports__.toString = toString;
76
+ // Sourced from lodash
77
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
78
+ var isFunction = function(value) {
79
+ return typeof value === 'function';
80
+ };
81
+ // fallback for older versions of Chrome and Safari
82
+ /* istanbul ignore next */
83
+ if (isFunction(/x/)) {
84
+ isFunction = function(value) {
85
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
86
+ };
87
+ }
88
+ var isFunction;
89
+ __exports__.isFunction = isFunction;
90
+ /* istanbul ignore next */
91
+ var isArray = Array.isArray || function(value) {
92
+ return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
93
+ };
94
+ __exports__.isArray = isArray;
95
+ // Older IE versions do not directly support indexOf so we must implement our own, sadly.
96
+ function indexOf(array, value) {
97
+ for (var i = 0, len = array.length; i < len; i++) {
98
+ if (array[i] === value) {
99
+ return i;
100
+ }
101
+ }
102
+ return -1;
103
+ }
104
+
105
+ __exports__.indexOf = indexOf;
106
+ function escapeExpression(string) {
107
+ // don't escape SafeStrings, since they're already safe
108
+ if (string && string.toHTML) {
109
+ return string.toHTML();
110
+ } else if (string == null) {
111
+ return "";
112
+ } else if (!string) {
113
+ return string + '';
114
+ }
115
+
116
+ // Force a string conversion as this will be done by the append regardless and
117
+ // the regex test will do this transparently behind the scenes, causing issues if
118
+ // an object's to string has escaped characters in it.
119
+ string = "" + string;
120
+
121
+ if(!possible.test(string)) { return string; }
122
+ return string.replace(badChars, escapeChar);
123
+ }
124
+
125
+ __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
126
+ if (!value && value !== 0) {
127
+ return true;
128
+ } else if (isArray(value) && value.length === 0) {
129
+ return true;
130
+ } else {
131
+ return false;
132
+ }
133
+ }
134
+
135
+ __exports__.isEmpty = isEmpty;function blockParams(params, ids) {
136
+ params.path = ids;
137
+ return params;
138
+ }
139
+
140
+ __exports__.blockParams = blockParams;function appendContextPath(contextPath, id) {
141
+ return (contextPath ? contextPath + '.' : '') + id;
142
+ }
143
+
144
+ __exports__.appendContextPath = appendContextPath;
145
+ return __exports__;
146
+ })();
147
+
148
+ // handlebars/exception.js
149
+ var __module4__ = (function() {
150
+ "use strict";
151
+ var __exports__;
152
+
153
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
154
+
155
+ function Exception(message, node) {
156
+ var loc = node && node.loc,
157
+ line,
158
+ column;
159
+ if (loc) {
160
+ line = loc.start.line;
161
+ column = loc.start.column;
162
+
163
+ message += ' - ' + line + ':' + column;
164
+ }
165
+
166
+ var tmp = Error.prototype.constructor.call(this, message);
167
+
168
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
169
+ for (var idx = 0; idx < errorProps.length; idx++) {
170
+ this[errorProps[idx]] = tmp[errorProps[idx]];
171
+ }
172
+
173
+ if (loc) {
174
+ this.lineNumber = line;
175
+ this.column = column;
176
+ }
177
+ }
178
+
179
+ Exception.prototype = new Error();
180
+
181
+ __exports__ = Exception;
182
+ return __exports__;
183
+ })();
184
+
185
+ // handlebars/base.js
186
+ var __module2__ = (function(__dependency1__, __dependency2__) {
187
+ "use strict";
188
+ var __exports__ = {};
189
+ var Utils = __dependency1__;
190
+ var Exception = __dependency2__;
191
+
192
+ var VERSION = "3.0.0";
193
+ __exports__.VERSION = VERSION;var COMPILER_REVISION = 6;
194
+ __exports__.COMPILER_REVISION = COMPILER_REVISION;
195
+ var REVISION_CHANGES = {
196
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
197
+ 2: '== 1.0.0-rc.3',
198
+ 3: '== 1.0.0-rc.4',
199
+ 4: '== 1.x.x',
200
+ 5: '== 2.0.0-alpha.x',
201
+ 6: '>= 2.0.0-beta.1'
202
+ };
203
+ __exports__.REVISION_CHANGES = REVISION_CHANGES;
204
+ var isArray = Utils.isArray,
205
+ isFunction = Utils.isFunction,
206
+ toString = Utils.toString,
207
+ objectType = '[object Object]';
208
+
209
+ function HandlebarsEnvironment(helpers, partials) {
210
+ this.helpers = helpers || {};
211
+ this.partials = partials || {};
212
+
213
+ registerDefaultHelpers(this);
214
+ }
215
+
216
+ __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
217
+ constructor: HandlebarsEnvironment,
218
+
219
+ logger: logger,
220
+ log: log,
221
+
222
+ registerHelper: function(name, fn) {
223
+ if (toString.call(name) === objectType) {
224
+ if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
225
+ Utils.extend(this.helpers, name);
226
+ } else {
227
+ this.helpers[name] = fn;
228
+ }
229
+ },
230
+ unregisterHelper: function(name) {
231
+ delete this.helpers[name];
232
+ },
233
+
234
+ registerPartial: function(name, partial) {
235
+ if (toString.call(name) === objectType) {
236
+ Utils.extend(this.partials, name);
237
+ } else {
238
+ if (typeof partial === 'undefined') {
239
+ throw new Exception('Attempting to register a partial as undefined');
240
+ }
241
+ this.partials[name] = partial;
242
+ }
243
+ },
244
+ unregisterPartial: function(name) {
245
+ delete this.partials[name];
246
+ }
247
+ };
248
+
249
+ function registerDefaultHelpers(instance) {
250
+ instance.registerHelper('helperMissing', function(/* [args, ]options */) {
251
+ if(arguments.length === 1) {
252
+ // A missing field in a {{foo}} constuct.
253
+ return undefined;
254
+ } else {
255
+ // Someone is actually trying to call something, blow up.
256
+ throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
257
+ }
258
+ });
259
+
260
+ instance.registerHelper('blockHelperMissing', function(context, options) {
261
+ var inverse = options.inverse,
262
+ fn = options.fn;
263
+
264
+ if(context === true) {
265
+ return fn(this);
266
+ } else if(context === false || context == null) {
267
+ return inverse(this);
268
+ } else if (isArray(context)) {
269
+ if(context.length > 0) {
270
+ if (options.ids) {
271
+ options.ids = [options.name];
272
+ }
273
+
274
+ return instance.helpers.each(context, options);
275
+ } else {
276
+ return inverse(this);
277
+ }
278
+ } else {
279
+ if (options.data && options.ids) {
280
+ var data = createFrame(options.data);
281
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
282
+ options = {data: data};
283
+ }
284
+
285
+ return fn(context, options);
286
+ }
287
+ });
288
+
289
+ instance.registerHelper('each', function(context, options) {
290
+ if (!options) {
291
+ throw new Exception('Must pass iterator to #each');
292
+ }
293
+
294
+ var fn = options.fn, inverse = options.inverse;
295
+ var i = 0, ret = "", data;
296
+
297
+ var contextPath;
298
+ if (options.data && options.ids) {
299
+ contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
300
+ }
301
+
302
+ if (isFunction(context)) { context = context.call(this); }
303
+
304
+ if (options.data) {
305
+ data = createFrame(options.data);
306
+ }
307
+
308
+ function execIteration(key, i, last) {
309
+ if (data) {
310
+ data.key = key;
311
+ data.index = i;
312
+ data.first = i === 0;
313
+ data.last = !!last;
314
+
315
+ if (contextPath) {
316
+ data.contextPath = contextPath + key;
317
+ }
318
+ }
319
+
320
+ ret = ret + fn(context[key], {
321
+ data: data,
322
+ blockParams: Utils.blockParams([context[key], key], [contextPath + key, null])
323
+ });
324
+ }
325
+
326
+ if(context && typeof context === 'object') {
327
+ if (isArray(context)) {
328
+ for(var j = context.length; i<j; i++) {
329
+ execIteration(i, i, i === context.length-1);
330
+ }
331
+ } else {
332
+ var priorKey;
333
+
334
+ for(var key in context) {
335
+ if(context.hasOwnProperty(key)) {
336
+ // We're running the iterations one step out of sync so we can detect
337
+ // the last iteration without have to scan the object twice and create
338
+ // an itermediate keys array.
339
+ if (priorKey) {
340
+ execIteration(priorKey, i-1);
341
+ }
342
+ priorKey = key;
343
+ i++;
344
+ }
345
+ }
346
+ if (priorKey) {
347
+ execIteration(priorKey, i-1, true);
348
+ }
349
+ }
350
+ }
351
+
352
+ if(i === 0){
353
+ ret = inverse(this);
354
+ }
355
+
356
+ return ret;
357
+ });
358
+
359
+ instance.registerHelper('if', function(conditional, options) {
360
+ if (isFunction(conditional)) { conditional = conditional.call(this); }
361
+
362
+ // Default behavior is to render the positive path if the value is truthy and not empty.
363
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
364
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
365
+ if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
366
+ return options.inverse(this);
367
+ } else {
368
+ return options.fn(this);
369
+ }
370
+ });
371
+
372
+ instance.registerHelper('unless', function(conditional, options) {
373
+ return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
374
+ });
375
+
376
+ instance.registerHelper('with', function(context, options) {
377
+ if (isFunction(context)) { context = context.call(this); }
378
+
379
+ var fn = options.fn;
380
+
381
+ if (!Utils.isEmpty(context)) {
382
+ if (options.data && options.ids) {
383
+ var data = createFrame(options.data);
384
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
385
+ options = {data:data};
386
+ }
387
+
388
+ return fn(context, options);
389
+ } else {
390
+ return options.inverse(this);
391
+ }
392
+ });
393
+
394
+ instance.registerHelper('log', function(message, options) {
395
+ var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
396
+ instance.log(level, message);
397
+ });
398
+
399
+ instance.registerHelper('lookup', function(obj, field) {
400
+ return obj && obj[field];
401
+ });
402
+ }
403
+
404
+ var logger = {
405
+ methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
406
+
407
+ // State enum
408
+ DEBUG: 0,
409
+ INFO: 1,
410
+ WARN: 2,
411
+ ERROR: 3,
412
+ level: 1,
413
+
414
+ // Can be overridden in the host environment
415
+ log: function(level, message) {
416
+ if (typeof console !== 'undefined' && logger.level <= level) {
417
+ var method = logger.methodMap[level];
418
+ (console[method] || console.log).call(console, message);
419
+ }
420
+ }
421
+ };
422
+ __exports__.logger = logger;
423
+ var log = logger.log;
424
+ __exports__.log = log;
425
+ var createFrame = function(object) {
426
+ var frame = Utils.extend({}, object);
427
+ frame._parent = object;
428
+ return frame;
429
+ };
430
+ __exports__.createFrame = createFrame;
431
+ return __exports__;
432
+ })(__module3__, __module4__);
433
+
434
+ // handlebars/safe-string.js
435
+ var __module5__ = (function() {
436
+ "use strict";
437
+ var __exports__;
438
+ // Build out our basic SafeString type
439
+ function SafeString(string) {
440
+ this.string = string;
441
+ }
442
+
443
+ SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
444
+ return "" + this.string;
445
+ };
446
+
447
+ __exports__ = SafeString;
448
+ return __exports__;
449
+ })();
450
+
451
+ // handlebars/runtime.js
452
+ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
453
+ "use strict";
454
+ var __exports__ = {};
455
+ var Utils = __dependency1__;
456
+ var Exception = __dependency2__;
457
+ var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
458
+ var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
459
+ var createFrame = __dependency3__.createFrame;
460
+
461
+ function checkRevision(compilerInfo) {
462
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
463
+ currentRevision = COMPILER_REVISION;
464
+
465
+ if (compilerRevision !== currentRevision) {
466
+ if (compilerRevision < currentRevision) {
467
+ var runtimeVersions = REVISION_CHANGES[currentRevision],
468
+ compilerVersions = REVISION_CHANGES[compilerRevision];
469
+ throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
470
+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
471
+ } else {
472
+ // Use the embedded version info since the runtime doesn't know about this revision yet
473
+ throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
474
+ "Please update your runtime to a newer version ("+compilerInfo[1]+").");
475
+ }
476
+ }
477
+ }
478
+
479
+ __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
480
+
481
+ function template(templateSpec, env) {
482
+ /* istanbul ignore next */
483
+ if (!env) {
484
+ throw new Exception("No environment passed to template");
485
+ }
486
+ if (!templateSpec || !templateSpec.main) {
487
+ throw new Exception('Unknown template object: ' + typeof templateSpec);
488
+ }
489
+
490
+ // Note: Using env.VM references rather than local var references throughout this section to allow
491
+ // for external users to override these as psuedo-supported APIs.
492
+ env.VM.checkRevision(templateSpec.compiler);
493
+
494
+ var invokePartialWrapper = function(partial, context, options) {
495
+ if (options.hash) {
496
+ context = Utils.extend({}, context, options.hash);
497
+ }
498
+
499
+ partial = env.VM.resolvePartial.call(this, partial, context, options);
500
+ var result = env.VM.invokePartial.call(this, partial, context, options);
501
+
502
+ if (result == null && env.compile) {
503
+ options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
504
+ result = options.partials[options.name](context, options);
505
+ }
506
+ if (result != null) {
507
+ if (options.indent) {
508
+ var lines = result.split('\n');
509
+ for (var i = 0, l = lines.length; i < l; i++) {
510
+ if (!lines[i] && i + 1 === l) {
511
+ break;
512
+ }
513
+
514
+ lines[i] = options.indent + lines[i];
515
+ }
516
+ result = lines.join('\n');
517
+ }
518
+ return result;
519
+ } else {
520
+ throw new Exception("The partial " + options.name + " could not be compiled when running in runtime-only mode");
521
+ }
522
+ };
523
+
524
+ // Just add water
525
+ var container = {
526
+ strict: function(obj, name) {
527
+ if (!(name in obj)) {
528
+ throw new Exception('"' + name + '" not defined in ' + obj);
529
+ }
530
+ return obj[name];
531
+ },
532
+ lookup: function(depths, name) {
533
+ var len = depths.length;
534
+ for (var i = 0; i < len; i++) {
535
+ if (depths[i] && depths[i][name] != null) {
536
+ return depths[i][name];
537
+ }
538
+ }
539
+ },
540
+ lambda: function(current, context) {
541
+ return typeof current === 'function' ? current.call(context) : current;
542
+ },
543
+
544
+ escapeExpression: Utils.escapeExpression,
545
+ invokePartial: invokePartialWrapper,
546
+
547
+ fn: function(i) {
548
+ return templateSpec[i];
549
+ },
550
+
551
+ programs: [],
552
+ program: function(i, data, declaredBlockParams, blockParams, depths) {
553
+ var programWrapper = this.programs[i],
554
+ fn = this.fn(i);
555
+ if (data || depths || blockParams || declaredBlockParams) {
556
+ programWrapper = program(this, i, fn, data, declaredBlockParams, blockParams, depths);
557
+ } else if (!programWrapper) {
558
+ programWrapper = this.programs[i] = program(this, i, fn);
559
+ }
560
+ return programWrapper;
561
+ },
562
+
563
+ data: function(data, depth) {
564
+ while (data && depth--) {
565
+ data = data._parent;
566
+ }
567
+ return data;
568
+ },
569
+ merge: function(param, common) {
570
+ var ret = param || common;
571
+
572
+ if (param && common && (param !== common)) {
573
+ ret = Utils.extend({}, common, param);
574
+ }
575
+
576
+ return ret;
577
+ },
578
+
579
+ noop: env.VM.noop,
580
+ compilerInfo: templateSpec.compiler
581
+ };
582
+
583
+ var ret = function(context, options) {
584
+ options = options || {};
585
+ var data = options.data;
586
+
587
+ ret._setup(options);
588
+ if (!options.partial && templateSpec.useData) {
589
+ data = initData(context, data);
590
+ }
591
+ var depths,
592
+ blockParams = templateSpec.useBlockParams ? [] : undefined;
593
+ if (templateSpec.useDepths) {
594
+ depths = options.depths ? [context].concat(options.depths) : [context];
595
+ }
596
+
597
+ return templateSpec.main.call(container, context, container.helpers, container.partials, data, blockParams, depths);
598
+ };
599
+ ret.isTop = true;
600
+
601
+ ret._setup = function(options) {
602
+ if (!options.partial) {
603
+ container.helpers = container.merge(options.helpers, env.helpers);
604
+
605
+ if (templateSpec.usePartial) {
606
+ container.partials = container.merge(options.partials, env.partials);
607
+ }
608
+ } else {
609
+ container.helpers = options.helpers;
610
+ container.partials = options.partials;
611
+ }
612
+ };
613
+
614
+ ret._child = function(i, data, blockParams, depths) {
615
+ if (templateSpec.useBlockParams && !blockParams) {
616
+ throw new Exception('must pass block params');
617
+ }
618
+ if (templateSpec.useDepths && !depths) {
619
+ throw new Exception('must pass parent depths');
620
+ }
621
+
622
+ return program(container, i, templateSpec[i], data, 0, blockParams, depths);
623
+ };
624
+ return ret;
625
+ }
626
+
627
+ __exports__.template = template;function program(container, i, fn, data, declaredBlockParams, blockParams, depths) {
628
+ var prog = function(context, options) {
629
+ options = options || {};
630
+
631
+ return fn.call(container,
632
+ context,
633
+ container.helpers, container.partials,
634
+ options.data || data,
635
+ blockParams && [options.blockParams].concat(blockParams),
636
+ depths && [context].concat(depths));
637
+ };
638
+ prog.program = i;
639
+ prog.depth = depths ? depths.length : 0;
640
+ prog.blockParams = declaredBlockParams || 0;
641
+ return prog;
642
+ }
643
+
644
+ __exports__.program = program;function resolvePartial(partial, context, options) {
645
+ if (!partial) {
646
+ partial = options.partials[options.name];
647
+ } else if (!partial.call && !options.name) {
648
+ // This is a dynamic partial that returned a string
649
+ options.name = partial;
650
+ partial = options.partials[partial];
651
+ }
652
+ return partial;
653
+ }
654
+
655
+ __exports__.resolvePartial = resolvePartial;function invokePartial(partial, context, options) {
656
+ options.partial = true;
657
+
658
+ if(partial === undefined) {
659
+ throw new Exception("The partial " + options.name + " could not be found");
660
+ } else if(partial instanceof Function) {
661
+ return partial(context, options);
662
+ }
663
+ }
664
+
665
+ __exports__.invokePartial = invokePartial;function noop() { return ""; }
666
+
667
+ __exports__.noop = noop;function initData(context, data) {
668
+ if (!data || !('root' in data)) {
669
+ data = data ? createFrame(data) : {};
670
+ data.root = context;
671
+ }
672
+ return data;
673
+ }
674
+ return __exports__;
675
+ })(__module3__, __module4__, __module2__);
676
+
677
+ // handlebars.runtime.js
678
+ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
679
+ "use strict";
680
+ var __exports__;
681
+ /*globals Handlebars: true */
682
+ var base = __dependency1__;
683
+
684
+ // Each of these augment the Handlebars object. No need to setup here.
685
+ // (This is done to easily share code between commonjs and browse envs)
686
+ var SafeString = __dependency2__;
687
+ var Exception = __dependency3__;
688
+ var Utils = __dependency4__;
689
+ var runtime = __dependency5__;
690
+
691
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
692
+ var create = function() {
693
+ var hb = new base.HandlebarsEnvironment();
694
+
695
+ Utils.extend(hb, base);
696
+ hb.SafeString = SafeString;
697
+ hb.Exception = Exception;
698
+ hb.Utils = Utils;
699
+ hb.escapeExpression = Utils.escapeExpression;
700
+
701
+ hb.VM = runtime;
702
+ hb.template = function(spec) {
703
+ return runtime.template(spec, hb);
704
+ };
705
+
706
+ return hb;
707
+ };
708
+
709
+ var Handlebars = create();
710
+ Handlebars.create = create;
711
+
712
+ /*jshint -W040 */
713
+ /* istanbul ignore next */
714
+ var root = typeof global !== 'undefined' ? global : window,
715
+ $Handlebars = root.Handlebars;
716
+ /* istanbul ignore next */
717
+ Handlebars.noConflict = function() {
718
+ if (root.Handlebars === Handlebars) {
719
+ root.Handlebars = $Handlebars;
720
+ }
721
+ };
722
+
723
+ Handlebars['default'] = Handlebars;
724
+
725
+ __exports__ = Handlebars;
726
+ return __exports__;
727
+ })(__module2__, __module5__, __module4__, __module3__, __module6__);
728
+
729
+ // handlebars/compiler/ast.js
730
+ var __module7__ = (function() {
731
+ "use strict";
732
+ var __exports__;
733
+ var AST = {
734
+ Program: function(statements, blockParams, strip, locInfo) {
735
+ this.loc = locInfo;
736
+ this.type = 'Program';
737
+ this.body = statements;
738
+
739
+ this.blockParams = blockParams;
740
+ this.strip = strip;
741
+ },
742
+
743
+ MustacheStatement: function(path, params, hash, escaped, strip, locInfo) {
744
+ this.loc = locInfo;
745
+ this.type = 'MustacheStatement';
746
+
747
+ this.path = path;
748
+ this.params = params || [];
749
+ this.hash = hash;
750
+ this.escaped = escaped;
751
+
752
+ this.strip = strip;
753
+ },
754
+
755
+ BlockStatement: function(path, params, hash, program, inverse, openStrip, inverseStrip, closeStrip, locInfo) {
756
+ this.loc = locInfo;
757
+ this.type = 'BlockStatement';
758
+
759
+ this.path = path;
760
+ this.params = params || [];
761
+ this.hash = hash;
762
+ this.program = program;
763
+ this.inverse = inverse;
764
+
765
+ this.openStrip = openStrip;
766
+ this.inverseStrip = inverseStrip;
767
+ this.closeStrip = closeStrip;
768
+ },
769
+
770
+ PartialStatement: function(name, params, hash, strip, locInfo) {
771
+ this.loc = locInfo;
772
+ this.type = 'PartialStatement';
773
+
774
+ this.name = name;
775
+ this.params = params || [];
776
+ this.hash = hash;
777
+
778
+ this.indent = '';
779
+ this.strip = strip;
780
+ },
781
+
782
+ ContentStatement: function(string, locInfo) {
783
+ this.loc = locInfo;
784
+ this.type = 'ContentStatement';
785
+ this.original = this.value = string;
786
+ },
787
+
788
+ CommentStatement: function(comment, strip, locInfo) {
789
+ this.loc = locInfo;
790
+ this.type = 'CommentStatement';
791
+ this.value = comment;
792
+
793
+ this.strip = strip;
794
+ },
795
+
796
+ SubExpression: function(path, params, hash, locInfo) {
797
+ this.loc = locInfo;
798
+
799
+ this.type = 'SubExpression';
800
+ this.path = path;
801
+ this.params = params || [];
802
+ this.hash = hash;
803
+ },
804
+
805
+ PathExpression: function(data, depth, parts, original, locInfo) {
806
+ this.loc = locInfo;
807
+ this.type = 'PathExpression';
808
+
809
+ this.data = data;
810
+ this.original = original;
811
+ this.parts = parts;
812
+ this.depth = depth;
813
+ },
814
+
815
+ StringLiteral: function(string, locInfo) {
816
+ this.loc = locInfo;
817
+ this.type = 'StringLiteral';
818
+ this.original =
819
+ this.value = string;
820
+ },
821
+
822
+ NumberLiteral: function(number, locInfo) {
823
+ this.loc = locInfo;
824
+ this.type = 'NumberLiteral';
825
+ this.original =
826
+ this.value = Number(number);
827
+ },
828
+
829
+ BooleanLiteral: function(bool, locInfo) {
830
+ this.loc = locInfo;
831
+ this.type = 'BooleanLiteral';
832
+ this.original =
833
+ this.value = bool === 'true';
834
+ },
835
+
836
+ Hash: function(pairs, locInfo) {
837
+ this.loc = locInfo;
838
+ this.type = 'Hash';
839
+ this.pairs = pairs;
840
+ },
841
+ HashPair: function(key, value, locInfo) {
842
+ this.loc = locInfo;
843
+ this.type = 'HashPair';
844
+ this.key = key;
845
+ this.value = value;
846
+ },
847
+
848
+ // Public API used to evaluate derived attributes regarding AST nodes
849
+ helpers: {
850
+ // a mustache is definitely a helper if:
851
+ // * it is an eligible helper, and
852
+ // * it has at least one parameter or hash segment
853
+ // TODO: Make these public utility methods
854
+ helperExpression: function(node) {
855
+ return !!(node.type === 'SubExpression' || node.params.length || node.hash);
856
+ },
857
+
858
+ scopedId: function(path) {
859
+ return (/^\.|this\b/).test(path.original);
860
+ },
861
+
862
+ // an ID is simple if it only has one part, and that part is not
863
+ // `..` or `this`.
864
+ simpleId: function(path) {
865
+ return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
866
+ }
867
+ }
868
+ };
869
+
870
+
871
+ // Must be exported as an object rather than the root of the module as the jison lexer
872
+ // must modify the object to operate properly.
873
+ __exports__ = AST;
874
+ return __exports__;
875
+ })();
876
+
877
+ // handlebars/compiler/parser.js
878
+ var __module9__ = (function() {
879
+ "use strict";
880
+ var __exports__;
881
+ /* jshint ignore:start */
882
+ /* istanbul ignore next */
883
+ /* Jison generated parser */
884
+ var handlebars = (function(){
885
+ var parser = {trace: function trace() { },
886
+ yy: {},
887
+ symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"content":12,"COMMENT":13,"CONTENT":14,"openRawBlock":15,"END_RAW_BLOCK":16,"OPEN_RAW_BLOCK":17,"helperName":18,"openRawBlock_repetition0":19,"openRawBlock_option0":20,"CLOSE_RAW_BLOCK":21,"openBlock":22,"block_option0":23,"closeBlock":24,"openInverse":25,"block_option1":26,"OPEN_BLOCK":27,"openBlock_repetition0":28,"openBlock_option0":29,"openBlock_option1":30,"CLOSE":31,"OPEN_INVERSE":32,"openInverse_repetition0":33,"openInverse_option0":34,"openInverse_option1":35,"openInverseChain":36,"OPEN_INVERSE_CHAIN":37,"openInverseChain_repetition0":38,"openInverseChain_option0":39,"openInverseChain_option1":40,"inverseAndProgram":41,"INVERSE":42,"inverseChain":43,"inverseChain_option0":44,"OPEN_ENDBLOCK":45,"OPEN":46,"mustache_repetition0":47,"mustache_option0":48,"OPEN_UNESCAPED":49,"mustache_repetition1":50,"mustache_option1":51,"CLOSE_UNESCAPED":52,"OPEN_PARTIAL":53,"partialName":54,"partial_repetition0":55,"partial_option0":56,"param":57,"sexpr":58,"OPEN_SEXPR":59,"sexpr_repetition0":60,"sexpr_option0":61,"CLOSE_SEXPR":62,"hash":63,"hash_repetition_plus0":64,"hashSegment":65,"ID":66,"EQUALS":67,"blockParams":68,"OPEN_BLOCK_PARAMS":69,"blockParams_repetition_plus0":70,"CLOSE_BLOCK_PARAMS":71,"path":72,"dataName":73,"STRING":74,"NUMBER":75,"BOOLEAN":76,"DATA":77,"pathSegments":78,"SEP":79,"$accept":0,"$end":1},
888
+ terminals_: {2:"error",5:"EOF",13:"COMMENT",14:"CONTENT",16:"END_RAW_BLOCK",17:"OPEN_RAW_BLOCK",21:"CLOSE_RAW_BLOCK",27:"OPEN_BLOCK",31:"CLOSE",32:"OPEN_INVERSE",37:"OPEN_INVERSE_CHAIN",42:"INVERSE",45:"OPEN_ENDBLOCK",46:"OPEN",49:"OPEN_UNESCAPED",52:"CLOSE_UNESCAPED",53:"OPEN_PARTIAL",59:"OPEN_SEXPR",62:"CLOSE_SEXPR",66:"ID",67:"EQUALS",69:"OPEN_BLOCK_PARAMS",71:"CLOSE_BLOCK_PARAMS",74:"STRING",75:"NUMBER",76:"BOOLEAN",77:"DATA",79:"SEP"},
889
+ productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[12,1],[10,3],[15,5],[9,4],[9,4],[22,6],[25,6],[36,6],[41,2],[43,3],[43,1],[24,3],[8,5],[8,5],[11,5],[57,1],[57,1],[58,5],[63,1],[65,3],[68,3],[18,1],[18,1],[18,1],[18,1],[18,1],[54,1],[54,1],[73,2],[72,1],[78,3],[78,1],[6,0],[6,2],[19,0],[19,2],[20,0],[20,1],[23,0],[23,1],[26,0],[26,1],[28,0],[28,2],[29,0],[29,1],[30,0],[30,1],[33,0],[33,2],[34,0],[34,1],[35,0],[35,1],[38,0],[38,2],[39,0],[39,1],[40,0],[40,1],[44,0],[44,1],[47,0],[47,2],[48,0],[48,1],[50,0],[50,2],[51,0],[51,1],[55,0],[55,2],[56,0],[56,1],[60,0],[60,2],[61,0],[61,1],[64,1],[64,2],[70,1],[70,2]],
890
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
891
+
892
+ var $0 = $$.length - 1;
893
+ switch (yystate) {
894
+ case 1: return $$[$0-1];
895
+ break;
896
+ case 2:this.$ = new yy.Program($$[$0], null, {}, yy.locInfo(this._$));
897
+ break;
898
+ case 3:this.$ = $$[$0];
899
+ break;
900
+ case 4:this.$ = $$[$0];
901
+ break;
902
+ case 5:this.$ = $$[$0];
903
+ break;
904
+ case 6:this.$ = $$[$0];
905
+ break;
906
+ case 7:this.$ = $$[$0];
907
+ break;
908
+ case 8:this.$ = new yy.CommentStatement(yy.stripComment($$[$0]), yy.stripFlags($$[$0], $$[$0]), yy.locInfo(this._$));
909
+ break;
910
+ case 9:this.$ = new yy.ContentStatement($$[$0], yy.locInfo(this._$));
911
+ break;
912
+ case 10:this.$ = yy.prepareRawBlock($$[$0-2], $$[$0-1], $$[$0], this._$);
913
+ break;
914
+ case 11:this.$ = { path: $$[$0-3], params: $$[$0-2], hash: $$[$0-1] };
915
+ break;
916
+ case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$);
917
+ break;
918
+ case 13:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$);
919
+ break;
920
+ case 14:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
921
+ break;
922
+ case 15:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
923
+ break;
924
+ case 16:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
925
+ break;
926
+ case 17:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] };
927
+ break;
928
+ case 18:
929
+ var inverse = yy.prepareBlock($$[$0-2], $$[$0-1], $$[$0], $$[$0], false, this._$),
930
+ program = new yy.Program([inverse], null, {}, yy.locInfo(this._$));
931
+ program.chained = true;
932
+
933
+ this.$ = { strip: $$[$0-2].strip, program: program, chain: true };
934
+
935
+ break;
936
+ case 19:this.$ = $$[$0];
937
+ break;
938
+ case 20:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])};
939
+ break;
940
+ case 21:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$);
941
+ break;
942
+ case 22:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$);
943
+ break;
944
+ case 23:this.$ = new yy.PartialStatement($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), yy.locInfo(this._$));
945
+ break;
946
+ case 24:this.$ = $$[$0];
947
+ break;
948
+ case 25:this.$ = $$[$0];
949
+ break;
950
+ case 26:this.$ = new yy.SubExpression($$[$0-3], $$[$0-2], $$[$0-1], yy.locInfo(this._$));
951
+ break;
952
+ case 27:this.$ = new yy.Hash($$[$0], yy.locInfo(this._$));
953
+ break;
954
+ case 28:this.$ = new yy.HashPair($$[$0-2], $$[$0], yy.locInfo(this._$));
955
+ break;
956
+ case 29:this.$ = $$[$0-1];
957
+ break;
958
+ case 30:this.$ = $$[$0];
959
+ break;
960
+ case 31:this.$ = $$[$0];
961
+ break;
962
+ case 32:this.$ = new yy.StringLiteral($$[$0], yy.locInfo(this._$));
963
+ break;
964
+ case 33:this.$ = new yy.NumberLiteral($$[$0], yy.locInfo(this._$));
965
+ break;
966
+ case 34:this.$ = new yy.BooleanLiteral($$[$0], yy.locInfo(this._$));
967
+ break;
968
+ case 35:this.$ = $$[$0];
969
+ break;
970
+ case 36:this.$ = $$[$0];
971
+ break;
972
+ case 37:this.$ = yy.preparePath(true, $$[$0], this._$);
973
+ break;
974
+ case 38:this.$ = yy.preparePath(false, $$[$0], this._$);
975
+ break;
976
+ case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
977
+ break;
978
+ case 40:this.$ = [{part: $$[$0]}];
979
+ break;
980
+ case 41:this.$ = [];
981
+ break;
982
+ case 42:$$[$0-1].push($$[$0]);
983
+ break;
984
+ case 43:this.$ = [];
985
+ break;
986
+ case 44:$$[$0-1].push($$[$0]);
987
+ break;
988
+ case 51:this.$ = [];
989
+ break;
990
+ case 52:$$[$0-1].push($$[$0]);
991
+ break;
992
+ case 57:this.$ = [];
993
+ break;
994
+ case 58:$$[$0-1].push($$[$0]);
995
+ break;
996
+ case 63:this.$ = [];
997
+ break;
998
+ case 64:$$[$0-1].push($$[$0]);
999
+ break;
1000
+ case 71:this.$ = [];
1001
+ break;
1002
+ case 72:$$[$0-1].push($$[$0]);
1003
+ break;
1004
+ case 75:this.$ = [];
1005
+ break;
1006
+ case 76:$$[$0-1].push($$[$0]);
1007
+ break;
1008
+ case 79:this.$ = [];
1009
+ break;
1010
+ case 80:$$[$0-1].push($$[$0]);
1011
+ break;
1012
+ case 83:this.$ = [];
1013
+ break;
1014
+ case 84:$$[$0-1].push($$[$0]);
1015
+ break;
1016
+ case 87:this.$ = [$$[$0]];
1017
+ break;
1018
+ case 88:$$[$0-1].push($$[$0]);
1019
+ break;
1020
+ case 89:this.$ = [$$[$0]];
1021
+ break;
1022
+ case 90:$$[$0-1].push($$[$0]);
1023
+ break;
1024
+ }
1025
+ },
1026
+ table: [{3:1,4:2,5:[2,41],6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],46:[2,41],49:[2,41],53:[2,41]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:[1,11],14:[1,18],15:16,17:[1,21],22:14,25:15,27:[1,19],32:[1,20],37:[2,2],42:[2,2],45:[2,2],46:[1,12],49:[1,13],53:[1,17]},{1:[2,1]},{5:[2,42],13:[2,42],14:[2,42],17:[2,42],27:[2,42],32:[2,42],37:[2,42],42:[2,42],45:[2,42],46:[2,42],49:[2,42],53:[2,42]},{5:[2,3],13:[2,3],14:[2,3],17:[2,3],27:[2,3],32:[2,3],37:[2,3],42:[2,3],45:[2,3],46:[2,3],49:[2,3],53:[2,3]},{5:[2,4],13:[2,4],14:[2,4],17:[2,4],27:[2,4],32:[2,4],37:[2,4],42:[2,4],45:[2,4],46:[2,4],49:[2,4],53:[2,4]},{5:[2,5],13:[2,5],14:[2,5],17:[2,5],27:[2,5],32:[2,5],37:[2,5],42:[2,5],45:[2,5],46:[2,5],49:[2,5],53:[2,5]},{5:[2,6],13:[2,6],14:[2,6],17:[2,6],27:[2,6],32:[2,6],37:[2,6],42:[2,6],45:[2,6],46:[2,6],49:[2,6],53:[2,6]},{5:[2,7],13:[2,7],14:[2,7],17:[2,7],27:[2,7],32:[2,7],37:[2,7],42:[2,7],45:[2,7],46:[2,7],49:[2,7],53:[2,7]},{5:[2,8],13:[2,8],14:[2,8],17:[2,8],27:[2,8],32:[2,8],37:[2,8],42:[2,8],45:[2,8],46:[2,8],49:[2,8],53:[2,8]},{18:22,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:31,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:32,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{4:33,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{12:34,14:[1,18]},{18:36,54:35,58:37,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,9],13:[2,9],14:[2,9],16:[2,9],17:[2,9],27:[2,9],32:[2,9],37:[2,9],42:[2,9],45:[2,9],46:[2,9],49:[2,9],53:[2,9]},{18:39,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:40,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:41,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[2,71],47:42,59:[2,71],66:[2,71],74:[2,71],75:[2,71],76:[2,71],77:[2,71]},{21:[2,30],31:[2,30],52:[2,30],59:[2,30],62:[2,30],66:[2,30],69:[2,30],74:[2,30],75:[2,30],76:[2,30],77:[2,30]},{21:[2,31],31:[2,31],52:[2,31],59:[2,31],62:[2,31],66:[2,31],69:[2,31],74:[2,31],75:[2,31],76:[2,31],77:[2,31]},{21:[2,32],31:[2,32],52:[2,32],59:[2,32],62:[2,32],66:[2,32],69:[2,32],74:[2,32],75:[2,32],76:[2,32],77:[2,32]},{21:[2,33],31:[2,33],52:[2,33],59:[2,33],62:[2,33],66:[2,33],69:[2,33],74:[2,33],75:[2,33],76:[2,33],77:[2,33]},{21:[2,34],31:[2,34],52:[2,34],59:[2,34],62:[2,34],66:[2,34],69:[2,34],74:[2,34],75:[2,34],76:[2,34],77:[2,34]},{21:[2,38],31:[2,38],52:[2,38],59:[2,38],62:[2,38],66:[2,38],69:[2,38],74:[2,38],75:[2,38],76:[2,38],77:[2,38],79:[1,43]},{66:[1,30],78:44},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{50:45,52:[2,75],59:[2,75],66:[2,75],74:[2,75],75:[2,75],76:[2,75],77:[2,75]},{23:46,36:48,37:[1,50],41:49,42:[1,51],43:47,45:[2,47]},{26:52,41:53,42:[1,51],45:[2,49]},{16:[1,54]},{31:[2,79],55:55,59:[2,79],66:[2,79],74:[2,79],75:[2,79],76:[2,79],77:[2,79]},{31:[2,35],59:[2,35],66:[2,35],74:[2,35],75:[2,35],76:[2,35],77:[2,35]},{31:[2,36],59:[2,36],66:[2,36],74:[2,36],75:[2,36],76:[2,36],77:[2,36]},{18:56,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{28:57,31:[2,51],59:[2,51],66:[2,51],69:[2,51],74:[2,51],75:[2,51],76:[2,51],77:[2,51]},{31:[2,57],33:58,59:[2,57],66:[2,57],69:[2,57],74:[2,57],75:[2,57],76:[2,57],77:[2,57]},{19:59,21:[2,43],59:[2,43],66:[2,43],74:[2,43],75:[2,43],76:[2,43],77:[2,43]},{18:63,31:[2,73],48:60,57:61,58:64,59:[1,38],63:62,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{66:[1,68]},{21:[2,37],31:[2,37],52:[2,37],59:[2,37],62:[2,37],66:[2,37],69:[2,37],74:[2,37],75:[2,37],76:[2,37],77:[2,37],79:[1,43]},{18:63,51:69,52:[2,77],57:70,58:64,59:[1,38],63:71,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{24:72,45:[1,73]},{45:[2,48]},{4:74,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{45:[2,19]},{18:75,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:76,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{24:77,45:[1,73]},{45:[2,50]},{5:[2,10],13:[2,10],14:[2,10],17:[2,10],27:[2,10],32:[2,10],37:[2,10],42:[2,10],45:[2,10],46:[2,10],49:[2,10],53:[2,10]},{18:63,31:[2,81],56:78,57:79,58:64,59:[1,38],63:80,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{59:[2,83],60:81,62:[2,83],66:[2,83],74:[2,83],75:[2,83],76:[2,83],77:[2,83]},{18:63,29:82,31:[2,53],57:83,58:64,59:[1,38],63:84,64:65,65:66,66:[1,67],69:[2,53],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,31:[2,59],34:85,57:86,58:64,59:[1,38],63:87,64:65,65:66,66:[1,67],69:[2,59],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,20:88,21:[2,45],57:89,58:64,59:[1,38],63:90,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[1,91]},{31:[2,72],59:[2,72],66:[2,72],74:[2,72],75:[2,72],76:[2,72],77:[2,72]},{31:[2,74]},{21:[2,24],31:[2,24],52:[2,24],59:[2,24],62:[2,24],66:[2,24],69:[2,24],74:[2,24],75:[2,24],76:[2,24],77:[2,24]},{21:[2,25],31:[2,25],52:[2,25],59:[2,25],62:[2,25],66:[2,25],69:[2,25],74:[2,25],75:[2,25],76:[2,25],77:[2,25]},{21:[2,27],31:[2,27],52:[2,27],62:[2,27],65:92,66:[1,93],69:[2,27]},{21:[2,87],31:[2,87],52:[2,87],62:[2,87],66:[2,87],69:[2,87]},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],67:[1,94],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{21:[2,39],31:[2,39],52:[2,39],59:[2,39],62:[2,39],66:[2,39],69:[2,39],74:[2,39],75:[2,39],76:[2,39],77:[2,39],79:[2,39]},{52:[1,95]},{52:[2,76],59:[2,76],66:[2,76],74:[2,76],75:[2,76],76:[2,76],77:[2,76]},{52:[2,78]},{5:[2,12],13:[2,12],14:[2,12],17:[2,12],27:[2,12],32:[2,12],37:[2,12],42:[2,12],45:[2,12],46:[2,12],49:[2,12],53:[2,12]},{18:96,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{36:48,37:[1,50],41:49,42:[1,51],43:98,44:97,45:[2,69]},{31:[2,63],38:99,59:[2,63],66:[2,63],69:[2,63],74:[2,63],75:[2,63],76:[2,63],77:[2,63]},{45:[2,17]},{5:[2,13],13:[2,13],14:[2,13],17:[2,13],27:[2,13],32:[2,13],37:[2,13],42:[2,13],45:[2,13],46:[2,13],49:[2,13],53:[2,13]},{31:[1,100]},{31:[2,80],59:[2,80],66:[2,80],74:[2,80],75:[2,80],76:[2,80],77:[2,80]},{31:[2,82]},{18:63,57:102,58:64,59:[1,38],61:101,62:[2,85],63:103,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{30:104,31:[2,55],68:105,69:[1,106]},{31:[2,52],59:[2,52],66:[2,52],69:[2,52],74:[2,52],75:[2,52],76:[2,52],77:[2,52]},{31:[2,54],69:[2,54]},{31:[2,61],35:107,68:108,69:[1,106]},{31:[2,58],59:[2,58],66:[2,58],69:[2,58],74:[2,58],75:[2,58],76:[2,58],77:[2,58]},{31:[2,60],69:[2,60]},{21:[1,109]},{21:[2,44],59:[2,44],66:[2,44],74:[2,44],75:[2,44],76:[2,44],77:[2,44]},{21:[2,46]},{5:[2,21],13:[2,21],14:[2,21],17:[2,21],27:[2,21],32:[2,21],37:[2,21],42:[2,21],45:[2,21],46:[2,21],49:[2,21],53:[2,21]},{21:[2,88],31:[2,88],52:[2,88],62:[2,88],66:[2,88],69:[2,88]},{67:[1,94]},{18:63,57:110,58:64,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,22],13:[2,22],14:[2,22],17:[2,22],27:[2,22],32:[2,22],37:[2,22],42:[2,22],45:[2,22],46:[2,22],49:[2,22],53:[2,22]},{31:[1,111]},{45:[2,18]},{45:[2,70]},{18:63,31:[2,65],39:112,57:113,58:64,59:[1,38],63:114,64:65,65:66,66:[1,67],69:[2,65],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,23],13:[2,23],14:[2,23],17:[2,23],27:[2,23],32:[2,23],37:[2,23],42:[2,23],45:[2,23],46:[2,23],49:[2,23],53:[2,23]},{62:[1,115]},{59:[2,84],62:[2,84],66:[2,84],74:[2,84],75:[2,84],76:[2,84],77:[2,84]},{62:[2,86]},{31:[1,116]},{31:[2,56]},{66:[1,118],70:117},{31:[1,119]},{31:[2,62]},{14:[2,11]},{21:[2,28],31:[2,28],52:[2,28],62:[2,28],66:[2,28],69:[2,28]},{5:[2,20],13:[2,20],14:[2,20],17:[2,20],27:[2,20],32:[2,20],37:[2,20],42:[2,20],45:[2,20],46:[2,20],49:[2,20],53:[2,20]},{31:[2,67],40:120,68:121,69:[1,106]},{31:[2,64],59:[2,64],66:[2,64],69:[2,64],74:[2,64],75:[2,64],76:[2,64],77:[2,64]},{31:[2,66],69:[2,66]},{21:[2,26],31:[2,26],52:[2,26],59:[2,26],62:[2,26],66:[2,26],69:[2,26],74:[2,26],75:[2,26],76:[2,26],77:[2,26]},{13:[2,14],14:[2,14],17:[2,14],27:[2,14],32:[2,14],37:[2,14],42:[2,14],45:[2,14],46:[2,14],49:[2,14],53:[2,14]},{66:[1,123],71:[1,122]},{66:[2,89],71:[2,89]},{13:[2,15],14:[2,15],17:[2,15],27:[2,15],32:[2,15],42:[2,15],45:[2,15],46:[2,15],49:[2,15],53:[2,15]},{31:[1,124]},{31:[2,68]},{31:[2,29]},{66:[2,90],71:[2,90]},{13:[2,16],14:[2,16],17:[2,16],27:[2,16],32:[2,16],37:[2,16],42:[2,16],45:[2,16],46:[2,16],49:[2,16],53:[2,16]}],
1027
+ defaultActions: {4:[2,1],47:[2,48],49:[2,19],53:[2,50],62:[2,74],71:[2,78],76:[2,17],80:[2,82],90:[2,46],97:[2,18],98:[2,70],103:[2,86],105:[2,56],108:[2,62],109:[2,11],121:[2,68],122:[2,29]},
1028
+ parseError: function parseError(str, hash) {
1029
+ throw new Error(str);
1030
+ },
1031
+ parse: function parse(input) {
1032
+ var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
1033
+ this.lexer.setInput(input);
1034
+ this.lexer.yy = this.yy;
1035
+ this.yy.lexer = this.lexer;
1036
+ this.yy.parser = this;
1037
+ if (typeof this.lexer.yylloc == "undefined")
1038
+ this.lexer.yylloc = {};
1039
+ var yyloc = this.lexer.yylloc;
1040
+ lstack.push(yyloc);
1041
+ var ranges = this.lexer.options && this.lexer.options.ranges;
1042
+ if (typeof this.yy.parseError === "function")
1043
+ this.parseError = this.yy.parseError;
1044
+ function popStack(n) {
1045
+ stack.length = stack.length - 2 * n;
1046
+ vstack.length = vstack.length - n;
1047
+ lstack.length = lstack.length - n;
1048
+ }
1049
+ function lex() {
1050
+ var token;
1051
+ token = self.lexer.lex() || 1;
1052
+ if (typeof token !== "number") {
1053
+ token = self.symbols_[token] || token;
1054
+ }
1055
+ return token;
1056
+ }
1057
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
1058
+ while (true) {
1059
+ state = stack[stack.length - 1];
1060
+ if (this.defaultActions[state]) {
1061
+ action = this.defaultActions[state];
1062
+ } else {
1063
+ if (symbol === null || typeof symbol == "undefined") {
1064
+ symbol = lex();
1065
+ }
1066
+ action = table[state] && table[state][symbol];
1067
+ }
1068
+ if (typeof action === "undefined" || !action.length || !action[0]) {
1069
+ var errStr = "";
1070
+ if (!recovering) {
1071
+ expected = [];
1072
+ for (p in table[state])
1073
+ if (this.terminals_[p] && p > 2) {
1074
+ expected.push("'" + this.terminals_[p] + "'");
1075
+ }
1076
+ if (this.lexer.showPosition) {
1077
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
1078
+ } else {
1079
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
1080
+ }
1081
+ this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
1082
+ }
1083
+ }
1084
+ if (action[0] instanceof Array && action.length > 1) {
1085
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
1086
+ }
1087
+ switch (action[0]) {
1088
+ case 1:
1089
+ stack.push(symbol);
1090
+ vstack.push(this.lexer.yytext);
1091
+ lstack.push(this.lexer.yylloc);
1092
+ stack.push(action[1]);
1093
+ symbol = null;
1094
+ if (!preErrorSymbol) {
1095
+ yyleng = this.lexer.yyleng;
1096
+ yytext = this.lexer.yytext;
1097
+ yylineno = this.lexer.yylineno;
1098
+ yyloc = this.lexer.yylloc;
1099
+ if (recovering > 0)
1100
+ recovering--;
1101
+ } else {
1102
+ symbol = preErrorSymbol;
1103
+ preErrorSymbol = null;
1104
+ }
1105
+ break;
1106
+ case 2:
1107
+ len = this.productions_[action[1]][1];
1108
+ yyval.$ = vstack[vstack.length - len];
1109
+ 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};
1110
+ if (ranges) {
1111
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
1112
+ }
1113
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
1114
+ if (typeof r !== "undefined") {
1115
+ return r;
1116
+ }
1117
+ if (len) {
1118
+ stack = stack.slice(0, -1 * len * 2);
1119
+ vstack = vstack.slice(0, -1 * len);
1120
+ lstack = lstack.slice(0, -1 * len);
1121
+ }
1122
+ stack.push(this.productions_[action[1]][0]);
1123
+ vstack.push(yyval.$);
1124
+ lstack.push(yyval._$);
1125
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
1126
+ stack.push(newState);
1127
+ break;
1128
+ case 3:
1129
+ return true;
1130
+ }
1131
+ }
1132
+ return true;
1133
+ }
1134
+ };
1135
+ /* Jison generated lexer */
1136
+ var lexer = (function(){
1137
+ var lexer = ({EOF:1,
1138
+ parseError:function parseError(str, hash) {
1139
+ if (this.yy.parser) {
1140
+ this.yy.parser.parseError(str, hash);
1141
+ } else {
1142
+ throw new Error(str);
1143
+ }
1144
+ },
1145
+ setInput:function (input) {
1146
+ this._input = input;
1147
+ this._more = this._less = this.done = false;
1148
+ this.yylineno = this.yyleng = 0;
1149
+ this.yytext = this.matched = this.match = '';
1150
+ this.conditionStack = ['INITIAL'];
1151
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
1152
+ if (this.options.ranges) this.yylloc.range = [0,0];
1153
+ this.offset = 0;
1154
+ return this;
1155
+ },
1156
+ input:function () {
1157
+ var ch = this._input[0];
1158
+ this.yytext += ch;
1159
+ this.yyleng++;
1160
+ this.offset++;
1161
+ this.match += ch;
1162
+ this.matched += ch;
1163
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
1164
+ if (lines) {
1165
+ this.yylineno++;
1166
+ this.yylloc.last_line++;
1167
+ } else {
1168
+ this.yylloc.last_column++;
1169
+ }
1170
+ if (this.options.ranges) this.yylloc.range[1]++;
1171
+
1172
+ this._input = this._input.slice(1);
1173
+ return ch;
1174
+ },
1175
+ unput:function (ch) {
1176
+ var len = ch.length;
1177
+ var lines = ch.split(/(?:\r\n?|\n)/g);
1178
+
1179
+ this._input = ch + this._input;
1180
+ this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
1181
+ //this.yyleng -= len;
1182
+ this.offset -= len;
1183
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
1184
+ this.match = this.match.substr(0, this.match.length-1);
1185
+ this.matched = this.matched.substr(0, this.matched.length-1);
1186
+
1187
+ if (lines.length-1) this.yylineno -= lines.length-1;
1188
+ var r = this.yylloc.range;
1189
+
1190
+ this.yylloc = {first_line: this.yylloc.first_line,
1191
+ last_line: this.yylineno+1,
1192
+ first_column: this.yylloc.first_column,
1193
+ last_column: lines ?
1194
+ (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
1195
+ this.yylloc.first_column - len
1196
+ };
1197
+
1198
+ if (this.options.ranges) {
1199
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
1200
+ }
1201
+ return this;
1202
+ },
1203
+ more:function () {
1204
+ this._more = true;
1205
+ return this;
1206
+ },
1207
+ less:function (n) {
1208
+ this.unput(this.match.slice(n));
1209
+ },
1210
+ pastInput:function () {
1211
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
1212
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
1213
+ },
1214
+ upcomingInput:function () {
1215
+ var next = this.match;
1216
+ if (next.length < 20) {
1217
+ next += this._input.substr(0, 20-next.length);
1218
+ }
1219
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
1220
+ },
1221
+ showPosition:function () {
1222
+ var pre = this.pastInput();
1223
+ var c = new Array(pre.length + 1).join("-");
1224
+ return pre + this.upcomingInput() + "\n" + c+"^";
1225
+ },
1226
+ next:function () {
1227
+ if (this.done) {
1228
+ return this.EOF;
1229
+ }
1230
+ if (!this._input) this.done = true;
1231
+
1232
+ var token,
1233
+ match,
1234
+ tempMatch,
1235
+ index,
1236
+ col,
1237
+ lines;
1238
+ if (!this._more) {
1239
+ this.yytext = '';
1240
+ this.match = '';
1241
+ }
1242
+ var rules = this._currentRules();
1243
+ for (var i=0;i < rules.length; i++) {
1244
+ tempMatch = this._input.match(this.rules[rules[i]]);
1245
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1246
+ match = tempMatch;
1247
+ index = i;
1248
+ if (!this.options.flex) break;
1249
+ }
1250
+ }
1251
+ if (match) {
1252
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
1253
+ if (lines) this.yylineno += lines.length;
1254
+ this.yylloc = {first_line: this.yylloc.last_line,
1255
+ last_line: this.yylineno+1,
1256
+ first_column: this.yylloc.last_column,
1257
+ last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1258
+ this.yytext += match[0];
1259
+ this.match += match[0];
1260
+ this.matches = match;
1261
+ this.yyleng = this.yytext.length;
1262
+ if (this.options.ranges) {
1263
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
1264
+ }
1265
+ this._more = false;
1266
+ this._input = this._input.slice(match[0].length);
1267
+ this.matched += match[0];
1268
+ token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1269
+ if (this.done && this._input) this.done = false;
1270
+ if (token) return token;
1271
+ else return;
1272
+ }
1273
+ if (this._input === "") {
1274
+ return this.EOF;
1275
+ } else {
1276
+ return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1277
+ {text: "", token: null, line: this.yylineno});
1278
+ }
1279
+ },
1280
+ lex:function lex() {
1281
+ var r = this.next();
1282
+ if (typeof r !== 'undefined') {
1283
+ return r;
1284
+ } else {
1285
+ return this.lex();
1286
+ }
1287
+ },
1288
+ begin:function begin(condition) {
1289
+ this.conditionStack.push(condition);
1290
+ },
1291
+ popState:function popState() {
1292
+ return this.conditionStack.pop();
1293
+ },
1294
+ _currentRules:function _currentRules() {
1295
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1296
+ },
1297
+ topState:function () {
1298
+ return this.conditionStack[this.conditionStack.length-2];
1299
+ },
1300
+ pushState:function begin(condition) {
1301
+ this.begin(condition);
1302
+ }});
1303
+ lexer.options = {};
1304
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1305
+
1306
+
1307
+ function strip(start, end) {
1308
+ return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1309
+ }
1310
+
1311
+
1312
+ var YYSTATE=YY_START
1313
+ switch($avoiding_name_collisions) {
1314
+ case 0:
1315
+ if(yy_.yytext.slice(-2) === "\\\\") {
1316
+ strip(0,1);
1317
+ this.begin("mu");
1318
+ } else if(yy_.yytext.slice(-1) === "\\") {
1319
+ strip(0,1);
1320
+ this.begin("emu");
1321
+ } else {
1322
+ this.begin("mu");
1323
+ }
1324
+ if(yy_.yytext) return 14;
1325
+
1326
+ break;
1327
+ case 1:return 14;
1328
+ break;
1329
+ case 2:
1330
+ this.popState();
1331
+ return 14;
1332
+
1333
+ break;
1334
+ case 3:
1335
+ yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9);
1336
+ this.popState();
1337
+ return 16;
1338
+
1339
+ break;
1340
+ case 4: return 14;
1341
+ break;
1342
+ case 5:
1343
+ this.popState();
1344
+ return 13;
1345
+
1346
+ break;
1347
+ case 6:return 59;
1348
+ break;
1349
+ case 7:return 62;
1350
+ break;
1351
+ case 8: return 17;
1352
+ break;
1353
+ case 9:
1354
+ this.popState();
1355
+ this.begin('raw');
1356
+ return 21;
1357
+
1358
+ break;
1359
+ case 10:return 53;
1360
+ break;
1361
+ case 11:return 27;
1362
+ break;
1363
+ case 12:return 45;
1364
+ break;
1365
+ case 13:this.popState(); return 42;
1366
+ break;
1367
+ case 14:this.popState(); return 42;
1368
+ break;
1369
+ case 15:return 32;
1370
+ break;
1371
+ case 16:return 37;
1372
+ break;
1373
+ case 17:return 49;
1374
+ break;
1375
+ case 18:return 46;
1376
+ break;
1377
+ case 19:
1378
+ this.unput(yy_.yytext);
1379
+ this.popState();
1380
+ this.begin('com');
1381
+
1382
+ break;
1383
+ case 20:
1384
+ this.popState();
1385
+ return 13;
1386
+
1387
+ break;
1388
+ case 21:return 46;
1389
+ break;
1390
+ case 22:return 67;
1391
+ break;
1392
+ case 23:return 66;
1393
+ break;
1394
+ case 24:return 66;
1395
+ break;
1396
+ case 25:return 79;
1397
+ break;
1398
+ case 26:// ignore whitespace
1399
+ break;
1400
+ case 27:this.popState(); return 52;
1401
+ break;
1402
+ case 28:this.popState(); return 31;
1403
+ break;
1404
+ case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 74;
1405
+ break;
1406
+ case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 74;
1407
+ break;
1408
+ case 31:return 77;
1409
+ break;
1410
+ case 32:return 76;
1411
+ break;
1412
+ case 33:return 76;
1413
+ break;
1414
+ case 34:return 75;
1415
+ break;
1416
+ case 35:return 69;
1417
+ break;
1418
+ case 36:return 71;
1419
+ break;
1420
+ case 37:return 66;
1421
+ break;
1422
+ case 38:yy_.yytext = strip(1,2); return 66;
1423
+ break;
1424
+ case 39:return 'INVALID';
1425
+ break;
1426
+ case 40:return 5;
1427
+ break;
1428
+ }
1429
+ };
1430
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1431
+ lexer.conditions = {"mu":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,40],"inclusive":true}};
1432
+ return lexer;})()
1433
+ parser.lexer = lexer;
1434
+ function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1435
+ return new Parser;
1436
+ })();__exports__ = handlebars;
1437
+ /* jshint ignore:end */
1438
+ return __exports__;
1439
+ })();
1440
+
1441
+ // handlebars/compiler/visitor.js
1442
+ var __module11__ = (function(__dependency1__, __dependency2__) {
1443
+ "use strict";
1444
+ var __exports__;
1445
+ var Exception = __dependency1__;
1446
+ var AST = __dependency2__;
1447
+
1448
+ function Visitor() {
1449
+ this.parents = [];
1450
+ }
1451
+
1452
+ Visitor.prototype = {
1453
+ constructor: Visitor,
1454
+ mutating: false,
1455
+
1456
+ // Visits a given value. If mutating, will replace the value if necessary.
1457
+ acceptKey: function(node, name) {
1458
+ var value = this.accept(node[name]);
1459
+ if (this.mutating) {
1460
+ // Hacky sanity check:
1461
+ if (value && (!value.type || !AST[value.type])) {
1462
+ throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
1463
+ }
1464
+ node[name] = value;
1465
+ }
1466
+ },
1467
+
1468
+ // Performs an accept operation with added sanity check to ensure
1469
+ // required keys are not removed.
1470
+ acceptRequired: function(node, name) {
1471
+ this.acceptKey(node, name);
1472
+
1473
+ if (!node[name]) {
1474
+ throw new Exception(node.type + ' requires ' + name);
1475
+ }
1476
+ },
1477
+
1478
+ // Traverses a given array. If mutating, empty respnses will be removed
1479
+ // for child elements.
1480
+ acceptArray: function(array) {
1481
+ for (var i = 0, l = array.length; i < l; i++) {
1482
+ this.acceptKey(array, i);
1483
+
1484
+ if (!array[i]) {
1485
+ array.splice(i, 1);
1486
+ i--;
1487
+ l--;
1488
+ }
1489
+ }
1490
+ },
1491
+
1492
+ accept: function(object) {
1493
+ if (!object) {
1494
+ return;
1495
+ }
1496
+
1497
+ if (this.current) {
1498
+ this.parents.unshift(this.current);
1499
+ }
1500
+ this.current = object;
1501
+
1502
+ var ret = this[object.type](object);
1503
+
1504
+ this.current = this.parents.shift();
1505
+
1506
+ if (!this.mutating || ret) {
1507
+ return ret;
1508
+ } else if (ret !== false) {
1509
+ return object;
1510
+ }
1511
+ },
1512
+
1513
+ Program: function(program) {
1514
+ this.acceptArray(program.body);
1515
+ },
1516
+
1517
+ MustacheStatement: function(mustache) {
1518
+ this.acceptRequired(mustache, 'path');
1519
+ this.acceptArray(mustache.params);
1520
+ this.acceptKey(mustache, 'hash');
1521
+ },
1522
+
1523
+ BlockStatement: function(block) {
1524
+ this.acceptRequired(block, 'path');
1525
+ this.acceptArray(block.params);
1526
+ this.acceptKey(block, 'hash');
1527
+
1528
+ this.acceptKey(block, 'program');
1529
+ this.acceptKey(block, 'inverse');
1530
+ },
1531
+
1532
+ PartialStatement: function(partial) {
1533
+ this.acceptRequired(partial, 'name');
1534
+ this.acceptArray(partial.params);
1535
+ this.acceptKey(partial, 'hash');
1536
+ },
1537
+
1538
+ ContentStatement: function(/* content */) {},
1539
+ CommentStatement: function(/* comment */) {},
1540
+
1541
+ SubExpression: function(sexpr) {
1542
+ this.acceptRequired(sexpr, 'path');
1543
+ this.acceptArray(sexpr.params);
1544
+ this.acceptKey(sexpr, 'hash');
1545
+ },
1546
+ PartialExpression: function(partial) {
1547
+ this.acceptRequired(partial, 'name');
1548
+ this.acceptArray(partial.params);
1549
+ this.acceptKey(partial, 'hash');
1550
+ },
1551
+
1552
+ PathExpression: function(/* path */) {},
1553
+
1554
+ StringLiteral: function(/* string */) {},
1555
+ NumberLiteral: function(/* number */) {},
1556
+ BooleanLiteral: function(/* bool */) {},
1557
+
1558
+ Hash: function(hash) {
1559
+ this.acceptArray(hash.pairs);
1560
+ },
1561
+ HashPair: function(pair) {
1562
+ this.acceptRequired(pair, 'value');
1563
+ }
1564
+ };
1565
+
1566
+ __exports__ = Visitor;
1567
+ return __exports__;
1568
+ })(__module4__, __module7__);
1569
+
1570
+ // handlebars/compiler/whitespace-control.js
1571
+ var __module10__ = (function(__dependency1__) {
1572
+ "use strict";
1573
+ var __exports__;
1574
+ var Visitor = __dependency1__;
1575
+
1576
+ function WhitespaceControl() {
1577
+ }
1578
+ WhitespaceControl.prototype = new Visitor();
1579
+
1580
+ WhitespaceControl.prototype.Program = function(program) {
1581
+ var isRoot = !this.isRootSeen;
1582
+ this.isRootSeen = true;
1583
+
1584
+ var body = program.body;
1585
+ for (var i = 0, l = body.length; i < l; i++) {
1586
+ var current = body[i],
1587
+ strip = this.accept(current);
1588
+
1589
+ if (!strip) {
1590
+ continue;
1591
+ }
1592
+
1593
+ var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
1594
+ _isNextWhitespace = isNextWhitespace(body, i, isRoot),
1595
+
1596
+ openStandalone = strip.openStandalone && _isPrevWhitespace,
1597
+ closeStandalone = strip.closeStandalone && _isNextWhitespace,
1598
+ inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
1599
+
1600
+ if (strip.close) {
1601
+ omitRight(body, i, true);
1602
+ }
1603
+ if (strip.open) {
1604
+ omitLeft(body, i, true);
1605
+ }
1606
+
1607
+ if (inlineStandalone) {
1608
+ omitRight(body, i);
1609
+
1610
+ if (omitLeft(body, i)) {
1611
+ // If we are on a standalone node, save the indent info for partials
1612
+ if (current.type === 'PartialStatement') {
1613
+ // Pull out the whitespace from the final line
1614
+ current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1];
1615
+ }
1616
+ }
1617
+ }
1618
+ if (openStandalone) {
1619
+ omitRight((current.program || current.inverse).body);
1620
+
1621
+ // Strip out the previous content node if it's whitespace only
1622
+ omitLeft(body, i);
1623
+ }
1624
+ if (closeStandalone) {
1625
+ // Always strip the next node
1626
+ omitRight(body, i);
1627
+
1628
+ omitLeft((current.inverse || current.program).body);
1629
+ }
1630
+ }
1631
+
1632
+ return program;
1633
+ };
1634
+ WhitespaceControl.prototype.BlockStatement = function(block) {
1635
+ this.accept(block.program);
1636
+ this.accept(block.inverse);
1637
+
1638
+ // Find the inverse program that is involed with whitespace stripping.
1639
+ var program = block.program || block.inverse,
1640
+ inverse = block.program && block.inverse,
1641
+ firstInverse = inverse,
1642
+ lastInverse = inverse;
1643
+
1644
+ if (inverse && inverse.chained) {
1645
+ firstInverse = inverse.body[0].program;
1646
+
1647
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
1648
+ while (lastInverse.chained) {
1649
+ lastInverse = lastInverse.body[lastInverse.body.length-1].program;
1650
+ }
1651
+ }
1652
+
1653
+ var strip = {
1654
+ open: block.openStrip.open,
1655
+ close: block.closeStrip.close,
1656
+
1657
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
1658
+ // so our parent can determine if we actually are standalone
1659
+ openStandalone: isNextWhitespace(program.body),
1660
+ closeStandalone: isPrevWhitespace((firstInverse || program).body)
1661
+ };
1662
+
1663
+ if (block.openStrip.close) {
1664
+ omitRight(program.body, null, true);
1665
+ }
1666
+
1667
+ if (inverse) {
1668
+ var inverseStrip = block.inverseStrip;
1669
+
1670
+ if (inverseStrip.open) {
1671
+ omitLeft(program.body, null, true);
1672
+ }
1673
+
1674
+ if (inverseStrip.close) {
1675
+ omitRight(firstInverse.body, null, true);
1676
+ }
1677
+ if (block.closeStrip.open) {
1678
+ omitLeft(lastInverse.body, null, true);
1679
+ }
1680
+
1681
+ // Find standalone else statments
1682
+ if (isPrevWhitespace(program.body)
1683
+ && isNextWhitespace(firstInverse.body)) {
1684
+
1685
+ omitLeft(program.body);
1686
+ omitRight(firstInverse.body);
1687
+ }
1688
+ } else {
1689
+ if (block.closeStrip.open) {
1690
+ omitLeft(program.body, null, true);
1691
+ }
1692
+ }
1693
+
1694
+ return strip;
1695
+ };
1696
+
1697
+ WhitespaceControl.prototype.MustacheStatement = function(mustache) {
1698
+ return mustache.strip;
1699
+ };
1700
+
1701
+ WhitespaceControl.prototype.PartialStatement =
1702
+ WhitespaceControl.prototype.CommentStatement = function(node) {
1703
+ /* istanbul ignore next */
1704
+ var strip = node.strip || {};
1705
+ return {
1706
+ inlineStandalone: true,
1707
+ open: strip.open,
1708
+ close: strip.close
1709
+ };
1710
+ };
1711
+
1712
+
1713
+ function isPrevWhitespace(body, i, isRoot) {
1714
+ if (i === undefined) {
1715
+ i = body.length;
1716
+ }
1717
+
1718
+ // Nodes that end with newlines are considered whitespace (but are special
1719
+ // cased for strip operations)
1720
+ var prev = body[i-1],
1721
+ sibling = body[i-2];
1722
+ if (!prev) {
1723
+ return isRoot;
1724
+ }
1725
+
1726
+ if (prev.type === 'ContentStatement') {
1727
+ return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
1728
+ }
1729
+ }
1730
+ function isNextWhitespace(body, i, isRoot) {
1731
+ if (i === undefined) {
1732
+ i = -1;
1733
+ }
1734
+
1735
+ var next = body[i+1],
1736
+ sibling = body[i+2];
1737
+ if (!next) {
1738
+ return isRoot;
1739
+ }
1740
+
1741
+ if (next.type === 'ContentStatement') {
1742
+ return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
1743
+ }
1744
+ }
1745
+
1746
+ // Marks the node to the right of the position as omitted.
1747
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
1748
+ //
1749
+ // If i is undefined, then the first child will be marked as such.
1750
+ //
1751
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1752
+ // content is met.
1753
+ function omitRight(body, i, multiple) {
1754
+ var current = body[i == null ? 0 : i + 1];
1755
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) {
1756
+ return;
1757
+ }
1758
+
1759
+ var original = current.value;
1760
+ current.value = current.value.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
1761
+ current.rightStripped = current.value !== original;
1762
+ }
1763
+
1764
+ // Marks the node to the left of the position as omitted.
1765
+ // I.e. ' '{{foo}} will mark the ' ' node as omitted.
1766
+ //
1767
+ // If i is undefined then the last child will be marked as such.
1768
+ //
1769
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1770
+ // content is met.
1771
+ function omitLeft(body, i, multiple) {
1772
+ var current = body[i == null ? body.length - 1 : i - 1];
1773
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) {
1774
+ return;
1775
+ }
1776
+
1777
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
1778
+ var original = current.value;
1779
+ current.value = current.value.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
1780
+ current.leftStripped = current.value !== original;
1781
+ return current.leftStripped;
1782
+ }
1783
+
1784
+ __exports__ = WhitespaceControl;
1785
+ return __exports__;
1786
+ })(__module11__);
1787
+
1788
+ // handlebars/compiler/helpers.js
1789
+ var __module12__ = (function(__dependency1__) {
1790
+ "use strict";
1791
+ var __exports__ = {};
1792
+ var Exception = __dependency1__;
1793
+
1794
+ function SourceLocation(source, locInfo) {
1795
+ this.source = source;
1796
+ this.start = {
1797
+ line: locInfo.first_line,
1798
+ column: locInfo.first_column
1799
+ };
1800
+ this.end = {
1801
+ line: locInfo.last_line,
1802
+ column: locInfo.last_column
1803
+ };
1804
+ }
1805
+
1806
+ __exports__.SourceLocation = SourceLocation;function stripFlags(open, close) {
1807
+ return {
1808
+ open: open.charAt(2) === '~',
1809
+ close: close.charAt(close.length-3) === '~'
1810
+ };
1811
+ }
1812
+
1813
+ __exports__.stripFlags = stripFlags;function stripComment(comment) {
1814
+ return comment.replace(/^\{\{~?\!-?-?/, '')
1815
+ .replace(/-?-?~?\}\}$/, '');
1816
+ }
1817
+
1818
+ __exports__.stripComment = stripComment;function preparePath(data, parts, locInfo) {
1819
+ /*jshint -W040 */
1820
+ locInfo = this.locInfo(locInfo);
1821
+
1822
+ var original = data ? '@' : '',
1823
+ dig = [],
1824
+ depth = 0,
1825
+ depthString = '';
1826
+
1827
+ for(var i=0,l=parts.length; i<l; i++) {
1828
+ var part = parts[i].part;
1829
+ original += (parts[i].separator || '') + part;
1830
+
1831
+ if (part === '..' || part === '.' || part === 'this') {
1832
+ if (dig.length > 0) {
1833
+ throw new Exception('Invalid path: ' + original, {loc: locInfo});
1834
+ } else if (part === '..') {
1835
+ depth++;
1836
+ depthString += '../';
1837
+ }
1838
+ } else {
1839
+ dig.push(part);
1840
+ }
1841
+ }
1842
+
1843
+ return new this.PathExpression(data, depth, dig, original, locInfo);
1844
+ }
1845
+
1846
+ __exports__.preparePath = preparePath;function prepareMustache(path, params, hash, open, strip, locInfo) {
1847
+ /*jshint -W040 */
1848
+ // Must use charAt to support IE pre-10
1849
+ var escapeFlag = open.charAt(3) || open.charAt(2),
1850
+ escaped = escapeFlag !== '{' && escapeFlag !== '&';
1851
+
1852
+ return new this.MustacheStatement(path, params, hash, escaped, strip, this.locInfo(locInfo));
1853
+ }
1854
+
1855
+ __exports__.prepareMustache = prepareMustache;function prepareRawBlock(openRawBlock, content, close, locInfo) {
1856
+ /*jshint -W040 */
1857
+ if (openRawBlock.path.original !== close) {
1858
+ var errorNode = {loc: openRawBlock.path.loc};
1859
+
1860
+ throw new Exception(openRawBlock.path.original + " doesn't match " + close, errorNode);
1861
+ }
1862
+
1863
+ locInfo = this.locInfo(locInfo);
1864
+ var program = new this.Program([content], null, {}, locInfo);
1865
+
1866
+ return new this.BlockStatement(
1867
+ openRawBlock.path, openRawBlock.params, openRawBlock.hash,
1868
+ program, undefined,
1869
+ {}, {}, {},
1870
+ locInfo);
1871
+ }
1872
+
1873
+ __exports__.prepareRawBlock = prepareRawBlock;function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
1874
+ /*jshint -W040 */
1875
+ // When we are chaining inverse calls, we will not have a close path
1876
+ if (close && close.path && openBlock.path.original !== close.path.original) {
1877
+ var errorNode = {loc: openBlock.path.loc};
1878
+
1879
+ throw new Exception(openBlock.path.original + ' doesn\'t match ' + close.path.original, errorNode);
1880
+ }
1881
+
1882
+ program.blockParams = openBlock.blockParams;
1883
+
1884
+ var inverse,
1885
+ inverseStrip;
1886
+
1887
+ if (inverseAndProgram) {
1888
+ if (inverseAndProgram.chain) {
1889
+ inverseAndProgram.program.body[0].closeStrip = close.strip;
1890
+ }
1891
+
1892
+ inverseStrip = inverseAndProgram.strip;
1893
+ inverse = inverseAndProgram.program;
1894
+ }
1895
+
1896
+ if (inverted) {
1897
+ inverted = inverse;
1898
+ inverse = program;
1899
+ program = inverted;
1900
+ }
1901
+
1902
+ return new this.BlockStatement(
1903
+ openBlock.path, openBlock.params, openBlock.hash,
1904
+ program, inverse,
1905
+ openBlock.strip, inverseStrip, close && close.strip,
1906
+ this.locInfo(locInfo));
1907
+ }
1908
+
1909
+ __exports__.prepareBlock = prepareBlock;
1910
+ return __exports__;
1911
+ })(__module4__);
1912
+
1913
+ // handlebars/compiler/base.js
1914
+ var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
1915
+ "use strict";
1916
+ var __exports__ = {};
1917
+ var parser = __dependency1__;
1918
+ var AST = __dependency2__;
1919
+ var WhitespaceControl = __dependency3__;
1920
+ var Helpers = __dependency4__;
1921
+ var extend = __dependency5__.extend;
1922
+
1923
+ __exports__.parser = parser;
1924
+
1925
+ var yy = {};
1926
+ extend(yy, Helpers, AST);
1927
+
1928
+ function parse(input, options) {
1929
+ // Just return if an already-compiled AST was passed in.
1930
+ if (input.type === 'Program') { return input; }
1931
+
1932
+ parser.yy = yy;
1933
+
1934
+ // Altering the shared object here, but this is ok as parser is a sync operation
1935
+ yy.locInfo = function(locInfo) {
1936
+ return new yy.SourceLocation(options && options.srcName, locInfo);
1937
+ };
1938
+
1939
+ var strip = new WhitespaceControl();
1940
+ return strip.accept(parser.parse(input));
1941
+ }
1942
+
1943
+ __exports__.parse = parse;
1944
+ return __exports__;
1945
+ })(__module9__, __module7__, __module10__, __module12__, __module3__);
1946
+
1947
+ // handlebars/compiler/compiler.js
1948
+ var __module13__ = (function(__dependency1__, __dependency2__, __dependency3__) {
1949
+ "use strict";
1950
+ var __exports__ = {};
1951
+ var Exception = __dependency1__;
1952
+ var isArray = __dependency2__.isArray;
1953
+ var indexOf = __dependency2__.indexOf;
1954
+ var AST = __dependency3__;
1955
+
1956
+ var slice = [].slice;
1957
+
1958
+
1959
+ function Compiler() {}
1960
+
1961
+ __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
1962
+ // function in a context. This is necessary for mustache compatibility, which
1963
+ // requires that context functions in blocks are evaluated by blockHelperMissing,
1964
+ // and then proceed as if the resulting value was provided to blockHelperMissing.
1965
+
1966
+ Compiler.prototype = {
1967
+ compiler: Compiler,
1968
+
1969
+ equals: function(other) {
1970
+ var len = this.opcodes.length;
1971
+ if (other.opcodes.length !== len) {
1972
+ return false;
1973
+ }
1974
+
1975
+ for (var i = 0; i < len; i++) {
1976
+ var opcode = this.opcodes[i],
1977
+ otherOpcode = other.opcodes[i];
1978
+ if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
1979
+ return false;
1980
+ }
1981
+ }
1982
+
1983
+ // We know that length is the same between the two arrays because they are directly tied
1984
+ // to the opcode behavior above.
1985
+ len = this.children.length;
1986
+ for (i = 0; i < len; i++) {
1987
+ if (!this.children[i].equals(other.children[i])) {
1988
+ return false;
1989
+ }
1990
+ }
1991
+
1992
+ return true;
1993
+ },
1994
+
1995
+ guid: 0,
1996
+
1997
+ compile: function(program, options) {
1998
+ this.sourceNode = [];
1999
+ this.opcodes = [];
2000
+ this.children = [];
2001
+ this.options = options;
2002
+ this.stringParams = options.stringParams;
2003
+ this.trackIds = options.trackIds;
2004
+
2005
+ options.blockParams = options.blockParams || [];
2006
+
2007
+ // These changes will propagate to the other compiler components
2008
+ var knownHelpers = options.knownHelpers;
2009
+ options.knownHelpers = {
2010
+ 'helperMissing': true,
2011
+ 'blockHelperMissing': true,
2012
+ 'each': true,
2013
+ 'if': true,
2014
+ 'unless': true,
2015
+ 'with': true,
2016
+ 'log': true,
2017
+ 'lookup': true
2018
+ };
2019
+ if (knownHelpers) {
2020
+ for (var name in knownHelpers) {
2021
+ options.knownHelpers[name] = knownHelpers[name];
2022
+ }
2023
+ }
2024
+
2025
+ return this.accept(program);
2026
+ },
2027
+
2028
+ compileProgram: function(program) {
2029
+ var result = new this.compiler().compile(program, this.options);
2030
+ var guid = this.guid++;
2031
+
2032
+ this.usePartial = this.usePartial || result.usePartial;
2033
+
2034
+ this.children[guid] = result;
2035
+ this.useDepths = this.useDepths || result.useDepths;
2036
+
2037
+ return guid;
2038
+ },
2039
+
2040
+ accept: function(node) {
2041
+ this.sourceNode.unshift(node);
2042
+ var ret = this[node.type](node);
2043
+ this.sourceNode.shift();
2044
+ return ret;
2045
+ },
2046
+
2047
+ Program: function(program) {
2048
+ this.options.blockParams.unshift(program.blockParams);
2049
+
2050
+ var body = program.body;
2051
+ for(var i=0, l=body.length; i<l; i++) {
2052
+ this.accept(body[i]);
2053
+ }
2054
+
2055
+ this.options.blockParams.shift();
2056
+
2057
+ this.isSimple = l === 1;
2058
+ this.blockParams = program.blockParams ? program.blockParams.length : 0;
2059
+
2060
+ return this;
2061
+ },
2062
+
2063
+ BlockStatement: function(block) {
2064
+ transformLiteralToPath(block);
2065
+
2066
+ var program = block.program,
2067
+ inverse = block.inverse;
2068
+
2069
+ program = program && this.compileProgram(program);
2070
+ inverse = inverse && this.compileProgram(inverse);
2071
+
2072
+ var type = this.classifySexpr(block);
2073
+
2074
+ if (type === 'helper') {
2075
+ this.helperSexpr(block, program, inverse);
2076
+ } else if (type === 'simple') {
2077
+ this.simpleSexpr(block);
2078
+
2079
+ // now that the simple mustache is resolved, we need to
2080
+ // evaluate it by executing `blockHelperMissing`
2081
+ this.opcode('pushProgram', program);
2082
+ this.opcode('pushProgram', inverse);
2083
+ this.opcode('emptyHash');
2084
+ this.opcode('blockValue', block.path.original);
2085
+ } else {
2086
+ this.ambiguousSexpr(block, program, inverse);
2087
+
2088
+ // now that the simple mustache is resolved, we need to
2089
+ // evaluate it by executing `blockHelperMissing`
2090
+ this.opcode('pushProgram', program);
2091
+ this.opcode('pushProgram', inverse);
2092
+ this.opcode('emptyHash');
2093
+ this.opcode('ambiguousBlockValue');
2094
+ }
2095
+
2096
+ this.opcode('append');
2097
+ },
2098
+
2099
+ PartialStatement: function(partial) {
2100
+ this.usePartial = true;
2101
+
2102
+ var params = partial.params;
2103
+ if (params.length > 1) {
2104
+ throw new Exception('Unsupported number of partial arguments: ' + params.length, partial);
2105
+ } else if (!params.length) {
2106
+ params.push({type: 'PathExpression', parts: [], depth: 0});
2107
+ }
2108
+
2109
+ var partialName = partial.name.original,
2110
+ isDynamic = partial.name.type === 'SubExpression';
2111
+ if (isDynamic) {
2112
+ this.accept(partial.name);
2113
+ }
2114
+
2115
+ this.setupFullMustacheParams(partial, undefined, undefined, true);
2116
+
2117
+ var indent = partial.indent || '';
2118
+ if (this.options.preventIndent && indent) {
2119
+ this.opcode('appendContent', indent);
2120
+ indent = '';
2121
+ }
2122
+
2123
+ this.opcode('invokePartial', isDynamic, partialName, indent);
2124
+ this.opcode('append');
2125
+ },
2126
+
2127
+ MustacheStatement: function(mustache) {
2128
+ this.SubExpression(mustache);
2129
+
2130
+ if(mustache.escaped && !this.options.noEscape) {
2131
+ this.opcode('appendEscaped');
2132
+ } else {
2133
+ this.opcode('append');
2134
+ }
2135
+ },
2136
+
2137
+ ContentStatement: function(content) {
2138
+ if (content.value) {
2139
+ this.opcode('appendContent', content.value);
2140
+ }
2141
+ },
2142
+
2143
+ CommentStatement: function() {},
2144
+
2145
+ SubExpression: function(sexpr) {
2146
+ transformLiteralToPath(sexpr);
2147
+ var type = this.classifySexpr(sexpr);
2148
+
2149
+ if (type === 'simple') {
2150
+ this.simpleSexpr(sexpr);
2151
+ } else if (type === 'helper') {
2152
+ this.helperSexpr(sexpr);
2153
+ } else {
2154
+ this.ambiguousSexpr(sexpr);
2155
+ }
2156
+ },
2157
+ ambiguousSexpr: function(sexpr, program, inverse) {
2158
+ var path = sexpr.path,
2159
+ name = path.parts[0],
2160
+ isBlock = program != null || inverse != null;
2161
+
2162
+ this.opcode('getContext', path.depth);
2163
+
2164
+ this.opcode('pushProgram', program);
2165
+ this.opcode('pushProgram', inverse);
2166
+
2167
+ this.accept(path);
2168
+
2169
+ this.opcode('invokeAmbiguous', name, isBlock);
2170
+ },
2171
+
2172
+ simpleSexpr: function(sexpr) {
2173
+ this.accept(sexpr.path);
2174
+ this.opcode('resolvePossibleLambda');
2175
+ },
2176
+
2177
+ helperSexpr: function(sexpr, program, inverse) {
2178
+ var params = this.setupFullMustacheParams(sexpr, program, inverse),
2179
+ path = sexpr.path,
2180
+ name = path.parts[0];
2181
+
2182
+ if (this.options.knownHelpers[name]) {
2183
+ this.opcode('invokeKnownHelper', params.length, name);
2184
+ } else if (this.options.knownHelpersOnly) {
2185
+ throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
2186
+ } else {
2187
+ path.falsy = true;
2188
+
2189
+ this.accept(path);
2190
+ this.opcode('invokeHelper', params.length, path.original, AST.helpers.simpleId(path));
2191
+ }
2192
+ },
2193
+
2194
+ PathExpression: function(path) {
2195
+ this.addDepth(path.depth);
2196
+ this.opcode('getContext', path.depth);
2197
+
2198
+ var name = path.parts[0],
2199
+ scoped = AST.helpers.scopedId(path),
2200
+ blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
2201
+
2202
+ if (blockParamId) {
2203
+ this.opcode('lookupBlockParam', blockParamId, path.parts);
2204
+ } else if (!name) {
2205
+ // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
2206
+ this.opcode('pushContext');
2207
+ } else if (path.data) {
2208
+ this.options.data = true;
2209
+ this.opcode('lookupData', path.depth, path.parts);
2210
+ } else {
2211
+ this.opcode('lookupOnContext', path.parts, path.falsy, scoped);
2212
+ }
2213
+ },
2214
+
2215
+ StringLiteral: function(string) {
2216
+ this.opcode('pushString', string.value);
2217
+ },
2218
+
2219
+ NumberLiteral: function(number) {
2220
+ this.opcode('pushLiteral', number.value);
2221
+ },
2222
+
2223
+ BooleanLiteral: function(bool) {
2224
+ this.opcode('pushLiteral', bool.value);
2225
+ },
2226
+
2227
+ Hash: function(hash) {
2228
+ var pairs = hash.pairs, i, l;
2229
+
2230
+ this.opcode('pushHash');
2231
+
2232
+ for (i=0, l=pairs.length; i<l; i++) {
2233
+ this.pushParam(pairs[i].value);
2234
+ }
2235
+ while (i--) {
2236
+ this.opcode('assignToHash', pairs[i].key);
2237
+ }
2238
+ this.opcode('popHash');
2239
+ },
2240
+
2241
+ // HELPERS
2242
+ opcode: function(name) {
2243
+ this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
2244
+ },
2245
+
2246
+ addDepth: function(depth) {
2247
+ if (!depth) {
2248
+ return;
2249
+ }
2250
+
2251
+ this.useDepths = true;
2252
+ },
2253
+
2254
+ classifySexpr: function(sexpr) {
2255
+ var isSimple = AST.helpers.simpleId(sexpr.path);
2256
+
2257
+ var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
2258
+
2259
+ // a mustache is an eligible helper if:
2260
+ // * its id is simple (a single part, not `this` or `..`)
2261
+ var isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr);
2262
+
2263
+ // if a mustache is an eligible helper but not a definite
2264
+ // helper, it is ambiguous, and will be resolved in a later
2265
+ // pass or at runtime.
2266
+ var isEligible = !isBlockParam && (isHelper || isSimple);
2267
+
2268
+ var options = this.options;
2269
+
2270
+ // if ambiguous, we can possibly resolve the ambiguity now
2271
+ // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
2272
+ if (isEligible && !isHelper) {
2273
+ var name = sexpr.path.parts[0];
2274
+
2275
+ if (options.knownHelpers[name]) {
2276
+ isHelper = true;
2277
+ } else if (options.knownHelpersOnly) {
2278
+ isEligible = false;
2279
+ }
2280
+ }
2281
+
2282
+ if (isHelper) { return 'helper'; }
2283
+ else if (isEligible) { return 'ambiguous'; }
2284
+ else { return 'simple'; }
2285
+ },
2286
+
2287
+ pushParams: function(params) {
2288
+ for(var i=0, l=params.length; i<l; i++) {
2289
+ this.pushParam(params[i]);
2290
+ }
2291
+ },
2292
+
2293
+ pushParam: function(val) {
2294
+ var value = val.value != null ? val.value : val.original || '';
2295
+
2296
+ if (this.stringParams) {
2297
+ if (value.replace) {
2298
+ value = value
2299
+ .replace(/^(\.?\.\/)*/g, '')
2300
+ .replace(/\//g, '.');
2301
+ }
2302
+
2303
+ if(val.depth) {
2304
+ this.addDepth(val.depth);
2305
+ }
2306
+ this.opcode('getContext', val.depth || 0);
2307
+ this.opcode('pushStringParam', value, val.type);
2308
+
2309
+ if (val.type === 'SubExpression') {
2310
+ // SubExpressions get evaluated and passed in
2311
+ // in string params mode.
2312
+ this.accept(val);
2313
+ }
2314
+ } else {
2315
+ if (this.trackIds) {
2316
+ var blockParamIndex;
2317
+ if (val.parts && !AST.helpers.scopedId(val) && !val.depth) {
2318
+ blockParamIndex = this.blockParamIndex(val.parts[0]);
2319
+ }
2320
+ if (blockParamIndex) {
2321
+ var blockParamChild = val.parts.slice(1).join('.');
2322
+ this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
2323
+ } else {
2324
+ value = val.original || value;
2325
+ if (value.replace) {
2326
+ value = value
2327
+ .replace(/^\.\//g, '')
2328
+ .replace(/^\.$/g, '');
2329
+ }
2330
+
2331
+ this.opcode('pushId', val.type, value);
2332
+ }
2333
+ }
2334
+ this.accept(val);
2335
+ }
2336
+ },
2337
+
2338
+ setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) {
2339
+ var params = sexpr.params;
2340
+ this.pushParams(params);
2341
+
2342
+ this.opcode('pushProgram', program);
2343
+ this.opcode('pushProgram', inverse);
2344
+
2345
+ if (sexpr.hash) {
2346
+ this.accept(sexpr.hash);
2347
+ } else {
2348
+ this.opcode('emptyHash', omitEmpty);
2349
+ }
2350
+
2351
+ return params;
2352
+ },
2353
+
2354
+ blockParamIndex: function(name) {
2355
+ for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
2356
+ var blockParams = this.options.blockParams[depth],
2357
+ param = blockParams && indexOf(blockParams, name);
2358
+ if (blockParams && param >= 0) {
2359
+ return [depth, param];
2360
+ }
2361
+ }
2362
+ }
2363
+ };
2364
+
2365
+ function precompile(input, options, env) {
2366
+ if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
2367
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
2368
+ }
2369
+
2370
+ options = options || {};
2371
+ if (!('data' in options)) {
2372
+ options.data = true;
2373
+ }
2374
+ if (options.compat) {
2375
+ options.useDepths = true;
2376
+ }
2377
+
2378
+ var ast = env.parse(input, options);
2379
+ var environment = new env.Compiler().compile(ast, options);
2380
+ return new env.JavaScriptCompiler().compile(environment, options);
2381
+ }
2382
+
2383
+ __exports__.precompile = precompile;function compile(input, options, env) {
2384
+ if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
2385
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2386
+ }
2387
+
2388
+ options = options || {};
2389
+
2390
+ if (!('data' in options)) {
2391
+ options.data = true;
2392
+ }
2393
+ if (options.compat) {
2394
+ options.useDepths = true;
2395
+ }
2396
+
2397
+ var compiled;
2398
+
2399
+ function compileInput() {
2400
+ var ast = env.parse(input, options);
2401
+ var environment = new env.Compiler().compile(ast, options);
2402
+ var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
2403
+ return env.template(templateSpec);
2404
+ }
2405
+
2406
+ // Template is only compiled on first use and cached after that point.
2407
+ var ret = function(context, options) {
2408
+ if (!compiled) {
2409
+ compiled = compileInput();
2410
+ }
2411
+ return compiled.call(this, context, options);
2412
+ };
2413
+ ret._setup = function(options) {
2414
+ if (!compiled) {
2415
+ compiled = compileInput();
2416
+ }
2417
+ return compiled._setup(options);
2418
+ };
2419
+ ret._child = function(i, data, blockParams, depths) {
2420
+ if (!compiled) {
2421
+ compiled = compileInput();
2422
+ }
2423
+ return compiled._child(i, data, blockParams, depths);
2424
+ };
2425
+ return ret;
2426
+ }
2427
+
2428
+ __exports__.compile = compile;function argEquals(a, b) {
2429
+ if (a === b) {
2430
+ return true;
2431
+ }
2432
+
2433
+ if (isArray(a) && isArray(b) && a.length === b.length) {
2434
+ for (var i = 0; i < a.length; i++) {
2435
+ if (!argEquals(a[i], b[i])) {
2436
+ return false;
2437
+ }
2438
+ }
2439
+ return true;
2440
+ }
2441
+ }
2442
+
2443
+ function transformLiteralToPath(sexpr) {
2444
+ if (!sexpr.path.parts) {
2445
+ var literal = sexpr.path;
2446
+ // Casting to string here to make false and 0 literal values play nicely with the rest
2447
+ // of the system.
2448
+ sexpr.path = new AST.PathExpression(false, 0, [literal.original+''], literal.original+'', literal.log);
2449
+ }
2450
+ }
2451
+ return __exports__;
2452
+ })(__module4__, __module3__, __module7__);
2453
+
2454
+ // handlebars/compiler/code-gen.js
2455
+ var __module15__ = (function(__dependency1__) {
2456
+ "use strict";
2457
+ var __exports__;
2458
+ var isArray = __dependency1__.isArray;
2459
+
2460
+ try {
2461
+ var SourceMap = require('source-map'),
2462
+ SourceNode = SourceMap.SourceNode;
2463
+ } catch (err) {
2464
+ /* istanbul ignore next: tested but not covered in istanbul due to dist build */
2465
+ SourceNode = function(line, column, srcFile, chunks) {
2466
+ this.src = '';
2467
+ if (chunks) {
2468
+ this.add(chunks);
2469
+ }
2470
+ };
2471
+ /* istanbul ignore next */
2472
+ SourceNode.prototype = {
2473
+ add: function(chunks) {
2474
+ if (isArray(chunks)) {
2475
+ chunks = chunks.join('');
2476
+ }
2477
+ this.src += chunks;
2478
+ },
2479
+ prepend: function(chunks) {
2480
+ if (isArray(chunks)) {
2481
+ chunks = chunks.join('');
2482
+ }
2483
+ this.src = chunks + this.src;
2484
+ },
2485
+ toStringWithSourceMap: function() {
2486
+ return {code: this.toString()};
2487
+ },
2488
+ toString: function() {
2489
+ return this.src;
2490
+ }
2491
+ };
2492
+ }
2493
+
2494
+
2495
+ function castChunk(chunk, codeGen, loc) {
2496
+ if (isArray(chunk)) {
2497
+ var ret = [];
2498
+
2499
+ for (var i = 0, len = chunk.length; i < len; i++) {
2500
+ ret.push(codeGen.wrap(chunk[i], loc));
2501
+ }
2502
+ return ret;
2503
+ } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
2504
+ // Handle primitives that the SourceNode will throw up on
2505
+ return chunk+'';
2506
+ }
2507
+ return chunk;
2508
+ }
2509
+
2510
+
2511
+ function CodeGen(srcFile) {
2512
+ this.srcFile = srcFile;
2513
+ this.source = [];
2514
+ }
2515
+
2516
+ CodeGen.prototype = {
2517
+ prepend: function(source, loc) {
2518
+ this.source.unshift(this.wrap(source, loc));
2519
+ },
2520
+ push: function(source, loc) {
2521
+ this.source.push(this.wrap(source, loc));
2522
+ },
2523
+
2524
+ merge: function() {
2525
+ var source = this.empty();
2526
+ this.each(function(line) {
2527
+ source.add([' ', line, '\n']);
2528
+ });
2529
+ return source;
2530
+ },
2531
+
2532
+ each: function(iter) {
2533
+ for (var i = 0, len = this.source.length; i < len; i++) {
2534
+ iter(this.source[i]);
2535
+ }
2536
+ },
2537
+
2538
+ empty: function(loc) {
2539
+ loc = loc || this.currentLocation || {start:{}};
2540
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
2541
+ },
2542
+ wrap: function(chunk, loc) {
2543
+ if (chunk instanceof SourceNode) {
2544
+ return chunk;
2545
+ }
2546
+
2547
+ loc = loc || this.currentLocation || {start:{}};
2548
+ chunk = castChunk(chunk, this, loc);
2549
+
2550
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
2551
+ },
2552
+
2553
+ functionCall: function(fn, type, params) {
2554
+ params = this.generateList(params);
2555
+ return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
2556
+ },
2557
+
2558
+ quotedString: function(str) {
2559
+ return '"' + (str + '')
2560
+ .replace(/\\/g, '\\\\')
2561
+ .replace(/"/g, '\\"')
2562
+ .replace(/\n/g, '\\n')
2563
+ .replace(/\r/g, '\\r')
2564
+ .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
2565
+ .replace(/\u2029/g, '\\u2029') + '"';
2566
+ },
2567
+
2568
+ objectLiteral: function(obj) {
2569
+ var pairs = [];
2570
+
2571
+ for (var key in obj) {
2572
+ if (obj.hasOwnProperty(key)) {
2573
+ var value = castChunk(obj[key], this);
2574
+ if (value !== 'undefined') {
2575
+ pairs.push([this.quotedString(key), ':', value]);
2576
+ }
2577
+ }
2578
+ }
2579
+
2580
+ var ret = this.generateList(pairs);
2581
+ ret.prepend('{');
2582
+ ret.add('}');
2583
+ return ret;
2584
+ },
2585
+
2586
+
2587
+ generateList: function(entries, loc) {
2588
+ var ret = this.empty(loc);
2589
+
2590
+ for (var i = 0, len = entries.length; i < len; i++) {
2591
+ if (i) {
2592
+ ret.add(',');
2593
+ }
2594
+
2595
+ ret.add(castChunk(entries[i], this, loc));
2596
+ }
2597
+
2598
+ return ret;
2599
+ },
2600
+
2601
+ generateArray: function(entries, loc) {
2602
+ var ret = this.generateList(entries, loc);
2603
+ ret.prepend('[');
2604
+ ret.add(']');
2605
+
2606
+ return ret;
2607
+ }
2608
+ };
2609
+
2610
+ __exports__ = CodeGen;
2611
+ return __exports__;
2612
+ })(__module3__);
2613
+
2614
+ // handlebars/compiler/javascript-compiler.js
2615
+ var __module14__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
2616
+ "use strict";
2617
+ var __exports__;
2618
+ var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
2619
+ var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
2620
+ var Exception = __dependency2__;
2621
+ var isArray = __dependency3__.isArray;
2622
+ var CodeGen = __dependency4__;
2623
+
2624
+ function Literal(value) {
2625
+ this.value = value;
2626
+ }
2627
+
2628
+ function JavaScriptCompiler() {}
2629
+
2630
+ JavaScriptCompiler.prototype = {
2631
+ // PUBLIC API: You can override these methods in a subclass to provide
2632
+ // alternative compiled forms for name lookup and buffering semantics
2633
+ nameLookup: function(parent, name /* , type*/) {
2634
+ if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
2635
+ return [parent, ".", name];
2636
+ } else {
2637
+ return [parent, "['", name, "']"];
2638
+ }
2639
+ },
2640
+ depthedLookup: function(name) {
2641
+ return [this.aliasable('this.lookup'), '(depths, "', name, '")'];
2642
+ },
2643
+
2644
+ compilerInfo: function() {
2645
+ var revision = COMPILER_REVISION,
2646
+ versions = REVISION_CHANGES[revision];
2647
+ return [revision, versions];
2648
+ },
2649
+
2650
+ appendToBuffer: function(source, location, explicit) {
2651
+ // Force a source as this simplifies the merge logic.
2652
+ if (!isArray(source)) {
2653
+ source = [source];
2654
+ }
2655
+ source = this.source.wrap(source, location);
2656
+
2657
+ if (this.environment.isSimple) {
2658
+ return ['return ', source, ';'];
2659
+ } else if (explicit) {
2660
+ // This is a case where the buffer operation occurs as a child of another
2661
+ // construct, generally braces. We have to explicitly output these buffer
2662
+ // operations to ensure that the emitted code goes in the correct location.
2663
+ return ['buffer += ', source, ';'];
2664
+ } else {
2665
+ source.appendToBuffer = true;
2666
+ return source;
2667
+ }
2668
+ },
2669
+
2670
+ initializeBuffer: function() {
2671
+ return this.quotedString("");
2672
+ },
2673
+ // END PUBLIC API
2674
+
2675
+ compile: function(environment, options, context, asObject) {
2676
+ this.environment = environment;
2677
+ this.options = options;
2678
+ this.stringParams = this.options.stringParams;
2679
+ this.trackIds = this.options.trackIds;
2680
+ this.precompile = !asObject;
2681
+
2682
+ this.name = this.environment.name;
2683
+ this.isChild = !!context;
2684
+ this.context = context || {
2685
+ programs: [],
2686
+ environments: []
2687
+ };
2688
+
2689
+ this.preamble();
2690
+
2691
+ this.stackSlot = 0;
2692
+ this.stackVars = [];
2693
+ this.aliases = {};
2694
+ this.registers = { list: [] };
2695
+ this.hashes = [];
2696
+ this.compileStack = [];
2697
+ this.inlineStack = [];
2698
+ this.blockParams = [];
2699
+
2700
+ this.compileChildren(environment, options);
2701
+
2702
+ this.useDepths = this.useDepths || environment.useDepths || this.options.compat;
2703
+ this.useBlockParams = this.useBlockParams || environment.useBlockParams;
2704
+
2705
+ var opcodes = environment.opcodes,
2706
+ opcode,
2707
+ firstLoc,
2708
+ i,
2709
+ l;
2710
+
2711
+ for (i = 0, l = opcodes.length; i < l; i++) {
2712
+ opcode = opcodes[i];
2713
+
2714
+ this.source.currentLocation = opcode.loc;
2715
+ firstLoc = firstLoc || opcode.loc;
2716
+ this[opcode.opcode].apply(this, opcode.args);
2717
+ }
2718
+
2719
+ // Flush any trailing content that might be pending.
2720
+ this.source.currentLocation = firstLoc;
2721
+ this.pushSource('');
2722
+
2723
+ /* istanbul ignore next */
2724
+ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
2725
+ throw new Exception('Compile completed with content left on stack');
2726
+ }
2727
+
2728
+ var fn = this.createFunctionContext(asObject);
2729
+ if (!this.isChild) {
2730
+ var ret = {
2731
+ compiler: this.compilerInfo(),
2732
+ main: fn
2733
+ };
2734
+ var programs = this.context.programs;
2735
+ for (i = 0, l = programs.length; i < l; i++) {
2736
+ if (programs[i]) {
2737
+ ret[i] = programs[i];
2738
+ }
2739
+ }
2740
+
2741
+ if (this.environment.usePartial) {
2742
+ ret.usePartial = true;
2743
+ }
2744
+ if (this.options.data) {
2745
+ ret.useData = true;
2746
+ }
2747
+ if (this.useDepths) {
2748
+ ret.useDepths = true;
2749
+ }
2750
+ if (this.useBlockParams) {
2751
+ ret.useBlockParams = true;
2752
+ }
2753
+ if (this.options.compat) {
2754
+ ret.compat = true;
2755
+ }
2756
+
2757
+ if (!asObject) {
2758
+ ret.compiler = JSON.stringify(ret.compiler);
2759
+
2760
+ this.source.currentLocation = {start: {line: 1, column: 0}};
2761
+ ret = this.objectLiteral(ret);
2762
+
2763
+ if (options.srcName) {
2764
+ ret = ret.toStringWithSourceMap({file: options.destName});
2765
+ ret.map = ret.map && ret.map.toString();
2766
+ } else {
2767
+ ret = ret.toString();
2768
+ }
2769
+ } else {
2770
+ ret.compilerOptions = this.options;
2771
+ }
2772
+
2773
+ return ret;
2774
+ } else {
2775
+ return fn;
2776
+ }
2777
+ },
2778
+
2779
+ preamble: function() {
2780
+ // track the last context pushed into place to allow skipping the
2781
+ // getContext opcode when it would be a noop
2782
+ this.lastContext = 0;
2783
+ this.source = new CodeGen(this.options.srcName);
2784
+ },
2785
+
2786
+ createFunctionContext: function(asObject) {
2787
+ var varDeclarations = '';
2788
+
2789
+ var locals = this.stackVars.concat(this.registers.list);
2790
+ if(locals.length > 0) {
2791
+ varDeclarations += ", " + locals.join(", ");
2792
+ }
2793
+
2794
+ // Generate minimizer alias mappings
2795
+ //
2796
+ // When using true SourceNodes, this will update all references to the given alias
2797
+ // as the source nodes are reused in situ. For the non-source node compilation mode,
2798
+ // aliases will not be used, but this case is already being run on the client and
2799
+ // we aren't concern about minimizing the template size.
2800
+ var aliasCount = 0;
2801
+ for (var alias in this.aliases) {
2802
+ var node = this.aliases[alias];
2803
+
2804
+ if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
2805
+ varDeclarations += ', alias' + (++aliasCount) + '=' + alias;
2806
+ node.children[0] = 'alias' + aliasCount;
2807
+ }
2808
+ }
2809
+
2810
+ var params = ["depth0", "helpers", "partials", "data"];
2811
+
2812
+ if (this.useBlockParams || this.useDepths) {
2813
+ params.push('blockParams');
2814
+ }
2815
+ if (this.useDepths) {
2816
+ params.push('depths');
2817
+ }
2818
+
2819
+ // Perform a second pass over the output to merge content when possible
2820
+ var source = this.mergeSource(varDeclarations);
2821
+
2822
+ if (asObject) {
2823
+ params.push(source);
2824
+
2825
+ return Function.apply(this, params);
2826
+ } else {
2827
+ return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
2828
+ }
2829
+ },
2830
+ mergeSource: function(varDeclarations) {
2831
+ var isSimple = this.environment.isSimple,
2832
+ appendOnly = !this.forceBuffer,
2833
+ appendFirst,
2834
+
2835
+ sourceSeen,
2836
+ bufferStart,
2837
+ bufferEnd;
2838
+ this.source.each(function(line) {
2839
+ if (line.appendToBuffer) {
2840
+ if (bufferStart) {
2841
+ line.prepend(' + ');
2842
+ } else {
2843
+ bufferStart = line;
2844
+ }
2845
+ bufferEnd = line;
2846
+ } else {
2847
+ if (bufferStart) {
2848
+ if (!sourceSeen) {
2849
+ appendFirst = true;
2850
+ } else {
2851
+ bufferStart.prepend('buffer += ');
2852
+ }
2853
+ bufferEnd.add(';');
2854
+ bufferStart = bufferEnd = undefined;
2855
+ }
2856
+
2857
+ sourceSeen = true;
2858
+ if (!isSimple) {
2859
+ appendOnly = false;
2860
+ }
2861
+ }
2862
+ });
2863
+
2864
+
2865
+ if (appendOnly) {
2866
+ if (bufferStart) {
2867
+ bufferStart.prepend('return ');
2868
+ bufferEnd.add(';');
2869
+ } else if (!sourceSeen) {
2870
+ this.source.push('return "";');
2871
+ }
2872
+ } else {
2873
+ varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());
2874
+
2875
+ if (bufferStart) {
2876
+ bufferStart.prepend('return buffer + ');
2877
+ bufferEnd.add(';');
2878
+ } else {
2879
+ this.source.push('return buffer;');
2880
+ }
2881
+ }
2882
+
2883
+ if (varDeclarations) {
2884
+ this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
2885
+ }
2886
+
2887
+ return this.source.merge();
2888
+ },
2889
+
2890
+ // [blockValue]
2891
+ //
2892
+ // On stack, before: hash, inverse, program, value
2893
+ // On stack, after: return value of blockHelperMissing
2894
+ //
2895
+ // The purpose of this opcode is to take a block of the form
2896
+ // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
2897
+ // replace it on the stack with the result of properly
2898
+ // invoking blockHelperMissing.
2899
+ blockValue: function(name) {
2900
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
2901
+ params = [this.contextName(0)];
2902
+ this.setupHelperArgs(name, 0, params);
2903
+
2904
+ var blockName = this.popStack();
2905
+ params.splice(1, 0, blockName);
2906
+
2907
+ this.push(this.source.functionCall(blockHelperMissing, 'call', params));
2908
+ },
2909
+
2910
+ // [ambiguousBlockValue]
2911
+ //
2912
+ // On stack, before: hash, inverse, program, value
2913
+ // Compiler value, before: lastHelper=value of last found helper, if any
2914
+ // On stack, after, if no lastHelper: same as [blockValue]
2915
+ // On stack, after, if lastHelper: value
2916
+ ambiguousBlockValue: function() {
2917
+ // We're being a bit cheeky and reusing the options value from the prior exec
2918
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
2919
+ params = [this.contextName(0)];
2920
+ this.setupHelperArgs('', 0, params, true);
2921
+
2922
+ this.flushInline();
2923
+
2924
+ var current = this.topStack();
2925
+ params.splice(1, 0, current);
2926
+
2927
+ this.pushSource([
2928
+ 'if (!', this.lastHelper, ') { ',
2929
+ current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params),
2930
+ '}']);
2931
+ },
2932
+
2933
+ // [appendContent]
2934
+ //
2935
+ // On stack, before: ...
2936
+ // On stack, after: ...
2937
+ //
2938
+ // Appends the string value of `content` to the current buffer
2939
+ appendContent: function(content) {
2940
+ if (this.pendingContent) {
2941
+ content = this.pendingContent + content;
2942
+ } else {
2943
+ this.pendingLocation = this.source.currentLocation;
2944
+ }
2945
+
2946
+ this.pendingContent = content;
2947
+ },
2948
+
2949
+ // [append]
2950
+ //
2951
+ // On stack, before: value, ...
2952
+ // On stack, after: ...
2953
+ //
2954
+ // Coerces `value` to a String and appends it to the current buffer.
2955
+ //
2956
+ // If `value` is truthy, or 0, it is coerced into a string and appended
2957
+ // Otherwise, the empty string is appended
2958
+ append: function() {
2959
+ if (this.isInline()) {
2960
+ this.replaceStack(function(current) {
2961
+ return [' != null ? ', current, ' : ""'];
2962
+ });
2963
+
2964
+ this.pushSource(this.appendToBuffer(this.popStack()));
2965
+ } else {
2966
+ var local = this.popStack();
2967
+ this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
2968
+ if (this.environment.isSimple) {
2969
+ this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
2970
+ }
2971
+ }
2972
+ },
2973
+
2974
+ // [appendEscaped]
2975
+ //
2976
+ // On stack, before: value, ...
2977
+ // On stack, after: ...
2978
+ //
2979
+ // Escape `value` and append it to the buffer
2980
+ appendEscaped: function() {
2981
+ this.pushSource(this.appendToBuffer(
2982
+ [this.aliasable('this.escapeExpression'), '(', this.popStack(), ')']));
2983
+ },
2984
+
2985
+ // [getContext]
2986
+ //
2987
+ // On stack, before: ...
2988
+ // On stack, after: ...
2989
+ // Compiler value, after: lastContext=depth
2990
+ //
2991
+ // Set the value of the `lastContext` compiler value to the depth
2992
+ getContext: function(depth) {
2993
+ this.lastContext = depth;
2994
+ },
2995
+
2996
+ // [pushContext]
2997
+ //
2998
+ // On stack, before: ...
2999
+ // On stack, after: currentContext, ...
3000
+ //
3001
+ // Pushes the value of the current context onto the stack.
3002
+ pushContext: function() {
3003
+ this.pushStackLiteral(this.contextName(this.lastContext));
3004
+ },
3005
+
3006
+ // [lookupOnContext]
3007
+ //
3008
+ // On stack, before: ...
3009
+ // On stack, after: currentContext[name], ...
3010
+ //
3011
+ // Looks up the value of `name` on the current context and pushes
3012
+ // it onto the stack.
3013
+ lookupOnContext: function(parts, falsy, scoped) {
3014
+ var i = 0;
3015
+
3016
+ if (!scoped && this.options.compat && !this.lastContext) {
3017
+ // The depthed query is expected to handle the undefined logic for the root level that
3018
+ // is implemented below, so we evaluate that directly in compat mode
3019
+ this.push(this.depthedLookup(parts[i++]));
3020
+ } else {
3021
+ this.pushContext();
3022
+ }
3023
+
3024
+ this.resolvePath('context', parts, i, falsy);
3025
+ },
3026
+
3027
+ // [lookupBlockParam]
3028
+ //
3029
+ // On stack, before: ...
3030
+ // On stack, after: blockParam[name], ...
3031
+ //
3032
+ // Looks up the value of `parts` on the given block param and pushes
3033
+ // it onto the stack.
3034
+ lookupBlockParam: function(blockParamId, parts) {
3035
+ this.useBlockParams = true;
3036
+
3037
+ this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
3038
+ this.resolvePath('context', parts, 1);
3039
+ },
3040
+
3041
+ // [lookupData]
3042
+ //
3043
+ // On stack, before: ...
3044
+ // On stack, after: data, ...
3045
+ //
3046
+ // Push the data lookup operator
3047
+ lookupData: function(depth, parts) {
3048
+ /*jshint -W083 */
3049
+ if (!depth) {
3050
+ this.pushStackLiteral('data');
3051
+ } else {
3052
+ this.pushStackLiteral('this.data(data, ' + depth + ')');
3053
+ }
3054
+
3055
+ this.resolvePath('data', parts, 0, true);
3056
+ },
3057
+
3058
+ resolvePath: function(type, parts, i, falsy) {
3059
+ /*jshint -W083 */
3060
+ if (this.options.strict || this.options.assumeObjects) {
3061
+ this.push(strictLookup(this.options.strict, this, parts, type));
3062
+ return;
3063
+ }
3064
+
3065
+ var len = parts.length;
3066
+ for (; i < len; i++) {
3067
+ this.replaceStack(function(current) {
3068
+ var lookup = this.nameLookup(current, parts[i], type);
3069
+ // We want to ensure that zero and false are handled properly if the context (falsy flag)
3070
+ // needs to have the special handling for these values.
3071
+ if (!falsy) {
3072
+ return [' != null ? ', lookup, ' : ', current];
3073
+ } else {
3074
+ // Otherwise we can use generic falsy handling
3075
+ return [' && ', lookup];
3076
+ }
3077
+ });
3078
+ }
3079
+ },
3080
+
3081
+ // [resolvePossibleLambda]
3082
+ //
3083
+ // On stack, before: value, ...
3084
+ // On stack, after: resolved value, ...
3085
+ //
3086
+ // If the `value` is a lambda, replace it on the stack by
3087
+ // the return value of the lambda
3088
+ resolvePossibleLambda: function() {
3089
+ this.push([this.aliasable('this.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
3090
+ },
3091
+
3092
+ // [pushStringParam]
3093
+ //
3094
+ // On stack, before: ...
3095
+ // On stack, after: string, currentContext, ...
3096
+ //
3097
+ // This opcode is designed for use in string mode, which
3098
+ // provides the string value of a parameter along with its
3099
+ // depth rather than resolving it immediately.
3100
+ pushStringParam: function(string, type) {
3101
+ this.pushContext();
3102
+ this.pushString(type);
3103
+
3104
+ // If it's a subexpression, the string result
3105
+ // will be pushed after this opcode.
3106
+ if (type !== 'SubExpression') {
3107
+ if (typeof string === 'string') {
3108
+ this.pushString(string);
3109
+ } else {
3110
+ this.pushStackLiteral(string);
3111
+ }
3112
+ }
3113
+ },
3114
+
3115
+ emptyHash: function(omitEmpty) {
3116
+ if (this.trackIds) {
3117
+ this.push('{}'); // hashIds
3118
+ }
3119
+ if (this.stringParams) {
3120
+ this.push('{}'); // hashContexts
3121
+ this.push('{}'); // hashTypes
3122
+ }
3123
+ this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
3124
+ },
3125
+ pushHash: function() {
3126
+ if (this.hash) {
3127
+ this.hashes.push(this.hash);
3128
+ }
3129
+ this.hash = {values: [], types: [], contexts: [], ids: []};
3130
+ },
3131
+ popHash: function() {
3132
+ var hash = this.hash;
3133
+ this.hash = this.hashes.pop();
3134
+
3135
+ if (this.trackIds) {
3136
+ this.push(this.objectLiteral(hash.ids));
3137
+ }
3138
+ if (this.stringParams) {
3139
+ this.push(this.objectLiteral(hash.contexts));
3140
+ this.push(this.objectLiteral(hash.types));
3141
+ }
3142
+
3143
+ this.push(this.objectLiteral(hash.values));
3144
+ },
3145
+
3146
+ // [pushString]
3147
+ //
3148
+ // On stack, before: ...
3149
+ // On stack, after: quotedString(string), ...
3150
+ //
3151
+ // Push a quoted version of `string` onto the stack
3152
+ pushString: function(string) {
3153
+ this.pushStackLiteral(this.quotedString(string));
3154
+ },
3155
+
3156
+ // [pushLiteral]
3157
+ //
3158
+ // On stack, before: ...
3159
+ // On stack, after: value, ...
3160
+ //
3161
+ // Pushes a value onto the stack. This operation prevents
3162
+ // the compiler from creating a temporary variable to hold
3163
+ // it.
3164
+ pushLiteral: function(value) {
3165
+ this.pushStackLiteral(value);
3166
+ },
3167
+
3168
+ // [pushProgram]
3169
+ //
3170
+ // On stack, before: ...
3171
+ // On stack, after: program(guid), ...
3172
+ //
3173
+ // Push a program expression onto the stack. This takes
3174
+ // a compile-time guid and converts it into a runtime-accessible
3175
+ // expression.
3176
+ pushProgram: function(guid) {
3177
+ if (guid != null) {
3178
+ this.pushStackLiteral(this.programExpression(guid));
3179
+ } else {
3180
+ this.pushStackLiteral(null);
3181
+ }
3182
+ },
3183
+
3184
+ // [invokeHelper]
3185
+ //
3186
+ // On stack, before: hash, inverse, program, params..., ...
3187
+ // On stack, after: result of helper invocation
3188
+ //
3189
+ // Pops off the helper's parameters, invokes the helper,
3190
+ // and pushes the helper's return value onto the stack.
3191
+ //
3192
+ // If the helper is not found, `helperMissing` is called.
3193
+ invokeHelper: function(paramSize, name, isSimple) {
3194
+ var nonHelper = this.popStack();
3195
+ var helper = this.setupHelper(paramSize, name);
3196
+ var simple = isSimple ? [helper.name, ' || '] : '';
3197
+
3198
+ var lookup = ['('].concat(simple, nonHelper);
3199
+ if (!this.options.strict) {
3200
+ lookup.push(' || ', this.aliasable('helpers.helperMissing'));
3201
+ }
3202
+ lookup.push(')');
3203
+
3204
+ this.push(this.source.functionCall(lookup, 'call', helper.callParams));
3205
+ },
3206
+
3207
+ // [invokeKnownHelper]
3208
+ //
3209
+ // On stack, before: hash, inverse, program, params..., ...
3210
+ // On stack, after: result of helper invocation
3211
+ //
3212
+ // This operation is used when the helper is known to exist,
3213
+ // so a `helperMissing` fallback is not required.
3214
+ invokeKnownHelper: function(paramSize, name) {
3215
+ var helper = this.setupHelper(paramSize, name);
3216
+ this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
3217
+ },
3218
+
3219
+ // [invokeAmbiguous]
3220
+ //
3221
+ // On stack, before: hash, inverse, program, params..., ...
3222
+ // On stack, after: result of disambiguation
3223
+ //
3224
+ // This operation is used when an expression like `{{foo}}`
3225
+ // is provided, but we don't know at compile-time whether it
3226
+ // is a helper or a path.
3227
+ //
3228
+ // This operation emits more code than the other options,
3229
+ // and can be avoided by passing the `knownHelpers` and
3230
+ // `knownHelpersOnly` flags at compile-time.
3231
+ invokeAmbiguous: function(name, helperCall) {
3232
+ this.useRegister('helper');
3233
+
3234
+ var nonHelper = this.popStack();
3235
+
3236
+ this.emptyHash();
3237
+ var helper = this.setupHelper(0, name, helperCall);
3238
+
3239
+ var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
3240
+
3241
+ var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
3242
+ if (!this.options.strict) {
3243
+ lookup[0] = '(helper = ';
3244
+ lookup.push(
3245
+ ' != null ? helper : ',
3246
+ this.aliasable('helpers.helperMissing')
3247
+ );
3248
+ }
3249
+
3250
+ this.push([
3251
+ '(', lookup,
3252
+ (helper.paramsInit ? ['),(', helper.paramsInit] : []), '),',
3253
+ '(typeof helper === ', this.aliasable('"function"'), ' ? ',
3254
+ this.source.functionCall('helper','call', helper.callParams), ' : helper))'
3255
+ ]);
3256
+ },
3257
+
3258
+ // [invokePartial]
3259
+ //
3260
+ // On stack, before: context, ...
3261
+ // On stack after: result of partial invocation
3262
+ //
3263
+ // This operation pops off a context, invokes a partial with that context,
3264
+ // and pushes the result of the invocation back.
3265
+ invokePartial: function(isDynamic, name, indent) {
3266
+ var params = [],
3267
+ options = this.setupParams(name, 1, params, false);
3268
+
3269
+ if (isDynamic) {
3270
+ name = this.popStack();
3271
+ delete options.name;
3272
+ }
3273
+
3274
+ if (indent) {
3275
+ options.indent = JSON.stringify(indent);
3276
+ }
3277
+ options.helpers = 'helpers';
3278
+ options.partials = 'partials';
3279
+
3280
+ if (!isDynamic) {
3281
+ params.unshift(this.nameLookup('partials', name, 'partial'));
3282
+ } else {
3283
+ params.unshift(name);
3284
+ }
3285
+
3286
+ if (this.options.compat) {
3287
+ options.depths = 'depths';
3288
+ }
3289
+ options = this.objectLiteral(options);
3290
+ params.push(options);
3291
+
3292
+ this.push(this.source.functionCall('this.invokePartial', '', params));
3293
+ },
3294
+
3295
+ // [assignToHash]
3296
+ //
3297
+ // On stack, before: value, ..., hash, ...
3298
+ // On stack, after: ..., hash, ...
3299
+ //
3300
+ // Pops a value off the stack and assigns it to the current hash
3301
+ assignToHash: function(key) {
3302
+ var value = this.popStack(),
3303
+ context,
3304
+ type,
3305
+ id;
3306
+
3307
+ if (this.trackIds) {
3308
+ id = this.popStack();
3309
+ }
3310
+ if (this.stringParams) {
3311
+ type = this.popStack();
3312
+ context = this.popStack();
3313
+ }
3314
+
3315
+ var hash = this.hash;
3316
+ if (context) {
3317
+ hash.contexts[key] = context;
3318
+ }
3319
+ if (type) {
3320
+ hash.types[key] = type;
3321
+ }
3322
+ if (id) {
3323
+ hash.ids[key] = id;
3324
+ }
3325
+ hash.values[key] = value;
3326
+ },
3327
+
3328
+ pushId: function(type, name, child) {
3329
+ if (type === 'BlockParam') {
3330
+ this.pushStackLiteral(
3331
+ 'blockParams[' + name[0] + '].path[' + name[1] + ']'
3332
+ + (child ? ' + ' + JSON.stringify('.' + child) : ''));
3333
+ } else if (type === 'PathExpression') {
3334
+ this.pushString(name);
3335
+ } else if (type === 'SubExpression') {
3336
+ this.pushStackLiteral('true');
3337
+ } else {
3338
+ this.pushStackLiteral('null');
3339
+ }
3340
+ },
3341
+
3342
+ // HELPERS
3343
+
3344
+ compiler: JavaScriptCompiler,
3345
+
3346
+ compileChildren: function(environment, options) {
3347
+ var children = environment.children, child, compiler;
3348
+
3349
+ for(var i=0, l=children.length; i<l; i++) {
3350
+ child = children[i];
3351
+ compiler = new this.compiler();
3352
+
3353
+ var index = this.matchExistingProgram(child);
3354
+
3355
+ if (index == null) {
3356
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
3357
+ index = this.context.programs.length;
3358
+ child.index = index;
3359
+ child.name = 'program' + index;
3360
+ this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
3361
+ this.context.environments[index] = child;
3362
+
3363
+ this.useDepths = this.useDepths || compiler.useDepths;
3364
+ this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
3365
+ } else {
3366
+ child.index = index;
3367
+ child.name = 'program' + index;
3368
+
3369
+ this.useDepths = this.useDepths || child.useDepths;
3370
+ this.useBlockParams = this.useBlockParams || child.useBlockParams;
3371
+ }
3372
+ }
3373
+ },
3374
+ matchExistingProgram: function(child) {
3375
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
3376
+ var environment = this.context.environments[i];
3377
+ if (environment && environment.equals(child)) {
3378
+ return i;
3379
+ }
3380
+ }
3381
+ },
3382
+
3383
+ programExpression: function(guid) {
3384
+ var child = this.environment.children[guid],
3385
+ programParams = [child.index, 'data', child.blockParams];
3386
+
3387
+ if (this.useBlockParams || this.useDepths) {
3388
+ programParams.push('blockParams');
3389
+ }
3390
+ if (this.useDepths) {
3391
+ programParams.push('depths');
3392
+ }
3393
+
3394
+ return 'this.program(' + programParams.join(', ') + ')';
3395
+ },
3396
+
3397
+ useRegister: function(name) {
3398
+ if(!this.registers[name]) {
3399
+ this.registers[name] = true;
3400
+ this.registers.list.push(name);
3401
+ }
3402
+ },
3403
+
3404
+ push: function(expr) {
3405
+ if (!(expr instanceof Literal)) {
3406
+ expr = this.source.wrap(expr);
3407
+ }
3408
+
3409
+ this.inlineStack.push(expr);
3410
+ return expr;
3411
+ },
3412
+
3413
+ pushStackLiteral: function(item) {
3414
+ this.push(new Literal(item));
3415
+ },
3416
+
3417
+ pushSource: function(source) {
3418
+ if (this.pendingContent) {
3419
+ this.source.push(
3420
+ this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
3421
+ this.pendingContent = undefined;
3422
+ }
3423
+
3424
+ if (source) {
3425
+ this.source.push(source);
3426
+ }
3427
+ },
3428
+
3429
+ replaceStack: function(callback) {
3430
+ var prefix = ['('],
3431
+ stack,
3432
+ createdStack,
3433
+ usedLiteral;
3434
+
3435
+ /* istanbul ignore next */
3436
+ if (!this.isInline()) {
3437
+ throw new Exception('replaceStack on non-inline');
3438
+ }
3439
+
3440
+ // We want to merge the inline statement into the replacement statement via ','
3441
+ var top = this.popStack(true);
3442
+
3443
+ if (top instanceof Literal) {
3444
+ // Literals do not need to be inlined
3445
+ stack = [top.value];
3446
+ prefix = ['(', stack];
3447
+ usedLiteral = true;
3448
+ } else {
3449
+ // Get or create the current stack name for use by the inline
3450
+ createdStack = true;
3451
+ var name = this.incrStack();
3452
+
3453
+ prefix = ['((', this.push(name), ' = ', top, ')'];
3454
+ stack = this.topStack();
3455
+ }
3456
+
3457
+ var item = callback.call(this, stack);
3458
+
3459
+ if (!usedLiteral) {
3460
+ this.popStack();
3461
+ }
3462
+ if (createdStack) {
3463
+ this.stackSlot--;
3464
+ }
3465
+ this.push(prefix.concat(item, ')'));
3466
+ },
3467
+
3468
+ incrStack: function() {
3469
+ this.stackSlot++;
3470
+ if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
3471
+ return this.topStackName();
3472
+ },
3473
+ topStackName: function() {
3474
+ return "stack" + this.stackSlot;
3475
+ },
3476
+ flushInline: function() {
3477
+ var inlineStack = this.inlineStack;
3478
+ this.inlineStack = [];
3479
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
3480
+ var entry = inlineStack[i];
3481
+ /* istanbul ignore if */
3482
+ if (entry instanceof Literal) {
3483
+ this.compileStack.push(entry);
3484
+ } else {
3485
+ var stack = this.incrStack();
3486
+ this.pushSource([stack, ' = ', entry, ';']);
3487
+ this.compileStack.push(stack);
3488
+ }
3489
+ }
3490
+ },
3491
+ isInline: function() {
3492
+ return this.inlineStack.length;
3493
+ },
3494
+
3495
+ popStack: function(wrapped) {
3496
+ var inline = this.isInline(),
3497
+ item = (inline ? this.inlineStack : this.compileStack).pop();
3498
+
3499
+ if (!wrapped && (item instanceof Literal)) {
3500
+ return item.value;
3501
+ } else {
3502
+ if (!inline) {
3503
+ /* istanbul ignore next */
3504
+ if (!this.stackSlot) {
3505
+ throw new Exception('Invalid stack pop');
3506
+ }
3507
+ this.stackSlot--;
3508
+ }
3509
+ return item;
3510
+ }
3511
+ },
3512
+
3513
+ topStack: function() {
3514
+ var stack = (this.isInline() ? this.inlineStack : this.compileStack),
3515
+ item = stack[stack.length - 1];
3516
+
3517
+ /* istanbul ignore if */
3518
+ if (item instanceof Literal) {
3519
+ return item.value;
3520
+ } else {
3521
+ return item;
3522
+ }
3523
+ },
3524
+
3525
+ contextName: function(context) {
3526
+ if (this.useDepths && context) {
3527
+ return 'depths[' + context + ']';
3528
+ } else {
3529
+ return 'depth' + context;
3530
+ }
3531
+ },
3532
+
3533
+ quotedString: function(str) {
3534
+ return this.source.quotedString(str);
3535
+ },
3536
+
3537
+ objectLiteral: function(obj) {
3538
+ return this.source.objectLiteral(obj);
3539
+ },
3540
+
3541
+ aliasable: function(name) {
3542
+ var ret = this.aliases[name];
3543
+ if (ret) {
3544
+ ret.referenceCount++;
3545
+ return ret;
3546
+ }
3547
+
3548
+ ret = this.aliases[name] = this.source.wrap(name);
3549
+ ret.aliasable = true;
3550
+ ret.referenceCount = 1;
3551
+
3552
+ return ret;
3553
+ },
3554
+
3555
+ setupHelper: function(paramSize, name, blockHelper) {
3556
+ var params = [],
3557
+ paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
3558
+ var foundHelper = this.nameLookup('helpers', name, 'helper');
3559
+
3560
+ return {
3561
+ params: params,
3562
+ paramsInit: paramsInit,
3563
+ name: foundHelper,
3564
+ callParams: [this.contextName(0)].concat(params)
3565
+ };
3566
+ },
3567
+
3568
+ setupParams: function(helper, paramSize, params) {
3569
+ var options = {}, contexts = [], types = [], ids = [], param;
3570
+
3571
+ options.name = this.quotedString(helper);
3572
+ options.hash = this.popStack();
3573
+
3574
+ if (this.trackIds) {
3575
+ options.hashIds = this.popStack();
3576
+ }
3577
+ if (this.stringParams) {
3578
+ options.hashTypes = this.popStack();
3579
+ options.hashContexts = this.popStack();
3580
+ }
3581
+
3582
+ var inverse = this.popStack(),
3583
+ program = this.popStack();
3584
+
3585
+ // Avoid setting fn and inverse if neither are set. This allows
3586
+ // helpers to do a check for `if (options.fn)`
3587
+ if (program || inverse) {
3588
+ options.fn = program || 'this.noop';
3589
+ options.inverse = inverse || 'this.noop';
3590
+ }
3591
+
3592
+ // The parameters go on to the stack in order (making sure that they are evaluated in order)
3593
+ // so we need to pop them off the stack in reverse order
3594
+ var i = paramSize;
3595
+ while (i--) {
3596
+ param = this.popStack();
3597
+ params[i] = param;
3598
+
3599
+ if (this.trackIds) {
3600
+ ids[i] = this.popStack();
3601
+ }
3602
+ if (this.stringParams) {
3603
+ types[i] = this.popStack();
3604
+ contexts[i] = this.popStack();
3605
+ }
3606
+ }
3607
+
3608
+ if (this.trackIds) {
3609
+ options.ids = this.source.generateArray(ids);
3610
+ }
3611
+ if (this.stringParams) {
3612
+ options.types = this.source.generateArray(types);
3613
+ options.contexts = this.source.generateArray(contexts);
3614
+ }
3615
+
3616
+ if (this.options.data) {
3617
+ options.data = 'data';
3618
+ }
3619
+ if (this.useBlockParams) {
3620
+ options.blockParams = 'blockParams';
3621
+ }
3622
+ return options;
3623
+ },
3624
+
3625
+ setupHelperArgs: function(helper, paramSize, params, useRegister) {
3626
+ var options = this.setupParams(helper, paramSize, params, true);
3627
+ options = this.objectLiteral(options);
3628
+ if (useRegister) {
3629
+ this.useRegister('options');
3630
+ params.push('options');
3631
+ return ['options=', options];
3632
+ } else {
3633
+ params.push(options);
3634
+ return '';
3635
+ }
3636
+ }
3637
+ };
3638
+
3639
+
3640
+ var reservedWords = (
3641
+ "break else new var" +
3642
+ " case finally return void" +
3643
+ " catch for switch while" +
3644
+ " continue function this with" +
3645
+ " default if throw" +
3646
+ " delete in try" +
3647
+ " do instanceof typeof" +
3648
+ " abstract enum int short" +
3649
+ " boolean export interface static" +
3650
+ " byte extends long super" +
3651
+ " char final native synchronized" +
3652
+ " class float package throws" +
3653
+ " const goto private transient" +
3654
+ " debugger implements protected volatile" +
3655
+ " double import public let yield await" +
3656
+ " null true false"
3657
+ ).split(" ");
3658
+
3659
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
3660
+
3661
+ for(var i=0, l=reservedWords.length; i<l; i++) {
3662
+ compilerWords[reservedWords[i]] = true;
3663
+ }
3664
+
3665
+ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
3666
+ return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
3667
+ };
3668
+
3669
+ function strictLookup(requireTerminal, compiler, parts, type) {
3670
+ var stack = compiler.popStack();
3671
+
3672
+ var i = 0,
3673
+ len = parts.length;
3674
+ if (requireTerminal) {
3675
+ len--;
3676
+ }
3677
+
3678
+ for (; i < len; i++) {
3679
+ stack = compiler.nameLookup(stack, parts[i], type);
3680
+ }
3681
+
3682
+ if (requireTerminal) {
3683
+ return [compiler.aliasable('this.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
3684
+ } else {
3685
+ return stack;
3686
+ }
3687
+ }
3688
+
3689
+ __exports__ = JavaScriptCompiler;
3690
+ return __exports__;
3691
+ })(__module2__, __module4__, __module3__, __module15__);
3692
+
3693
+ // handlebars.js
3694
+ var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
3695
+ "use strict";
3696
+ var __exports__;
3697
+ /*globals Handlebars: true */
3698
+ var Handlebars = __dependency1__;
3699
+
3700
+ // Compiler imports
3701
+ var AST = __dependency2__;
3702
+ var Parser = __dependency3__.parser;
3703
+ var parse = __dependency3__.parse;
3704
+ var Compiler = __dependency4__.Compiler;
3705
+ var compile = __dependency4__.compile;
3706
+ var precompile = __dependency4__.precompile;
3707
+ var JavaScriptCompiler = __dependency5__;
3708
+
3709
+ var _create = Handlebars.create;
3710
+ var create = function() {
3711
+ var hb = _create();
3712
+
3713
+ hb.compile = function(input, options) {
3714
+ return compile(input, options, hb);
3715
+ };
3716
+ hb.precompile = function (input, options) {
3717
+ return precompile(input, options, hb);
3718
+ };
3719
+
3720
+ hb.AST = AST;
3721
+ hb.Compiler = Compiler;
3722
+ hb.JavaScriptCompiler = JavaScriptCompiler;
3723
+ hb.Parser = Parser;
3724
+ hb.parse = parse;
3725
+
3726
+ return hb;
3727
+ };
3728
+
3729
+ Handlebars = create();
3730
+ Handlebars.create = create;
3731
+
3732
+ /*jshint -W040 */
3733
+ /* istanbul ignore next */
3734
+ var root = typeof global !== 'undefined' ? global : window,
3735
+ $Handlebars = root.Handlebars;
3736
+ /* istanbul ignore next */
3737
+ Handlebars.noConflict = function() {
3738
+ if (root.Handlebars === Handlebars) {
3739
+ root.Handlebars = $Handlebars;
3740
+ }
3741
+ };
3742
+
3743
+ Handlebars['default'] = Handlebars;
3744
+
3745
+ __exports__ = Handlebars;
3746
+ return __exports__;
3747
+ })(__module1__, __module7__, __module8__, __module13__, __module14__);
3748
+
3749
+ return __module0__;
3750
+ }));