ultimate-base 0.3.1.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +15 -15
 - data/app/assets/javascripts/ultimate/backbone/lib/backbone.js +70 -56
 - data/app/assets/javascripts/ultimate/backbone/model.js.coffee +2 -2
 - data/app/assets/javascripts/ultimate/backbone/view.js.coffee +5 -4
 - data/app/assets/javascripts/ultimate/backbone/views/typed-fields.js.coffee +1 -1
 - data/app/assets/javascripts/ultimate/helpers/asset_tag.js.coffee +21 -19
 - data/app/assets/javascripts/ultimate/helpers/form_options.js.coffee +65 -0
 - data/app/assets/javascripts/ultimate/helpers/form_tag.js.coffee +177 -0
 - data/app/assets/javascripts/ultimate/helpers/javascript.js.coffee +31 -0
 - data/app/assets/javascripts/ultimate/helpers/record_tag.js.coffee +29 -15
 - data/app/assets/javascripts/ultimate/helpers/tag.js.coffee +7 -3
 - data/app/assets/javascripts/ultimate/helpers/url.js.coffee +62 -7
 - data/app/assets/javascripts/ultimate/jquery-plugin-adapter.js.coffee +1 -0
 - data/app/assets/javascripts/ultimate/jquery-plugin-class.js.coffee +35 -16
 - data/app/assets/javascripts/ultimate/jquery.base.js.coffee +1 -1
 - data/app/assets/javascripts/ultimate/underscore/underscore.js +292 -192
 - data/app/assets/javascripts/ultimate/underscore/underscore.outcasts.js.coffee +27 -2
 - data/app/assets/javascripts/ultimate/underscore/underscore.string.js +4 -4
 - data/app/assets/stylesheets/polyfills/PIE.htc +81 -81
 - data/app/assets/stylesheets/polyfills/boxsizing.htc +255 -54
 - data/app/assets/stylesheets/ultimate/mixins/_vendors.scss +9 -0
 - data/app/assets/stylesheets/ultimate/mixins/css3.scss +39 -28
 - data/app/assets/stylesheets/ultimate/mixins/microstructures.scss +32 -6
 - data/lib/ultimate/base/version.rb +1 -1
 - data/test/javascripts/tests/helpers/asset_tag_test.js.coffee +1 -1
 - data/test/javascripts/tests/helpers/form_options_test.js.coffee +96 -0
 - data/test/javascripts/tests/helpers/form_tag_test.js.coffee +225 -0
 - data/test/javascripts/tests/helpers/javascript_test.js.coffee +25 -0
 - data/test/javascripts/tests/helpers/record_tag_test.js.coffee +5 -3
 - data/test/javascripts/tests/helpers/tag_test.js.coffee +22 -17
 - data/test/javascripts/tests/helpers/url_test.js.coffee +50 -6
 - data/test/javascripts/tests/underscore/underscore.outcasts.test.js.coffee +9 -0
 - metadata +8 -4
 - data/app/assets/javascripts/ultimate/helpers/translation.js.coffee +0 -97
 - data/test/javascripts/tests/helpers/translation_test.js.coffee +0 -140
 
| 
         @@ -14,6 +14,7 @@ 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            Ultimate.createJQueryPlugin = (pluginName, pluginClass) ->
         
     | 
| 
       16 
16 
     | 
    
         
             
              Ultimate.debug(".createJQueryPlugin()", pluginName, pluginClass)  if _.isFunction(Ultimate.debug)
         
     | 
| 
      
 17 
     | 
    
         
            +
              pluginClass.pluginName ||= pluginName
         
     | 
| 
       17 
18 
     | 
    
         
             
              jQuery.fn[pluginName] = -> @ultimatePluginAdapter pluginName, pluginClass, arguments
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
20 
     | 
    
         | 
| 
         @@ -1,8 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # TODO simlify translations infrastructure
         
     | 
| 
       1 
2 
     | 
    
         
             
            # `pluginClass` must store propery `$el` as jQuery object wrapped on the target DOM-object in his instance.
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            #= require ./base
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
      
 6 
     | 
    
         
            +
            # TODO minimize requirements
         
     | 
| 
      
 7 
     | 
    
         
            +
            # requirements stats:
         
     | 
| 
      
 8 
     | 
    
         
            +
            # 4 _.result
         
     | 
| 
      
 9 
     | 
    
         
            +
            # 3 _.extend
         
     | 
| 
      
 10 
     | 
    
         
            +
            # 2 _.isFunction
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 2 _.isObject
         
     | 
| 
      
 12 
     | 
    
         
            +
            # 1 _.isString
         
     | 
| 
      
 13 
     | 
    
         
            +
            # 1 _.isArray
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 1 _.bind
         
     | 
| 
      
 15 
     | 
    
         
            +
            # 1 _.clone
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 1 _.outcasts.delete
         
     | 
| 
      
 17 
     | 
    
         
            +
            # 1 _.string.underscored
         
     | 
| 
      
 18 
     | 
    
         
            +
            # 1 _.string.startsWith
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       5 
20 
     | 
    
         
             
            class Ultimate.Plugin
         
     | 
| 
      
 21 
     | 
    
         
            +
              el: null
         
     | 
| 
       6 
22 
     | 
    
         
             
              $el: null
         
     | 
| 
       7 
23 
     | 
    
         
             
              nodes: {}
         
     | 
| 
       8 
24 
     | 
    
         
             
              events: {}
         
     | 
| 
         @@ -13,7 +29,8 @@ class Ultimate.Plugin 
     | 
|
| 
       13 
29 
     | 
    
         
             
              translations: {}
         
     | 
| 
       14 
30 
     | 
    
         | 
| 
       15 
31 
     | 
    
         
             
              constructor: (options) ->
         
     | 
| 
       16 
     | 
    
         
            -
                 
     | 
| 
      
 32 
     | 
    
         
            +
                @_configure(options || {});
         
     | 
| 
      
 33 
     | 
    
         
            +
                @$el = $(@el)
         
     | 
| 
       17 
34 
     | 
    
         
             
                @findNodes()
         
     | 
| 
       18 
35 
     | 
    
         
             
                @initialize arguments...
         
     | 
| 
       19 
36 
     | 
    
         
             
                @delegateEvents()
         
     | 
| 
         @@ -30,7 +47,7 @@ class Ultimate.Plugin 
     | 
|
| 
       30 
47 
     | 
    
         | 
| 
       31 
48 
     | 
    
         
             
              findNodes: (jRoot = @$el, nodes = @nodes) ->
         
     | 
| 
       32 
49 
     | 
    
         
             
                jNodes = {}
         
     | 
| 
       33 
     | 
    
         
            -
                nodes = nodes() 
     | 
| 
      
 50 
     | 
    
         
            +
                nodes = if _.isFunction(nodes) then @nodes.call(@) else _.clone(nodes)
         
     | 
| 
       34 
51 
     | 
    
         
             
                if _.isObject(nodes)
         
     | 
| 
       35 
52 
     | 
    
         
             
                  for nodeName, selector of nodes
         
     | 
| 
       36 
53 
     | 
    
         
             
                    _isObject = _.isObject(selector)
         
     | 
| 
         @@ -77,8 +94,9 @@ class Ultimate.Plugin 
     | 
|
| 
       77 
94 
     | 
    
         
             
                  for key, method of events
         
     | 
| 
       78 
95 
     | 
    
         
             
                    [[], eventName, selector] = key.match(delegateEventSplitter)
         
     | 
| 
       79 
96 
     | 
    
         
             
                    selector = _.result(@, selector)
         
     | 
| 
       80 
     | 
    
         
            -
                    selector = selector.selector 
     | 
| 
      
 97 
     | 
    
         
            +
                    selector = selector.selector  if selector instanceof jQuery
         
     | 
| 
       81 
98 
     | 
    
         
             
                    if _.isString(selector)
         
     | 
| 
      
 99 
     | 
    
         
            +
                      selector = selector.replace(@$el.selector, '')  if _.string.startsWith(selector, @$el.selector)
         
     | 
| 
       82 
100 
     | 
    
         
             
                      key = "#{eventName} #{selector}"
         
     | 
| 
       83 
101 
     | 
    
         
             
                    normalizedEvents[key] = method
         
     | 
| 
       84 
102 
     | 
    
         
             
                  events = normalizedEvents
         
     | 
| 
         @@ -89,8 +107,9 @@ class Ultimate.Plugin 
     | 
|
| 
       89 
107 
     | 
    
         
             
                @initTranslations()
         
     | 
| 
       90 
108 
     | 
    
         
             
                @reflectOptions()
         
     | 
| 
       91 
