smashing 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of smashing might be problematic. Click here for more details.

Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +10 -0
  3. data/bin/smashing +9 -0
  4. data/javascripts/batman.jquery.js +163 -0
  5. data/javascripts/batman.js +13680 -0
  6. data/javascripts/dashing.coffee +130 -0
  7. data/javascripts/es5-shim.js +1021 -0
  8. data/javascripts/jquery.js +4 -0
  9. data/lib/dashing.rb +6 -0
  10. data/lib/dashing/app.rb +181 -0
  11. data/lib/dashing/cli.rb +109 -0
  12. data/lib/dashing/downloader.rb +18 -0
  13. data/templates/dashboard/%name%.erb.tt +7 -0
  14. data/templates/job/%name%.rb +4 -0
  15. data/templates/project/.gitignore +2 -0
  16. data/templates/project/Gemfile +6 -0
  17. data/templates/project/README.md +1 -0
  18. data/templates/project/assets/fonts/FontAwesome.otf +0 -0
  19. data/templates/project/assets/fonts/fontawesome-webfont.eot +0 -0
  20. data/templates/project/assets/fonts/fontawesome-webfont.svg +655 -0
  21. data/templates/project/assets/fonts/fontawesome-webfont.ttf +0 -0
  22. data/templates/project/assets/fonts/fontawesome-webfont.woff +0 -0
  23. data/templates/project/assets/fonts/fontawesome-webfont.woff2 +0 -0
  24. data/templates/project/assets/images/logo.png +0 -0
  25. data/templates/project/assets/javascripts/application.coffee +25 -0
  26. data/templates/project/assets/javascripts/d3-3.2.8.js +5 -0
  27. data/templates/project/assets/javascripts/dashing.gridster.coffee +37 -0
  28. data/templates/project/assets/javascripts/gridster/jquery.gridster.min.js +2 -0
  29. data/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js +5 -0
  30. data/templates/project/assets/javascripts/jquery.knob.js +646 -0
  31. data/templates/project/assets/javascripts/rickshaw-1.4.3.min.js +2 -0
  32. data/templates/project/assets/stylesheets/application.scss +258 -0
  33. data/templates/project/assets/stylesheets/font-awesome.css +2086 -0
  34. data/templates/project/assets/stylesheets/jquery.gridster.min.css +2 -0
  35. data/templates/project/config.ru +18 -0
  36. data/templates/project/dashboards/layout.erb +32 -0
  37. data/templates/project/dashboards/sample.erb +25 -0
  38. data/templates/project/dashboards/sampletv.erb +56 -0
  39. data/templates/project/jobs/buzzwords.rb +9 -0
  40. data/templates/project/jobs/convergence.rb +14 -0
  41. data/templates/project/jobs/sample.rb +13 -0
  42. data/templates/project/jobs/twitter.rb +28 -0
  43. data/templates/project/lib/.empty_directory +1 -0
  44. data/templates/project/public/404.html +26 -0
  45. data/templates/project/public/favicon.ico +0 -0
  46. data/templates/project/widgets/clock/clock.coffee +18 -0
  47. data/templates/project/widgets/clock/clock.html +2 -0
  48. data/templates/project/widgets/clock/clock.scss +13 -0
  49. data/templates/project/widgets/comments/comments.coffee +24 -0
  50. data/templates/project/widgets/comments/comments.html +7 -0
  51. data/templates/project/widgets/comments/comments.scss +33 -0
  52. data/templates/project/widgets/graph/graph.coffee +37 -0
  53. data/templates/project/widgets/graph/graph.html +5 -0
  54. data/templates/project/widgets/graph/graph.scss +65 -0
  55. data/templates/project/widgets/iframe/iframe.coffee +9 -0
  56. data/templates/project/widgets/iframe/iframe.html +1 -0
  57. data/templates/project/widgets/iframe/iframe.scss +8 -0
  58. data/templates/project/widgets/image/image.coffee +9 -0
  59. data/templates/project/widgets/image/image.html +1 -0
  60. data/templates/project/widgets/image/image.scss +13 -0
  61. data/templates/project/widgets/list/list.coffee +6 -0
  62. data/templates/project/widgets/list/list.html +18 -0
  63. data/templates/project/widgets/list/list.scss +60 -0
  64. data/templates/project/widgets/meter/meter.coffee +14 -0
  65. data/templates/project/widgets/meter/meter.html +7 -0
  66. data/templates/project/widgets/meter/meter.scss +35 -0
  67. data/templates/project/widgets/number/number.coffee +24 -0
  68. data/templates/project/widgets/number/number.html +11 -0
  69. data/templates/project/widgets/number/number.scss +39 -0
  70. data/templates/project/widgets/text/text.coffee +1 -0
  71. data/templates/project/widgets/text/text.html +7 -0
  72. data/templates/project/widgets/text/text.scss +32 -0
  73. data/templates/widget/%name%/%name%.coffee.tt +9 -0
  74. data/templates/widget/%name%/%name%.html +1 -0
  75. data/templates/widget/%name%/%name%.scss.tt +3 -0
  76. metadata +347 -0
