d2c0ad08543c78f0a5d8df70059ed1f07cc1e3be
[motion.git] / public / bower_components / es5-shim / es5-shim.js
1 /*!
2  * https://github.com/es-shims/es5-shim
3  * @license es5-shim Copyright 2009-2015 by contributors, MIT License
4  * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
5  */
6
7 // vim: ts=4 sts=4 sw=4 expandtab
8
9 // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
10 ;
11
12 // UMD (Universal Module Definition)
13 // see https://github.com/umdjs/umd/blob/master/returnExports.js
14 (function (root, factory) {
15     'use strict';
16
17     /* global define, exports, module */
18     if (typeof define === 'function' && define.amd) {
19         // AMD. Register as an anonymous module.
20         define(factory);
21     } else if (typeof exports === 'object') {
22         // Node. Does not work with strict CommonJS, but
23         // only CommonJS-like enviroments that support module.exports,
24         // like Node.
25         module.exports = factory();
26     } else {
27         // Browser globals (root is window)
28         root.returnExports = factory();
29     }
30 }(this, function () {
31
32 /**
33  * Brings an environment as close to ECMAScript 5 compliance
34  * as is possible with the facilities of erstwhile engines.
35  *
36  * Annotated ES5: http://es5.github.com/ (specific links below)
37  * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
38  * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
39  */
40
41 // Shortcut to an often accessed properties, in order to avoid multiple
42 // dereference that costs universally. This also holds a reference to known-good
43 // functions.
44 var $Array = Array;
45 var ArrayPrototype = $Array.prototype;
46 var $Object = Object;
47 var ObjectPrototype = $Object.prototype;
48 var FunctionPrototype = Function.prototype;
49 var $String = String;
50 var StringPrototype = $String.prototype;
51 var $Number = Number;
52 var NumberPrototype = $Number.prototype;
53 var array_slice = ArrayPrototype.slice;
54 var array_splice = ArrayPrototype.splice;
55 var array_push = ArrayPrototype.push;
56 var array_unshift = ArrayPrototype.unshift;
57 var array_concat = ArrayPrototype.concat;
58 var call = FunctionPrototype.call;
59 var max = Math.max;
60 var min = Math.min;
61
62 // Having a toString local variable name breaks in Opera so use to_string.
63 var to_string = ObjectPrototype.toString;
64
65 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
66 var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
67 var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
68 var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
69
70 /* inlined from http://npmjs.com/define-properties */
71 var defineProperties = (function (has) {
72   var supportsDescriptors = $Object.defineProperty && (function () {
73       try {
74           var obj = {};
75           $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
76           for (var _ in obj) { return false; }
77           return obj.x === obj;
78       } catch (e) { /* this is ES3 */
79           return false;
80       }
81   }());
82
83   // Define configurable, writable and non-enumerable props
84   // if they don't exist.
85   var defineProperty;
86   if (supportsDescriptors) {
87       defineProperty = function (object, name, method, forceAssign) {
88           if (!forceAssign && (name in object)) { return; }
89           $Object.defineProperty(object, name, {
90               configurable: true,
91               enumerable: false,
92               writable: true,
93               value: method
94           });
95       };
96   } else {
97       defineProperty = function (object, name, method, forceAssign) {
98           if (!forceAssign && (name in object)) { return; }
99           object[name] = method;
100       };
101   }
102   return function defineProperties(object, map, forceAssign) {
103       for (var name in map) {
104           if (has.call(map, name)) {
105             defineProperty(object, name, map[name], forceAssign);
106           }
107       }
108   };
109 }(ObjectPrototype.hasOwnProperty));
110
111 //
112 // Util
113 // ======
114 //
115
116 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
117 var isPrimitive = function isPrimitive(input) {
118     var type = typeof input;
119     return input === null || (type !== 'object' && type !== 'function');
120 };
121
122 var isActualNaN = $Number.isNaN || function (x) { return x !== x; };
123
124 var ES = {
125     // ES5 9.4
126     // http://es5.github.com/#x9.4
127     // http://jsperf.com/to-integer
128     /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
129     ToInteger: function ToInteger(num) {
130         var n = +num;
131         if (isActualNaN(n)) {
132             n = 0;
133         } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
134             n = (n > 0 || -1) * Math.floor(Math.abs(n));
135         }
136         return n;
137     },
138
139     /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
140     ToPrimitive: function ToPrimitive(input) {
141         var val, valueOf, toStr;
142         if (isPrimitive(input)) {
143             return input;
144         }
145         valueOf = input.valueOf;
146         if (isCallable(valueOf)) {
147             val = valueOf.call(input);
148             if (isPrimitive(val)) {
149                 return val;
150             }
151         }
152         toStr = input.toString;
153         if (isCallable(toStr)) {
154             val = toStr.call(input);
155             if (isPrimitive(val)) {
156                 return val;
157             }
158         }
159         throw new TypeError();
160     },
161
162     // ES5 9.9
163     // http://es5.github.com/#x9.9
164     /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
165     ToObject: function (o) {
166         /* jshint eqnull: true */
167         if (o == null) { // this matches both null and undefined
168             throw new TypeError("can't convert " + o + ' to object');
169         }
170         return $Object(o);
171     },
172
173     /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
174     ToUint32: function ToUint32(x) {
175         return x >>> 0;
176     }
177 };
178
179 //
180 // Function
181 // ========
182 //
183
184 // ES-5 15.3.4.5
185 // http://es5.github.com/#x15.3.4.5
186
187 var Empty = function Empty() {};
188
189 defineProperties(FunctionPrototype, {
190     bind: function bind(that) { // .length is 1
191         // 1. Let Target be the this value.
192         var target = this;
193         // 2. If IsCallable(Target) is false, throw a TypeError exception.
194         if (!isCallable(target)) {
195             throw new TypeError('Function.prototype.bind called on incompatible ' + target);
196         }
197         // 3. Let A be a new (possibly empty) internal list of all of the
198         //   argument values provided after thisArg (arg1, arg2 etc), in order.
199         // XXX slicedArgs will stand in for "A" if used
200         var args = array_slice.call(arguments, 1); // for normal call
201         // 4. Let F be a new native ECMAScript object.
202         // 11. Set the [[Prototype]] internal property of F to the standard
203         //   built-in Function prototype object as specified in 15.3.3.1.
204         // 12. Set the [[Call]] internal property of F as described in
205         //   15.3.4.5.1.
206         // 13. Set the [[Construct]] internal property of F as described in
207         //   15.3.4.5.2.
208         // 14. Set the [[HasInstance]] internal property of F as described in
209         //   15.3.4.5.3.
210         var bound;
211         var binder = function () {
212
213             if (this instanceof bound) {
214                 // 15.3.4.5.2 [[Construct]]
215                 // When the [[Construct]] internal method of a function object,
216                 // F that was created using the bind function is called with a
217                 // list of arguments ExtraArgs, the following steps are taken:
218                 // 1. Let target be the value of F's [[TargetFunction]]
219                 //   internal property.
220                 // 2. If target has no [[Construct]] internal method, a
221                 //   TypeError exception is thrown.
222                 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
223                 //   property.
224                 // 4. Let args be a new list containing the same values as the
225                 //   list boundArgs in the same order followed by the same
226                 //   values as the list ExtraArgs in the same order.
227                 // 5. Return the result of calling the [[Construct]] internal
228                 //   method of target providing args as the arguments.
229
230                 var result = target.apply(
231                     this,
232                     array_concat.call(args, array_slice.call(arguments))
233                 );
234                 if ($Object(result) === result) {
235                     return result;
236                 }
237                 return this;
238
239             } else {
240                 // 15.3.4.5.1 [[Call]]
241                 // When the [[Call]] internal method of a function object, F,
242                 // which was created using the bind function is called with a
243                 // this value and a list of arguments ExtraArgs, the following
244                 // steps are taken:
245                 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
246                 //   property.
247                 // 2. Let boundThis be the value of F's [[BoundThis]] internal
248                 //   property.
249                 // 3. Let target be the value of F's [[TargetFunction]] internal
250                 //   property.
251                 // 4. Let args be a new list containing the same values as the
252                 //   list boundArgs in the same order followed by the same
253                 //   values as the list ExtraArgs in the same order.
254                 // 5. Return the result of calling the [[Call]] internal method
255                 //   of target providing boundThis as the this value and
256                 //   providing args as the arguments.
257
258                 // equiv: target.call(this, ...boundArgs, ...args)
259                 return target.apply(
260                     that,
261                     array_concat.call(args, array_slice.call(arguments))
262                 );
263
264             }
265
266         };
267
268         // 15. If the [[Class]] internal property of Target is "Function", then
269         //     a. Let L be the length property of Target minus the length of A.
270         //     b. Set the length own property of F to either 0 or L, whichever is
271         //       larger.
272         // 16. Else set the length own property of F to 0.
273
274         var boundLength = max(0, target.length - args.length);
275
276         // 17. Set the attributes of the length own property of F to the values
277         //   specified in 15.3.5.1.
278         var boundArgs = [];
279         for (var i = 0; i < boundLength; i++) {
280             array_push.call(boundArgs, '$' + i);
281         }
282
283         // XXX Build a dynamic function with desired amount of arguments is the only
284         // way to set the length property of a function.
285         // In environments where Content Security Policies enabled (Chrome extensions,
286         // for ex.) all use of eval or Function costructor throws an exception.
287         // However in all of these environments Function.prototype.bind exists
288         // and so this code will never be executed.
289         bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
290
291         if (target.prototype) {
292             Empty.prototype = target.prototype;
293             bound.prototype = new Empty();
294             // Clean up dangling references.
295             Empty.prototype = null;
296         }
297
298         // TODO
299         // 18. Set the [[Extensible]] internal property of F to true.
300
301         // TODO
302         // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
303         // 20. Call the [[DefineOwnProperty]] internal method of F with
304         //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
305         //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
306         //   false.
307         // 21. Call the [[DefineOwnProperty]] internal method of F with
308         //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
309         //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
310         //   and false.
311
312         // TODO
313         // NOTE Function objects created using Function.prototype.bind do not
314         // have a prototype property or the [[Code]], [[FormalParameters]], and
315         // [[Scope]] internal properties.
316         // XXX can't delete prototype in pure-js.
317
318         // 22. Return F.
319         return bound;
320     }
321 });
322
323 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
324 // us it in defining shortcuts.
325 var owns = call.bind(ObjectPrototype.hasOwnProperty);
326 var toStr = call.bind(ObjectPrototype.toString);
327 var strSlice = call.bind(StringPrototype.slice);
328 var strSplit = call.bind(StringPrototype.split);
329
330 //
331 // Array
332 // =====
333 //
334
335 var isArray = $Array.isArray || function isArray(obj) {
336     return toStr(obj) === '[object Array]';
337 };
338
339 // ES5 15.4.4.12
340 // http://es5.github.com/#x15.4.4.13
341 // Return len+argCount.
342 // [bugfix, ielt8]
343 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
344 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
345 defineProperties(ArrayPrototype, {
346     unshift: function () {
347         array_unshift.apply(this, arguments);
348         return this.length;
349     }
350 }, hasUnshiftReturnValueBug);
351
352 // ES5 15.4.3.2
353 // http://es5.github.com/#x15.4.3.2
354 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
355 defineProperties($Array, { isArray: isArray });
356
357 // The IsCallable() check in the Array functions
358 // has been replaced with a strict check on the
359 // internal class of the object to trap cases where
360 // the provided function was actually a regular
361 // expression literal, which in V8 and
362 // JavaScriptCore is a typeof "function".  Only in
363 // V8 are regular expression literals permitted as
364 // reduce parameters, so it is desirable in the
365 // general case for the shim to match the more
366 // strict and common behavior of rejecting regular
367 // expressions.
368
369 // ES5 15.4.4.18
370 // http://es5.github.com/#x15.4.4.18
371 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
372
373 // Check failure of by-index access of string characters (IE < 9)
374 // and failure of `0 in boxedString` (Rhino)
375 var boxedString = $Object('a');
376 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
377
378 var properlyBoxesContext = function properlyBoxed(method) {
379     // Check node 0.6.21 bug where third parameter is not boxed
380     var properlyBoxesNonStrict = true;
381     var properlyBoxesStrict = true;
382     if (method) {
383         method.call('foo', function (_, __, context) {
384             if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
385         });
386
387         method.call([1], function () {
388             'use strict';
389
390             properlyBoxesStrict = typeof this === 'string';
391         }, 'x');
392     }
393     return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
394 };
395
396 defineProperties(ArrayPrototype, {
397     forEach: function forEach(callbackfn /*, thisArg*/) {
398         var object = ES.ToObject(this);
399         var self = splitString && isString(this) ? strSplit(this, '') : object;
400         var i = -1;
401         var length = ES.ToUint32(self.length);
402         var T;
403         if (arguments.length > 1) {
404           T = arguments[1];
405         }
406
407         // If no callback function or if callback is not a callable function
408         if (!isCallable(callbackfn)) {
409             throw new TypeError('Array.prototype.forEach callback must be a function');
410         }
411
412         while (++i < length) {
413             if (i in self) {
414                 // Invoke the callback function with call, passing arguments:
415                 // context, property value, property key, thisArg object
416                 if (typeof T === 'undefined') {
417                     callbackfn(self[i], i, object);
418                 } else {
419                     callbackfn.call(T, self[i], i, object);
420                 }
421             }
422         }
423     }
424 }, !properlyBoxesContext(ArrayPrototype.forEach));
425
426 // ES5 15.4.4.19
427 // http://es5.github.com/#x15.4.4.19
428 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
429 defineProperties(ArrayPrototype, {
430     map: function map(callbackfn/*, thisArg*/) {
431         var object = ES.ToObject(this);
432         var self = splitString && isString(this) ? strSplit(this, '') : object;
433         var length = ES.ToUint32(self.length);
434         var result = $Array(length);
435         var T;
436         if (arguments.length > 1) {
437             T = arguments[1];
438         }
439
440         // If no callback function or if callback is not a callable function
441         if (!isCallable(callbackfn)) {
442             throw new TypeError('Array.prototype.map callback must be a function');
443         }
444
445         for (var i = 0; i < length; i++) {
446             if (i in self) {
447                 if (typeof T === 'undefined') {
448                     result[i] = callbackfn(self[i], i, object);
449                 } else {
450                     result[i] = callbackfn.call(T, self[i], i, object);
451                 }
452             }
453         }
454         return result;
455     }
456 }, !properlyBoxesContext(ArrayPrototype.map));
457
458 // ES5 15.4.4.20
459 // http://es5.github.com/#x15.4.4.20
460 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
461 defineProperties(ArrayPrototype, {
462     filter: function filter(callbackfn /*, thisArg*/) {
463         var object = ES.ToObject(this);
464         var self = splitString && isString(this) ? strSplit(this, '') : object;
465         var length = ES.ToUint32(self.length);
466         var result = [];
467         var value;
468         var T;
469         if (arguments.length > 1) {
470             T = arguments[1];
471         }
472
473         // If no callback function or if callback is not a callable function
474         if (!isCallable(callbackfn)) {
475             throw new TypeError('Array.prototype.filter callback must be a function');
476         }
477
478         for (var i = 0; i < length; i++) {
479             if (i in self) {
480                 value = self[i];
481                 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
482                     array_push.call(result, value);
483                 }
484             }
485         }
486         return result;
487     }
488 }, !properlyBoxesContext(ArrayPrototype.filter));
489
490 // ES5 15.4.4.16
491 // http://es5.github.com/#x15.4.4.16
492 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
493 defineProperties(ArrayPrototype, {
494     every: function every(callbackfn /*, thisArg*/) {
495         var object = ES.ToObject(this);
496         var self = splitString && isString(this) ? strSplit(this, '') : object;
497         var length = ES.ToUint32(self.length);
498         var T;
499         if (arguments.length > 1) {
500             T = arguments[1];
501         }
502
503         // If no callback function or if callback is not a callable function
504         if (!isCallable(callbackfn)) {
505             throw new TypeError('Array.prototype.every callback must be a function');
506         }
507
508         for (var i = 0; i < length; i++) {
509             if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
510                 return false;
511             }
512         }
513         return true;
514     }
515 }, !properlyBoxesContext(ArrayPrototype.every));
516
517 // ES5 15.4.4.17
518 // http://es5.github.com/#x15.4.4.17
519 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
520 defineProperties(ArrayPrototype, {
521     some: function some(callbackfn/*, thisArg */) {
522         var object = ES.ToObject(this);
523         var self = splitString && isString(this) ? strSplit(this, '') : object;
524         var length = ES.ToUint32(self.length);
525         var T;
526         if (arguments.length > 1) {
527             T = arguments[1];
528         }
529
530         // If no callback function or if callback is not a callable function
531         if (!isCallable(callbackfn)) {
532             throw new TypeError('Array.prototype.some callback must be a function');
533         }
534
535         for (var i = 0; i < length; i++) {
536             if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
537                 return true;
538             }
539         }
540         return false;
541     }
542 }, !properlyBoxesContext(ArrayPrototype.some));
543
544 // ES5 15.4.4.21
545 // http://es5.github.com/#x15.4.4.21
546 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
547 var reduceCoercesToObject = false;
548 if (ArrayPrototype.reduce) {
549     reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
550 }
551 defineProperties(ArrayPrototype, {
552     reduce: function reduce(callbackfn /*, initialValue*/) {
553         var object = ES.ToObject(this);
554         var self = splitString && isString(this) ? strSplit(this, '') : object;
555         var length = ES.ToUint32(self.length);
556
557         // If no callback function or if callback is not a callable function
558         if (!isCallable(callbackfn)) {
559             throw new TypeError('Array.prototype.reduce callback must be a function');
560         }
561
562         // no value to return if no initial value and an empty array
563         if (length === 0 && arguments.length === 1) {
564             throw new TypeError('reduce of empty array with no initial value');
565         }
566
567         var i = 0;
568         var result;
569         if (arguments.length >= 2) {
570             result = arguments[1];
571         } else {
572             do {
573                 if (i in self) {
574                     result = self[i++];
575                     break;
576                 }
577
578                 // if array contains no values, no initial value to return
579                 if (++i >= length) {
580                     throw new TypeError('reduce of empty array with no initial value');
581                 }
582             } while (true);
583         }
584
585         for (; i < length; i++) {
586             if (i in self) {
587                 result = callbackfn(result, self[i], i, object);
588             }
589         }
590
591         return result;
592     }
593 }, !reduceCoercesToObject);
594
595 // ES5 15.4.4.22
596 // http://es5.github.com/#x15.4.4.22
597 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
598 var reduceRightCoercesToObject = false;
599 if (ArrayPrototype.reduceRight) {
600     reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
601 }
602 defineProperties(ArrayPrototype, {
603     reduceRight: function reduceRight(callbackfn/*, initial*/) {
604         var object = ES.ToObject(this);
605         var self = splitString && isString(this) ? strSplit(this, '') : object;
606         var length = ES.ToUint32(self.length);
607
608         // If no callback function or if callback is not a callable function
609         if (!isCallable(callbackfn)) {
610             throw new TypeError('Array.prototype.reduceRight callback must be a function');
611         }
612
613         // no value to return if no initial value, empty array
614         if (length === 0 && arguments.length === 1) {
615             throw new TypeError('reduceRight of empty array with no initial value');
616         }
617
618         var result;
619         var i = length - 1;
620         if (arguments.length >= 2) {
621             result = arguments[1];
622         } else {
623             do {
624                 if (i in self) {
625                     result = self[i--];
626                     break;
627                 }
628
629                 // if array contains no values, no initial value to return
630                 if (--i < 0) {
631                     throw new TypeError('reduceRight of empty array with no initial value');
632                 }
633             } while (true);
634         }
635
636         if (i < 0) {
637             return result;
638         }
639
640         do {
641             if (i in self) {
642                 result = callbackfn(result, self[i], i, object);
643             }
644         } while (i--);
645
646         return result;
647     }
648 }, !reduceRightCoercesToObject);
649
650 // ES5 15.4.4.14
651 // http://es5.github.com/#x15.4.4.14
652 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
653 var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
654 defineProperties(ArrayPrototype, {
655     indexOf: function indexOf(searchElement /*, fromIndex */) {
656         var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
657         var length = ES.ToUint32(self.length);
658
659         if (length === 0) {
660             return -1;
661         }
662
663         var i = 0;
664         if (arguments.length > 1) {
665             i = ES.ToInteger(arguments[1]);
666         }
667
668         // handle negative indices
669         i = i >= 0 ? i : max(0, length + i);
670         for (; i < length; i++) {
671             if (i in self && self[i] === searchElement) {
672                 return i;
673             }
674         }
675         return -1;
676     }
677 }, hasFirefox2IndexOfBug);
678
679 // ES5 15.4.4.15
680 // http://es5.github.com/#x15.4.4.15
681 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
682 var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
683 defineProperties(ArrayPrototype, {
684     lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
685         var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
686         var length = ES.ToUint32(self.length);
687
688         if (length === 0) {
689             return -1;
690         }
691         var i = length - 1;
692         if (arguments.length > 1) {
693             i = min(i, ES.ToInteger(arguments[1]));
694         }
695         // handle negative indices
696         i = i >= 0 ? i : length - Math.abs(i);
697         for (; i >= 0; i--) {
698             if (i in self && searchElement === self[i]) {
699                 return i;
700             }
701         }
702         return -1;
703     }
704 }, hasFirefox2LastIndexOfBug);
705
706 // ES5 15.4.4.12
707 // http://es5.github.com/#x15.4.4.12
708 var spliceNoopReturnsEmptyArray = (function () {
709     var a = [1, 2];
710     var result = a.splice();
711     return a.length === 2 && isArray(result) && result.length === 0;
712 }());
713 defineProperties(ArrayPrototype, {
714     // Safari 5.0 bug where .splice() returns undefined
715     splice: function splice(start, deleteCount) {
716         if (arguments.length === 0) {
717             return [];
718         } else {
719             return array_splice.apply(this, arguments);
720         }
721     }
722 }, !spliceNoopReturnsEmptyArray);
723
724 var spliceWorksWithEmptyObject = (function () {
725     var obj = {};
726     ArrayPrototype.splice.call(obj, 0, 0, 1);
727     return obj.length === 1;
728 }());
729 defineProperties(ArrayPrototype, {
730     splice: function splice(start, deleteCount) {
731         if (arguments.length === 0) { return []; }
732         var args = arguments;
733         this.length = max(ES.ToInteger(this.length), 0);
734         if (arguments.length > 0 && typeof deleteCount !== 'number') {
735             args = array_slice.call(arguments);
736             if (args.length < 2) {
737                 array_push.call(args, this.length - start);
738             } else {
739                 args[1] = ES.ToInteger(deleteCount);
740             }
741         }
742         return array_splice.apply(this, args);
743     }
744 }, !spliceWorksWithEmptyObject);
745 var spliceWorksWithLargeSparseArrays = (function () {
746     // Per https://github.com/es-shims/es5-shim/issues/295
747     // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
748     var arr = new $Array(1e5);
749     // note: the index MUST be 8 or larger or the test will false pass
750     arr[8] = 'x';
751     arr.splice(1, 1);
752     // note: this test must be defined *after* the indexOf shim
753     // per https://github.com/es-shims/es5-shim/issues/313
754     return arr.indexOf('x') === 7;
755 }());
756 var spliceWorksWithSmallSparseArrays = (function () {
757     // Per https://github.com/es-shims/es5-shim/issues/295
758     // Opera 12.15 breaks on this, no idea why.
759     var n = 256;
760     var arr = [];
761     arr[n] = 'a';
762     arr.splice(n + 1, 0, 'b');
763     return arr[n] === 'a';
764 }());
765 defineProperties(ArrayPrototype, {
766     splice: function splice(start, deleteCount) {
767         var O = ES.ToObject(this);
768         var A = [];
769         var len = ES.ToUint32(O.length);
770         var relativeStart = ES.ToInteger(start);
771         var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
772         var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
773
774         var k = 0;
775         var from;
776         while (k < actualDeleteCount) {
777             from = $String(actualStart + k);
778             if (owns(O, from)) {
779                 A[k] = O[from];
780             }
781             k += 1;
782         }
783
784         var items = array_slice.call(arguments, 2);
785         var itemCount = items.length;
786         var to;
787         if (itemCount < actualDeleteCount) {
788             k = actualStart;
789             while (k < (len - actualDeleteCount)) {
790                 from = $String(k + actualDeleteCount);
791                 to = $String(k + itemCount);
792                 if (owns(O, from)) {
793                     O[to] = O[from];
794                 } else {
795                     delete O[to];
796                 }
797                 k += 1;
798             }
799             k = len;
800             while (k > (len - actualDeleteCount + itemCount)) {
801                 delete O[k - 1];
802                 k -= 1;
803             }
804         } else if (itemCount > actualDeleteCount) {
805             k = len - actualDeleteCount;
806             while (k > actualStart) {
807                 from = $String(k + actualDeleteCount - 1);
808                 to = $String(k + itemCount - 1);
809                 if (owns(O, from)) {
810                     O[to] = O[from];
811                 } else {
812                     delete O[to];
813                 }
814                 k -= 1;
815             }
816         }
817         k = actualStart;
818         for (var i = 0; i < items.length; ++i) {
819             O[k] = items[i];
820             k += 1;
821         }
822         O.length = len - actualDeleteCount + itemCount;
823
824         return A;
825     }
826 }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
827
828 //
829 // Object
830 // ======
831 //
832
833 // ES5 15.2.3.14
834 // http://es5.github.com/#x15.2.3.14
835
836 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
837 var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
838 var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
839 var hasStringEnumBug = !owns('x', '0');
840 var equalsConstructorPrototype = function (o) {
841     var ctor = o.constructor;
842     return ctor && ctor.prototype === o;
843 };
844 var blacklistedKeys = {
845     $window: true,
846     $console: true,
847     $parent: true,
848     $self: true,
849     $frame: true,
850     $frames: true,
851     $frameElement: true,
852     $webkitIndexedDB: true,
853     $webkitStorageInfo: true
854 };
855 var hasAutomationEqualityBug = (function () {
856     /* globals window */
857     if (typeof window === 'undefined') { return false; }
858     for (var k in window) {
859         try {
860             if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
861                 equalsConstructorPrototype(window[k]);
862             }
863         } catch (e) {
864             return true;
865         }
866     }
867     return false;
868 }());
869 var equalsConstructorPrototypeIfNotBuggy = function (object) {
870     if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); }
871     try {
872         return equalsConstructorPrototype(object);
873     } catch (e) {
874         return false;
875     }
876 };
877 var dontEnums = [
878     'toString',
879     'toLocaleString',
880     'valueOf',
881     'hasOwnProperty',
882     'isPrototypeOf',
883     'propertyIsEnumerable',
884     'constructor'
885 ];
886 var dontEnumsLength = dontEnums.length;
887
888 // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
889 // can be replaced with require('is-arguments') if we ever use a build process instead
890 var isStandardArguments = function isArguments(value) {
891     return toStr(value) === '[object Arguments]';
892 };
893 var isLegacyArguments = function isArguments(value) {
894     return value !== null &&
895         typeof value === 'object' &&
896         typeof value.length === 'number' &&
897         value.length >= 0 &&
898         !isArray(value) &&
899         isCallable(value.callee);
900 };
901 var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
902
903 defineProperties($Object, {
904     keys: function keys(object) {
905         var isFn = isCallable(object);
906         var isArgs = isArguments(object);
907         var isObject = object !== null && typeof object === 'object';
908         var isStr = isObject && isString(object);
909
910         if (!isObject && !isFn && !isArgs) {
911             throw new TypeError('Object.keys called on a non-object');
912         }
913
914         var theKeys = [];
915         var skipProto = hasProtoEnumBug && isFn;
916         if ((isStr && hasStringEnumBug) || isArgs) {
917             for (var i = 0; i < object.length; ++i) {
918                 array_push.call(theKeys, $String(i));
919             }
920         }
921
922         if (!isArgs) {
923             for (var name in object) {
924                 if (!(skipProto && name === 'prototype') && owns(object, name)) {
925                     array_push.call(theKeys, $String(name));
926                 }
927             }
928         }
929
930         if (hasDontEnumBug) {
931             var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
932             for (var j = 0; j < dontEnumsLength; j++) {
933                 var dontEnum = dontEnums[j];
934                 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
935                     array_push.call(theKeys, dontEnum);
936                 }
937             }
938         }
939         return theKeys;
940     }
941 });
942
943 var keysWorksWithArguments = $Object.keys && (function () {
944     // Safari 5.0 bug
945     return $Object.keys(arguments).length === 2;
946 }(1, 2));
947 var keysHasArgumentsLengthBug = $Object.keys && (function () {
948     var argKeys = $Object.keys(arguments);
949     return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
950 }(1));
951 var originalKeys = $Object.keys;
952 defineProperties($Object, {
953     keys: function keys(object) {
954         if (isArguments(object)) {
955             return originalKeys(array_slice.call(object));
956         } else {
957             return originalKeys(object);
958         }
959     }
960 }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
961
962 //
963 // Date
964 // ====
965 //
966
967 // ES5 15.9.5.43
968 // http://es5.github.com/#x15.9.5.43
969 // This function returns a String value represent the instance in time
970 // represented by this Date object. The format of the String is the Date Time
971 // string format defined in 15.9.1.15. All fields are present in the String.
972 // The time zone is always UTC, denoted by the suffix Z. If the time value of
973 // this object is not a finite Number a RangeError exception is thrown.
974 var negativeDate = -62198755200000;
975 var negativeYearString = '-000001';
976 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
977 var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
978
979 defineProperties(Date.prototype, {
980     toISOString: function toISOString() {
981         var result, length, value, year, month;
982         if (!isFinite(this)) {
983             throw new RangeError('Date.prototype.toISOString called on non-finite value.');
984         }
985
986         year = this.getUTCFullYear();
987
988         month = this.getUTCMonth();
989         // see https://github.com/es-shims/es5-shim/issues/111
990         year += Math.floor(month / 12);
991         month = (month % 12 + 12) % 12;
992
993         // the date time string format is specified in 15.9.1.15.
994         result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
995         year = (
996             (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
997             strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
998         );
999
1000         length = result.length;
1001         while (length--) {
1002             value = result[length];
1003             // pad months, days, hours, minutes, and seconds to have two
1004             // digits.
1005             if (value < 10) {
1006                 result[length] = '0' + value;
1007             }
1008         }
1009         // pad milliseconds to have three digits.
1010         return (
1011             year + '-' + array_slice.call(result, 0, 2).join('-') +
1012             'T' + array_slice.call(result, 2).join(':') + '.' +
1013             strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'
1014         );
1015     }
1016 }, hasNegativeDateBug || hasSafari51DateBug);
1017
1018 // ES5 15.9.5.44
1019 // http://es5.github.com/#x15.9.5.44
1020 // This function provides a String representation of a Date object for use by
1021 // JSON.stringify (15.12.3).
1022 var dateToJSONIsSupported = (function () {
1023     try {
1024         return Date.prototype.toJSON &&
1025             new Date(NaN).toJSON() === null &&
1026             new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
1027             Date.prototype.toJSON.call({ // generic
1028                 toISOString: function () { return true; }
1029             });
1030     } catch (e) {
1031         return false;
1032     }
1033 }());
1034 if (!dateToJSONIsSupported) {
1035     Date.prototype.toJSON = function toJSON(key) {
1036         // When the toJSON method is called with argument key, the following
1037         // steps are taken:
1038
1039         // 1.  Let O be the result of calling ToObject, giving it the this
1040         // value as its argument.
1041         // 2. Let tv be ES.ToPrimitive(O, hint Number).
1042         var O = $Object(this);
1043         var tv = ES.ToPrimitive(O);
1044         // 3. If tv is a Number and is not finite, return null.
1045         if (typeof tv === 'number' && !isFinite(tv)) {
1046             return null;
1047         }
1048         // 4. Let toISO be the result of calling the [[Get]] internal method of
1049         // O with argument "toISOString".
1050         var toISO = O.toISOString;
1051         // 5. If IsCallable(toISO) is false, throw a TypeError exception.
1052         if (!isCallable(toISO)) {
1053             throw new TypeError('toISOString property is not callable');
1054         }
1055         // 6. Return the result of calling the [[Call]] internal method of
1056         //  toISO with O as the this value and an empty argument list.
1057         return toISO.call(O);
1058
1059         // NOTE 1 The argument is ignored.
1060
1061         // NOTE 2 The toJSON function is intentionally generic; it does not
1062         // require that its this value be a Date object. Therefore, it can be
1063         // transferred to other kinds of objects for use as a method. However,
1064         // it does require that any such object have a toISOString method. An
1065         // object is free to use the argument key to filter its
1066         // stringification.
1067     };
1068 }
1069
1070 // ES5 15.9.4.2
1071 // http://es5.github.com/#x15.9.4.2
1072 // based on work shared by Daniel Friesen (dantman)
1073 // http://gist.github.com/303249
1074 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
1075 var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
1076 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
1077 if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
1078     // XXX global assignment won't work in embeddings that use
1079     // an alternate object for the context.
1080     /* global Date: true */
1081     /* eslint-disable no-undef */
1082     var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
1083     var secondsWithinMaxSafeUnsigned32Bit = Math.floor(maxSafeUnsigned32Bit / 1e3);
1084     var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
1085     Date = (function (NativeDate) {
1086     /* eslint-enable no-undef */
1087         // Date.length === 7
1088         var DateShim = function Date(Y, M, D, h, m, s, ms) {
1089             var length = arguments.length;
1090             var date;
1091             if (this instanceof NativeDate) {
1092                 var seconds = s;
1093                 var millis = ms;
1094                 if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
1095                     // work around a Safari 8/9 bug where it treats the seconds as signed
1096                     var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1097                     var sToShift = Math.floor(msToShift / 1e3);
1098                     seconds += sToShift;
1099                     millis -= sToShift * 1e3;
1100                 }
1101                 date = length === 1 && $String(Y) === Y ? // isString(Y)
1102                     // We explicitly pass it through parse:
1103                     new NativeDate(DateShim.parse(Y)) :
1104                     // We have to manually make calls depending on argument
1105                     // length here
1106                     length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
1107                     length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
1108                     length >= 5 ? new NativeDate(Y, M, D, h, m) :
1109                     length >= 4 ? new NativeDate(Y, M, D, h) :
1110                     length >= 3 ? new NativeDate(Y, M, D) :
1111                     length >= 2 ? new NativeDate(Y, M) :
1112                     length >= 1 ? new NativeDate(Y) :
1113                                   new NativeDate();
1114             } else {
1115                 date = NativeDate.apply(this, arguments);
1116             }
1117             if (!isPrimitive(date)) {
1118               // Prevent mixups with unfixed Date object
1119               defineProperties(date, { constructor: DateShim }, true);
1120             }
1121             return date;
1122         };
1123
1124         // 15.9.1.15 Date Time String Format.
1125         var isoDateExpression = new RegExp('^' +
1126             '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
1127                                       // 6-digit extended year
1128             '(?:-(\\d{2})' + // optional month capture
1129             '(?:-(\\d{2})' + // optional day capture
1130             '(?:' + // capture hours:minutes:seconds.milliseconds
1131                 'T(\\d{2})' + // hours capture
1132                 ':(\\d{2})' + // minutes capture
1133                 '(?:' + // optional :seconds.milliseconds
1134                     ':(\\d{2})' + // seconds capture
1135                     '(?:(\\.\\d{1,}))?' + // milliseconds capture
1136                 ')?' +
1137             '(' + // capture UTC offset component
1138                 'Z|' + // UTC capture
1139                 '(?:' + // offset specifier +/-hours:minutes
1140                     '([-+])' + // sign capture
1141                     '(\\d{2})' + // hours offset capture
1142                     ':(\\d{2})' + // minutes offset capture
1143                 ')' +
1144             ')?)?)?)?' +
1145         '$');
1146
1147         var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
1148
1149         var dayFromMonth = function dayFromMonth(year, month) {
1150             var t = month > 1 ? 1 : 0;
1151             return (
1152                 months[month] +
1153                 Math.floor((year - 1969 + t) / 4) -
1154                 Math.floor((year - 1901 + t) / 100) +
1155                 Math.floor((year - 1601 + t) / 400) +
1156                 365 * (year - 1970)
1157             );
1158         };
1159
1160         var toUTC = function toUTC(t) {
1161             var s = 0;
1162             var ms = t;
1163             if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
1164                 // work around a Safari 8/9 bug where it treats the seconds as signed
1165                 var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1166                 var sToShift = Math.floor(msToShift / 1e3);
1167                 s += sToShift;
1168                 ms -= sToShift * 1e3;
1169             }
1170             return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
1171         };
1172
1173         // Copy any custom methods a 3rd party library may have added
1174         for (var key in NativeDate) {
1175             if (owns(NativeDate, key)) {
1176                 DateShim[key] = NativeDate[key];
1177             }
1178         }
1179
1180         // Copy "native" methods explicitly; they may be non-enumerable
1181         defineProperties(DateShim, {
1182             now: NativeDate.now,
1183             UTC: NativeDate.UTC
1184         }, true);
1185         DateShim.prototype = NativeDate.prototype;
1186         defineProperties(DateShim.prototype, {
1187             constructor: DateShim
1188         }, true);
1189
1190         // Upgrade Date.parse to handle simplified ISO 8601 strings
1191         var parseShim = function parse(string) {
1192             var match = isoDateExpression.exec(string);
1193             if (match) {
1194                 // parse months, days, hours, minutes, seconds, and milliseconds
1195                 // provide default values if necessary
1196                 // parse the UTC offset component
1197                 var year = $Number(match[1]),
1198                     month = $Number(match[2] || 1) - 1,
1199                     day = $Number(match[3] || 1) - 1,
1200                     hour = $Number(match[4] || 0),
1201                     minute = $Number(match[5] || 0),
1202                     second = $Number(match[6] || 0),
1203                     millisecond = Math.floor($Number(match[7] || 0) * 1000),
1204                     // When time zone is missed, local offset should be used
1205                     // (ES 5.1 bug)
1206                     // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1207                     isLocalTime = Boolean(match[4] && !match[8]),
1208                     signOffset = match[9] === '-' ? 1 : -1,
1209                     hourOffset = $Number(match[10] || 0),
1210                     minuteOffset = $Number(match[11] || 0),
1211                     result;
1212                 var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
1213                 if (
1214                     hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
1215                     minute < 60 && second < 60 && millisecond < 1000 &&
1216                     month > -1 && month < 12 && hourOffset < 24 &&
1217                     minuteOffset < 60 && // detect invalid offsets
1218                     day > -1 &&
1219                     day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
1220                 ) {
1221                     result = (
1222                         (dayFromMonth(year, month) + day) * 24 +
1223                         hour +
1224                         hourOffset * signOffset
1225                     ) * 60;
1226                     result = (
1227                         (result + minute + minuteOffset * signOffset) * 60 +
1228                         second
1229                     ) * 1000 + millisecond;
1230                     if (isLocalTime) {
1231                         result = toUTC(result);
1232                     }
1233                     if (-8.64e15 <= result && result <= 8.64e15) {
1234                         return result;
1235                     }
1236                 }
1237                 return NaN;
1238             }
1239             return NativeDate.parse.apply(this, arguments);
1240         };
1241         defineProperties(DateShim, { parse: parseShim });
1242
1243         return DateShim;
1244     }(Date));
1245     /* global Date: false */
1246 }
1247
1248 // ES5 15.9.4.4
1249 // http://es5.github.com/#x15.9.4.4
1250 if (!Date.now) {
1251     Date.now = function now() {
1252         return new Date().getTime();
1253     };
1254 }
1255
1256 //
1257 // Number
1258 // ======
1259 //
1260
1261 // ES5.1 15.7.4.5
1262 // http://es5.github.com/#x15.7.4.5
1263 var hasToFixedBugs = NumberPrototype.toFixed && (
1264   (0.00008).toFixed(3) !== '0.000' ||
1265   (0.9).toFixed(0) !== '1' ||
1266   (1.255).toFixed(2) !== '1.25' ||
1267   (1000000000000000128).toFixed(0) !== '1000000000000000128'
1268 );
1269
1270 var toFixedHelpers = {
1271   base: 1e7,
1272   size: 6,
1273   data: [0, 0, 0, 0, 0, 0],
1274   multiply: function multiply(n, c) {
1275       var i = -1;
1276       var c2 = c;
1277       while (++i < toFixedHelpers.size) {
1278           c2 += n * toFixedHelpers.data[i];
1279           toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1280           c2 = Math.floor(c2 / toFixedHelpers.base);
1281       }
1282   },
1283   divide: function divide(n) {
1284       var i = toFixedHelpers.size, c = 0;
1285       while (--i >= 0) {
1286           c += toFixedHelpers.data[i];
1287           toFixedHelpers.data[i] = Math.floor(c / n);
1288           c = (c % n) * toFixedHelpers.base;
1289       }
1290   },
1291   numToString: function numToString() {
1292       var i = toFixedHelpers.size;
1293       var s = '';
1294       while (--i >= 0) {
1295           if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1296               var t = $String(toFixedHelpers.data[i]);
1297               if (s === '') {
1298                   s = t;
1299               } else {
1300                   s += strSlice('0000000', 0, 7 - t.length) + t;
1301               }
1302           }
1303       }
1304       return s;
1305   },
1306   pow: function pow(x, n, acc) {
1307       return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1308   },
1309   log: function log(x) {
1310       var n = 0;
1311       var x2 = x;
1312       while (x2 >= 4096) {
1313           n += 12;
1314           x2 /= 4096;
1315       }
1316       while (x2 >= 2) {
1317           n += 1;
1318           x2 /= 2;
1319       }
1320       return n;
1321   }
1322 };
1323
1324 defineProperties(NumberPrototype, {
1325     toFixed: function toFixed(fractionDigits) {
1326         var f, x, s, m, e, z, j, k;
1327
1328         // Test for NaN and round fractionDigits down
1329         f = $Number(fractionDigits);
1330         f = isActualNaN(f) ? 0 : Math.floor(f);
1331
1332         if (f < 0 || f > 20) {
1333             throw new RangeError('Number.toFixed called with invalid number of decimals');
1334         }
1335
1336         x = $Number(this);
1337
1338         if (isActualNaN(x)) {
1339             return 'NaN';
1340         }
1341
1342         // If it is too big or small, return the string value of the number
1343         if (x <= -1e21 || x >= 1e21) {
1344             return $String(x);
1345         }
1346
1347         s = '';
1348
1349         if (x < 0) {
1350             s = '-';
1351             x = -x;
1352         }
1353
1354         m = '0';
1355
1356         if (x > 1e-21) {
1357             // 1e-21 < x < 1e21
1358             // -70 < log2(x) < 70
1359             e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1360             z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1361             z *= 0x10000000000000; // Math.pow(2, 52);
1362             e = 52 - e;
1363
1364             // -18 < e < 122
1365             // x = z / 2 ^ e
1366             if (e > 0) {
1367                 toFixedHelpers.multiply(0, z);
1368                 j = f;
1369
1370                 while (j >= 7) {
1371                     toFixedHelpers.multiply(1e7, 0);
1372                     j -= 7;
1373                 }
1374
1375                 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1376                 j = e - 1;
1377
1378                 while (j >= 23) {
1379                     toFixedHelpers.divide(1 << 23);
1380                     j -= 23;
1381                 }
1382
1383                 toFixedHelpers.divide(1 << j);
1384                 toFixedHelpers.multiply(1, 1);
1385                 toFixedHelpers.divide(2);
1386                 m = toFixedHelpers.numToString();
1387             } else {
1388                 toFixedHelpers.multiply(0, z);
1389                 toFixedHelpers.multiply(1 << (-e), 0);
1390                 m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
1391             }
1392         }
1393
1394         if (f > 0) {
1395             k = m.length;
1396
1397             if (k <= f) {
1398                 m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
1399             } else {
1400                 m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
1401             }
1402         } else {
1403             m = s + m;
1404         }
1405
1406         return m;
1407     }
1408 }, hasToFixedBugs);
1409
1410 //
1411 // String
1412 // ======
1413 //
1414
1415 // ES5 15.5.4.14
1416 // http://es5.github.com/#x15.5.4.14
1417
1418 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1419 // Many browsers do not split properly with regular expressions or they
1420 // do not perform the split correctly under obscure conditions.
1421 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1422 // I've tested in many browsers and this seems to cover the deviant ones:
1423 //    'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1424 //    '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1425 //    'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1426 //       [undefined, "t", undefined, "e", ...]
1427 //    ''.split(/.?/) should be [], not [""]
1428 //    '.'.split(/()()/) should be ["."], not ["", "", "."]
1429
1430 if (
1431     'ab'.split(/(?:ab)*/).length !== 2 ||
1432     '.'.split(/(.?)(.?)/).length !== 4 ||
1433     'tesst'.split(/(s)*/)[1] === 't' ||
1434     'test'.split(/(?:)/, -1).length !== 4 ||
1435     ''.split(/.?/).length ||
1436     '.'.split(/()()/).length > 1
1437 ) {
1438     (function () {
1439         var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1440         var maxSafe32BitInt = Math.pow(2, 32) - 1;
1441
1442         StringPrototype.split = function (separator, limit) {
1443             var string = this;
1444             if (typeof separator === 'undefined' && limit === 0) {
1445                 return [];
1446             }
1447
1448             // If `separator` is not a regex, use native split
1449             if (!isRegex(separator)) {
1450                 return strSplit(this, separator, limit);
1451             }
1452
1453             var output = [];
1454             var flags = (separator.ignoreCase ? 'i' : '') +
1455                         (separator.multiline ? 'm' : '') +
1456                         (separator.unicode ? 'u' : '') + // in ES6
1457                         (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
1458                 lastLastIndex = 0,
1459                 // Make `global` and avoid `lastIndex` issues by working with a copy
1460                 separator2, match, lastIndex, lastLength;
1461             var separatorCopy = new RegExp(separator.source, flags + 'g');
1462             string += ''; // Type-convert
1463             if (!compliantExecNpcg) {
1464                 // Doesn't need flags gy, but they don't hurt
1465                 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
1466             }
1467             /* Values for `limit`, per the spec:
1468              * If undefined: 4294967295 // maxSafe32BitInt
1469              * If 0, Infinity, or NaN: 0
1470              * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1471              * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1472              * If other: Type-convert, then use the above rules
1473              */
1474             var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
1475             match = separatorCopy.exec(string);
1476             while (match) {
1477                 // `separatorCopy.lastIndex` is not reliable cross-browser
1478                 lastIndex = match.index + match[0].length;
1479                 if (lastIndex > lastLastIndex) {
1480                     array_push.call(output, strSlice(string, lastLastIndex, match.index));
1481                     // Fix browsers whose `exec` methods don't consistently return `undefined` for
1482                     // nonparticipating capturing groups
1483                     if (!compliantExecNpcg && match.length > 1) {
1484                         /* eslint-disable no-loop-func */
1485                         match[0].replace(separator2, function () {
1486                             for (var i = 1; i < arguments.length - 2; i++) {
1487                                 if (typeof arguments[i] === 'undefined') {
1488                                     match[i] = void 0;
1489                                 }
1490                             }
1491                         });
1492                         /* eslint-enable no-loop-func */
1493                     }
1494                     if (match.length > 1 && match.index < string.length) {
1495                         array_push.apply(output, array_slice.call(match, 1));
1496                     }
1497                     lastLength = match[0].length;
1498                     lastLastIndex = lastIndex;
1499                     if (output.length >= splitLimit) {
1500                         break;
1501                     }
1502                 }
1503                 if (separatorCopy.lastIndex === match.index) {
1504                     separatorCopy.lastIndex++; // Avoid an infinite loop
1505                 }
1506                 match = separatorCopy.exec(string);
1507             }
1508             if (lastLastIndex === string.length) {
1509                 if (lastLength || !separatorCopy.test('')) {
1510                     array_push.call(output, '');
1511                 }
1512             } else {
1513                 array_push.call(output, strSlice(string, lastLastIndex));
1514             }
1515             return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output;
1516         };
1517     }());
1518
1519 // [bugfix, chrome]
1520 // If separator is undefined, then the result array contains just one String,
1521 // which is the this value (converted to a String). If limit is not undefined,
1522 // then the output array is truncated so that it contains no more than limit
1523 // elements.
1524 // "0".split(undefined, 0) -> []
1525 } else if ('0'.split(void 0, 0).length) {
1526     StringPrototype.split = function split(separator, limit) {
1527         if (typeof separator === 'undefined' && limit === 0) { return []; }
1528         return strSplit(this, separator, limit);
1529     };
1530 }
1531
1532 var str_replace = StringPrototype.replace;
1533 var replaceReportsGroupsCorrectly = (function () {
1534     var groups = [];
1535     'x'.replace(/x(.)?/g, function (match, group) {
1536         array_push.call(groups, group);
1537     });
1538     return groups.length === 1 && typeof groups[0] === 'undefined';
1539 }());
1540
1541 if (!replaceReportsGroupsCorrectly) {
1542     StringPrototype.replace = function replace(searchValue, replaceValue) {
1543         var isFn = isCallable(replaceValue);
1544         var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
1545         if (!isFn || !hasCapturingGroups) {
1546             return str_replace.call(this, searchValue, replaceValue);
1547         } else {
1548             var wrappedReplaceValue = function (match) {
1549                 var length = arguments.length;
1550                 var originalLastIndex = searchValue.lastIndex;
1551                 searchValue.lastIndex = 0;
1552                 var args = searchValue.exec(match) || [];
1553                 searchValue.lastIndex = originalLastIndex;
1554                 array_push.call(args, arguments[length - 2], arguments[length - 1]);
1555                 return replaceValue.apply(this, args);
1556             };
1557             return str_replace.call(this, searchValue, wrappedReplaceValue);
1558         }
1559     };
1560 }
1561
1562 // ECMA-262, 3rd B.2.3
1563 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1564 // non-normative section suggesting uniform semantics and it should be
1565 // normalized across all browsers
1566 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1567 var string_substr = StringPrototype.substr;
1568 var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1569 defineProperties(StringPrototype, {
1570     substr: function substr(start, length) {
1571         var normalizedStart = start;
1572         if (start < 0) {
1573             normalizedStart = max(this.length + start, 0);
1574         }
1575         return string_substr.call(this, normalizedStart, length);
1576     }
1577 }, hasNegativeSubstrBug);
1578
1579 // ES5 15.5.4.20
1580 // whitespace from: http://es5.github.io/#x15.5.4.20
1581 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
1582     '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
1583     '\u2029\uFEFF';
1584 var zeroWidth = '\u200b';
1585 var wsRegexChars = '[' + ws + ']';
1586 var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
1587 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
1588 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
1589 defineProperties(StringPrototype, {
1590     // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1591     // http://perfectionkills.com/whitespace-deviations/
1592     trim: function trim() {
1593         if (typeof this === 'undefined' || this === null) {
1594             throw new TypeError("can't convert " + this + ' to object');
1595         }
1596         return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
1597     }
1598 }, hasTrimWhitespaceBug);
1599
1600 // ES-5 15.1.2.2
1601 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
1602     /* global parseInt: true */
1603     parseInt = (function (origParseInt) {
1604         var hexRegex = /^0[xX]/;
1605         return function parseInt(str, radix) {
1606             var string = $String(str).trim();
1607             var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
1608             return origParseInt(string, defaultedRadix);
1609         };
1610     }(parseInt));
1611 }
1612
1613 }));