109 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
              reflectOptions: ( 
     | 
| 
       93 
     | 
    
         
            -
                 
     | 
| 
      
 110 
     | 
    
         
            +
              reflectOptions: (reflectableOptions = _.result(@, "reflectableOptions"), options = @options) ->
         
     | 
| 
      
 111 
     | 
    
         
            +
                if _.isArray(reflectableOptions)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  @[attr] = options[attr]  for attr in reflectableOptions  when typeof options[attr] isnt "undefined"
         
     | 
| 
       94 
113 
     | 
    
         
             
                @[attr] = value  for attr, value of options  when typeof @[attr] isnt "undefined"
         
     | 
| 
       95 
114 
     | 
    
         
             
                @
         
     | 
| 
       96 
115 
     | 
    
         | 
| 
         @@ -98,17 +117,17 @@ class Ultimate.Plugin 
     | 
|
| 
       98 
117 
     | 
    
         
             
              # modify and return merged data
         
     | 
| 
       99 
118 
     | 
    
         
             
              initTranslations: (options = @options) ->
         
     | 
| 
       100 
119 
     | 
    
         
             
                # if global compatible I18n
         
     | 
| 
       101 
     | 
    
         
            -
                if I18n? and I18n.locale and I18n.t
         
     | 
| 
       102 
     | 
    
         
            -
                  options["locale"] ||= I18n.locale
         
     | 
| 
       103 
     | 
    
         
            -
                  if options["locale"] is I18n.locale
         
     | 
| 
       104 
     | 
    
         
            -
                    # pointing to defaults locales of language specified in I18n
         
     | 
| 
       105 
     | 
    
         
            -
                    _defaultLocales = @constructor.defaultLocales?[I18n.locale] ||= {}
         
     | 
| 
       106 
     | 
    
         
            -
                    unless _defaultLocales["loaded"]
         
     | 
| 
       107 
     | 
    
         
            -
                      _defaultLocales["loaded"] = true
         
     | 
| 
       108 
     | 
    
         
            -
                      # try read localized strings
         
     | 
| 
       109 
     | 
    
         
            -
                      if _localesFromI18n = I18n.t(options["i18nKey"] or _.underscored(@constructor.pluginName or @constructor.name))
         
     | 
| 
       110 
     | 
    
         
            -
                        # fill it from I18n
         
     | 
| 
       111 
     | 
    
         
            -
                        _.extend _defaultLocales, _localesFromI18n
         
     | 
| 
      
 120 
     | 
    
         
            +
            #    if I18n? and I18n.locale and I18n.t
         
     | 
| 
      
 121 
     | 
    
         
            +
            #      options["locale"] ||= I18n.locale
         
     | 
| 
      
 122 
     | 
    
         
            +
            #      if options["locale"] is I18n.locale
         
     | 
| 
      
 123 
     | 
    
         
            +
            #        # pointing to defaults locales of language specified in I18n
         
     | 
| 
      
 124 
     | 
    
         
            +
            #        _defaultLocales = @constructor.defaultLocales?[I18n.locale] ||= {}
         
     | 
| 
      
 125 
     | 
    
         
            +
            #        unless _defaultLocales["loaded"]
         
     | 
| 
      
 126 
     | 
    
         
            +
            #          _defaultLocales["loaded"] = true
         
     | 
| 
      
 127 
     | 
    
         
            +
            #          # try read localized strings
         
     | 
| 
      
 128 
     | 
    
         
            +
            #          if _localesFromI18n = I18n.t(options["i18nKey"] or _.string.underscored(@constructor.pluginName or @constructor.name))
         
     | 
| 
      
 129 
     | 
    
         
            +
            #            # fill it from I18n
         
     | 
| 
      
 130 
     | 
    
         
            +
            #            _.extend _defaultLocales, _localesFromI18n
         
     | 
| 
       112 
131 
     | 
    
         
             
                @locale = options["locale"]  if options["locale"]
         
     | 
| 
       113 
132 
     | 
    
         
             
                translations = if @locale then @constructor.defaultLocales?[@locale] or {} else {}
         
     | 
| 
       114 
133 
     | 
    
         
             
                $.extend true, options, translations: translations, options
         
     | 
| 
         @@ -1,10 +1,7 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            //     Underscore.js 1. 
     | 
| 
      
 1 
     | 
    
         
            +
            //     Underscore.js 1.4.2
         
     | 
| 
      
 2 
     | 
    
         
            +
            //     http://underscorejs.org
         
     | 
| 
       2 
3 
     | 
    
         
             
            //     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
         
     | 
| 
       3 
4 
     | 
    
         
             
            //     Underscore may be freely distributed under the MIT license.
         
     | 
| 
       4 
     | 
    
         
            -
            //     Portions of Underscore are inspired or borrowed from Prototype,
         
     | 
| 
       5 
     | 
    
         
            -
            //     Oliver Steele's Functional, and John Resig's Micro-Templating.
         
     | 
| 
       6 
     | 
    
         
            -
            //     For all details and documentation:
         
     | 
| 
       7 
     | 
    
         
            -
            //     http://documentcloud.github.com/underscore
         
     | 
| 
       8 
5 
     | 
    
         | 
| 
       9 
6 
     | 
    
         
             
            (function() {
         
     | 
| 
       10 
7 
     | 
    
         | 
| 
         @@ -26,6 +23,7 @@ 
     | 
|
| 
       26 
23 
     | 
    
         
             
              // Create quick reference variables for speed access to core prototypes.
         
     | 
| 
       27 
24 
     | 
    
         
             
              var push             = ArrayProto.push,
         
     | 
| 
       28 
25 
     | 
    
         
             
                  slice            = ArrayProto.slice,
         
     | 
| 
      
 26 
     | 
    
         
            +
                  concat           = ArrayProto.concat,
         
     | 
| 
       29 
27 
     | 
    
         
             
                  unshift          = ArrayProto.unshift,
         
     | 
| 
       30 
28 
     | 
    
         
             
                  toString         = ObjProto.toString,
         
     | 
| 
       31 
29 
     | 
    
         
             
                  hasOwnProperty   = ObjProto.hasOwnProperty;
         
     | 
| 
         @@ -47,7 +45,11 @@ 
     | 
|
| 
       47 
45 
     | 
    
         
             
                nativeBind         = FuncProto.bind;
         
     | 
| 
       48 
46 
     | 
    
         | 
| 
       49 
47 
     | 
    
         
             
              // Create a safe reference to the Underscore object for use below.
         
     | 
| 
       50 
     | 
    
         
            -
              var _ = function(obj) { 
     | 
| 
      
 48 
     | 
    
         
            +
              var _ = function(obj) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                if (obj instanceof _) return obj;
         
     | 
| 
      
 50 
     | 
    
         
            +
                if (!(this instanceof _)) return new _(obj);
         
     | 
| 
      
 51 
     | 
    
         
            +
                this._wrapped = obj;
         
     | 
| 
      
 52 
     | 
    
         
            +
              };
         
     | 
| 
       51 
53 
     | 
    
         | 
| 
       52 
54 
     | 
    
         
             
              // Export the Underscore object for **Node.js**, with
         
     | 
| 
       53 
55 
     | 
    
         
             
              // backwards-compatibility for the old `require()` API. If we're in
         
     | 
| 
         @@ -63,7 +65,7 @@ 
     | 
|
| 
       63 
65 
     | 
    
         
             
              }
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
       65 
67 
     | 
    
         
             
              // Current version.
         
     | 
| 
       66 
     | 
    
         
            -
              _.VERSION = '1. 
     | 
| 
      
 68 
     | 
    
         
            +
              _.VERSION = '1.4.2';
         
     | 
| 
       67 
69 
     | 
    
         | 
| 
       68 
70 
     | 
    
         
             
              // Collection Functions
         
     | 
| 
       69 
71 
     | 
    
         
             
              // --------------------
         
     | 
| 
         @@ -128,11 +130,24 @@ 
     | 
|
| 
       128 
130 
     | 
    
         
             
                if (obj == null) obj = [];
         
     | 
| 
       129 
131 
     | 
    
         
             
                if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
         
     | 
| 
       130 
132 
     | 
    
         
             
                  if (context) iterator = _.bind(iterator, context);
         
     | 
| 
       131 
     | 
    
         
            -
                  return  
     | 
| 
      
 133 
     | 
    
         
            +
                  return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
         
     | 
| 
      
 134 
     | 
    
         
            +
                }
         
     | 
| 
      
 135 
     | 
    
         
            +
                var length = obj.length;
         
     | 
| 
      
 136 
     | 
    
         
            +
                if (length !== +length) {
         
     | 
| 
      
 137 
     | 
    
         
            +
                  var keys = _.keys(obj);
         
     | 
| 
      
 138 
     | 
    
         
            +
                  length = keys.length;
         
     | 
| 
       132 
139 
     | 
    
         
             
                }
         
     | 
| 
       133 
     | 
    
         
            -
                 
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
      
 140 
     | 
    
         
            +
                each(obj, function(value, index, list) {
         
     | 
| 
      
 141 
     | 
    
         
            +
                  index = keys ? keys[--length] : --length;
         
     | 
| 
      
 142 
     | 
    
         
            +
                  if (!initial) {
         
     | 
| 
      
 143 
     | 
    
         
            +
                    memo = obj[index];
         
     | 
| 
      
 144 
     | 
    
         
            +
                    initial = true;
         
     | 
| 
      
 145 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 146 
     | 
    
         
            +
                    memo = iterator.call(context, memo, obj[index], index, list);
         
     | 
| 
      
 147 
     | 
    
         
            +
                  }
         
     | 
| 
      
 148 
     | 
    
         
            +
                });
         
     | 
| 
      
 149 
     | 
    
         
            +
                if (!initial) throw new TypeError('Reduce of empty array with no initial value');
         
     | 
| 
      
 150 
     | 
    
         
            +
                return memo;
         
     | 
| 
       136 
151 
     | 
    
         
             
              };
         
     | 
| 
       137 
152 
     | 
    
         | 
| 
       138 
153 
     | 
    
         
             
              // Return the first value which passes a truth test. Aliased as `detect`.
         
     | 
| 
         @@ -174,6 +189,7 @@ 
     | 
|
| 
       174 
189 
     | 
    
         
             
              // Delegates to **ECMAScript 5**'s native `every` if available.
         
     | 
| 
       175 
190 
     | 
    
         
             
              // Aliased as `all`.
         
     | 
| 
       176 
191 
     | 
    
         
             
              _.every = _.all = function(obj, iterator, context) {
         
     | 
| 
      
 192 
     | 
    
         
            +
                iterator || (iterator = _.identity);
         
     | 
| 
       177 
193 
     | 
    
         
             
                var result = true;
         
     | 
| 
       178 
194 
     | 
    
         
             
                if (obj == null) return result;
         
     | 
| 
       179 
195 
     | 
    
         
             
                if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
         
     | 
| 
         @@ -197,9 +213,9 @@ 
     | 
|
| 
       197 
213 
     | 
    
         
             
                return !!result;
         
     | 
| 
       198 
214 
     | 
    
         
             
              };
         
     | 
| 
       199 
215 
     | 
    
         | 
| 
       200 
     | 
    
         
            -
              // Determine if  
     | 
| 
       201 
     | 
    
         
            -
              // Aliased as ` 
     | 
| 
       202 
     | 
    
         
            -
              _. 
     | 
| 
      
 216 
     | 
    
         
            +
              // Determine if the array or object contains a given value (using `===`).
         
     | 
| 
      
 217 
     | 
    
         
            +
              // Aliased as `include`.
         
     | 
| 
      
 218 
     | 
    
         
            +
              _.contains = _.include = function(obj, target) {
         
     | 
| 
       203 
219 
     | 
    
         
             
                var found = false;
         
     | 
| 
       204 
220 
     | 
    
         
             
                if (obj == null) return found;
         
     | 
| 
       205 
221 
     | 
    
         
             
                if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
         
     | 
| 
         @@ -222,6 +238,18 @@ 
     | 
|
| 
       222 
238 
     | 
    
         
             
                return _.map(obj, function(value){ return value[key]; });
         
     | 
| 
       223 
239 
     | 
    
         
             
              };
         
     | 
| 
       224 
240 
     | 
    
         | 
| 
      
 241 
     | 
    
         
            +
              // Convenience version of a common use case of `filter`: selecting only objects
         
     | 
| 
      
 242 
     | 
    
         
            +
              // with specific `key:value` pairs.
         
     | 
| 
      
 243 
     | 
    
         
            +
              _.where = function(obj, attrs) {
         
     | 
| 
      
 244 
     | 
    
         
            +
                if (_.isEmpty(attrs)) return [];
         
     | 
| 
      
 245 
     | 
    
         
            +
                return _.filter(obj, function(value) {
         
     | 
| 
      
 246 
     | 
    
         
            +
                  for (var key in attrs) {
         
     | 
| 
      
 247 
     | 
    
         
            +
                    if (attrs[key] !== value[key]) return false;
         
     | 
| 
      
 248 
     | 
    
         
            +
                  }
         
     | 
| 
      
 249 
     | 
    
         
            +
                  return true;
         
     | 
| 
      
 250 
     | 
    
         
            +
                });
         
     | 
| 
      
 251 
     | 
    
         
            +
              };
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
       225 
253 
     | 
    
         
             
              // Return the maximum element or (element-based computation).
         
     | 
| 
       226 