@@ -0,0 +1,130 @@
1
+ #= require jquery
2
+ #= require es5-shim
3
+ #= require batman
4
+ #= require batman.jquery
5
+
6
+
7
+ Batman.Filters.prettyNumber = (num) ->
8
+ num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") unless isNaN(num)
9
+
10
+ Batman.Filters.dashize = (str) ->
11
+ dashes_rx1 = /([A-Z]+)([A-Z][a-z])/g;
12
+ dashes_rx2 = /([a-z\d])([A-Z])/g;
13
+
14
+ return str.replace(dashes_rx1, '$1_$2').replace(dashes_rx2, '$1_$2').replace(/_/g, '-').toLowerCase()
15
+
16
+ Batman.Filters.shortenedNumber = (num) ->
17
+ return num if isNaN(num)
18
+ if num >= 1000000000
19
+ (num / 1000000000).toFixed(1) + 'B'
20
+ else if num >= 1000000
21
+ (num / 1000000).toFixed(1) + 'M'
22
+ else if num >= 1000
23
+ (num / 1000).toFixed(1) + 'K'
24
+ else
25
+ num
26
+
27
+ class window.Dashing extends Batman.App
28
+ @on 'reload', (data) ->
29
+ window.location.reload(true)
30
+
31
+ @root ->
32
+ Dashing.params = Batman.URI.paramsFromQuery(window.location.search.slice(1));
33
+
34
+ class Dashing.Widget extends Batman.View
35
+ constructor: ->
36
+ # Set the view path
37
+ @constructor::source = Batman.Filters.underscore(@constructor.name)
38
+ super
39
+
40
+ @mixin($(@node).data())
41
+ Dashing.widgets[@id] ||= []
42
+ Dashing.widgets[@id].push(@)
43
+
44
+ type = Batman.Filters.dashize(@view)
45
+ $(@node).addClass("widget widget-#{type} #{@id}")
46
+
47
+ @accessor 'updatedAtMessage', ->
48
+ if updatedAt = @get('updatedAt')
49
+ timestamp = new Date(updatedAt * 1000)
50
+ hours = timestamp.getHours()
51
+ minutes = ("0" + timestamp.getMinutes()).slice(-2)
52
+ "Last updated at #{hours}:#{minutes}"
53
+
54
+ @::on 'ready', ->
55
+ Dashing.Widget.fire 'ready'
56
+
57
+ # In case the events from the server came before the widget was rendered
58
+ lastData = Dashing.lastEvents[@id]
59
+ if lastData
60
+ @mixin(lastData)
61
+ @onData(lastData)
62
+
63
+ receiveData: (data) =>
64
+ @mixin(data)
65
+ @onData(data)
66
+
67
+ onData: (data) =>
68
+ # Widgets override this to handle incoming data
69
+
70
+ Dashing.AnimatedValue =
71
+ get: Batman.Property.defaultAccessor.get
72
+ set: (k, to) ->
73
+ if !to? || isNaN(to)
74
+ @[k] = to
75
+ else
76
+ timer = "interval_#{k}"
77
+ num = if (!isNaN(@[k]) && @[k]?) then @[k] else 0
78
+ unless @[timer] || num == to
79
+ to = parseFloat(to)
80
+ num = parseFloat(num)
81
+ up = to > num
82
+ num_interval = Math.abs(num - to) / 90
83
+ @[timer] =
84
+ setInterval =>
85
+ num = if up then Math.ceil(num+num_interval) else Math.floor(num-num_interval)
86
+ if (up && num > to) || (!up && num < to)
87
+ num = to
88
+ clearInterval(@[timer])
89
+ @[timer] = null
90
+ delete @[timer]
91
+ @[k] = num
92
+ @set k, to
93
+ , 10
94
+ @[k] = num
95
+
96
+ Dashing.widgets = widgets = {}
97
+ Dashing.lastEvents = lastEvents = {}
98
+ Dashing.debugMode = false
99
+
100
+ source = new EventSource('events')
101
+ source.addEventListener 'open', (e) ->
102
+ console.log("Connection opened", e)
103
+
104
+ source.addEventListener 'error', (e)->
105
+ console.log("Connection error", e)
106
+ if (e.currentTarget.readyState == EventSource.CLOSED)
107
+ console.log("Connection closed")
108
+ setTimeout (->
109
+ window.location.reload()
110
+ ), 5*60*1000
111
+
112
+ source.addEventListener 'message', (e) ->
113
+ data = JSON.parse(e.data)
114
+ if lastEvents[data.id]?.updatedAt != data.updatedAt
115
+ if Dashing.debugMode
116
+ console.log("Received data for #{data.id}", data)
117
+ lastEvents[data.id] = data
118
+ if widgets[data.id]?.length > 0
119
+ for widget in widgets[data.id]
120
+ widget.receiveData(data)
121
+
122
+ source.addEventListener 'dashboards', (e) ->
123
+ data = JSON.parse(e.data)
124
+ if Dashing.debugMode
125
+ console.log("Received data for dashboards", data)
126
+ if data.dashboard is '*' or window.location.pathname is "/#{data.dashboard}"
127
+ Dashing.fire data.event, data
128
+
129
+ $(document).ready ->
130
+ Dashing.run()
@@ -0,0 +1,1021 @@
1
+ // vim: ts=4 sts=4 sw=4 expandtab
2
+ // -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License
3
+ // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
4
+ // -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA
5
+ // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
6
+ // -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License
7
+ // -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License
8
+ // -- kossnocorp Sasha Koss XXX TODO License or CLA
9
+ // -- bryanforbes Bryan Forbes XXX TODO License or CLA
10
+ // -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence
11
+ // -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License
12
+ // -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License
13
+ // -- bbqsrc Brendan Molloy XXX TODO License or CLA
14
+ // -- iwyg XXX TODO License or CLA
15
+ // -- DomenicDenicola Domenic Denicola XXX TODO License or CLA
16
+ // -- xavierm02 Montillet Xavier XXX TODO License or CLA
17
+ // -- Raynos Raynos XXX TODO License or CLA
18
+ // -- samsonjs Sami Samhuri XXX TODO License or CLA
19
+ // -- rwldrn Rick Waldron Copyright (C) 2011 MIT License
20
+ // -- lexer Alexey Zakharov XXX TODO License or CLA
21
+
22
+ /*!
23
+ Copyright (c) 2009, 280 North Inc. http://280north.com/
24
+ MIT License. http://github.com/280north/narwhal/blob/master/README.md
25
+ */
26
+
27
+ // Module systems magic dance
28
+ (function (definition) {
29
+ // RequireJS
30
+ if (typeof define == "function") {
31
+ define(definition);
32
+ // CommonJS and <script>
33
+ } else {
34
+ definition();
35
+ }
36
+ })(function () {
37
+
38
+ /**
39
+ * Brings an environment as close to ECMAScript 5 compliance
40
+ * as is possible with the facilities of erstwhile engines.
41
+ *
42
+ * ES5 Draft
43
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-050.pdf
44
+ *
45
+ * NOTE: this is a draft, and as such, the URL is subject to change. If the
46
+ * link is broken, check in the parent directory for the latest TC39 PDF.
47
+ * http://www.ecma-international.org/publications/files/drafts/
48
+ *
49
+ * Previous ES5 Draft
50
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
51
+ * This is a broken link to the previous draft of ES5 on which most of the
52
+ * numbered specification references and quotes herein were taken. Updating
53
+ * these references and quotes to reflect the new document would be a welcome
54
+ * volunteer project.
55
+ *
56
+ * @module
57
+ */
58
+
59
+ /*whatsupdoc*/
60
+
61
+ //
62
+ // Function
63
+ // ========
64
+ //
65
+
66
+ // ES-5 15.3.4.5
67
+ // http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
68
+
69
+ if (!Function.prototype.bind) {
70
+ Function.prototype.bind = function bind(that) { // .length is 1
71
+ // 1. Let Target be the this value.
72
+ var target = this;
73
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
74
+ if (typeof target != "function")
75
+ throw new TypeError(); // TODO message
76
+ // 3. Let A be a new (possibly empty) internal list of all of the
77
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
78
+ // XXX slicedArgs will stand in for "A" if used
79
+ var args = slice.call(arguments, 1); // for normal call
80
+ // 4. Let F be a new native ECMAScript object.
81
+ // 9. Set the [[Prototype]] internal property of F to the standard
82
+ // built-in Function prototype object as specified in 15.3.3.1.
83
+ // 10. Set the [[Call]] internal property of F as described in
84
+ // 15.3.4.5.1.
85
+ // 11. Set the [[Construct]] internal property of F as described in
86
+ // 15.3.4.5.2.
87
+ // 12. Set the [[HasInstance]] internal property of F as described in
88
+ // 15.3.4.5.3.
89
+ // 13. The [[Scope]] internal property of F is unused and need not
90
+ // exist.
91
+ var bound = function () {
92
+
93
+ if (this instanceof bound) {
94
+ // 15.3.4.5.2 [[Construct]]
95
+ // When the [[Construct]] internal method of a function object,
96
+ // F that was created using the bind function is called with a
97
+ // list of arguments ExtraArgs the following steps are taken:
98
+ // 1. Let target be the value of F's [[TargetFunction]]
99
+ // internal property.
100
+ // 2. If target has no [[Construct]] internal method, a
101
+ // TypeError exception is thrown.
102
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
103
+ // property.
104
+ // 4. Let args be a new list containing the same values as the
105
+ // list boundArgs in the same order followed by the same
106
+ // values as the list ExtraArgs in the same order.
107
+
108
+ var F = function(){};
109
+ F.prototype = target.prototype;
110
+ var self = new F;
111
+
112
+ var result = target.apply(
113
+ self,
114
+ args.concat(slice.call(arguments))
115
+ );
116
+ if (result !== null && Object(result) === result)
117
+ return result;
118
+ return self;
119
+
120
+ } else {
121
+ // 15.3.4.5.1 [[Call]]
122
+ // When the [[Call]] internal method of a function object, F,
123
+ // which was created using the bind function is called with a
124
+ // this value and a list of arguments ExtraArgs the following
125
+ // steps are taken:
126
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
127
+ // property.
128
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
129
+ // property.
130
+ // 3. Let target be the value of F's [[TargetFunction]] internal
131
+ // property.
132
+ // 4. Let args be a new list containing the same values as the list
133
+ // boundArgs in the same order followed by the same values as
134
+ // the list ExtraArgs in the same order. 5. Return the
135
+ // result of calling the [[Call]] internal method of target
136
+ // providing boundThis as the this value and providing args
137
+ // as the arguments.
138
+
139
+ // equiv: target.call(this, ...boundArgs, ...args)
140
+ return target.apply(
141
+ that,
142
+ args.concat(slice.call(arguments))
143
+ );
144
+
145
+ }
146
+
147
+ };
148
+ // XXX bound.length is never writable, so don't even try
149
+ //
150
+ // 16. The length own property of F is given attributes as specified in
151
+ // 15.3.5.1.
152
+ // TODO
153
+ // 17. Set the [[Extensible]] internal property of F to true.
154
+ // TODO
155
+ // 18. Call the [[DefineOwnProperty]] internal method of F with
156
+ // arguments "caller", PropertyDescriptor {[[Value]]: null,
157
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
158
+ // false}, and false.
159
+ // TODO
160
+ // 19. Call the [[DefineOwnProperty]] internal method of F with
161
+ // arguments "arguments", PropertyDescriptor {[[Value]]: null,
162
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
163
+ // false}, and false.
164
+ // TODO
165
+ // NOTE Function objects created using Function.prototype.bind do not
166
+ // have a prototype property.
167
+ // XXX can't delete it in pure-js.
168
+ return bound;
169
+ };
170
+ }
171
+
172
+ // Shortcut to an often accessed properties, in order to avoid multiple
173
+ // dereference that costs universally.
174
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
175
+ // us it in defining shortcuts.
176
+ var call = Function.prototype.call;
177
+ var prototypeOfArray = Array.prototype;
178
+ var prototypeOfObject = Object.prototype;
179
+ var slice = prototypeOfArray.slice;
180
+ var toString = call.bind(prototypeOfObject.toString);
181
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
182
+
183
+ // If JS engine supports accessors creating shortcuts.
184
+ var defineGetter;
185
+ var defineSetter;
186
+ var lookupGetter;
187
+ var lookupSetter;
188
+ var supportsAccessors;
189
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
190
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
191
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
192
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
193
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
194
+ }
195
+
196
+ //
197
+ // Array
198
+ // =====
199
+ //
200
+
201
+ // ES5 15.4.3.2
202
+ if (!Array.isArray) {
203
+ Array.isArray = function isArray(obj) {
204
+ return toString(obj) == "[object Array]";
205
+ };
206
+ }
207
+
208
+ // The IsCallable() check in the Array functions
209
+ // has been replaced with a strict check on the
210
+ // internal class of the object to trap cases where
211
+ // the provided function was actually a regular
212
+ // expression literal, which in V8 and
213
+ // JavaScriptCore is a typeof "function". Only in
214
+ // V8 are regular expression literals permitted as
215
+ // reduce parameters, so it is desirable in the
216
+ // general case for the shim to match the more
217
+ // strict and common behavior of rejecting regular
218
+ // expressions.
219
+
220
+ // ES5 15.4.4.18
221
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
222
+ if (!Array.prototype.forEach) {
223
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
224
+ var self = toObject(this),
225
+ thisp = arguments[1],
226
+ i = 0,
227
+ length = self.length >>> 0;
228
+
229
+ // If no callback function or if callback is not a callable function
230
+ if (toString(fun) != "[object Function]") {
231
+ throw new TypeError(); // TODO message
232
+ }
233
+
234
+ while (i < length) {
235
+ if (i in self) {
236
+ // Invoke the callback function with call, passing arguments:
237
+ // context, property value, property key, thisArg object context
238
+ fun.call(thisp, self[i], i, self);
239
+ }
240
+ i++;
241
+ }
242
+ };
243
+ }
244
+
245
+ // ES5 15.4.4.19
246
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
247
+ if (!Array.prototype.map) {
248
+ Array.prototype.map = function map(fun /*, thisp*/) {
249
+ var self = toObject(this),
250
+ length = self.length >>> 0,
251
+ result = Array(length),
252
+ thisp = arguments[1];
253
+
254
+ // If no callback function or if callback is not a callable function
255
+ if (toString(fun) != "[object Function]") {
256
+ throw new TypeError(); // TODO message
257
+ }
258
+
259
+ for (var i = 0; i < length; i++) {
260
+ if (i in self)
261
+ result[i] = fun.call(thisp, self[i], i, self);
262
+ }
263
+ return result;
264
+ };
265
+ }
266
+
267
+ // ES5 15.4.4.20
268
+ if (!Array.prototype.filter) {
269
+ Array.prototype.filter = function filter(fun /*, thisp */) {
270
+ var self = toObject(this),
271
+ length = self.length >>> 0,
272
+ result = [],
273
+ thisp = arguments[1];
274
+
275
+ // If no callback function or if callback is not a callable function
276
+ if (toString(fun) != "[object Function]") {
277
+ throw new TypeError(); // TODO message
278
+ }
279
+
280
+ for (var i = 0; i < length; i++) {
281
+ if (i in self && fun.call(thisp, self[i], i, self))
282
+ result.push(self[i]);
283
+ }
284
+ return result;
285
+ };
286
+ }
287
+
288
+ // ES5 15.4.4.16
289
+ if (!Array.prototype.every) {
290
+ Array.prototype.every = function every(fun /*, thisp */) {
291
+ var self = toObject(this),
292
+ length = self.length >>> 0,
293
+ thisp = arguments[1];
294
+
295
+ // If no callback function or if callback is not a callable function
296
+ if (toString(fun) != "[object Function]") {
297
+ throw new TypeError(); // TODO message
298
+ }
299
+
300
+ for (var i = 0; i < length; i++) {
301
+ if (i in self && !fun.call(thisp, self[i], i, self))
302
+ return false;
303
+ }
304
+ return true;
305
+ };
306
+ }
307
+
308
+ // ES5 15.4.4.17
309
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
310
+ if (!Array.prototype.some) {
311
+ Array.prototype.some = function some(fun /*, thisp */) {
312
+ var self = toObject(this),
313
+ length = self.length >>> 0,
314
+ thisp = arguments[1];
315
+
316
+ // If no callback function or if callback is not a callable function
317
+ if (toString(fun) != "[object Function]") {
318
+ throw new TypeError(); // TODO message
319
+ }
320
+
321
+ for (var i = 0; i < length; i++) {
322
+ if (i in self && fun.call(thisp, self[i], i, self))
323
+ return true;
324
+ }
325
+ return false;
326
+ };
327
+ }
328
+
329
+ // ES5 15.4.4.21
330
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
331
+ if (!Array.prototype.reduce) {
332
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
333
+ var self = toObject(this),
334
+ length = self.length >>> 0;
335
+
336
+ // If no callback function or if callback is not a callable function
337
+ if (toString(fun) != "[object Function]") {
338
+ throw new TypeError(); // TODO message
339
+ }
340
+
341
+ // no value to return if no initial value and an empty array
342
+ if (!length && arguments.length == 1)
343
+ throw new TypeError(); // TODO message
344
+
345
+ var i = 0;
346
+ var result;
347
+ if (arguments.length >= 2) {
348
+ result = arguments[1];
349
+ } else {
350
+ do {
351
+ if (i in self) {
352
+ result = self[i++];
353
+ break;
354
+ }
355
+
356
+ // if array contains no values, no initial value to return
357
+ if (++i >= length)
358
+ throw new TypeError(); // TODO message
359
+ } while (true);
360
+ }
361
+
362
+ for (; i < length; i++) {
363
+ if (i in self)
364
+ result = fun.call(void 0, result, self[i], i, self);
365
+ }
366
+
367
+ return result;
368
+ };
369
+ }
370
+
371
+ // ES5 15.4.4.22
372
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
373
+ if (!Array.prototype.reduceRight) {
374
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
375
+ var self = toObject(this),
376
+ length = self.length >>> 0;
377
+
378
+ // If no callback function or if callback is not a callable function
379
+ if (toString(fun) != "[object Function]") {
380
+ throw new TypeError(); // TODO message
381
+ }
382
+
383
+ // no value to return if no initial value, empty array
384
+ if (!length && arguments.length == 1)
385
+ throw new TypeError(); // TODO message
386
+
387
+ var result, i = length - 1;
388
+ if (arguments.length >= 2) {
389
+ result = arguments[1];
390
+ } else {
391
+ do {
392
+ if (i in self) {
393
+ result = self[i--];
394
+ break;
395
+ }
396
+
397
+ // if array contains no values, no initial value to return
398
+ if (--i < 0)
399
+ throw new TypeError(); // TODO message
400
+ } while (true);
401
+ }
402
+
403
+ do {
404
+ if (i in this)
405
+ result = fun.call(void 0, result, self[i], i, self);
406
+ } while (i--);
407
+
408
+ return result;
409
+ };
410
+ }
411
+
412
+ // ES5 15.4.4.14
413
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
414
+ if (!Array.prototype.indexOf) {
415
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
416
+ var self = toObject(this),
417
+ length = self.length >>> 0;
418
+
419
+ if (!length)
420
+ return -1;
421
+
422
+ var i = 0;
423
+ if (arguments.length > 1)
424
+ i = toInteger(arguments[1]);
425
+
426
+ // handle negative indices
427
+ i = i >= 0 ? i : length - Math.abs(i);
428
+ for (; i < length; i++) {
429
+ if (i in self && self[i] === sought) {
430
+ return i;
431
+ }
432
+ }
433
+ return -1;
434
+ };
435
+ }
436
+
437
+ // ES5 15.4.4.15
438
+ if (!Array.prototype.lastIndexOf) {
439
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
440
+ var self = toObject(this),
441
+ length = self.length >>> 0;
442
+
443
+ if (!length)
444
+ return -1;
445
+ var i = length - 1;
446
+ if (arguments.length > 1)
447
+ i = toInteger(arguments[1]);
448
+ // handle negative indices
449
+ i = i >= 0 ? i : length - Math.abs(i);
450
+ for (; i >= 0; i--) {
451
+ if (i in self && sought === self[i])
452
+ return i;
453
+ }
454
+ return -1;
455
+ };
456
+ }
457
+
458
+ //
459
+ // Object
460
+ // ======
461
+ //
462
+
463
+ // ES5 15.2.3.2
464
+ if (!Object.getPrototypeOf) {
465
+ // https://github.com/kriskowal/es5-shim/issues#issue/2
466
+ // http://ejohn.org/blog/objectgetprototypeof/
467
+ // recommended by fschaefer on github
468
+ Object.getPrototypeOf = function getPrototypeOf(object) {
469
+ return object.__proto__ || (
470
+ object.constructor ?
471
+ object.constructor.prototype :
472
+ prototypeOfObject
473
+ );
474
+ };
475
+ }
476
+
477
+ // ES5 15.2.3.3
478
+ if (!Object.getOwnPropertyDescriptor) {
479
+ var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
480
+ "non-object: ";
481
+ Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
482
+ if ((typeof object != "object" && typeof object != "function") || object === null)
483
+ throw new TypeError(ERR_NON_OBJECT + object);
484
+ // If object does not owns property return undefined immediately.
485
+ if (!owns(object, property))
486
+ return;
487
+
488
+ var descriptor, getter, setter;
489
+
490
+ // If object has a property then it's for sure both `enumerable` and
491
+ // `configurable`.
492
+ descriptor = { enumerable: true, configurable: true };
493
+
494
+ // If JS engine supports accessor properties then property may be a
495
+ // getter or setter.
496
+ if (supportsAccessors) {
497
+ // Unfortunately `__lookupGetter__` will return a getter even
498
+ // if object has own non getter property along with a same named
499
+ // inherited getter. To avoid misbehavior we temporary remove
500
+ // `__proto__` so that `__lookupGetter__` will return getter only
501
+ // if it's owned by an object.
502
+ var prototype = object.__proto__;
503
+ object.__proto__ = prototypeOfObject;
504
+
505
+ var getter = lookupGetter(object, property);
506
+ var setter = lookupSetter(object, property);
507
+
508
+ // Once we have getter and setter we can put values back.
509
+ object.__proto__ = prototype;
510
+
511
+ if (getter || setter) {
512
+ if (getter) descriptor.get = getter;
513
+ if (setter) descriptor.set = setter;
514
+
515
+ // If it was accessor property we're done and return here
516
+ // in order to avoid adding `value` to the descriptor.
517
+ return descriptor;
518
+ }
519
+ }
520
+
521
+ // If we got this far we know that object has an own property that is
522
+ // not an accessor so we set it as a value and return descriptor.
523
+ descriptor.value = object[property];
524
+ return descriptor;
525
+ };
526
+ }
527
+
528
+ // ES5 15.2.3.4
529
+ if (!Object.getOwnPropertyNames) {
530
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
531
+ return Object.keys(object);
532
+ };
533
+ }
534
+
535
+ // ES5 15.2.3.5
536
+ if (!Object.create) {
537
+ Object.create = function create(prototype, properties) {
538
+ var object;
539
+ if (prototype === null) {
540
+ object = { "__proto__": null };
541
+ } else {
542
+ if (typeof prototype != "object")
543
+ throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
544
+ var Type = function () {};
545
+ Type.prototype = prototype;
546
+ object = new Type();
547
+ // IE has no built-in implementation of `Object.getPrototypeOf`
548
+ // neither `__proto__`, but this manually setting `__proto__` will
549
+ // guarantee that `Object.getPrototypeOf` will work as expected with
550
+ // objects created using `Object.create`
551
+ object.__proto__ = prototype;
552
+ }
553
+ if (properties !== void 0)
554
+ Object.defineProperties(object, properties);
555
+ return object;
556
+ };
557
+ }
558
+
559
+ // ES5 15.2.3.6
560
+
561
+ // Patch for WebKit and IE8 standard mode
562
+ // Designed by hax <hax.github.com>
563
+ // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
564
+ // IE8 Reference:
565
+ // http://msdn.microsoft.com/en-us/library/dd282900.aspx
566
+ // http://msdn.microsoft.com/en-us/library/dd229916.aspx
567
+ // WebKit Bugs:
568
+ // https://bugs.webkit.org/show_bug.cgi?id=36423
569
+
570
+ function doesDefinePropertyWork(object) {
571
+ try {
572
+ Object.defineProperty(object, "sentinel", {});
573
+ return "sentinel" in object;
574
+ } catch (exception) {
575
+ // returns falsy
576
+ }
577
+ }
578
+
579
+ // check whether defineProperty works if it's given. Otherwise,
580
+ // shim partially.
581
+ if (Object.defineProperty) {
582
+ var definePropertyWorksOnObject = doesDefinePropertyWork({});
583
+ var definePropertyWorksOnDom = typeof document == "undefined" ||
584
+ doesDefinePropertyWork(document.createElement("div"));
585
+ if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
586
+ var definePropertyFallback = Object.defineProperty;
587
+ }
588
+ }
589
+
590
+ if (!Object.defineProperty || definePropertyFallback) {
591
+ var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
592
+ var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
593
+ var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
594
+ "on this javascript engine";
595
+
596
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
597
+ if ((typeof object != "object" && typeof object != "function") || object === null)
598
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
599
+ if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
600
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
601
+
602
+ // make a valiant attempt to use the real defineProperty
603
+ // for I8's DOM elements.
604
+ if (definePropertyFallback) {
605
+ try {
606
+ return definePropertyFallback.call(Object, object, property, descriptor);
607
+ } catch (exception) {
608
+ // try the shim if the real one doesn't work
609
+ }
610
+ }
611
+
612
+ // If it's a data property.
613
+ if (owns(descriptor, "value")) {
614
+ // fail silently if "writable", "enumerable", or "configurable"
615
+ // are requested but not supported
616
+ /*
617
+ // alternate approach:
618
+ if ( // can't implement these features; allow false but not true
619
+ !(owns(descriptor, "writable") ? descriptor.writable : true) ||
620
+ !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
621
+ !(owns(descriptor, "configurable") ? descriptor.configurable : true)
622
+ )
623
+ throw new RangeError(
624
+ "This implementation of Object.defineProperty does not " +
625
+ "support configurable, enumerable, or writable."
626
+ );
627
+ */
628
+
629
+ if (supportsAccessors && (lookupGetter(object, property) ||
630
+ lookupSetter(object, property)))
631
+ {
632
+ // As accessors are supported only on engines implementing
633
+ // `__proto__` we can safely override `__proto__` while defining
634
+ // a property to make sure that we don't hit an inherited
635
+ // accessor.
636
+ var prototype = object.__proto__;
637
+ object.__proto__ = prototypeOfObject;
638
+ // Deleting a property anyway since getter / setter may be
639
+ // defined on object itself.
640
+ delete object[property];
641
+ object[property] = descriptor.value;
642
+ // Setting original `__proto__` back now.
643
+ object.__proto__ = prototype;
644
+ } else {
645
+ object[property] = descriptor.value;
646
+ }
647
+ } else {
648
+ if (!supportsAccessors)
649
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
650
+ // If we got that far then getters and setters can be defined !!
651
+ if (owns(descriptor, "get"))
652
+ defineGetter(object, property, descriptor.get);
653
+ if (owns(descriptor, "set"))
654
+ defineSetter(object, property, descriptor.set);
655
+ }
656
+
657
+ return object;
658
+ };
659
+ }
660
+
661
+ // ES5 15.2.3.7
662
+ if (!Object.defineProperties) {
663
+ Object.defineProperties = function defineProperties(object, properties) {
664
+ for (var property in properties) {
665
+ if (owns(properties, property))
666
+ Object.defineProperty(object, property, properties[property]);
667
+ }
668
+ return object;
669
+ };
670
+ }
671
+
672
+ // ES5 15.2.3.8
673
+ if (!Object.seal) {
674
+ Object.seal = function seal(object) {
675
+ // this is misleading and breaks feature-detection, but
676
+ // allows "securable" code to "gracefully" degrade to working
677
+ // but insecure code.
678
+ return object;
679
+ };
680
+ }
681
+
682
+ // ES5 15.2.3.9
683
+ if (!Object.freeze) {
684
+ Object.freeze = function freeze(object) {
685
+ // this is misleading and breaks feature-detection, but
686
+ // allows "securable" code to "gracefully" degrade to working
687
+ // but insecure code.
688
+ return object;
689
+ };
690
+ }
691
+
692
+ // detect a Rhino bug and patch it
693
+ try {
694
+ Object.freeze(function () {});
695
+ } catch (exception) {
696
+ Object.freeze = (function freeze(freezeObject) {
697
+ return function freeze(object) {
698
+ if (typeof object == "function") {
699
+ return object;
700
+ } else {
701
+ return freezeObject(object);
702
+ }
703
+ };
704
+ })(Object.freeze);
705
+ }
706
+
707
+ // ES5 15.2.3.10
708
+ if (!Object.preventExtensions) {
709
+ Object.preventExtensions = function preventExtensions(object) {
710
+ // this is misleading and breaks feature-detection, but
711
+ // allows "securable" code to "gracefully" degrade to working
712
+ // but insecure code.
713
+ return object;
714
+ };
715
+ }
716
+
717
+ // ES5 15.2.3.11
718
+ if (!Object.isSealed) {
719
+ Object.isSealed = function isSealed(object) {
720
+ return false;
721
+ };
722
+ }
723
+
724
+ // ES5 15.2.3.12
725
+ if (!Object.isFrozen) {
726
+ Object.isFrozen = function isFrozen(object) {
727
+ return false;
728
+ };
729
+ }
730
+
731
+ // ES5 15.2.3.13
732
+ if (!Object.isExtensible) {
733
+ Object.isExtensible = function isExtensible(object) {
734
+ // 1. If Type(O) is not Object throw a TypeError exception.
735
+ if (Object(object) === object) {
736
+ throw new TypeError(); // TODO message
737
+ }
738
+ // 2. Return the Boolean value of the [[Extensible]] internal property of O.
739
+ var name = '';
740
+ while (owns(object, name)) {
741
+ name += '?';
742
+ }
743
+ object[name] = true;
744
+ var returnValue = owns(object, name);
745
+ delete object[name];
746
+ return returnValue;
747
+ };
748
+ }
749
+
750
+ // ES5 15.2.3.14
751
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
752
+ if (!Object.keys) {
753
+
754
+ var hasDontEnumBug = true,
755
+ dontEnums = [
756
+ "toString",
757
+ "toLocaleString",
758
+ "valueOf",
759
+ "hasOwnProperty",
760
+ "isPrototypeOf",
761
+ "propertyIsEnumerable",
762
+ "constructor"
763
+ ],
764
+ dontEnumsLength = dontEnums.length;
765
+
766
+ for (var key in {"toString": null})
767
+ hasDontEnumBug = false;
768
+
769
+ Object.keys = function keys(object) {
770
+
771
+ if ((typeof object != "object" && typeof object != "function") || object === null)
772
+ throw new TypeError("Object.keys called on a non-object");
773
+
774
+ var keys = [];
775
+ for (var name in object) {
776
+ if (owns(object, name)) {
777
+ keys.push(name);
778
+ }
779
+ }
780
+
781
+ if (hasDontEnumBug) {
782
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
783
+ var dontEnum = dontEnums[i];
784
+ if (owns(object, dontEnum)) {
785
+ keys.push(dontEnum);
786
+ }
787
+ }
788
+ }
789
+
790
+ return keys;
791
+ };
792
+
793
+ }
794
+
795
+ //
796
+ // Date
797
+ // ====
798
+ //
799
+
800
+ // ES5 15.9.5.43
801
+ // Format a Date object as a string according to a simplified subset of the ISO 8601
802
+ // standard as defined in 15.9.1.15.
803
+ if (!Date.prototype.toISOString) {
804
+ Date.prototype.toISOString = function toISOString() {
805
+ var result, length, value;
806
+ if (!isFinite(this))
807
+ throw new RangeError;
808
+
809
+ // the date time string format is specified in 15.9.1.15.
810
+ result = [this.getUTCFullYear(), this.getUTCMonth() + 1, this.getUTCDate(),
811
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
812
+
813
+ length = result.length;
814
+ while (length--) {
815
+ value = result[length];
816
+ // pad months, days, hours, minutes, and seconds to have two digits.
817
+ if (value < 10)
818
+ result[length] = "0" + value;
819
+ }
820
+ // pad milliseconds to have three digits.
821
+ return result.slice(0, 3).join("-") + "T" + result.slice(3).join(":") + "." +
822
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
823
+ }
824
+ }
825
+
826
+ // ES5 15.9.4.4
827
+ if (!Date.now) {
828
+ Date.now = function now() {
829
+ return new Date().getTime();
830
+ };
831
+ }
832
+
833
+ // ES5 15.9.5.44
834
+ if (!Date.prototype.toJSON) {
835
+ Date.prototype.toJSON = function toJSON(key) {
836
+ // This function provides a String representation of a Date object for
837
+ // use by JSON.stringify (15.12.3). When the toJSON method is called
838
+ // with argument key, the following steps are taken:
839
+
840
+ // 1. Let O be the result of calling ToObject, giving it the this
841
+ // value as its argument.
842
+ // 2. Let tv be ToPrimitive(O, hint Number).
843
+ // 3. If tv is a Number and is not finite, return null.
844
+ // XXX
845
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
846
+ // O with argument "toISOString".
847
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
848
+ if (typeof this.toISOString != "function")
849
+ throw new TypeError(); // TODO message
850
+ // 6. Return the result of calling the [[Call]] internal method of
851
+ // toISO with O as the this value and an empty argument list.
852
+ return this.toISOString();
853
+
854
+ // NOTE 1 The argument is ignored.
855
+
856
+ // NOTE 2 The toJSON function is intentionally generic; it does not
857
+ // require that its this value be a Date object. Therefore, it can be
858
+ // transferred to other kinds of objects for use as a method. However,
859
+ // it does require that any such object have a toISOString method. An
860
+ // object is free to use the argument key to filter its
861
+ // stringification.
862
+ };
863
+ }
864
+
865
+ // 15.9.4.2 Date.parse (string)
866
+ // 15.9.1.15 Date Time String Format
867
+ // Date.parse
868
+ // based on work shared by Daniel Friesen (dantman)
869
+ // http://gist.github.com/303249
870
+ if (isNaN(Date.parse("2011-06-15T21:40:05+06:00"))) {
871
+ // XXX global assignment won't work in embeddings that use
872
+ // an alternate object for the context.
873
+ Date = (function(NativeDate) {
874
+
875
+ // Date.length === 7
876
+ var Date = function Date(Y, M, D, h, m, s, ms) {
877
+ var length = arguments.length;
878
+ if (this instanceof NativeDate) {
879
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
880
+ // We explicitly pass it through parse:
881
+ new NativeDate(Date.parse(Y)) :
882
+ // We have to manually make calls depending on argument
883
+ // length here
884
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
885
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
886
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
887
+ length >= 4 ? new NativeDate(Y, M, D, h) :
888
+ length >= 3 ? new NativeDate(Y, M, D) :
889
+ length >= 2 ? new NativeDate(Y, M) :
890
+ length >= 1 ? new NativeDate(Y) :
891
+ new NativeDate();
892
+ // Prevent mixups with unfixed Date object
893
+ date.constructor = Date;
894
+ return date;
895
+ }
896
+ return NativeDate.apply(this, arguments);
897
+ };
898
+
899
+ // 15.9.1.15 Date Time String Format. This pattern does not implement
900
+ // extended years (15.9.1.15.1), as `Date.UTC` cannot parse them.
901
+ var isoDateExpression = new RegExp("^" +
902
+ "(\\d{4})" + // four-digit year capture
903
+ "(?:-(\\d{2})" + // optional month capture
904
+ "(?:-(\\d{2})" + // optional day capture
905
+ "(?:" + // capture hours:minutes:seconds.milliseconds
906
+ "T(\\d{2})" + // hours capture
907
+ ":(\\d{2})" + // minutes capture
908
+ "(?:" + // optional :seconds.milliseconds
909
+ ":(\\d{2})" + // seconds capture
910
+ "(?:\\.(\\d{3}))?" + // milliseconds capture
911
+ ")?" +
912
+ "(?:" + // capture UTC offset component
913
+ "Z|" + // UTC capture
914
+ "(?:" + // offset specifier +/-hours:minutes
915
+ "([-+])" + // sign capture
916
+ "(\\d{2})" + // hours offset capture
917
+ ":(\\d{2})" + // minutes offset capture
918
+ ")" +
919
+ ")?)?)?)?" +
920
+ "$");
921
+
922
+ // Copy any custom methods a 3rd party library may have added
923
+ for (var key in NativeDate)
924
+ Date[key] = NativeDate[key];
925
+
926
+ // Copy "native" methods explicitly; they may be non-enumerable
927
+ Date.now = NativeDate.now;
928
+ Date.UTC = NativeDate.UTC;
929
+ Date.prototype = NativeDate.prototype;
930
+ Date.prototype.constructor = Date;
931
+
932
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
933
+ Date.parse = function parse(string) {
934
+ var match = isoDateExpression.exec(string);
935
+ if (match) {
936
+ match.shift(); // kill match[0], the full match
937
+ // parse months, days, hours, minutes, seconds, and milliseconds
938
+ for (var i = 1; i < 7; i++) {
939
+ // provide default values if necessary
940
+ match[i] = +(match[i] || (i < 3 ? 1 : 0));
941
+ // match[1] is the month. Months are 0-11 in JavaScript
942
+ // `Date` objects, but 1-12 in ISO notation, so we
943
+ // decrement.
944
+ if (i == 1)
945
+ match[i]--;
946
+ }
947
+
948
+ // parse the UTC offset component
949
+ var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
950
+
951
+ // compute the explicit time zone offset if specified
952
+ var offset = 0;
953
+ if (sign) {
954
+ // detect invalid offsets and return early
955
+ if (hourOffset > 23 || minuteOffset > 59)
956
+ return NaN;
957
+
958
+ // express the provided time zone offset in minutes. The offset is
959
+ // negative for time zones west of UTC; positive otherwise.
960
+ offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
961
+ }
962
+
963
+ // compute a new UTC date value, accounting for the optional offset
964
+ return NativeDate.UTC.apply(this, match) + offset;
965
+ }
966
+ return NativeDate.parse.apply(this, arguments);
967
+ };
968
+
969
+ return Date;
970
+ })(Date);
971
+ }
972
+
973
+ //
974
+ // String
975
+ // ======
976
+ //
977
+
978
+ // ES5 15.5.4.20
979
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
980
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
981
+ "\u2029\uFEFF";
982
+ if (!String.prototype.trim || ws.trim()) {
983
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
984
+ // http://perfectionkills.com/whitespace-deviations/
985
+ ws = "[" + ws + "]";
986
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
987
+ trimEndRegexp = new RegExp(ws + ws + "*$");
988
+ String.prototype.trim = function trim() {
989
+ return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
990
+ };
991
+ }
992
+
993
+ //
994
+ // Util
995
+ // ======
996
+ //
997
+
998
+ // http://jsperf.com/to-integer
999
+ var toInteger = function (n) {
1000
+ n = +n;
1001
+ if (n !== n) // isNaN
1002
+ n = -1;
1003
+ else if (n !== 0 && n !== (1/0) && n !== -(1/0))
1004
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1005
+ return n;
1006
+ };
1007
+
1008
+ var prepareString = "a"[0] != "a",
1009
+ // ES5 9.9
1010
+ toObject = function (o) {
1011
+ if (o == null) { // this matches both null and undefined
1012
+ throw new TypeError(); // TODO message
1013
+ }
1014
+ // If the implementation doesn't support by-index access of
1015
+ // string characters (ex. IE < 7), split the string
1016
+ if (prepareString && typeof o == "string" && o) {
1017
+ return o.split("");
1018
+ }
1019
+ return Object(o);
1020
+ };
1021
+ });