254 
     | 
    
         
             
              // Can't optimize arrays of integers longer than 65,535 elements.
         
     | 
| 
       227 
255 
     | 
    
         
             
              // See: https://bugs.webkit.org/show_bug.cgi?id=80797
         
     | 
| 
         @@ -258,40 +286,44 @@ 
     | 
|
| 
       258 
286 
     | 
    
         
             
                var index = 0;
         
     | 
| 
       259 
287 
     | 
    
         
             
                var shuffled = [];
         
     | 
| 
       260 
288 
     | 
    
         
             
                each(obj, function(value) {
         
     | 
| 
       261 
     | 
    
         
            -
                  rand =  
     | 
| 
      
 289 
     | 
    
         
            +
                  rand = _.random(index++);
         
     | 
| 
       262 
290 
     | 
    
         
             
                  shuffled[index - 1] = shuffled[rand];
         
     | 
| 
       263 
291 
     | 
    
         
             
                  shuffled[rand] = value;
         
     | 
| 
       264 
292 
     | 
    
         
             
                });
         
     | 
| 
       265 
293 
     | 
    
         
             
                return shuffled;
         
     | 
| 
       266 
294 
     | 
    
         
             
              };
         
     | 
| 
       267 
295 
     | 
    
         | 
| 
      
 296 
     | 
    
         
            +
              // An internal function to generate lookup iterators.
         
     | 
| 
      
 297 
     | 
    
         
            +
              var lookupIterator = function(value) {
         
     | 
| 
      
 298 
     | 
    
         
            +
                return _.isFunction(value) ? value : function(obj){ return obj[value]; };
         
     | 
| 
      
 299 
     | 
    
         
            +
              };
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
       268 
301 
     | 
    
         
             
              // Sort the object's values by a criterion produced by an iterator.
         
     | 
| 
       269 
     | 
    
         
            -
              _.sortBy = function(obj,  
     | 
| 
       270 
     | 
    
         
            -
                var iterator = lookupIterator( 
     | 
| 
      
 302 
     | 
    
         
            +
              _.sortBy = function(obj, value, context) {
         
     | 
| 
      
 303 
     | 
    
         
            +
                var iterator = lookupIterator(value);
         
     | 
| 
       271 
304 
     | 
    
         
             
                return _.pluck(_.map(obj, function(value, index, list) {
         
     | 
| 
       272 
305 
     | 
    
         
             
                  return {
         
     | 
| 
       273 
306 
     | 
    
         
             
                    value : value,
         
     | 
| 
      
 307 
     | 
    
         
            +
                    index : index,
         
     | 
| 
       274 
308 
     | 
    
         
             
                    criteria : iterator.call(context, value, index, list)
         
     | 
| 
       275 
309 
     | 
    
         
             
                  };
         
     | 
| 
       276 
310 
     | 
    
         
             
                }).sort(function(left, right) {
         
     | 
| 
       277 
     | 
    
         
            -
                  var a = left.criteria 
     | 
| 
       278 
     | 
    
         
            -
                   
     | 
| 
       279 
     | 
    
         
            -
                  if ( 
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
      
 311 
     | 
    
         
            +
                  var a = left.criteria;
         
     | 
| 
      
 312 
     | 
    
         
            +
                  var b = right.criteria;
         
     | 
| 
      
 313 
     | 
    
         
            +
                  if (a !== b) {
         
     | 
| 
      
 314 
     | 
    
         
            +
                    if (a > b || a === void 0) return 1;
         
     | 
| 
      
 315 
     | 
    
         
            +
                    if (a < b || b === void 0) return -1;
         
     | 
| 
      
 316 
     | 
    
         
            +
                  }
         
     | 
| 
      
 317 
     | 
    
         
            +
                  return left.index < right.index ? -1 : 1;
         
     | 
| 
       281 
318 
     | 
    
         
             
                }), 'value');
         
     | 
| 
       282 
319 
     | 
    
         
             
              };
         
     | 
| 
       283 
320 
     | 
    
         | 
| 
       284 
     | 
    
         
            -
              // An internal function to generate lookup iterators.
         
     | 
| 
       285 
     | 
    
         
            -
              var lookupIterator = function(obj, val) {
         
     | 
| 
       286 
     | 
    
         
            -
                return _.isFunction(val) ? val : function(obj) { return obj[val]; };
         
     | 
| 
       287 
     | 
    
         
            -
              };
         
     | 
| 
       288 
     | 
    
         
            -
             
     | 
| 
       289 
321 
     | 
    
         
             
              // An internal function used for aggregate "group by" operations.
         
     | 
| 
       290 
     | 
    
         
            -
              var group = function(obj,  
     | 
| 
      
 322 
     | 
    
         
            +
              var group = function(obj, value, context, behavior) {
         
     | 
| 
       291 
323 
     | 
    
         
             
                var result = {};
         
     | 
| 
       292 
     | 
    
         
            -
                var iterator = lookupIterator( 
     | 
| 
      
 324 
     | 
    
         
            +
                var iterator = lookupIterator(value);
         
     | 
| 
       293 
325 
     | 
    
         
             
                each(obj, function(value, index) {
         
     | 
| 
       294 
     | 
    
         
            -
                  var key = iterator(value, index);
         
     | 
| 
      
 326 
     | 
    
         
            +
                  var key = iterator.call(context, value, index, obj);
         
     | 
| 
       295 
327 
     | 
    
         
             
                  behavior(result, key, value);
         
     | 
| 
       296 
328 
     | 
    
         
             
                });
         
     | 
| 
       297 
329 
     | 
    
         
             
                return result;
         
     | 
| 
         @@ -299,47 +331,46 @@ 
     | 
|
| 
       299 
331 
     | 
    
         | 
| 
       300 
332 
     | 
    
         
             
              // Groups the object's values by a criterion. Pass either a string attribute
         
     | 
| 
       301 
333 
     | 
    
         
             
              // to group by, or a function that returns the criterion.
         
     | 
| 
       302 
     | 
    
         
            -
              _.groupBy = function(obj,  
     | 
| 
       303 
     | 
    
         
            -
                return group(obj,  
     | 
| 
       304 
     | 
    
         
            -
                  (result[key]  
     | 
| 
      
 334 
     | 
    
         
            +
              _.groupBy = function(obj, value, context) {
         
     | 
| 
      
 335 
     | 
    
         
            +
                return group(obj, value, context, function(result, key, value) {
         
     | 
| 
      
 336 
     | 
    
         
            +
                  (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
         
     | 
| 
       305 
337 
     | 
    
         
             
                });
         
     | 
| 
       306 
338 
     | 
    
         
             
              };
         
     | 
| 
       307 
339 
     | 
    
         | 
| 
       308 
340 
     | 
    
         
             
              // Counts instances of an object that group by a certain criterion. Pass
         
     | 
| 
       309 
341 
     | 
    
         
             
              // either a string attribute to count by, or a function that returns the
         
     | 
| 
       310 
342 
     | 
    
         
             
              // criterion.
         
     | 
| 
       311 
     | 
    
         
            -
              _.countBy = function(obj,  
     | 
| 
       312 
     | 
    
         
            -
                return group(obj,  
     | 
| 
       313 
     | 
    
         
            -
                  result 
     | 
| 
      
 343 
     | 
    
         
            +
              _.countBy = function(obj, value, context) {
         
     | 
| 
      
 344 
     | 
    
         
            +
                return group(obj, value, context, function(result, key, value) {
         
     | 
| 
      
 345 
     | 
    
         
            +
                  if (!_.has(result, key)) result[key] = 0;
         
     | 
| 
       314 
346 
     | 
    
         
             
                  result[key]++;
         
     | 
| 
       315 
347 
     | 
    
         
             
                });
         
     | 
| 
       316 
348 
     | 
    
         
             
              };
         
     | 
| 
       317 
349 
     | 
    
         | 
| 
       318 
350 
     | 
    
         
             
              // Use a comparator function to figure out the smallest index at which
         
     | 
| 
       319 
351 
     | 
    
         
             
              // an object should be inserted so as to maintain order. Uses binary search.
         
     | 
| 
       320 
     | 
    
         
            -
              _.sortedIndex = function(array, obj, iterator) {
         
     | 
| 
       321 
     | 
    
         
            -
                iterator  
     | 
| 
       322 
     | 
    
         
            -
                var value = iterator(obj);
         
     | 
| 
      
 352 
     | 
    
         
            +
              _.sortedIndex = function(array, obj, iterator, context) {
         
     | 
| 
      
 353 
     | 
    
         
            +
                iterator = iterator == null ? _.identity : lookupIterator(iterator);
         
     | 
| 
      
 354 
     | 
    
         
            +
                var value = iterator.call(context, obj);
         
     | 
| 
       323 
355 
     | 
    
         
             
                var low = 0, high = array.length;
         
     | 
| 
       324 
356 
     | 
    
         
             
                while (low < high) {
         
     | 
| 
       325 
     | 
    
         
            -
                  var mid = (low + high)  
     | 
| 
       326 
     | 
    
         
            -
                  iterator(array[mid]) < value ? low = mid + 1 : high = mid;
         
     | 
| 
      
 357 
     | 
    
         
            +
                  var mid = (low + high) >>> 1;
         
     | 
| 
      
 358 
     | 
    
         
            +
                  iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
         
     | 
| 
       327 
359 
     | 
    
         
             
                }
         
     | 
| 
       328 
360 
     | 
    
         
             
                return low;
         
     | 
| 
       329 
361 
     | 
    
         
             
              };
         
     | 
| 
       330 
362 
     | 
    
         | 
| 
       331 
363 
     | 
    
         
             
              // Safely convert anything iterable into a real, live array.
         
     | 
| 
       332 
364 
     | 
    
         
             
              _.toArray = function(obj) {
         
     | 
| 
       333 
     | 
    
         
            -
                if (!obj) 
     | 
| 
       334 
     | 
    
         
            -
                if ( 
     | 
| 
       335 
     | 
    
         
            -
                if (_.isArguments(obj))                       return slice.call(obj);
         
     | 
| 
       336 
     | 
    
         
            -
                if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();
         
     | 
| 
      
 365 
     | 
    
         
            +
                if (!obj) return [];
         
     | 
| 
      
 366 
     | 
    
         
            +
                if (obj.length === +obj.length) return slice.call(obj);
         
     | 
| 
       337 
367 
     | 
    
         
             
                return _.values(obj);
         
     | 
| 
       338 
368 
     | 
    
         
             
              };
         
     | 
| 
       339 
369 
     | 
    
         | 
| 
       340 
370 
     | 
    
         
             
              // Return the number of elements in an object.
         
     | 
| 
       341 
371 
     | 
    
         
             
              _.size = function(obj) {
         
     | 
| 
       342 
     | 
    
         
            -
                 
     | 
| 
      
 372 
     | 
    
         
            +
                if (obj == null) return 0;
         
     | 
| 
      
 373 
     | 
    
         
            +
                return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
         
     | 
| 
       343 
374 
     | 
    
         
             
              };
         
     | 
| 
       344 
375 
     | 
    
         | 
| 
       345 
376 
     | 
    
         
             
              // Array Functions
         
     | 
| 
         @@ -349,6 +380,7 @@ 
     | 
|
| 
       349 
380 
     | 
    
         
             
              // values in the array. Aliased as `head` and `take`. The **guard** check
         
     | 
| 
       350 
381 
     | 
    
         
             
              // allows it to work with `_.map`.
         
     | 
| 
       351 
382 
     | 
    
         
             
              _.first = _.head = _.take = function(array, n, guard) {
         
     | 
| 
      
 383 
     | 
    
         
            +
                if (array == null) return void 0;
         
     | 
| 
       352 
384 
     | 
    
         
             
                return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
         
     | 
| 
       353 
385 
     | 
    
         
             
              };
         
     | 
| 
       354 
386 
     | 
    
         | 
| 
         @@ -363,6 +395,7 @@ 
     | 
|
| 
       363 
395 
     | 
    
         
             
              // Get the last element of an array. Passing **n** will return the last N
         
     | 
| 
       364 
396 
     | 
    
         
             
              // values in the array. The **guard** check allows it to work with `_.map`.
         
     | 
| 
       365 
397 
     | 
    
         
             
              _.last = function(array, n, guard) {
         
     | 
| 
      
 398 
     | 
    
         
            +
                if (array == null) return void 0;
         
     | 
| 
       366 
399 
     | 
    
         
             
                if ((n != null) && !guard) {
         
     | 
| 
       367 
400 
     | 
    
         
             
                  return slice.call(array, Math.max(array.length - n, 0));
         
     | 
| 
       368 
401 
     | 
    
         
             
                } else {
         
     | 
| 
         @@ -370,12 +403,12 @@ 
     | 
|
| 
       370 
403 
     | 
    
         
             
                }
         
     | 
| 
       371 
404 
     | 
    
         
             
              };
         
     | 
| 
       372 
405 
     | 
    
         | 
| 
       373 
     | 
    
         
            -
              // Returns everything but the first entry of the array. Aliased as `tail`.
         
     | 
| 
       374 
     | 
    
         
            -
              // Especially useful on the arguments object. Passing an ** 
     | 
| 
       375 
     | 
    
         
            -
              // the rest  
     | 
| 
      
 406 
     | 
    
         
            +
              // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
         
     | 
| 
      
 407 
     | 
    
         
            +
              // Especially useful on the arguments object. Passing an **n** will return
         
     | 
| 
      
 408 
     | 
    
         
            +
              // the rest N values in the array. The **guard**
         
     | 
| 
       376 
409 
     | 
    
         
             
              // check allows it to work with `_.map`.
         
     | 
| 
       377 
     | 
    
         
            -
              _.rest = _.tail = function(array,  
     | 
| 
       378 
     | 
    
         
            -
                return slice.call(array, ( 
     | 
| 
      
 410 
     | 
    
         
            +
              _.rest = _.tail = _.drop = function(array, n, guard) {
         
     | 
| 
      
 411 
     | 
    
         
            +
                return slice.call(array, (n == null) || guard ? 1 : n);
         
     | 
| 
       379 
412 
     | 
    
         
             
              };
         
     | 
| 
       380 
413 
     | 
    
         | 
| 
       381 
414 
     | 
    
         
             
              // Trim out all falsy values from an array.
         
     | 
| 
         @@ -408,23 +441,23 @@ 
     | 
|
| 
       408 
441 
     | 
    
         
             
              // Produce a duplicate-free version of the array. If the array has already
         
     | 
| 
       409 
442 
     | 
    
         
             
              // been sorted, you have the option of using a faster algorithm.
         
     | 
| 
       410 
443 
     | 
    
         
             
              // Aliased as `unique`.
         
     | 
| 
       411 
     | 
    
         
            -
              _.uniq = _.unique = function(array, isSorted, iterator) {
         
     | 
| 
       412 
     | 
    
         
            -
                var initial = iterator ? _.map(array, iterator) : array;
         
     | 
| 
      
 444 
     | 
    
         
            +
              _.uniq = _.unique = function(array, isSorted, iterator, context) {
         
     | 
| 
      
 445 
     | 
    
         
            +
                var initial = iterator ? _.map(array, iterator, context) : array;
         
     | 
| 
       413 
446 
     | 
    
         
             
                var results = [];
         
     | 
| 
       414 
     | 
    
         
            -
                 
     | 
| 
       415 
     | 
    
         
            -
             
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
      
 447 
     | 
    
         
            +
                var seen = [];
         
     | 
| 
      
 448 
     | 
    
         
            +
                each(initial, function(value, index) {
         
     | 
| 
      
 449 
     | 
    
         
            +
                  if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
         
     | 
| 
      
 450 
     | 
    
         
            +
                    seen.push(value);
         
     | 
| 
       417 
451 
     | 
    
         
             
                    results.push(array[index]);
         
     | 
| 
       418 
452 
     | 
    
         
             
                  }
         
     | 
| 
       419 
     | 
    
         
            -
             
     | 
| 
       420 
     | 
    
         
            -
                }, []);
         
     | 
| 
      
 453 
     | 
    
         
            +
                });
         
     | 
| 
       421 
454 
     | 
    
         
             
                return results;
         
     | 
| 
       422 
455 
     | 
    
         
             
              };
         
     | 
| 
       423 
456 
     | 
    
         | 
| 
       424 
457 
     | 
    
         
             
              // Produce an array that contains the union: each distinct element from all of
         
     | 
| 
       425 
458 
     | 
    
         
             
              // the passed-in arrays.
         
     | 
| 
       426 
459 
     | 
    
         
             
              _.union = function() {
         
     | 
| 
       427 
     | 
    
         
            -
                return _.uniq( 
     | 
| 
      
 460 
     | 
    
         
            +
                return _.uniq(concat.apply(ArrayProto, arguments));
         
     | 
| 
       428 
461 
     | 
    
         
             
              };
         
     | 
| 
       429 
462 
     | 
    
         | 
| 
       430 
463 
     | 
    
         
             
              // Produce an array that contains every item shared between all the
         
     | 
| 
         @@ -441,8 +474,8 @@ 
     | 
|
| 
       441 
474 
     | 
    
         
             
              // Take the difference between one array and a number of other arrays.
         
     | 
| 
       442 
475 
     | 
    
         
             
              // Only the elements present in just the first array will remain.
         
     | 
| 
       443 
476 
     | 
    
         
             
              _.difference = function(array) {
         
     | 
| 
       444 
     | 
    
         
            -
                var rest =  
     | 
| 
       445 
     | 
    
         
            -
                return _.filter(array, function(value){ return !_. 
     | 
| 
      
 477 
     | 
    
         
            +
                var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
         
     | 
| 
      
 478 
     | 
    
         
            +
                return _.filter(array, function(value){ return !_.contains(rest, value); });
         
     | 
| 
       446 
479 
     | 
    
         
             
              };
         
     | 
| 
       447 
480 
     | 
    
         | 
| 
       448 
481 
     | 
    
         
             
              // Zip together multiple lists into a single array -- elements that share
         
     | 
| 
         @@ -457,12 +490,18 @@ 
     | 
|
| 
       457 
490 
     | 
    
         
             
                return results;
         
     | 
| 
       458 
491 
     | 
    
         
             
              };
         
     | 
| 
       459 
492 
     | 
    
         | 
| 
       460 
     | 
    
         
            -
              //  
     | 
| 
       461 
     | 
    
         
            -
              //  
     | 
| 
       462 
     | 
    
         
            -
               
     | 
| 
      
 493 
     | 
    
         
            +
              // Converts lists into objects. Pass either a single array of `[key, value]`
         
     | 
| 
      
 494 
     | 
    
         
            +
              // pairs, or two parallel arrays of the same length -- one of keys, and one of
         
     | 
| 
      
 495 
     | 
    
         
            +
              // the corresponding values.
         
     | 
| 
      
 496 
     | 
    
         
            +
              _.object = function(list, values) {
         
     | 
| 
      
 497 
     | 
    
         
            +
                if (list == null) return {};
         
     | 
| 
       463 
498 
     | 
    
         
             
                var result = {};
         
     | 
| 
       464 
     | 
    
         
            -
                for (var i = 0, l =  
     | 
| 
       465 
     | 
    
         
            -
                   
     | 
| 
      
 499 
     | 
    
         
            +
                for (var i = 0, l = list.length; i < l; i++) {
         
     | 
| 
      
 500 
     | 
    
         
            +
                  if (values) {
         
     | 
| 
      
 501 
     | 
    
         
            +
                    result[list[i]] = values[i];
         
     | 
| 
      
 502 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 503 
     | 
    
         
            +
                    result[list[i][0]] = list[i][1];
         
     | 
| 
      
 504 
     | 
    
         
            +
                  }
         
     | 
| 
       466 
505 
     | 
    
         
             
                }
         
     | 
| 
       467 
506 
     | 
    
         
             
                return result;
         
     | 
| 
       468 
507 
     | 
    
         
             
              };
         
     | 
| 
         @@ -475,21 +514,28 @@ 
     | 
|
| 
       475 
514 
     | 
    
         
             
              // for **isSorted** to use binary search.
         
     | 
| 
       476 
515 
     | 
    
         
             
              _.indexOf = function(array, item, isSorted) {
         
     | 
| 
       477 
516 
     | 
    
         
             
                if (array == null) return -1;
         
     | 
| 
       478 
     | 
    
         
            -
                var i, l;
         
     | 
| 
      
 517 
     | 
    
         
            +
                var i = 0, l = array.length;
         
     | 
| 
       479 
518 
     | 
    
         
             
                if (isSorted) {
         
     | 
| 
       480 
     | 
    
         
            -
                   
     | 
| 
       481 
     | 
    
         
            -
             
     | 
| 
      
 519 
     | 
    
         
            +
                  if (typeof isSorted == 'number') {
         
     | 
| 
      
 520 
     | 
    
         
            +
                    i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
         
     | 
| 
      
 521 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 522 
     | 
    
         
            +
                    i = _.sortedIndex(array, item);
         
     | 
| 
      
 523 
     | 
    
         
            +
                    return array[i] === item ? i : -1;
         
     | 
| 
      
 524 
     | 
    
         
            +
                  }
         
     | 
| 
       482 
525 
     | 
    
         
             
                }
         
     | 
| 
       483 
     | 
    
         
            -
                if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
         
     | 
| 
       484 
     | 
    
         
            -
                for ( 
     | 
| 
      
 526 
     | 
    
         
            +
                if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
         
     | 
| 
      
 527 
     | 
    
         
            +
                for (; i < l; i++) if (array[i] === item) return i;
         
     | 
| 
       485 
528 
     | 
    
         
             
                return -1;
         
     | 
| 
       486 
529 
     | 
    
         
             
              };
         
     | 
| 
       487 
530 
     | 
    
         | 
| 
       488 
531 
     | 
    
         
             
              // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
         
     | 
| 
       489 
     | 
    
         
            -
              _.lastIndexOf = function(array, item) {
         
     | 
| 
      
 532 
     | 
    
         
            +
              _.lastIndexOf = function(array, item, from) {
         
     | 
| 
       490 
533 
     | 
    
         
             
                if (array == null) return -1;
         
     | 
| 
       491 
     | 
    
         
            -
                 
     | 
| 
       492 
     | 
    
         
            -
                 
     | 
| 
      
 534 
     | 
    
         
            +
                var hasIndex = from != null;
         
     | 
| 
      
 535 
     | 
    
         
            +
                if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
         
     | 
| 
      
 536 
     | 
    
         
            +
                  return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
         
     | 
| 
      
 537 
     | 
    
         
            +
                }
         
     | 
| 
      
 538 
     | 
    
         
            +
                var i = (hasIndex ? from : array.length);
         
     | 
| 
       493 
539 
     | 
    
         
             
                while (i--) if (array[i] === item) return i;
         
     | 
| 
       494 
540 
     | 
    
         
             
                return -1;
         
     | 
| 
       495 
541 
     | 
    
         
             
              };
         
     | 
| 
         @@ -582,7 +628,9 @@ 
     | 
|
| 
       582 
628 
     | 
    
         
             
                  context = this; args = arguments;
         
     | 
| 
       583 
629 
     | 
    
         
             
                  var later = function() {
         
     | 
| 
       584 
630 
     | 
    
         
             
                    timeout = null;
         
     | 
| 
       585 
     | 
    
         
            -
                    if (more)  
     | 
| 
      
 631 
     | 
    
         
            +
                    if (more) {
         
     | 
| 
      
 632 
     | 
    
         
            +
                      result = func.apply(context, args);
         
     | 
| 
      
 633 
     | 
    
         
            +
                    }
         
     | 
| 
       586 
634 
     | 
    
         
             
                    whenDone();
         
     | 
| 
       587 
635 
     | 
    
         
             
                  };
         
     | 
| 
       588 
636 
     | 
    
         
             
                  if (!timeout) timeout = setTimeout(later, wait);
         
     | 
| 
         @@ -602,17 +650,18 @@ 
     | 
|
| 
       602 
650 
     | 
    
         
             
              // N milliseconds. If `immediate` is passed, trigger the function on the
         
     | 
| 
       603 
651 
     | 
    
         
             
              // leading edge, instead of the trailing.
         
     | 
| 
       604 
652 
     | 
    
         
             
              _.debounce = function(func, wait, immediate) {
         
     | 
| 
       605 
     | 
    
         
            -
                var timeout;
         
     | 
| 
      
 653 
     | 
    
         
            +
                var timeout, result;
         
     | 
| 
       606 
654 
     | 
    
         
             
                return function() {
         
     | 
| 
       607 
655 
     | 
    
         
             
                  var context = this, args = arguments;
         
     | 
| 
       608 
656 
     | 
    
         
             
                  var later = function() {
         
     | 
| 
       609 
657 
     | 
    
         
             
                    timeout = null;
         
     | 
| 
       610 
     | 
    
         
            -
                    if (!immediate) func.apply(context, args);
         
     | 
| 
      
 658 
     | 
    
         
            +
                    if (!immediate) result = func.apply(context, args);
         
     | 
| 
       611 
659 
     | 
    
         
             
                  };
         
     | 
| 
       612 
660 
     | 
    
         
             
                  var callNow = immediate && !timeout;
         
     | 
| 
       613 
661 
     | 
    
         
             
                  clearTimeout(timeout);
         
     | 
| 
       614 
662 
     | 
    
         
             
                  timeout = setTimeout(later, wait);
         
     | 
| 
       615 
     | 
    
         
            -
                  if (callNow) func.apply(context, args);
         
     | 
| 
      
 663 
     | 
    
         
            +
                  if (callNow) result = func.apply(context, args);
         
     | 
| 
      
 664 
     | 
    
         
            +
                  return result;
         
     | 
| 
       616 
665 
     | 
    
         
             
                };
         
     | 
| 
       617 
666 
     | 
    
         
             
              };
         
     | 
| 
       618 
667 
     | 
    
         | 
| 
         @@ -623,7 +672,9 @@ 
     | 
|
| 
       623 
672 
     | 
    
         
             
                return function() {
         
     | 
| 
       624 
673 
     | 
    
         
             
                  if (ran) return memo;
         
     | 
| 
       625 
674 
     | 
    
         
             
                  ran = true;
         
     | 
| 
       626 
     | 
    
         
            -
                   
     | 
| 
      
 675 
     | 
    
         
            +
                  memo = func.apply(this, arguments);
         
     | 
| 
      
 676 
     | 
    
         
            +
                  func = null;
         
     | 
| 
      
 677 
     | 
    
         
            +
                  return memo;
         
     | 
| 
       627 
678 
     | 
    
         
             
                };
         
     | 
| 
       628 
679 
     | 
    
         
             
              };
         
     | 
| 
       629 
680 
     | 
    
         | 
| 
         @@ -632,7 +683,8 @@ 
     | 
|
| 
       632 
683 
     | 
    
         
             
              // conditionally execute the original function.
         
     | 
| 
       633 
684 
     | 
    
         
             
              _.wrap = function(func, wrapper) {
         
     | 
| 
       634 
685 
     | 
    
         
             
                return function() {
         
     | 
| 
       635 
     | 
    
         
            -
                  var args = [func] 
     | 
| 
      
 686 
     | 
    
         
            +
                  var args = [func];
         
     | 
| 
      
 687 
     | 
    
         
            +
                  push.apply(args, arguments);
         
     | 
| 
       636 
688 
     | 
    
         
             
                  return wrapper.apply(this, args);
         
     | 
| 
       637 
689 
     | 
    
         
             
                };
         
     | 
| 
       638 
690 
     | 
    
         
             
              };
         
     | 
| 
         @@ -674,7 +726,23 @@ 
     | 
|
| 
       674 
726 
     | 
    
         | 
| 
       675 
727 
     | 
    
         
             
              // Retrieve the values of an object's properties.
         
     | 
| 
       676 
728 
     | 
    
         
             
              _.values = function(obj) {
         
     | 
| 
       677 
     | 
    
         
            -
                 
     | 
| 
      
 729 
     | 
    
         
            +
                var values = [];
         
     | 
| 
      
 730 
     | 
    
         
            +
                for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
         
     | 
| 
      
 731 
     | 
    
         
            +
                return values;
         
     | 
| 
      
 732 
     | 
    
         
            +
              };
         
     | 
| 
      
 733 
     | 
    
         
            +
             
     | 
| 
      
 734 
     | 
    
         
            +
              // Convert an object into a list of `[key, value]` pairs.
         
     | 
| 
      
 735 
     | 
    
         
            +
              _.pairs = function(obj) {
         
     | 
| 
      
 736 
     | 
    
         
            +
                var pairs = [];
         
     | 
| 
      
 737 
     | 
    
         
            +
                for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
         
     | 
| 
      
 738 
     | 
    
         
            +
                return pairs;
         
     | 
| 
      
 739 
     | 
    
         
            +
              };
         
     | 
| 
      
 740 
     | 
    
         
            +
             
     | 
| 
      
 741 
     | 
    
         
            +
              // Invert the keys and values of an object. The values must be serializable.
         
     | 
| 
      
 742 
     | 
    
         
            +
              _.invert = function(obj) {
         
     | 
| 
      
 743 
     | 
    
         
            +
                var result = {};
         
     | 
| 
      
 744 
     | 
    
         
            +
                for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
         
     | 
| 
      
 745 
     | 
    
         
            +
                return result;
         
     | 
| 
       678 
746 
     | 
    
         
             
              };
         
     | 
| 
       679 
747 
     | 
    
         | 
| 
       680 
748 
     | 
    
         
             
              // Return a sorted list of the function names available on the object.
         
     | 
| 
         @@ -699,11 +767,22 @@ 
     | 
|
| 
       699 
767 
     | 
    
         | 
| 
       700 
768 
     | 
    
         
             
              // Return a copy of the object only containing the whitelisted properties.
         
     | 
| 
       701 
769 
     | 
    
         
             
              _.pick = function(obj) {
         
     | 
| 
       702 
     | 
    
         
            -
                var  
     | 
| 
       703 
     | 
    
         
            -
                 
     | 
| 
       704 
     | 
    
         
            -
             
     | 
| 
      
 770 
     | 
    
         
            +
                var copy = {};
         
     | 
| 
      
 771 
     | 
    
         
            +
                var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
         
     | 
| 
      
 772 
     | 
    
         
            +
                each(keys, function(key) {
         
     | 
| 
      
 773 
     | 
    
         
            +
                  if (key in obj) copy[key] = obj[key];
         
     | 
| 
       705 
774 
     | 
    
         
             
                });
         
     | 
| 
       706 
     | 
    
         
            -
                return  
     | 
| 
      
 775 
     | 
    
         
            +
                return copy;
         
     | 
| 
      
 776 
     | 
    
         
            +
              };
         
     | 
| 
      
 777 
     | 
    
         
            +
             
     | 
| 
      
 778 
     | 
    
         
            +
               // Return a copy of the object without the blacklisted properties.
         
     | 
| 
      
 779 
     | 
    
         
            +
              _.omit = function(obj) {
         
     | 
| 
      
 780 
     | 
    
         
            +
                var copy = {};
         
     | 
| 
      
 781 
     | 
    
         
            +
                var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
         
     | 
| 
      
 782 
     | 
    
         
            +
                for (var key in obj) {
         
     | 
| 
      
 783 
     | 
    
         
            +
                  if (!_.contains(keys, key)) copy[key] = obj[key];
         
     | 
| 
      
 784 
     | 
    
         
            +
                }
         
     | 
| 
      
 785 
     | 
    
         
            +
                return copy;
         
     | 
| 
       707 
786 
     | 
    
         
             
              };
         
     | 
| 
       708 
787 
     | 
    
         | 
| 
       709 
788 
     | 
    
         
             
              // Fill in a given object with default properties.
         
     | 
| 
         @@ -731,18 +810,15 @@ 
     | 
|
| 
       731 
810 
     | 
    
         
             
              };
         
     | 
| 
       732 
811 
     | 
    
         | 
| 
       733 
812 
     | 
    
         
             
              // Internal recursive comparison function for `isEqual`.
         
     | 
| 
       734 
     | 
    
         
            -
              var eq = function(a, b,  
     | 
| 
      
 813 
     | 
    
         
            +
              var eq = function(a, b, aStack, bStack) {
         
     | 
| 
       735 
814 
     | 
    
         
             
                // Identical objects are equal. `0 === -0`, but they aren't identical.
         
     | 
| 
       736 
815 
     | 
    
         
             
                // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
         
     | 
| 
       737 
816 
     | 
    
         
             
                if (a === b) return a !== 0 || 1 / a == 1 / b;
         
     | 
| 
       738 
817 
     | 
    
         
             
                // A strict comparison is necessary because `null == undefined`.
         
     | 
| 
       739 
818 
     | 
    
         
             
                if (a == null || b == null) return a === b;
         
     | 
| 
       740 
819 
     | 
    
         
             
                // Unwrap any wrapped objects.
         
     | 
| 
       741 
     | 
    
         
            -
                if (a 
     | 
| 
       742 
     | 
    
         
            -
                if (b 
     | 
| 
       743 
     | 
    
         
            -
                // Invoke a custom `isEqual` method if one is provided.
         
     | 
| 
       744 
     | 
    
         
            -
                if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
         
     | 
| 
       745 
     | 
    
         
            -
                if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
         
     | 
| 
      
 820 
     | 
    
         
            +
                if (a instanceof _) a = a._wrapped;
         
     | 
| 
      
 821 
     | 
    
         
            +
                if (b instanceof _) b = b._wrapped;
         
     | 
| 
       746 
822 
     | 
    
         
             
                // Compare `[[Class]]` names.
         
     | 
| 
       747 
823 
     | 
    
         
             
                var className = toString.call(a);
         
     | 
| 
       748 
824 
     | 
    
         
             
                if (className != toString.call(b)) return false;
         
     | 
| 
         @@ -772,14 +848,15 @@ 
     | 
|
| 
       772 
848 
     | 
    
         
             
                if (typeof a != 'object' || typeof b != 'object') return false;
         
     | 
| 
       773 
849 
     | 
    
         
             
                // Assume equality for cyclic structures. The algorithm for detecting cyclic
         
     | 
| 
       774 
850 
     | 
    
         
             
                // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
         
     | 
| 
       775 
     | 
    
         
            -
                var length =  
     | 
| 
      
 851 
     | 
    
         
            +
                var length = aStack.length;
         
     | 
| 
       776 
852 
     | 
    
         
             
                while (length--) {
         
     | 
| 
       777 
853 
     | 
    
         
             
                  // Linear search. Performance is inversely proportional to the number of
         
     | 
| 
       778 
854 
     | 
    
         
             
                  // unique nested structures.
         
     | 
| 
       779 
     | 
    
         
            -
                  if ( 
     | 
| 
      
 855 
     | 
    
         
            +
                  if (aStack[length] == a) return bStack[length] == b;
         
     | 
| 
       780 
856 
     | 
    
         
             
                }
         
     | 
| 
       781 
857 
     | 
    
         
             
                // Add the first object to the stack of traversed objects.
         
     | 
| 
       782 
     | 
    
         
            -
                 
     | 
| 
      
 858 
     | 
    
         
            +
                aStack.push(a);
         
     | 
| 
      
 859 
     | 
    
         
            +
                bStack.push(b);
         
     | 
| 
       783 
860 
     | 
    
         
             
                var size = 0, result = true;
         
     | 
| 
       784 
861 
     | 
    
         
             
                // Recursively compare objects and arrays.
         
     | 
| 
       785 
862 
     | 
    
         
             
                if (className == '[object Array]') {
         
     | 
| 
         @@ -789,20 +866,24 @@ 
     | 
|
| 
       789 
866 
     | 
    
         
             
                  if (result) {
         
     | 
| 
       790 
867 
     | 
    
         
             
                    // Deep compare the contents, ignoring non-numeric properties.
         
     | 
| 
       791 
868 
     | 
    
         
             
                    while (size--) {
         
     | 
| 
       792 
     | 
    
         
            -
                       
     | 
| 
       793 
     | 
    
         
            -
                      if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
         
     | 
| 
      
 869 
     | 
    
         
            +
                      if (!(result = eq(a[size], b[size], aStack, bStack))) break;
         
     | 
| 
       794 
870 
     | 
    
         
             
                    }
         
     | 
| 
       795 
871 
     | 
    
         
             
                  }
         
     | 
| 
       796 
872 
     | 
    
         
             
                } else {
         
     | 
| 
       797 
     | 
    
         
            -
                  // Objects with different constructors are not equivalent 
     | 
| 
       798 
     | 
    
         
            -
                   
     | 
| 
      
 873 
     | 
    
         
            +
                  // Objects with different constructors are not equivalent, but `Object`s
         
     | 
| 
      
 874 
     | 
    
         
            +
                  // from different frames are.
         
     | 
| 
      
 875 
     | 
    
         
            +
                  var aCtor = a.constructor, bCtor = b.constructor;
         
     | 
| 
      
 876 
     | 
    
         
            +
                  if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
         
     | 
| 
      
 877 
     | 
    
         
            +
                                           _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
         
     | 
| 
      
 878 
     | 
    
         
            +
                    return false;
         
     | 
| 
      
 879 
     | 
    
         
            +
                  }
         
     | 
| 
       799 
880 
     | 
    
         
             
                  // Deep compare objects.
         
     | 
| 
       800 
881 
     | 
    
         
             
                  for (var key in a) {
         
     | 
| 
       801 
882 
     | 
    
         
             
                    if (_.has(a, key)) {
         
     | 
| 
       802 
883 
     | 
    
         
             
                      // Count the expected number of properties.
         
     | 
| 
       803 
884 
     | 
    
         
             
                      size++;
         
     | 
| 
       804 
885 
     | 
    
         
             
                      // Deep compare each member.
         
     | 
| 
       805 
     | 
    
         
            -
                      if (!(result = _.has(b, key) && eq(a[key], b[key],  
     | 
| 
      
 886 
     | 
    
         
            +
                      if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
         
     | 
| 
       806 
887 
     | 
    
         
             
                    }
         
     | 
| 
       807 
888 
     | 
    
         
             
                  }
         
     | 
| 
       808 
889 
     | 
    
         
             
                  // Ensure that both objects contain the same number of properties.
         
     | 
| 
         @@ -814,13 +895,14 @@ 
     | 
|
| 
       814 
895 
     | 
    
         
             
                  }
         
     | 
| 
       815 
896 
     | 
    
         
             
                }
         
     | 
| 
       816 
897 
     | 
    
         
             
                // Remove the first object from the stack of traversed objects.
         
     | 
| 
       817 
     | 
    
         
            -
                 
     | 
| 
      
 898 
     | 
    
         
            +
                aStack.pop();
         
     | 
| 
      
 899 
     | 
    
         
            +
                bStack.pop();
         
     | 
| 
       818 
900 
     | 
    
         
             
                return result;
         
     | 
| 
       819 
901 
     | 
    
         
             
              };
         
     | 
| 
       820 
902 
     | 
    
         | 
| 
       821 
903 
     | 
    
         
             
              // Perform a deep comparison to check if two objects are equal.
         
     | 
| 
       822 
904 
     | 
    
         
             
              _.isEqual = function(a, b) {
         
     | 
| 
       823 
     | 
    
         
            -
                return eq(a, b, []);
         
     | 
| 
      
 905 
     | 
    
         
            +
                return eq(a, b, [], []);
         
     | 
| 
       824 
906 
     | 
    
         
             
              };
         
     | 
| 
       825 
907 
     | 
    
         | 
| 
       826 
908 
     | 
    
         
             
              // Is a given array, string, or object empty?
         
     | 
| 
         @@ -834,7 +916,7 @@ 
     | 
|
| 
       834 
916 
     | 
    
         | 
| 
       835 
917 
     | 
    
         
             
              // Is a given value a DOM element?
         
     | 
| 
       836 
918 
     | 
    
         
             
              _.isElement = function(obj) {
         
     | 
| 
       837 
     | 
    
         
            -
                return !!(obj && obj.nodeType  
     | 
| 
      
 919 
     | 
    
         
            +
                return !!(obj && obj.nodeType === 1);
         
     | 
| 
       838 
920 
     | 
    
         
             
              };
         
     | 
| 
       839 
921 
     | 
    
         | 
| 
       840 
922 
     | 
    
         
             
              // Is a given value an array?
         
     | 
| 
         @@ -863,15 +945,21 @@ 
     | 
|
| 
       863 
945 
     | 
    
         
             
                };
         
     | 
| 
       864 
946 
     | 
    
         
             
              }
         
     | 
| 
       865 
947 
     | 
    
         | 
| 
      
 948 
     | 
    
         
            +
              // Optimize `isFunction` if appropriate.
         
     | 
| 
      
 949 
     | 
    
         
            +
              if (typeof (/./) !== 'function') {
         
     | 
| 
      
 950 
     | 
    
         
            +
                _.isFunction = function(obj) {
         
     | 
| 
      
 951 
     | 
    
         
            +
                  return typeof obj === 'function';
         
     | 
| 
      
 952 
     | 
    
         
            +
                };
         
     | 
| 
      
 953 
     | 
    
         
            +
              }
         
     | 
| 
      
 954 
     | 
    
         
            +
             
     | 
| 
       866 
955 
     | 
    
         
             
              // Is a given object a finite number?
         
     | 
| 
       867 
956 
     | 
    
         
             
              _.isFinite = function(obj) {
         
     | 
| 
       868 
957 
     | 
    
         
             
                return _.isNumber(obj) && isFinite(obj);
         
     | 
| 
       869 
958 
     | 
    
         
             
              };
         
     | 
| 
       870 
959 
     | 
    
         | 
| 
       871 
     | 
    
         
            -
              // Is the given value `NaN`?
         
     | 
| 
      
 960 
     | 
    
         
            +
              // Is the given value `NaN`? (NaN is the only number which does not equal itself).
         
     | 
| 
       872 
961 
     | 
    
         
             
              _.isNaN = function(obj) {
         
     | 
| 
       873 
     | 
    
         
            -
                 
     | 
| 
       874 
     | 
    
         
            -
                return obj !== obj;
         
     | 
| 
      
 962 
     | 
    
         
            +
                return _.isNumber(obj) && obj != +obj;
         
     | 
| 
       875 
963 
     | 
    
         
             
              };
         
     | 
| 
       876 
964 
     | 
    
         | 
| 
       877 
965 
     | 
    
         
             
              // Is a given value a boolean?
         
     | 
| 
         @@ -915,25 +1003,43 @@ 
     | 
|
| 
       915 
1003 
     | 
    
         
             
                for (var i = 0; i < n; i++) iterator.call(context, i);
         
     | 
| 
       916 
1004 
     | 
    
         
             
              };
         
     | 
| 
       917 
1005 
     | 
    
         | 
| 
      
 1006 
     | 
    
         
            +
              // Return a random integer between min and max (inclusive).
         
     | 
| 
      
 1007 
     | 
    
         
            +
              _.random = function(min, max) {
         
     | 
| 
      
 1008 
     | 
    
         
            +
                if (max == null) {
         
     | 
| 
      
 1009 
     | 
    
         
            +
                  max = min;
         
     | 
| 
      
 1010 
     | 
    
         
            +
                  min = 0;
         
     | 
| 
      
 1011 
     | 
    
         
            +
                }
         
     | 
| 
      
 1012 
     | 
    
         
            +
                return min + (0 | Math.random() * (max - min + 1));
         
     | 
| 
      
 1013 
     | 
    
         
            +
              };
         
     | 
| 
      
 1014 
     | 
    
         
            +
             
     | 
| 
       918 
1015 
     | 
    
         
             
              // List of HTML entities for escaping.
         
     | 
| 
       919 
     | 
    
         
            -
              var  
     | 
| 
       920 
     | 
    
         
            -
                 
     | 
| 
       921 
     | 
    
         
            -
             
     | 
| 
       922 
     | 
    
         
            -
             
     | 
| 
       923 
     | 
    
         
            -
             
     | 
| 
       924 
     | 
    
         
            -
             
     | 
| 
       925 
     | 
    
         
            -
             
     | 
| 
       926 
     | 
    
         
            -
             
     | 
| 
       927 
     | 
    
         
            -
             
     | 
| 
       928 
     | 
    
         
            -
              // Regex containing the keys listed immediately above.
         
     | 
| 
       929 
     | 
    
         
            -
              var htmlEscaper = /[&<>"'\/]/g;
         
     | 
| 
       930 
     | 
    
         
            -
             
     | 
| 
       931 
     | 
    
         
            -
              // Escape a string for HTML interpolation.
         
     | 
| 
       932 
     | 
    
         
            -
              _.escape = function(string) {
         
     | 
| 
       933 
     | 
    
         
            -
                return ('' + string).replace(htmlEscaper, function(match) {
         
     | 
| 
       934 
     | 
    
         
            -
                  return htmlEscapes[match];
         
     | 
| 
       935 
     | 
    
         
            -
                });
         
     | 
| 
      
 1016 
     | 
    
         
            +
              var entityMap = {
         
     | 
| 
      
 1017 
     | 
    
         
            +
                escape: {
         
     | 
| 
      
 1018 
     | 
    
         
            +
                  '&': '&',
         
     | 
| 
      
 1019 
     | 
    
         
            +
                  '<': '<',
         
     | 
| 
      
 1020 
     | 
    
         
            +
                  '>': '>',
         
     | 
| 
      
 1021 
     | 
    
         
            +
                  '"': '"',
         
     | 
| 
      
 1022 
     | 
    
         
            +
                  "'": ''',
         
     | 
| 
      
 1023 
     | 
    
         
            +
                  '/': '/'
         
     | 
| 
      
 1024 
     | 
    
         
            +
                }
         
     | 
| 
       936 
1025 
     | 
    
         
             
              };
         
     | 
| 
      
 1026 
     | 
    
         
            +
              entityMap.unescape = _.invert(entityMap.escape);
         
     | 
| 
      
 1027 
     | 
    
         
            +
             
     | 
| 
      
 1028 
     | 
    
         
            +
              // Regexes containing the keys and values listed immediately above.
         
     | 
| 
      
 1029 
     | 
    
         
            +
              var entityRegexes = {
         
     | 
| 
      
 1030 
     | 
    
         
            +
                escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
         
     | 
| 
      
 1031 
     | 
    
         
            +
                unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
         
     | 
| 
      
 1032 
     | 
    
         
            +
              };
         
     | 
| 
      
 1033 
     | 
    
         
            +
             
     | 
| 
      
 1034 
     | 
    
         
            +
              // Functions for escaping and unescaping strings to/from HTML interpolation.
         
     | 
| 
      
 1035 
     | 
    
         
            +
              _.each(['escape', 'unescape'], function(method) {
         
     | 
| 
      
 1036 
     | 
    
         
            +
                _[method] = function(string) {
         
     | 
| 
      
 1037 
     | 
    
         
            +
                  if (string == null) return '';
         
     | 
| 
      
 1038 
     | 
    
         
            +
                  return ('' + string).replace(entityRegexes[method], function(match) {
         
     | 
| 
      
 1039 
     | 
    
         
            +
                    return entityMap[method][match];
         
     | 
| 
      
 1040 
     | 
    
         
            +
                  });
         
     | 
| 
      
 1041 
     | 
    
         
            +
                };
         
     | 
| 
      
 1042 
     | 
    
         
            +
              });
         
     | 
| 
       937 
1043 
     | 
    
         | 
| 
       938 
1044 
     | 
    
         
             
              // If the value of the named property is a function then invoke it;
         
     | 
| 
       939 
1045 
     | 
    
         
             
              // otherwise, return it.
         
     | 
| 
         @@ -943,11 +1049,15 @@ 
     | 
|
| 
       943 
1049 
     | 
    
         
             
                return _.isFunction(value) ? value.call(object) : value;
         
     | 
| 
       944 
1050 
     | 
    
         
             
              };
         
     | 
| 
       945 
1051 
     | 
    
         | 
| 
       946 
     | 
    
         
            -
              // Add your own custom functions to the Underscore object 
     | 
| 
       947 
     | 
    
         
            -
              // they're correctly added to the OOP wrapper as well.
         
     | 
| 
      
 1052 
     | 
    
         
            +
              // Add your own custom functions to the Underscore object.
         
     | 
| 
       948 
1053 
     | 
    
         
             
              _.mixin = function(obj) {
         
     | 
| 
       949 
1054 
     | 
    
         
             
                each(_.functions(obj), function(name){
         
     | 
| 
       950 
     | 
    
         
            -
                   
     | 
| 
      
 1055 
     | 
    
         
            +
                  var func = _[name] = obj[name];
         
     | 
| 
      
 1056 
     | 
    
         
            +
                  _.prototype[name] = function() {
         
     | 
| 
      
 1057 
     | 
    
         
            +
                    var args = [this._wrapped];
         
     | 
| 
      
 1058 
     | 
    
         
            +
                    push.apply(args, arguments);
         
     | 
| 
      
 1059 
     | 
    
         
            +
                    return result.call(this, func.apply(_, args));
         
     | 
| 
      
 1060 
     | 
    
         
            +
                  };
         
     | 
| 
       951 
1061 
     | 
    
         
             
                });
         
     | 
| 
       952 
1062 
     | 
    
         
             
              };
         
     | 
| 
       953 
1063 
     | 
    
         | 
| 
         @@ -970,63 +1080,63 @@ 
     | 
|
| 
       970 
1080 
     | 
    
         
             
              // When customizing `templateSettings`, if you don't want to define an
         
     | 
| 
       971 
1081 
     | 
    
         
             
              // interpolation, evaluation or escaping regex, we need one that is
         
     | 
| 
       972 
1082 
     | 
    
         
             
              // guaranteed not to match.
         
     | 
| 
       973 
     | 
    
         
            -
              var noMatch =  
     | 
| 
      
 1083 
     | 
    
         
            +
              var noMatch = /(.)^/;
         
     | 
| 
       974 
1084 
     | 
    
         | 
| 
       975 
1085 
     | 
    
         
             
              // Certain characters need to be escaped so that they can be put into a
         
     | 
| 
       976 
1086 
     | 
    
         
             
              // string literal.
         
     | 
| 
       977 
1087 
     | 
    
         
             
              var escapes = {
         
     | 
| 
       978 
     | 
    
         
            -
                ' 
     | 
| 
       979 
     | 
    
         
            -
                 
     | 
| 
       980 
     | 
    
         
            -
                r: 
     | 
| 
       981 
     | 
    
         
            -
                n: 
     | 
| 
       982 
     | 
    
         
            -
                t: 
     | 
| 
       983 
     | 
    
         
            -
                u2028: 
     | 
| 
       984 
     | 
    
         
            -
                u2029: 
     | 
| 
      
 1088 
     | 
    
         
            +
                "'":      "'",
         
     | 
| 
      
 1089 
     | 
    
         
            +
                '\\':     '\\',
         
     | 
| 
      
 1090 
     | 
    
         
            +
                '\r':     'r',
         
     | 
| 
      
 1091 
     | 
    
         
            +
                '\n':     'n',
         
     | 
| 
      
 1092 
     | 
    
         
            +
                '\t':     't',
         
     | 
| 
      
 1093 
     | 
    
         
            +
                '\u2028': 'u2028',
         
     | 
| 
      
 1094 
     | 
    
         
            +
                '\u2029': 'u2029'
         
     | 
| 
       985 
1095 
     | 
    
         
             
              };
         
     | 
| 
       986 
1096 
     | 
    
         | 
| 
       987 
     | 
    
         
            -
              for (var key in escapes) escapes[escapes[key]] = key;
         
     | 
| 
       988 
1097 
     | 
    
         
             
              var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
         
     | 
| 
       989 
     | 
    
         
            -
              var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
         
     | 
| 
       990 
     | 
    
         
            -
             
     | 
| 
       991 
     | 
    
         
            -
              // Within an interpolation, evaluation, or escaping, remove HTML escaping
         
     | 
| 
       992 
     | 
    
         
            -
              // that had been previously added.
         
     | 
| 
       993 
     | 
    
         
            -
              var unescape = function(code) {
         
     | 
| 
       994 
     | 
    
         
            -
                return code.replace(unescaper, function(match, escape) {
         
     | 
| 
       995 
     | 
    
         
            -
                  return escapes[escape];
         
     | 
| 
       996 
     | 
    
         
            -
                });
         
     | 
| 
       997 
     | 
    
         
            -
              };
         
     | 
| 
       998 
1098 
     | 
    
         | 
| 
       999 
1099 
     | 
    
         
             
              // JavaScript micro-templating, similar to John Resig's implementation.
         
     | 
| 
       1000 
1100 
     | 
    
         
             
              // Underscore templating handles arbitrary delimiters, preserves whitespace,
         
     | 
| 
       1001 
1101 
     | 
    
         
             
              // and correctly escapes quotes within interpolated code.
         
     | 
| 
       1002 
1102 
     | 
    
         
             
              _.template = function(text, data, settings) {
         
     | 
| 
       1003 
     | 
    
         
            -
                settings = _.defaults( 
     | 
| 
       1004 
     | 
    
         
            -
             
     | 
| 
       1005 
     | 
    
         
            -
                //  
     | 
| 
       1006 
     | 
    
         
            -
                 
     | 
| 
       1007 
     | 
    
         
            -
             
     | 
| 
       1008 
     | 
    
         
            -
             
     | 
| 
       1009 
     | 
    
         
            -
                  . 
     | 
| 
       1010 
     | 
    
         
            -
             
     | 
| 
       1011 
     | 
    
         
            -
             
     | 
| 
       1012 
     | 
    
         
            -
             
     | 
| 
       1013 
     | 
    
         
            -
             
     | 
| 
       1014 
     | 
    
         
            -
             
     | 
| 
       1015 
     | 
    
         
            -
             
     | 
| 
       1016 
     | 
    
         
            -
             
     | 
| 
       1017 
     | 
    
         
            -
             
     | 
| 
       1018 
     | 
    
         
            -
                   
     | 
| 
       1019 
     | 
    
         
            -
                     
     | 
| 
       1020 
     | 
    
         
            -
             
     | 
| 
      
 1103 
     | 
    
         
            +
                settings = _.defaults({}, settings, _.templateSettings);
         
     | 
| 
      
 1104 
     | 
    
         
            +
             
     | 
| 
      
 1105 
     | 
    
         
            +
                // Combine delimiters into one regular expression via alternation.
         
     | 
| 
      
 1106 
     | 
    
         
            +
                var matcher = new RegExp([
         
     | 
| 
      
 1107 
     | 
    
         
            +
                  (settings.escape || noMatch).source,
         
     | 
| 
      
 1108 
     | 
    
         
            +
                  (settings.interpolate || noMatch).source,
         
     | 
| 
      
 1109 
     | 
    
         
            +
                  (settings.evaluate || noMatch).source
         
     | 
| 
      
 1110 
     | 
    
         
            +
                ].join('|') + '|$', 'g');
         
     | 
| 
      
 1111 
     | 
    
         
            +
             
     | 
| 
      
 1112 
     | 
    
         
            +
                // Compile the template source, escaping string literals appropriately.
         
     | 
| 
      
 1113 
     | 
    
         
            +
                var index = 0;
         
     | 
| 
      
 1114 
     | 
    
         
            +
                var source = "__p+='";
         
     | 
| 
      
 1115 
     | 
    
         
            +
                text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
         
     | 
| 
      
 1116 
     | 
    
         
            +
                  source += text.slice(index, offset)
         
     | 
| 
      
 1117 
     | 
    
         
            +
                    .replace(escaper, function(match) { return '\\' + escapes[match]; });
         
     | 
| 
      
 1118 
     | 
    
         
            +
                  source +=
         
     | 
| 
      
 1119 
     | 
    
         
            +
                    escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
         
     | 
| 
      
 1120 
     | 
    
         
            +
                    interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
         
     | 
| 
      
 1121 
     | 
    
         
            +
                    evaluate ? "';\n" + evaluate + "\n__p+='" : '';
         
     | 
| 
      
 1122 
     | 
    
         
            +
                  index = offset + match.length;
         
     | 
| 
      
 1123 
     | 
    
         
            +
                });
         
     | 
| 
      
 1124 
     | 
    
         
            +
                source += "';\n";
         
     | 
| 
       1021 
1125 
     | 
    
         | 
| 
       1022 
1126 
     | 
    
         
             
                // If a variable is not specified, place data values in local scope.
         
     | 
| 
       1023 
1127 
     | 
    
         
             
                if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
         
     | 
| 
       1024 
1128 
     | 
    
         | 
| 
       1025 
1129 
     | 
    
         
             
                source = "var __t,__p='',__j=Array.prototype.join," +
         
     | 
| 
       1026 
     | 
    
         
            -
                  "print=function(){__p+=__j.call(arguments,'')};\n" +
         
     | 
| 
      
 1130 
     | 
    
         
            +
                  "print=function(){__p+=__j.call(arguments,'');};\n" +
         
     | 
| 
       1027 
1131 
     | 
    
         
             
                  source + "return __p;\n";
         
     | 
| 
       1028 
1132 
     | 
    
         | 
| 
       1029 
     | 
    
         
            -
                 
     | 
| 
      
 1133 
     | 
    
         
            +
                try {
         
     | 
| 
      
 1134 
     | 
    
         
            +
                  var render = new Function(settings.variable || 'obj', '_', source);
         
     | 
| 
      
 1135 
     | 
    
         
            +
                } catch (e) {
         
     | 
| 
      
 1136 
     | 
    
         
            +
                  e.source = source;
         
     | 
| 
      
 1137 
     | 
    
         
            +
                  throw e;
         
     | 
| 
      
 1138 
     | 
    
         
            +
                }
         
     | 
| 
      
 1139 
     | 
    
         
            +
             
     | 
| 
       1030 
1140 
     | 
    
         
             
                if (data) return render(data, _);
         
     | 
| 
       1031 
1141 
     | 
    
         
             
                var template = function(data) {
         
     | 
| 
       1032 
1142 
     | 
    
         
             
                  return render.call(this, data, _);
         
     | 
| 
         @@ -1043,29 +1153,15 @@ 
     | 
|
| 
       1043 
1153 
     | 
    
         
             
                return _(obj).chain();
         
     | 
| 
       1044 
1154 
     | 
    
         
             
              };
         
     | 
| 
       1045 
1155 
     | 
    
         | 
| 
       1046 
     | 
    
         
            -
              //  
     | 
| 
      
 1156 
     | 
    
         
            +
              // OOP
         
     | 
| 
       1047 
1157 
     | 
    
         
             
              // ---------------
         
     | 
| 
       1048 
     | 
    
         
            -
             
     | 
| 
       1049 
1158 
     | 
    
         
             
              // If Underscore is called as a function, it returns a wrapped object that
         
     | 
| 
       1050 
1159 
     | 
    
         
             
              // can be used OO-style. This wrapper holds altered versions of all the
         
     | 
| 
       1051 
1160 
     | 
    
         
             
              // underscore functions. Wrapped objects may be chained.
         
     | 
| 
       1052 
     | 
    
         
            -
              var wrapper = function(obj) { this._wrapped = obj; };
         
     | 
| 
       1053 
     | 
    
         
            -
             
     | 
| 
       1054 
     | 
    
         
            -
              // Expose `wrapper.prototype` as `_.prototype`
         
     | 
| 
       1055 
     | 
    
         
            -
              _.prototype = wrapper.prototype;
         
     | 
| 
       1056 
1161 
     | 
    
         | 
| 
       1057 
1162 
     | 
    
         
             
              // Helper function to continue chaining intermediate results.
         
     | 
| 
       1058 
     | 
    
         
            -
              var result = function(obj 
     | 
| 
       1059 
     | 
    
         
            -
                return  
     | 
| 
       1060 
     | 
    
         
            -
              };
         
     | 
| 
       1061 
     | 
    
         
            -
             
     | 
| 
       1062 
     | 
    
         
            -
              // A method to easily add functions to the OOP wrapper.
         
     | 
| 
       1063 
     | 
    
         
            -
              var addToWrapper = function(name, func) {
         
     | 
| 
       1064 
     | 
    
         
            -
                wrapper.prototype[name] = function() {
         
     | 
| 
       1065 
     | 
    
         
            -
                  var args = slice.call(arguments);
         
     | 
| 
       1066 
     | 
    
         
            -
                  unshift.call(args, this._wrapped);
         
     | 
| 
       1067 
     | 
    
         
            -
                  return result(func.apply(_, args), this._chain);
         
     | 
| 
       1068 
     | 
    
         
            -
                };
         
     | 
| 
      
 1163 
     | 
    
         
            +
              var result = function(obj) {
         
     | 
| 
      
 1164 
     | 
    
         
            +
                return this._chain ? _(obj).chain() : obj;
         
     | 
| 
       1069 
1165 
     | 
    
         
             
              };
         
     | 
| 
       1070 
1166 
     | 
    
         | 
| 
       1071 
1167 
     | 
    
         
             
              // Add all of the Underscore functions to the wrapper object.
         
     | 
| 
         @@ -1074,31 +1170,35 @@ 
     | 
|
| 
       1074 
1170 
     | 
    
         
             
              // Add all mutator Array functions to the wrapper.
         
     | 
| 
       1075 
1171 
     | 
    
         
             
              each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
         
     | 
| 
       1076 
1172 
     | 
    
         
             
                var method = ArrayProto[name];
         
     | 
| 
       1077 
     | 
    
         
            -
                 
     | 
| 
      
 1173 
     | 
    
         
            +
                _.prototype[name] = function() {
         
     | 
| 
       1078 
1174 
     | 
    
         
             
                  var obj = this._wrapped;
         
     | 
| 
       1079 
1175 
     | 
    
         
             
                  method.apply(obj, arguments);
         
     | 
| 
       1080 
1176 
     | 
    
         
             
                  if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
         
     | 
| 
       1081 
     | 
    
         
            -
                  return result( 
     | 
| 
      
 1177 
     | 
    
         
            +
                  return result.call(this, obj);
         
     | 
| 
       1082 
1178 
     | 
    
         
             
                };
         
     | 
| 
       1083 
1179 
     | 
    
         
             
              });
         
     | 
| 
       1084 
1180 
     | 
    
         | 
| 
       1085 
1181 
     | 
    
         
             
              // Add all accessor Array functions to the wrapper.
         
     | 
| 
       1086 
1182 
     | 
    
         
             
              each(['concat', 'join', 'slice'], function(name) {
         
     | 
| 
       1087 
1183 
     | 
    
         
             
                var method = ArrayProto[name];
         
     | 
| 
       1088 
     | 
    
         
            -
                 
     | 
| 
       1089 
     | 
    
         
            -
                  return result(method.apply(this._wrapped, arguments) 
     | 
| 
      
 1184 
     | 
    
         
            +
                _.prototype[name] = function() {
         
     | 
| 
      
 1185 
     | 
    
         
            +
                  return result.call(this, method.apply(this._wrapped, arguments));
         
     | 
| 
       1090 
1186 
     | 
    
         
             
                };
         
     | 
| 
       1091 
1187 
     | 
    
         
             
              });
         
     | 
| 
       1092 
1188 
     | 
    
         | 
| 
       1093 
     | 
    
         
            -
               
     | 
| 
       1094 
     | 
    
         
            -
              wrapper.prototype.chain = function() {
         
     | 
| 
       1095 
     | 
    
         
            -
                this._chain = true;
         
     | 
| 
       1096 
     | 
    
         
            -
                return this;
         
     | 
| 
       1097 
     | 
    
         
            -
              };
         
     | 
| 
      
 1189 
     | 
    
         
            +
              _.extend(_.prototype, {
         
     | 
| 
       1098 
1190 
     | 
    
         | 
| 
       1099 
     | 
    
         
            -
             
     | 
| 
       1100 
     | 
    
         
            -
             
     | 
| 
       1101 
     | 
    
         
            -
             
     | 
| 
       1102 
     | 
    
         
            -
             
     | 
| 
      
 1191 
     | 
    
         
            +
                // Start chaining a wrapped Underscore object.
         
     | 
| 
      
 1192 
     | 
    
         
            +
                chain: function() {
         
     | 
| 
      
 1193 
     | 
    
         
            +
                  this._chain = true;
         
     | 
| 
      
 1194 
     | 
    
         
            +
                  return this;
         
     | 
| 
      
 1195 
     | 
    
         
            +
                },
         
     | 
| 
      
 1196 
     | 
    
         
            +
             
     | 
| 
      
 1197 
     | 
    
         
            +
                // Extracts the result from a wrapped and chained object.
         
     | 
| 
      
 1198 
     | 
    
         
            +
                value: function() {
         
     | 
| 
      
 1199 
     | 
    
         
            +
                  return this._wrapped;
         
     | 
| 
      
 1200 
     | 
    
         
            +
                }
         
     | 
| 
      
 1201 
     | 
    
         
            +
             
     | 
| 
      
 1202 
     | 
    
         
            +
              });
         
     | 
| 
       1103 
1203 
     | 
    
         | 
| 
       1104 
1204 
     | 
    
         
             
            }).call(this);
         
     |