UNPKG

93.4 kBJavaScriptView Raw
1/*!
2 * https://github.com/es-shims/es5-shim
3 * @license es5-shim Copyright 2009-2020 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; // eslint-disable-line no-extra-semi
11
12// UMD (Universal Module Definition)
13// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
14(function (root, factory) {
15 'use strict';
16
17 /* global define */
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(); // eslint-disable-line no-param-reassign
29 }
30}(this, function () {
31 /**
32 * Brings an environment as close to ECMAScript 5 compliance
33 * as is possible with the facilities of erstwhile engines.
34 *
35 * Annotated ES5: http://es5.github.com/ (specific links below)
36 * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
37 * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
38 */
39
40 // Shortcut to an often accessed properties, in order to avoid multiple
41 // dereference that costs universally. This also holds a reference to known-good
42 // functions.
43 var $Array = Array;
44 var ArrayPrototype = $Array.prototype;
45 var $Object = Object;
46 var ObjectPrototype = $Object.prototype;
47 var $Function = Function;
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 array_join = ArrayPrototype.join;
59 var call = FunctionPrototype.call;
60 var apply = FunctionPrototype.apply;
61 var max = Math.max;
62 var min = Math.min;
63 var floor = Math.floor;
64 var abs = Math.abs;
65 var pow = Math.pow;
66 var round = Math.round;
67 var log = Math.log;
68 var LOG10E = Math.LOG10E;
69 var log10 = Math.log10 || function log10(value) {
70 return log(value) * LOG10E;
71 };
72
73 // Having a toString local variable name breaks in Opera so use to_string.
74 var to_string = ObjectPrototype.toString;
75
76 /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
77 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
78 var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
79
80 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; };
81 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; };
82 /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
83
84 /* inlined from http://npmjs.com/define-properties */
85 var supportsDescriptors = $Object.defineProperty && (function () {
86 try {
87 var obj = {};
88 $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
89 // eslint-disable-next-line no-unreachable-loop, max-statements-per-line
90 for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables
91 return obj.x === obj;
92 } catch (e) { /* this is ES3 */
93 return false;
94 }
95 }());
96 var defineProperties = (function (has) {
97 // Define configurable, writable, and non-enumerable props
98 // if they don't exist.
99 var defineProperty;
100 if (supportsDescriptors) {
101 defineProperty = function (object, name, method, forceAssign) {
102 if (!forceAssign && (name in object)) {
103 return;
104 }
105 $Object.defineProperty(object, name, {
106 configurable: true,
107 enumerable: false,
108 writable: true,
109 value: method
110 });
111 };
112 } else {
113 defineProperty = function (object, name, method, forceAssign) {
114 if (!forceAssign && (name in object)) {
115 return;
116 }
117 object[name] = method; // eslint-disable-line no-param-reassign
118 };
119 }
120 return function defineProperties(object, map, forceAssign) {
121 for (var name in map) {
122 if (has.call(map, name)) {
123 defineProperty(object, name, map[name], forceAssign);
124 }
125 }
126 };
127 }(ObjectPrototype.hasOwnProperty));
128
129 // this is needed in Chrome 15 (probably earlier) - 36
130 // https://bugs.chromium.org/p/v8/issues/detail?id=3334
131 if ($Object.defineProperty) {
132 var F = function () {};
133 var toStringSentinel = {};
134 var sentinel = { toString: toStringSentinel };
135 $Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });
136 if ((new F()).toString !== toStringSentinel) {
137 var $dP = $Object.defineProperty;
138 defineProperties($Object, {
139 defineProperty: function defineProperty(o, k, d) {
140 var key = $String(k);
141 if (key === 'prototype' && 'writable' in d && 'value' in d) {
142 o[key] = d.value; // eslint-disable-line no-param-reassign
143 }
144 return $dP(o, key, d);
145 }
146 }, true);
147 }
148 }
149
150 //
151 // Util
152 // ======
153 //
154
155 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
156 var isPrimitive = function isPrimitive(input) {
157 var type = typeof input;
158 return input === null || (type !== 'object' && type !== 'function');
159 };
160
161 var isActualNaN = $Number.isNaN || function isActualNaN(x) {
162 return x !== x;
163 };
164
165 var ES = {
166 // ES5 9.4
167 // http://es5.github.com/#x9.4
168 // http://jsperf.com/to-integer
169 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
170 ToInteger: function ToInteger(num) {
171 var n = +num;
172 if (isActualNaN(n)) {
173 n = 0;
174 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
175 n = (n > 0 || -1) * floor(abs(n));
176 }
177 return n;
178 },
179
180 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
181 ToPrimitive: function ToPrimitive(input) {
182 var val, valueOf, toStr;
183 if (isPrimitive(input)) {
184 return input;
185 }
186 valueOf = input.valueOf;
187 if (isCallable(valueOf)) {
188 val = valueOf.call(input);
189 if (isPrimitive(val)) {
190 return val;
191 }
192 }
193 toStr = input.toString;
194 if (isCallable(toStr)) {
195 val = toStr.call(input);
196 if (isPrimitive(val)) {
197 return val;
198 }
199 }
200 throw new TypeError();
201 },
202
203 // ES5 9.9
204 // http://es5.github.com/#x9.9
205 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
206 ToObject: function (o) {
207 if (o == null) { // this matches both null and undefined
208 throw new TypeError("can't convert " + o + ' to object');
209 }
210 return $Object(o);
211 },
212
213 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
214 ToUint32: function ToUint32(x) {
215 return x >>> 0;
216 }
217 };
218
219 //
220 // Function
221 // ========
222 //
223
224 // ES-5 15.3.4.5
225 // http://es5.github.com/#x15.3.4.5
226
227 var Empty = function Empty() {};
228
229 defineProperties(FunctionPrototype, {
230 bind: function bind(that) { // .length is 1
231 // 1. Let Target be the this value.
232 var target = this;
233 // 2. If IsCallable(Target) is false, throw a TypeError exception.
234 if (!isCallable(target)) {
235 throw new TypeError('Function.prototype.bind called on incompatible ' + target);
236 }
237 // 3. Let A be a new (possibly empty) internal list of all of the
238 // argument values provided after thisArg (arg1, arg2 etc), in order.
239 // XXX slicedArgs will stand in for "A" if used
240 var args = array_slice.call(arguments, 1); // for normal call
241 // 4. Let F be a new native ECMAScript object.
242 // 11. Set the [[Prototype]] internal property of F to the standard
243 // built-in Function prototype object as specified in 15.3.3.1.
244 // 12. Set the [[Call]] internal property of F as described in
245 // 15.3.4.5.1.
246 // 13. Set the [[Construct]] internal property of F as described in
247 // 15.3.4.5.2.
248 // 14. Set the [[HasInstance]] internal property of F as described in
249 // 15.3.4.5.3.
250 var bound;
251 var binder = function () {
252
253 if (this instanceof bound) {
254 // 15.3.4.5.2 [[Construct]]
255 // When the [[Construct]] internal method of a function object,
256 // F that was created using the bind function is called with a
257 // list of arguments ExtraArgs, the following steps are taken:
258 // 1. Let target be the value of F's [[TargetFunction]]
259 // internal property.
260 // 2. If target has no [[Construct]] internal method, a
261 // TypeError exception is thrown.
262 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
263 // property.
264 // 4. Let args be a new list containing the same values as the
265 // list boundArgs in the same order followed by the same
266 // values as the list ExtraArgs in the same order.
267 // 5. Return the result of calling the [[Construct]] internal
268 // method of target providing args as the arguments.
269
270 var result = apply.call(
271 target,
272 this,
273 array_concat.call(args, array_slice.call(arguments))
274 );
275 if ($Object(result) === result) {
276 return result;
277 }
278 return this;
279
280 }
281 // 15.3.4.5.1 [[Call]]
282 // When the [[Call]] internal method of a function object, F,
283 // which was created using the bind function is called with a
284 // this value and a list of arguments ExtraArgs, the following
285 // steps are taken:
286 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
287 // property.
288 // 2. Let boundThis be the value of F's [[BoundThis]] internal
289 // property.
290 // 3. Let target be the value of F's [[TargetFunction]] internal
291 // property.
292 // 4. Let args be a new list containing the same values as the
293 // list boundArgs in the same order followed by the same
294 // values as the list ExtraArgs in the same order.
295 // 5. Return the result of calling the [[Call]] internal method
296 // of target providing boundThis as the this value and
297 // providing args as the arguments.
298
299 // equiv: target.call(this, ...boundArgs, ...args)
300 return apply.call(
301 target,
302 that,
303 array_concat.call(args, array_slice.call(arguments))
304 );
305
306 };
307
308 // 15. If the [[Class]] internal property of Target is "Function", then
309 // a. Let L be the length property of Target minus the length of A.
310 // b. Set the length own property of F to either 0 or L, whichever is
311 // larger.
312 // 16. Else set the length own property of F to 0.
313
314 var boundLength = max(0, target.length - args.length);
315
316 // 17. Set the attributes of the length own property of F to the values
317 // specified in 15.3.5.1.
318 var boundArgs = [];
319 for (var i = 0; i < boundLength; i++) {
320 array_push.call(boundArgs, '$' + i);
321 }
322
323 // XXX Build a dynamic function with desired amount of arguments is the only
324 // way to set the length property of a function.
325 // In environments where Content Security Policies enabled (Chrome extensions,
326 // for ex.) all use of eval or Function costructor throws an exception.
327 // However in all of these environments Function.prototype.bind exists
328 // and so this code will never be executed.
329 bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
330
331 if (target.prototype) {
332 Empty.prototype = target.prototype;
333 bound.prototype = new Empty();
334 // Clean up dangling references.
335 Empty.prototype = null;
336 }
337
338 // TODO
339 // 18. Set the [[Extensible]] internal property of F to true.
340
341 // TODO
342 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
343 // 20. Call the [[DefineOwnProperty]] internal method of F with
344 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
345 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
346 // false.
347 // 21. Call the [[DefineOwnProperty]] internal method of F with
348 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
349 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
350 // and false.
351
352 // TODO
353 // NOTE Function objects created using Function.prototype.bind do not
354 // have a prototype property or the [[Code]], [[FormalParameters]], and
355 // [[Scope]] internal properties.
356 // XXX can't delete prototype in pure-js.
357
358 // 22. Return F.
359 return bound;
360 }
361 });
362
363 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
364 // use it in defining shortcuts.
365 var owns = call.bind(ObjectPrototype.hasOwnProperty);
366 var toStr = call.bind(ObjectPrototype.toString);
367 var arraySlice = call.bind(array_slice);
368 var arraySliceApply = apply.bind(array_slice);
369 /* globals document */
370 if (typeof document === 'object' && document && document.documentElement) {
371 try {
372 arraySlice(document.documentElement.childNodes);
373 } catch (e) {
374 var origArraySlice = arraySlice;
375 var origArraySliceApply = arraySliceApply;
376 arraySlice = function arraySliceIE(arr) {
377 var r = [];
378 var i = arr.length;
379 while (i-- > 0) {
380 r[i] = arr[i];
381 }
382 return origArraySliceApply(r, origArraySlice(arguments, 1));
383 };
384 arraySliceApply = function arraySliceApplyIE(arr, args) {
385 return origArraySliceApply(arraySlice(arr), args);
386 };
387 }
388 }
389 var strSlice = call.bind(StringPrototype.slice);
390 var strSplit = call.bind(StringPrototype.split);
391 var strIndexOf = call.bind(StringPrototype.indexOf);
392 var pushCall = call.bind(array_push);
393 var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
394 var arraySort = call.bind(ArrayPrototype.sort);
395
396 //
397 // Array
398 // =====
399 //
400
401 var isArray = $Array.isArray || function isArray(obj) {
402 return toStr(obj) === '[object Array]';
403 };
404
405 // ES5 15.4.4.12
406 // http://es5.github.com/#x15.4.4.13
407 // Return len+argCount.
408 // [bugfix, ielt8]
409 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
410 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
411 defineProperties(ArrayPrototype, {
412 unshift: function () {
413 array_unshift.apply(this, arguments);
414 return this.length;
415 }
416 }, hasUnshiftReturnValueBug);
417
418 // ES5 15.4.3.2
419 // http://es5.github.com/#x15.4.3.2
420 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
421 defineProperties($Array, { isArray: isArray });
422
423 // The IsCallable() check in the Array functions
424 // has been replaced with a strict check on the
425 // internal class of the object to trap cases where
426 // the provided function was actually a regular
427 // expression literal, which in V8 and
428 // JavaScriptCore is a typeof "function". Only in
429 // V8 are regular expression literals permitted as
430 // reduce parameters, so it is desirable in the
431 // general case for the shim to match the more
432 // strict and common behavior of rejecting regular
433 // expressions.
434
435 // ES5 15.4.4.18
436 // http://es5.github.com/#x15.4.4.18
437 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
438
439 // Check failure of by-index access of string characters (IE < 9)
440 // and failure of `0 in boxedString` (Rhino)
441 var boxedString = $Object('a');
442 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
443
444 var properlyBoxesContext = function properlyBoxed(method) {
445 // Check node 0.6.21 bug where third parameter is not boxed
446 var properlyBoxesNonStrict = true;
447 var properlyBoxesStrict = true;
448 var threwException = false;
449 if (method) {
450 try {
451 method.call('foo', function (_, __, context) {
452 if (typeof context !== 'object') {
453 properlyBoxesNonStrict = false;
454 }
455 });
456
457 method.call([1], function () {
458 'use strict';
459
460 properlyBoxesStrict = typeof this === 'string';
461 }, 'x');
462 } catch (e) {
463 threwException = true;
464 }
465 }
466 return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
467 };
468
469 defineProperties(ArrayPrototype, {
470 forEach: function forEach(callbackfn/*, thisArg*/) {
471 var object = ES.ToObject(this);
472 var self = splitString && isString(this) ? strSplit(this, '') : object;
473 var i = -1;
474 var length = ES.ToUint32(self.length);
475 var T;
476 if (arguments.length > 1) {
477 T = arguments[1];
478 }
479
480 // If no callback function or if callback is not a callable function
481 if (!isCallable(callbackfn)) {
482 throw new TypeError('Array.prototype.forEach callback must be a function');
483 }
484
485 while (++i < length) {
486 if (i in self) {
487 // Invoke the callback function with call, passing arguments:
488 // context, property value, property key, thisArg object
489 if (typeof T === 'undefined') {
490 callbackfn(self[i], i, object);
491 } else {
492 callbackfn.call(T, self[i], i, object);
493 }
494 }
495 }
496 }
497 }, !properlyBoxesContext(ArrayPrototype.forEach));
498
499 // ES5 15.4.4.19
500 // http://es5.github.com/#x15.4.4.19
501 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
502 defineProperties(ArrayPrototype, {
503 map: function map(callbackfn/*, thisArg*/) {
504 var object = ES.ToObject(this);
505 var self = splitString && isString(this) ? strSplit(this, '') : object;
506 var length = ES.ToUint32(self.length);
507 var result = $Array(length);
508 var T;
509 if (arguments.length > 1) {
510 T = arguments[1];
511 }
512
513 // If no callback function or if callback is not a callable function
514 if (!isCallable(callbackfn)) {
515 throw new TypeError('Array.prototype.map callback must be a function');
516 }
517
518 for (var i = 0; i < length; i++) {
519 if (i in self) {
520 if (typeof T === 'undefined') {
521 result[i] = callbackfn(self[i], i, object);
522 } else {
523 result[i] = callbackfn.call(T, self[i], i, object);
524 }
525 }
526 }
527 return result;
528 }
529 }, !properlyBoxesContext(ArrayPrototype.map));
530
531 // ES5 15.4.4.20
532 // http://es5.github.com/#x15.4.4.20
533 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
534 defineProperties(ArrayPrototype, {
535 filter: function filter(callbackfn/*, thisArg*/) {
536 var object = ES.ToObject(this);
537 var self = splitString && isString(this) ? strSplit(this, '') : object;
538 var length = ES.ToUint32(self.length);
539 var result = [];
540 var value;
541 var T;
542 if (arguments.length > 1) {
543 T = arguments[1];
544 }
545
546 // If no callback function or if callback is not a callable function
547 if (!isCallable(callbackfn)) {
548 throw new TypeError('Array.prototype.filter callback must be a function');
549 }
550
551 for (var i = 0; i < length; i++) {
552 if (i in self) {
553 value = self[i];
554 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
555 pushCall(result, value);
556 }
557 }
558 }
559 return result;
560 }
561 }, !properlyBoxesContext(ArrayPrototype.filter));
562
563 // ES5 15.4.4.16
564 // http://es5.github.com/#x15.4.4.16
565 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
566 defineProperties(ArrayPrototype, {
567 every: function every(callbackfn/*, thisArg*/) {
568 var object = ES.ToObject(this);
569 var self = splitString && isString(this) ? strSplit(this, '') : object;
570 var length = ES.ToUint32(self.length);
571 var T;
572 if (arguments.length > 1) {
573 T = arguments[1];
574 }
575
576 // If no callback function or if callback is not a callable function
577 if (!isCallable(callbackfn)) {
578 throw new TypeError('Array.prototype.every callback must be a function');
579 }
580
581 for (var i = 0; i < length; i++) {
582 if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
583 return false;
584 }
585 }
586 return true;
587 }
588 }, !properlyBoxesContext(ArrayPrototype.every));
589
590 // ES5 15.4.4.17
591 // http://es5.github.com/#x15.4.4.17
592 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
593 defineProperties(ArrayPrototype, {
594 some: function some(callbackfn/*, thisArg */) {
595 var object = ES.ToObject(this);
596 var self = splitString && isString(this) ? strSplit(this, '') : object;
597 var length = ES.ToUint32(self.length);
598 var T;
599 if (arguments.length > 1) {
600 T = arguments[1];
601 }
602
603 // If no callback function or if callback is not a callable function
604 if (!isCallable(callbackfn)) {
605 throw new TypeError('Array.prototype.some callback must be a function');
606 }
607
608 for (var i = 0; i < length; i++) {
609 if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
610 return true;
611 }
612 }
613 return false;
614 }
615 }, !properlyBoxesContext(ArrayPrototype.some));
616
617 // ES5 15.4.4.21
618 // http://es5.github.com/#x15.4.4.21
619 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
620 var reduceCoercesToObject = false;
621 if (ArrayPrototype.reduce) {
622 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
623 return list;
624 }) === 'object';
625 }
626 defineProperties(ArrayPrototype, {
627 reduce: function reduce(callbackfn/*, initialValue*/) {
628 var object = ES.ToObject(this);
629 var self = splitString && isString(this) ? strSplit(this, '') : object;
630 var length = ES.ToUint32(self.length);
631
632 // If no callback function or if callback is not a callable function
633 if (!isCallable(callbackfn)) {
634 throw new TypeError('Array.prototype.reduce callback must be a function');
635 }
636
637 // no value to return if no initial value and an empty array
638 if (length === 0 && arguments.length === 1) {
639 throw new TypeError('reduce of empty array with no initial value');
640 }
641
642 var i = 0;
643 var result;
644 if (arguments.length >= 2) {
645 result = arguments[1];
646 } else {
647 do {
648 if (i in self) {
649 result = self[i++];
650 break;
651 }
652
653 // if array contains no values, no initial value to return
654 if (++i >= length) {
655 throw new TypeError('reduce of empty array with no initial value');
656 }
657 } while (true);
658 }
659
660 for (; i < length; i++) {
661 if (i in self) {
662 result = callbackfn(result, self[i], i, object);
663 }
664 }
665
666 return result;
667 }
668 }, !reduceCoercesToObject);
669
670 // ES5 15.4.4.22
671 // http://es5.github.com/#x15.4.4.22
672 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
673 var reduceRightCoercesToObject = false;
674 if (ArrayPrototype.reduceRight) {
675 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
676 return list;
677 }) === 'object';
678 }
679 defineProperties(ArrayPrototype, {
680 reduceRight: function reduceRight(callbackfn/*, initial*/) {
681 var object = ES.ToObject(this);
682 var self = splitString && isString(this) ? strSplit(this, '') : object;
683 var length = ES.ToUint32(self.length);
684
685 // If no callback function or if callback is not a callable function
686 if (!isCallable(callbackfn)) {
687 throw new TypeError('Array.prototype.reduceRight callback must be a function');
688 }
689
690 // no value to return if no initial value, empty array
691 if (length === 0 && arguments.length === 1) {
692 throw new TypeError('reduceRight of empty array with no initial value');
693 }
694
695 var result;
696 var i = length - 1;
697 if (arguments.length >= 2) {
698 result = arguments[1];
699 } else {
700 do {
701 if (i in self) {
702 result = self[i--];
703 break;
704 }
705
706 // if array contains no values, no initial value to return
707 if (--i < 0) {
708 throw new TypeError('reduceRight of empty array with no initial value');
709 }
710 } while (true);
711 }
712
713 if (i < 0) {
714 return result;
715 }
716
717 do {
718 if (i in self) {
719 result = callbackfn(result, self[i], i, object);
720 }
721 } while (i--);
722
723 return result;
724 }
725 }, !reduceRightCoercesToObject);
726
727 // ES5 15.4.4.14
728 // http://es5.github.com/#x15.4.4.14
729 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
730 var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
731 defineProperties(ArrayPrototype, {
732 indexOf: function indexOf(searchElement/*, fromIndex */) {
733 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
734 var length = ES.ToUint32(self.length);
735
736 if (length === 0) {
737 return -1;
738 }
739
740 var i = 0;
741 if (arguments.length > 1) {
742 i = ES.ToInteger(arguments[1]);
743 }
744
745 // handle negative indices
746 i = i >= 0 ? i : max(0, length + i);
747 for (; i < length; i++) {
748 if (i in self && self[i] === searchElement) {
749 return i;
750 }
751 }
752 return -1;
753 }
754 }, hasFirefox2IndexOfBug);
755
756 // ES5 15.4.4.15
757 // http://es5.github.com/#x15.4.4.15
758 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
759 var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
760 defineProperties(ArrayPrototype, {
761 lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
762 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
763 var length = ES.ToUint32(self.length);
764
765 if (length === 0) {
766 return -1;
767 }
768 var i = length - 1;
769 if (arguments.length > 1) {
770 i = min(i, ES.ToInteger(arguments[1]));
771 }
772 // handle negative indices
773 i = i >= 0 ? i : length - abs(i);
774 for (; i >= 0; i--) {
775 if (i in self && searchElement === self[i]) {
776 return i;
777 }
778 }
779 return -1;
780 }
781 }, hasFirefox2LastIndexOfBug);
782
783 // ES5 15.4.4.12
784 // http://es5.github.com/#x15.4.4.12
785 var spliceNoopReturnsEmptyArray = (function () {
786 var a = [1, 2];
787 var result = a.splice();
788 return a.length === 2 && isArray(result) && result.length === 0;
789 }());
790 defineProperties(ArrayPrototype, {
791 // Safari 5.0 bug where .splice() returns undefined
792 splice: function splice(start, deleteCount) {
793 if (arguments.length === 0) {
794 return [];
795 }
796 return array_splice.apply(this, arguments);
797
798 }
799 }, !spliceNoopReturnsEmptyArray);
800
801 var spliceWorksWithEmptyObject = (function () {
802 var obj = {};
803 ArrayPrototype.splice.call(obj, 0, 0, 1);
804 return obj.length === 1;
805 }());
806 defineProperties(ArrayPrototype, {
807 splice: function splice(start, deleteCount) {
808 if (arguments.length === 0) {
809 return [];
810 }
811 var args = arguments;
812 this.length = max(ES.ToInteger(this.length), 0);
813 if (arguments.length > 0 && typeof deleteCount !== 'number') {
814 args = arraySlice(arguments);
815 if (args.length < 2) {
816 pushCall(args, this.length - start);
817 } else {
818 args[1] = ES.ToInteger(deleteCount);
819 }
820 }
821 return array_splice.apply(this, args);
822 }
823 }, !spliceWorksWithEmptyObject);
824 var spliceWorksWithLargeSparseArrays = (function () {
825 // Per https://github.com/es-shims/es5-shim/issues/295
826 // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
827 var arr = new $Array(1e5);
828 // note: the index MUST be 8 or larger or the test will false pass
829 arr[8] = 'x';
830 arr.splice(1, 1);
831 // note: this test must be defined *after* the indexOf shim
832 // per https://github.com/es-shims/es5-shim/issues/313
833 return arr.indexOf('x') === 7;
834 }());
835 var spliceWorksWithSmallSparseArrays = (function () {
836 // Per https://github.com/es-shims/es5-shim/issues/295
837 // Opera 12.15 breaks on this, no idea why.
838 var n = 256;
839 var arr = [];
840 arr[n] = 'a';
841 arr.splice(n + 1, 0, 'b');
842 return arr[n] === 'a';
843 }());
844 defineProperties(ArrayPrototype, {
845 splice: function splice(start, deleteCount) {
846 var O = ES.ToObject(this);
847 var A = [];
848 var len = ES.ToUint32(O.length);
849 var relativeStart = ES.ToInteger(start);
850 var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
851 var actualDeleteCount = arguments.length === 0
852 ? 0
853 : arguments.length === 1
854 ? len - actualStart
855 : min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
856
857 var k = 0;
858 var from;
859 while (k < actualDeleteCount) {
860 from = $String(actualStart + k);
861 if (owns(O, from)) {
862 A[k] = O[from];
863 }
864 k += 1;
865 }
866
867 var items = arraySlice(arguments, 2);
868 var itemCount = items.length;
869 var to;
870 if (itemCount < actualDeleteCount) {
871 k = actualStart;
872 var maxK = len - actualDeleteCount;
873 while (k < maxK) {
874 from = $String(k + actualDeleteCount);
875 to = $String(k + itemCount);
876 if (owns(O, from)) {
877 O[to] = O[from];
878 } else {
879 delete O[to];
880 }
881 k += 1;
882 }
883 k = len;
884 var minK = len - actualDeleteCount + itemCount;
885 while (k > minK) {
886 delete O[k - 1];
887 k -= 1;
888 }
889 } else if (itemCount > actualDeleteCount) {
890 k = len - actualDeleteCount;
891 while (k > actualStart) {
892 from = $String(k + actualDeleteCount - 1);
893 to = $String(k + itemCount - 1);
894 if (owns(O, from)) {
895 O[to] = O[from];
896 } else {
897 delete O[to];
898 }
899 k -= 1;
900 }
901 }
902 k = actualStart;
903 for (var i = 0; i < items.length; ++i) {
904 O[k] = items[i];
905 k += 1;
906 }
907 O.length = len - actualDeleteCount + itemCount;
908
909 return A;
910 }
911 }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
912
913 var originalJoin = ArrayPrototype.join;
914 var hasStringJoinBug;
915 try {
916 hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
917 } catch (e) {
918 hasStringJoinBug = true;
919 }
920 if (hasStringJoinBug) {
921 defineProperties(ArrayPrototype, {
922 join: function join(separator) {
923 var sep = typeof separator === 'undefined' ? ',' : separator;
924 return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
925 }
926 }, hasStringJoinBug);
927 }
928
929 var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
930 if (hasJoinUndefinedBug) {
931 defineProperties(ArrayPrototype, {
932 join: function join(separator) {
933 var sep = typeof separator === 'undefined' ? ',' : separator;
934 return originalJoin.call(this, sep);
935 }
936 }, hasJoinUndefinedBug);
937 }
938
939 var pushShim = function push(item) {
940 var O = ES.ToObject(this);
941 var n = ES.ToUint32(O.length);
942 var i = 0;
943 while (i < arguments.length) {
944 O[n + i] = arguments[i];
945 i += 1;
946 }
947 O.length = n + i;
948 return n + i;
949 };
950
951 var pushIsNotGeneric = (function () {
952 var obj = {};
953 var result = Array.prototype.push.call(obj, undefined);
954 return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
955 }());
956 defineProperties(ArrayPrototype, {
957 push: function push(item) {
958 if (isArray(this)) {
959 return array_push.apply(this, arguments);
960 }
961 return pushShim.apply(this, arguments);
962 }
963 }, pushIsNotGeneric);
964
965 // This fixes a very weird bug in Opera 10.6 when pushing `undefined
966 var pushUndefinedIsWeird = (function () {
967 var arr = [];
968 var result = arr.push(undefined);
969 return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
970 }());
971 defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
972
973 // ES5 15.2.3.14
974 // http://es5.github.io/#x15.4.4.10
975 // Fix boxed string bug
976 defineProperties(ArrayPrototype, {
977 slice: function (start, end) {
978 var arr = isString(this) ? strSplit(this, '') : this;
979 return arraySliceApply(arr, arguments);
980 }
981 }, splitString);
982
983 var sortIgnoresNonFunctions = (function () {
984 try {
985 [1, 2].sort(null);
986 } catch (e) {
987 try {
988 [1, 2].sort({});
989 } catch (e2) {
990 return false;
991 }
992 }
993 return true;
994 }());
995 var sortThrowsOnRegex = (function () {
996 // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
997 try {
998 [1, 2].sort(/a/);
999 return false;
1000 } catch (e) {}
1001 return true;
1002 }());
1003 var sortIgnoresUndefined = (function () {
1004 // applies in IE 8, for one.
1005 try {
1006 [1, 2].sort(undefined);
1007 return true;
1008 } catch (e) {}
1009 return false;
1010 }());
1011 defineProperties(ArrayPrototype, {
1012 sort: function sort(compareFn) {
1013 if (typeof compareFn === 'undefined') {
1014 return arraySort(this);
1015 }
1016 if (!isCallable(compareFn)) {
1017 throw new TypeError('Array.prototype.sort callback must be a function');
1018 }
1019 return arraySort(this, compareFn);
1020 }
1021 }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
1022
1023 //
1024 // Object
1025 // ======
1026 //
1027
1028 // ES5 15.2.3.14
1029 // http://es5.github.com/#x15.2.3.14
1030
1031 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
1032 // eslint-disable-next-line quote-props
1033 var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString'); // jscs:ignore disallowQuotedKeysInObjects
1034 var hasProtoEnumBug = isEnum(function () {}, 'prototype');
1035 var hasStringEnumBug = !owns('x', '0');
1036 var equalsConstructorPrototype = function (o) {
1037 var ctor = o.constructor;
1038 return ctor && ctor.prototype === o;
1039 };
1040 var excludedKeys = {
1041 $applicationCache: true,
1042 $console: true,
1043 $external: true,
1044 $frame: true,
1045 $frameElement: true,
1046 $frames: true,
1047 $innerHeight: true,
1048 $innerWidth: true,
1049 $onmozfullscreenchange: true,
1050 $onmozfullscreenerror: true,
1051 $outerHeight: true,
1052 $outerWidth: true,
1053 $pageXOffset: true,
1054 $pageYOffset: true,
1055 $parent: true,
1056 $scrollLeft: true,
1057 $scrollTop: true,
1058 $scrollX: true,
1059 $scrollY: true,
1060 $self: true,
1061 $webkitIndexedDB: true,
1062 $webkitStorageInfo: true,
1063 $window: true,
1064
1065 $width: true,
1066 $height: true,
1067 $top: true,
1068 $localStorage: true
1069 };
1070 var hasAutomationEqualityBug = (function () {
1071 /* globals window */
1072 if (typeof window === 'undefined') {
1073 return false;
1074 }
1075 for (var k in window) {
1076 try {
1077 if (!excludedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
1078 equalsConstructorPrototype(window[k]);
1079 }
1080 } catch (e) {
1081 return true;
1082 }
1083 }
1084 return false;
1085 }());
1086 var equalsConstructorPrototypeIfNotBuggy = function (object) {
1087 if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
1088 return equalsConstructorPrototype(object);
1089 }
1090 try {
1091 return equalsConstructorPrototype(object);
1092 } catch (e) {
1093 return false;
1094 }
1095 };
1096 var dontEnums = [
1097 'toString',
1098 'toLocaleString',
1099 'valueOf',
1100 'hasOwnProperty',
1101 'isPrototypeOf',
1102 'propertyIsEnumerable',
1103 'constructor'
1104 ];
1105 var dontEnumsLength = dontEnums.length;
1106
1107 // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
1108 // can be replaced with require('is-arguments') if we ever use a build process instead
1109 var isStandardArguments = function isArguments(value) {
1110 return toStr(value) === '[object Arguments]';
1111 };
1112 var isLegacyArguments = function isArguments(value) {
1113 return value !== null
1114 && typeof value === 'object'
1115 && typeof value.length === 'number'
1116 && value.length >= 0
1117 && !isArray(value)
1118 && isCallable(value.callee);
1119 };
1120 var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
1121
1122 defineProperties($Object, {
1123 keys: function keys(object) {
1124 var isFn = isCallable(object);
1125 var isArgs = isArguments(object);
1126 var isObject = object !== null && typeof object === 'object';
1127 var isStr = isObject && isString(object);
1128
1129 if (!isObject && !isFn && !isArgs) {
1130 throw new TypeError('Object.keys called on a non-object');
1131 }
1132
1133 var theKeys = [];
1134 var skipProto = hasProtoEnumBug && isFn;
1135 if ((isStr && hasStringEnumBug) || isArgs) {
1136 for (var i = 0; i < object.length; ++i) {
1137 pushCall(theKeys, $String(i));
1138 }
1139 }
1140
1141 if (!isArgs) {
1142 for (var name in object) {
1143 if (!(skipProto && name === 'prototype') && owns(object, name)) {
1144 pushCall(theKeys, $String(name));
1145 }
1146 }
1147 }
1148
1149 if (hasDontEnumBug) {
1150 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
1151 for (var j = 0; j < dontEnumsLength; j++) {
1152 var dontEnum = dontEnums[j];
1153 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
1154 pushCall(theKeys, dontEnum);
1155 }
1156 }
1157 }
1158 return theKeys;
1159 }
1160 });
1161
1162 var keysWorksWithArguments = $Object.keys && (function () {
1163 // Safari 5.0 bug
1164 return $Object.keys(arguments).length === 2;
1165 }(1, 2));
1166 var keysHasArgumentsLengthBug = $Object.keys && (function () {
1167 var argKeys = $Object.keys(arguments);
1168 return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
1169 }(1));
1170 var originalKeys = $Object.keys;
1171 defineProperties($Object, {
1172 keys: function keys(object) {
1173 if (isArguments(object)) {
1174 return originalKeys(arraySlice(object));
1175 }
1176 return originalKeys(object);
1177
1178 }
1179 }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
1180
1181 //
1182 // Date
1183 // ====
1184 //
1185
1186 var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
1187 var aNegativeTestDate = new Date(-1509842289600292);
1188 var aPositiveTestDate = new Date(1449662400000);
1189 var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
1190 var hasToDateStringFormatBug;
1191 var hasToStringFormatBug;
1192 var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
1193 if (timeZoneOffset < -720) {
1194 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
1195 hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-+]\d\d\d\d(?: |$)/).test(String(aPositiveTestDate));
1196 } else {
1197 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
1198 hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-+]\d\d\d\d(?: |$)/).test(String(aPositiveTestDate));
1199 }
1200
1201 var originalGetFullYear = call.bind(Date.prototype.getFullYear);
1202 var originalGetMonth = call.bind(Date.prototype.getMonth);
1203 var originalGetDate = call.bind(Date.prototype.getDate);
1204 var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
1205 var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
1206 var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
1207 var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
1208 var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
1209 var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
1210 var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
1211 var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
1212 var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
1213 var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1214 var daysInMonth = function daysInMonth(month, year) {
1215 return originalGetDate(new Date(year, month, 0));
1216 };
1217
1218 defineProperties(Date.prototype, {
1219 getFullYear: function getFullYear() {
1220 if (!this || !(this instanceof Date)) {
1221 throw new TypeError('this is not a Date object.');
1222 }
1223 var year = originalGetFullYear(this);
1224 if (year < 0 && originalGetMonth(this) > 11) {
1225 return year + 1;
1226 }
1227 return year;
1228 },
1229 getMonth: function getMonth() {
1230 if (!this || !(this instanceof Date)) {
1231 throw new TypeError('this is not a Date object.');
1232 }
1233 var year = originalGetFullYear(this);
1234 var month = originalGetMonth(this);
1235 if (year < 0 && month > 11) {
1236 return 0;
1237 }
1238 return month;
1239 },
1240 getDate: function getDate() {
1241 if (!this || !(this instanceof Date)) {
1242 throw new TypeError('this is not a Date object.');
1243 }
1244 var year = originalGetFullYear(this);
1245 var month = originalGetMonth(this);
1246 var date = originalGetDate(this);
1247 if (year < 0 && month > 11) {
1248 if (month === 12) {
1249 return date;
1250 }
1251 var days = daysInMonth(0, year + 1);
1252 return (days - date) + 1;
1253 }
1254 return date;
1255 },
1256 getUTCFullYear: function getUTCFullYear() {
1257 if (!this || !(this instanceof Date)) {
1258 throw new TypeError('this is not a Date object.');
1259 }
1260 var year = originalGetUTCFullYear(this);
1261 if (year < 0 && originalGetUTCMonth(this) > 11) {
1262 return year + 1;
1263 }
1264 return year;
1265 },
1266 getUTCMonth: function getUTCMonth() {
1267 if (!this || !(this instanceof Date)) {
1268 throw new TypeError('this is not a Date object.');
1269 }
1270 var year = originalGetUTCFullYear(this);
1271 var month = originalGetUTCMonth(this);
1272 if (year < 0 && month > 11) {
1273 return 0;
1274 }
1275 return month;
1276 },
1277 getUTCDate: function getUTCDate() {
1278 if (!this || !(this instanceof Date)) {
1279 throw new TypeError('this is not a Date object.');
1280 }
1281 var year = originalGetUTCFullYear(this);
1282 var month = originalGetUTCMonth(this);
1283 var date = originalGetUTCDate(this);
1284 if (year < 0 && month > 11) {
1285 if (month === 12) {
1286 return date;
1287 }
1288 var days = daysInMonth(0, year + 1);
1289 return (days - date) + 1;
1290 }
1291 return date;
1292 }
1293 }, hasNegativeMonthYearBug);
1294
1295 defineProperties(Date.prototype, {
1296 toUTCString: function toUTCString() {
1297 if (!this || !(this instanceof Date)) {
1298 throw new TypeError('this is not a Date object.');
1299 }
1300 var day = originalGetUTCDay(this);
1301 var date = originalGetUTCDate(this);
1302 var month = originalGetUTCMonth(this);
1303 var year = originalGetUTCFullYear(this);
1304 var hour = originalGetUTCHours(this);
1305 var minute = originalGetUTCMinutes(this);
1306 var second = originalGetUTCSeconds(this);
1307 return dayName[day] + ', '
1308 + (date < 10 ? '0' + date : date) + ' '
1309 + monthName[month] + ' '
1310 + year + ' '
1311 + (hour < 10 ? '0' + hour : hour) + ':'
1312 + (minute < 10 ? '0' + minute : minute) + ':'
1313 + (second < 10 ? '0' + second : second) + ' GMT';
1314 }
1315 }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
1316
1317 // Opera 12 has `,`
1318 defineProperties(Date.prototype, {
1319 toDateString: function toDateString() {
1320 if (!this || !(this instanceof Date)) {
1321 throw new TypeError('this is not a Date object.');
1322 }
1323 var day = this.getDay();
1324 var date = this.getDate();
1325 var month = this.getMonth();
1326 var year = this.getFullYear();
1327 return dayName[day] + ' '
1328 + monthName[month] + ' '
1329 + (date < 10 ? '0' + date : date) + ' '
1330 + year;
1331 }
1332 }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
1333
1334 // can't use defineProperties here because of toString enumeration issue in IE <= 8
1335 if (hasNegativeMonthYearBug || hasToStringFormatBug) {
1336 Date.prototype.toString = function toString() {
1337 if (!this || !(this instanceof Date)) {
1338 throw new TypeError('this is not a Date object.');
1339 }
1340 var day = this.getDay();
1341 var date = this.getDate();
1342 var month = this.getMonth();
1343 var year = this.getFullYear();
1344 var hour = this.getHours();
1345 var minute = this.getMinutes();
1346 var second = this.getSeconds();
1347 var timezoneOffset = this.getTimezoneOffset();
1348 var hoursOffset = floor(abs(timezoneOffset) / 60);
1349 var minutesOffset = floor(abs(timezoneOffset) % 60);
1350 return dayName[day] + ' '
1351 + monthName[month] + ' '
1352 + (date < 10 ? '0' + date : date) + ' '
1353 + year + ' '
1354 + (hour < 10 ? '0' + hour : hour) + ':'
1355 + (minute < 10 ? '0' + minute : minute) + ':'
1356 + (second < 10 ? '0' + second : second) + ' GMT'
1357 + (timezoneOffset > 0 ? '-' : '+')
1358 + (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset)
1359 + (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
1360 };
1361 if (supportsDescriptors) {
1362 $Object.defineProperty(Date.prototype, 'toString', {
1363 configurable: true,
1364 enumerable: false,
1365 writable: true
1366 });
1367 }
1368 }
1369
1370 // ES5 15.9.5.43
1371 // http://es5.github.com/#x15.9.5.43
1372 // This function returns a String value represent the instance in time
1373 // represented by this Date object. The format of the String is the Date Time
1374 // string format defined in 15.9.1.15. All fields are present in the String.
1375 // The time zone is always UTC, denoted by the suffix Z. If the time value of
1376 // this object is not a finite Number a RangeError exception is thrown.
1377 var negativeDate = -62198755200000;
1378 var negativeYearString = '-000001';
1379 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; // eslint-disable-line max-len
1380 var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
1381
1382 var getTime = call.bind(Date.prototype.getTime);
1383
1384 defineProperties(Date.prototype, {
1385 toISOString: function toISOString() {
1386 if (!isFinite(this) || !isFinite(getTime(this))) {
1387 // Adope Photoshop requires the second check.
1388 throw new RangeError('Date.prototype.toISOString called on non-finite value.');
1389 }
1390
1391 var year = originalGetUTCFullYear(this);
1392
1393 var month = originalGetUTCMonth(this);
1394 // see https://github.com/es-shims/es5-shim/issues/111
1395 year += floor(month / 12);
1396 month = ((month % 12) + 12) % 12;
1397
1398 // the date time string format is specified in 15.9.1.15.
1399 var result = [
1400 month + 1,
1401 originalGetUTCDate(this),
1402 originalGetUTCHours(this),
1403 originalGetUTCMinutes(this),
1404 originalGetUTCSeconds(this)
1405 ];
1406 year = (
1407 (year < 0 ? '-' : (year > 9999 ? '+' : ''))
1408 + strSlice('00000' + abs(year), (0 <= year && year <= 9999) ? -4 : -6)
1409 );
1410
1411 for (var i = 0; i < result.length; ++i) {
1412 // pad months, days, hours, minutes, and seconds to have two digits.
1413 result[i] = strSlice('00' + result[i], -2);
1414 }
1415 // pad milliseconds to have three digits.
1416 return (
1417 year + '-' + arraySlice(result, 0, 2).join('-')
1418 + 'T' + arraySlice(result, 2).join(':') + '.'
1419 + strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
1420 );
1421 }
1422 }, hasNegativeDateBug || hasSafari51DateBug);
1423
1424 // ES5 15.9.5.44
1425 // http://es5.github.com/#x15.9.5.44
1426 // This function provides a String representation of a Date object for use by
1427 // JSON.stringify (15.12.3).
1428 var dateToJSONIsSupported = (function () {
1429 try {
1430 return Date.prototype.toJSON
1431 && new Date(NaN).toJSON() === null
1432 && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1
1433 && Date.prototype.toJSON.call({ // generic
1434 toISOString: function () { return true; }
1435 });
1436 } catch (e) {
1437 return false;
1438 }
1439 }());
1440 if (!dateToJSONIsSupported) {
1441 Date.prototype.toJSON = function toJSON(key) {
1442 // When the toJSON method is called with argument key, the following
1443 // steps are taken:
1444
1445 // 1. Let O be the result of calling ToObject, giving it the this
1446 // value as its argument.
1447 // 2. Let tv be ES.ToPrimitive(O, hint Number).
1448 var O = $Object(this);
1449 var tv = ES.ToPrimitive(O);
1450 // 3. If tv is a Number and is not finite, return null.
1451 if (typeof tv === 'number' && !isFinite(tv)) {
1452 return null;
1453 }
1454 // 4. Let toISO be the result of calling the [[Get]] internal method of
1455 // O with argument "toISOString".
1456 var toISO = O.toISOString;
1457 // 5. If IsCallable(toISO) is false, throw a TypeError exception.
1458 if (!isCallable(toISO)) {
1459 throw new TypeError('toISOString property is not callable');
1460 }
1461 // 6. Return the result of calling the [[Call]] internal method of
1462 // toISO with O as the this value and an empty argument list.
1463 return toISO.call(O);
1464
1465 // NOTE 1 The argument is ignored.
1466
1467 // NOTE 2 The toJSON function is intentionally generic; it does not
1468 // require that its this value be a Date object. Therefore, it can be
1469 // transferred to other kinds of objects for use as a method. However,
1470 // it does require that any such object have a toISOString method. An
1471 // object is free to use the argument key to filter its
1472 // stringification.
1473 };
1474 }
1475
1476 // ES5 15.9.4.2
1477 // http://es5.github.com/#x15.9.4.2
1478 // based on work shared by Daniel Friesen (dantman)
1479 // http://gist.github.com/303249
1480 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
1481 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'));
1482 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
1483 if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
1484 // XXX global assignment won't work in embeddings that use
1485 // an alternate object for the context.
1486 var maxSafeUnsigned32Bit = pow(2, 31) - 1;
1487 var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
1488 // eslint-disable-next-line no-implicit-globals, no-global-assign
1489 Date = (function (NativeDate) {
1490 // Date.length === 7
1491 var DateShim = function Date(Y, M, D, h, m, s, ms) {
1492 var length = arguments.length;
1493 var date;
1494 if (this instanceof NativeDate) {
1495 var seconds = s;
1496 var millis = ms;
1497 if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
1498 // work around a Safari 8/9 bug where it treats the seconds as signed
1499 var msToShift = floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1500 var sToShift = floor(msToShift / 1e3);
1501 seconds += sToShift;
1502 millis -= sToShift * 1e3;
1503 }
1504 date = length === 1 && $String(Y) === Y // isString(Y)
1505 // We explicitly pass it through parse:
1506 ? new NativeDate(DateShim.parse(Y))
1507 // We have to manually make calls depending on argument
1508 // length here
1509 : length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis)
1510 : length >= 6 ? new NativeDate(Y, M, D, h, m, seconds)
1511 : length >= 5 ? new NativeDate(Y, M, D, h, m)
1512 : length >= 4 ? new NativeDate(Y, M, D, h)
1513 : length >= 3 ? new NativeDate(Y, M, D)
1514 : length >= 2 ? new NativeDate(Y, M)
1515 : length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y)
1516 : new NativeDate();
1517 } else {
1518 date = NativeDate.apply(this, arguments);
1519 }
1520 if (!isPrimitive(date)) {
1521 // Prevent mixups with unfixed Date object
1522 defineProperties(date, { constructor: DateShim }, true);
1523 }
1524 return date;
1525 };
1526
1527 // 15.9.1.15 Date Time String Format.
1528 var isoDateExpression = new RegExp('^'
1529 + '(\\d{4}|[+-]\\d{6})' // four-digit year capture or sign + 6-digit extended year
1530 + '(?:-(\\d{2})' // optional month capture
1531 + '(?:-(\\d{2})' // optional day capture
1532 + '(?:' // capture hours:minutes:seconds.milliseconds
1533 + 'T(\\d{2})' // hours capture
1534 + ':(\\d{2})' // minutes capture
1535 + '(?:' // optional :seconds.milliseconds
1536 + ':(\\d{2})' // seconds capture
1537 + '(?:(\\.\\d{1,}))?' // milliseconds capture
1538 + ')?'
1539 + '(' // capture UTC offset component
1540 + 'Z|' // UTC capture
1541 + '(?:' // offset specifier +/-hours:minutes
1542 + '([-+])' // sign capture
1543 + '(\\d{2})' // hours offset capture
1544 + ':(\\d{2})' // minutes offset capture
1545 + ')'
1546 + ')?)?)?)?'
1547 + '$');
1548
1549 var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
1550
1551 var dayFromMonth = function dayFromMonth(year, month) {
1552 var t = month > 1 ? 1 : 0;
1553 return (
1554 months[month]
1555 + floor((year - 1969 + t) / 4)
1556 - floor((year - 1901 + t) / 100)
1557 + floor((year - 1601 + t) / 400)
1558 + (365 * (year - 1970))
1559 );
1560 };
1561
1562 var toUTC = function toUTC(t) {
1563 var s = 0;
1564 var ms = t;
1565 if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
1566 // work around a Safari 8/9 bug where it treats the seconds as signed
1567 var msToShift = floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1568 var sToShift = floor(msToShift / 1e3);
1569 s += sToShift;
1570 ms -= sToShift * 1e3;
1571 }
1572 return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
1573 };
1574
1575 // Copy any custom methods a 3rd party library may have added
1576 for (var key in NativeDate) {
1577 if (owns(NativeDate, key)) {
1578 DateShim[key] = NativeDate[key];
1579 }
1580 }
1581
1582 // Copy "native" methods explicitly; they may be non-enumerable
1583 defineProperties(DateShim, {
1584 now: NativeDate.now,
1585 UTC: NativeDate.UTC
1586 }, true);
1587 DateShim.prototype = NativeDate.prototype;
1588 defineProperties(DateShim.prototype, { constructor: DateShim }, true);
1589
1590 // Upgrade Date.parse to handle simplified ISO 8601 strings
1591 var parseShim = function parse(string) {
1592 var match = isoDateExpression.exec(string);
1593 if (match) {
1594 // parse months, days, hours, minutes, seconds, and milliseconds
1595 // provide default values if necessary
1596 // parse the UTC offset component
1597 var year = $Number(match[1]),
1598 month = $Number(match[2] || 1) - 1,
1599 day = $Number(match[3] || 1) - 1,
1600 hour = $Number(match[4] || 0),
1601 minute = $Number(match[5] || 0),
1602 second = $Number(match[6] || 0),
1603 millisecond = floor($Number(match[7] || 0) * 1000),
1604 // When time zone is missed, local offset should be used
1605 // (ES 5.1 bug)
1606 // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1607 isLocalTime = Boolean(match[4] && !match[8]),
1608 signOffset = match[9] === '-' ? 1 : -1,
1609 hourOffset = $Number(match[10] || 0),
1610 minuteOffset = $Number(match[11] || 0),
1611 result;
1612 var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
1613 if (
1614 hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25)
1615 && minute < 60 && second < 60 && millisecond < 1000
1616 && month > -1 && month < 12 && hourOffset < 24
1617 && minuteOffset < 60 // detect invalid offsets
1618 && day > -1
1619 && day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
1620 ) {
1621 result = (
1622 ((dayFromMonth(year, month) + day) * 24)
1623 + hour
1624 + (hourOffset * signOffset)
1625 ) * 60;
1626 result = ((
1627 ((result + minute + (minuteOffset * signOffset)) * 60)
1628 + second
1629 ) * 1000) + millisecond;
1630 if (isLocalTime) {
1631 result = toUTC(result);
1632 }
1633 if (-8.64e15 <= result && result <= 8.64e15) {
1634 return result;
1635 }
1636 }
1637 return NaN;
1638 }
1639 return NativeDate.parse.apply(this, arguments);
1640 };
1641 defineProperties(DateShim, { parse: parseShim });
1642
1643 return DateShim;
1644 }(Date));
1645 }
1646
1647 // ES5 15.9.4.4
1648 // http://es5.github.com/#x15.9.4.4
1649 if (!Date.now) {
1650 Date.now = function now() {
1651 return new Date().getTime();
1652 };
1653 }
1654
1655 //
1656 // Number
1657 // ======
1658 //
1659
1660 // ES5.1 15.7.4.5
1661 // http://es5.github.com/#x15.7.4.5
1662 var hasToFixedBugs = NumberPrototype.toFixed && (
1663 (0.00008).toFixed(3) !== '0.000'
1664 || (0.9).toFixed(0) !== '1'
1665 || (1.255).toFixed(2) !== '1.25'
1666 || (1000000000000000128).toFixed(0) !== '1000000000000000128'
1667 );
1668
1669 var toFixedHelpers = {
1670 base: 1e7,
1671 size: 6,
1672 data: [0, 0, 0, 0, 0, 0],
1673 multiply: function multiply(n, c) {
1674 var i = -1;
1675 var c2 = c;
1676 while (++i < toFixedHelpers.size) {
1677 c2 += n * toFixedHelpers.data[i];
1678 toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1679 c2 = floor(c2 / toFixedHelpers.base);
1680 }
1681 },
1682 divide: function divide(n) {
1683 var i = toFixedHelpers.size;
1684 var c = 0;
1685 while (--i >= 0) {
1686 c += toFixedHelpers.data[i];
1687 toFixedHelpers.data[i] = floor(c / n);
1688 c = (c % n) * toFixedHelpers.base;
1689 }
1690 },
1691 numToString: function numToString() {
1692 var i = toFixedHelpers.size;
1693 var s = '';
1694 while (--i >= 0) {
1695 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1696 var t = $String(toFixedHelpers.data[i]);
1697 if (s === '') {
1698 s = t;
1699 } else {
1700 s += strSlice('0000000', 0, 7 - t.length) + t;
1701 }
1702 }
1703 }
1704 return s;
1705 },
1706 pow: function pow(x, n, acc) {
1707 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1708 },
1709 log: function log(x) {
1710 var n = 0;
1711 var x2 = x;
1712 while (x2 >= 4096) {
1713 n += 12;
1714 x2 /= 4096;
1715 }
1716 while (x2 >= 2) {
1717 n += 1;
1718 x2 /= 2;
1719 }
1720 return n;
1721 }
1722 };
1723
1724 var toFixedShim = function toFixed(fractionDigits) {
1725 var f, x, s, m, e, z, j, k;
1726
1727 // Test for NaN and round fractionDigits down
1728 f = $Number(fractionDigits);
1729 f = isActualNaN(f) ? 0 : floor(f);
1730
1731 if (f < 0 || f > 20) {
1732 throw new RangeError('Number.toFixed called with invalid number of decimals');
1733 }
1734
1735 x = $Number(this);
1736
1737 if (isActualNaN(x)) {
1738 return 'NaN';
1739 }
1740
1741 // If it is too big or small, return the string value of the number
1742 if (x <= -1e21 || x >= 1e21) {
1743 return $String(x);
1744 }
1745
1746 s = '';
1747
1748 if (x < 0) {
1749 s = '-';
1750 x = -x;
1751 }
1752
1753 m = '0';
1754
1755 if (x > 1e-21) {
1756 // 1e-21 < x < 1e21
1757 // -70 < log2(x) < 70
1758 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1759 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1760 z *= 0x10000000000000; // pow(2, 52);
1761 e = 52 - e;
1762
1763 // -18 < e < 122
1764 // x = z / 2 ^ e
1765 if (e > 0) {
1766 toFixedHelpers.multiply(0, z);
1767 j = f;
1768
1769 while (j >= 7) {
1770 toFixedHelpers.multiply(1e7, 0);
1771 j -= 7;
1772 }
1773
1774 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1775 j = e - 1;
1776
1777 while (j >= 23) {
1778 toFixedHelpers.divide(1 << 23);
1779 j -= 23;
1780 }
1781
1782 toFixedHelpers.divide(1 << j);
1783 toFixedHelpers.multiply(1, 1);
1784 toFixedHelpers.divide(2);
1785 m = toFixedHelpers.numToString();
1786 } else {
1787 toFixedHelpers.multiply(0, z);
1788 toFixedHelpers.multiply(1 << (-e), 0);
1789 m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
1790 }
1791 }
1792
1793 if (f > 0) {
1794 k = m.length;
1795
1796 if (k <= f) {
1797 m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
1798 } else {
1799 m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
1800 }
1801 } else {
1802 m = s + m;
1803 }
1804
1805 return m;
1806 };
1807 defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
1808
1809 var hasToExponentialRoundingBug = (function () {
1810 try {
1811 return (-6.9e-11).toExponential(4) !== '-6.9000e-11';
1812 } catch (e) {
1813 return false;
1814 }
1815 }());
1816 var toExponentialAllowsInfiniteDigits = (function () {
1817 try {
1818 (1).toExponential(Infinity);
1819 (1).toExponential(-Infinity);
1820 return true;
1821 } catch (e) {
1822 return false;
1823 }
1824 }());
1825 var originalToExponential = call.bind(NumberPrototype.toExponential);
1826 var numberToString = call.bind(NumberPrototype.toString);
1827 var numberValueOf = call.bind(NumberPrototype.valueOf);
1828 defineProperties(NumberPrototype, {
1829 toExponential: function toExponential(fractionDigits) {
1830 // 1: Let x be this Number value.
1831 var x = numberValueOf(this);
1832
1833 if (typeof fractionDigits === 'undefined') {
1834 return originalToExponential(x);
1835 }
1836 var f = ES.ToInteger(fractionDigits);
1837 if (isActualNaN(x)) {
1838 return 'NaN';
1839 }
1840
1841 if (f < 0 || f > 20) {
1842 // this will probably have thrown already
1843 return originalToExponential(x, f);
1844 }
1845
1846 // only cases left are a finite receiver + in-range fractionDigits
1847
1848 // implementation adapted from https://gist.github.com/SheetJSDev/1100ad56b9f856c95299ed0e068eea08
1849
1850 // 4: Let s be the empty string
1851 var s = '';
1852
1853 // 5: If x < 0
1854 if (x < 0) {
1855 s = '-';
1856 x = -x;
1857 }
1858
1859 // 6: If x = +Infinity
1860 if (x === Infinity) {
1861 return s + 'Infinity';
1862 }
1863
1864 // 7: If fractionDigits is not undefined and (f < 0 or f > 20), throw a RangeError exception.
1865 if (typeof fractionDigits !== 'undefined' && (f < 0 || f > 20)) {
1866 throw new RangeError('Fraction digits ' + fractionDigits + ' out of range');
1867 }
1868
1869 var m = '';
1870 var e = 0;
1871 var c = '';
1872 var d = '';
1873
1874 // 8: If x = 0 then
1875 if (x === 0) {
1876 e = 0;
1877 f = 0;
1878 m = '0';
1879 } else { // 9: Else, x != 0
1880 var L = log10(x);
1881 e = floor(L); // 10 ** e <= x and x < 10 ** (e+1)
1882 var n = 0;
1883 if (typeof fractionDigits !== 'undefined') { // eslint-disable-line no-negated-condition
1884 var w = pow(10, e - f); // x / 10 ** (f+1) < w and w <= x / 10 ** f
1885 n = round(x / w); // 10 ** f <= n and n < 10 ** (f+1)
1886 if (2 * x >= (((2 * n) + 1) * w)) {
1887 n += 1; // pick larger value
1888 }
1889 if (n >= pow(10, f + 1)) { // 10e-1 = 1e0
1890 n /= 10;
1891 e += 1;
1892 }
1893 } else {
1894 f = 16; // start from Math.ceil(Math.log10(Number.MAX_SAFE_INTEGER)) and loop down
1895 var guess_n = round(pow(10, L - e + f));
1896 var target_f = f;
1897 while (f-- > 0) {
1898 guess_n = round(pow(10, L - e + f));
1899 if (
1900 abs((guess_n * pow(10, e - f)) - x)
1901 <= abs((n * pow(10, e - target_f)) - x)
1902 ) {
1903 target_f = f;
1904 n = guess_n;
1905 }
1906 }
1907 }
1908 m = numberToString(n, 10);
1909 if (typeof fractionDigits === 'undefined') {
1910 while (strSlice(m, -1) === '0') {
1911 m = strSlice(m, 0, -1);
1912 d += 1;
1913 }
1914 }
1915 }
1916
1917 // 10: If f != 0, then
1918 if (f !== 0) {
1919 m = strSlice(m, 0, 1) + '.' + strSlice(m, 1);
1920 }
1921
1922 // 11: If e = 0, then
1923 if (e === 0) {
1924 c = '+';
1925 d = '0';
1926 } else { // 12: Else
1927 c = e > 0 ? '+' : '-';
1928 d = numberToString(abs(e), 10);
1929 }
1930
1931 // 13: Let m be the concatenation of the four Strings m, "e", c, and d.
1932 m += 'e' + c + d;
1933
1934 // 14: Return the concatenation of the Strings s and m.
1935 return s + m;
1936 }
1937 }, hasToExponentialRoundingBug || toExponentialAllowsInfiniteDigits);
1938
1939 var hasToPrecisionUndefinedBug = (function () {
1940 try {
1941 return 1.0.toPrecision(undefined) === '1';
1942 } catch (e) {
1943 return true;
1944 }
1945 }());
1946 var originalToPrecision = call.bind(NumberPrototype.toPrecision);
1947 defineProperties(NumberPrototype, {
1948 toPrecision: function toPrecision(precision) {
1949 return typeof precision === 'undefined' ? originalToPrecision(this) : originalToPrecision(this, precision);
1950 }
1951 }, hasToPrecisionUndefinedBug);
1952
1953 //
1954 // String
1955 // ======
1956 //
1957
1958 // ES5 15.5.4.14
1959 // http://es5.github.com/#x15.5.4.14
1960
1961 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1962 // Many browsers do not split properly with regular expressions or they
1963 // do not perform the split correctly under obscure conditions.
1964 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1965 // I've tested in many browsers and this seems to cover the deviant ones:
1966 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1967 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1968 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1969 // [undefined, "t", undefined, "e", ...]
1970 // ''.split(/.?/) should be [], not [""]
1971 // '.'.split(/()()/) should be ["."], not ["", "", "."]
1972
1973 if (
1974 'ab'.split(/(?:ab)*/).length !== 2
1975 || '.'.split(/(.?)(.?)/).length !== 4
1976 || 'tesst'.split(/(s)*/)[1] === 't'
1977 || 'test'.split(/(?:)/, -1).length !== 4
1978 || ''.split(/.?/).length
1979 || '.'.split(/()()/).length > 1
1980 ) {
1981 (function () {
1982 var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1983 var maxSafe32BitInt = pow(2, 32) - 1;
1984
1985 StringPrototype.split = function split(separator, limit) {
1986 var string = String(this);
1987 if (typeof separator === 'undefined' && limit === 0) {
1988 return [];
1989 }
1990
1991 // If `separator` is not a regex, use native split
1992 if (!isRegex(separator)) {
1993 return strSplit(this, separator, limit);
1994 }
1995
1996 var output = [];
1997 var flags = (separator.ignoreCase ? 'i' : '')
1998 + (separator.multiline ? 'm' : '')
1999 + (separator.unicode ? 'u' : '') // in ES6
2000 + (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
2001 lastLastIndex = 0,
2002 // Make `global` and avoid `lastIndex` issues by working with a copy
2003 separator2, match, lastIndex, lastLength;
2004 var separatorCopy = new RegExp(separator.source, flags + 'g');
2005 if (!compliantExecNpcg) {
2006 // Doesn't need flags gy, but they don't hurt
2007 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
2008 }
2009 /* Values for `limit`, per the spec:
2010 * If undefined: 4294967295 // maxSafe32BitInt
2011 * If 0, Infinity, or NaN: 0
2012 * If positive number: limit = floor(limit); if (limit > 4294967295) limit -= 4294967296;
2013 * If negative number: 4294967296 - floor(abs(limit))
2014 * If other: Type-convert, then use the above rules
2015 */
2016 var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
2017 match = separatorCopy.exec(string);
2018 while (match) {
2019 // `separatorCopy.lastIndex` is not reliable cross-browser
2020 lastIndex = match.index + match[0].length;
2021 if (lastIndex > lastLastIndex) {
2022 pushCall(output, strSlice(string, lastLastIndex, match.index));
2023 // Fix browsers whose `exec` methods don't consistently return `undefined` for
2024 // nonparticipating capturing groups
2025 if (!compliantExecNpcg && match.length > 1) {
2026 /* eslint-disable no-loop-func */
2027 match[0].replace(separator2, function () {
2028 for (var i = 1; i < arguments.length - 2; i++) {
2029 if (typeof arguments[i] === 'undefined') {
2030 match[i] = void 0;
2031 }
2032 }
2033 });
2034 /* eslint-enable no-loop-func */
2035 }
2036 if (match.length > 1 && match.index < string.length) {
2037 array_push.apply(output, arraySlice(match, 1));
2038 }
2039 lastLength = match[0].length;
2040 lastLastIndex = lastIndex;
2041 if (output.length >= splitLimit) {
2042 break;
2043 }
2044 }
2045 if (separatorCopy.lastIndex === match.index) {
2046 separatorCopy.lastIndex++; // Avoid an infinite loop
2047 }
2048 match = separatorCopy.exec(string);
2049 }
2050 if (lastLastIndex === string.length) {
2051 if (lastLength || !separatorCopy.test('')) {
2052 pushCall(output, '');
2053 }
2054 } else {
2055 pushCall(output, strSlice(string, lastLastIndex));
2056 }
2057 return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
2058 };
2059 }());
2060
2061 // [bugfix, chrome]
2062 // If separator is undefined, then the result array contains just one String,
2063 // which is the this value (converted to a String). If limit is not undefined,
2064 // then the output array is truncated so that it contains no more than limit
2065 // elements.
2066 // "0".split(undefined, 0) -> []
2067 } else if ('0'.split(void 0, 0).length) {
2068 StringPrototype.split = function split(separator, limit) {
2069 if (typeof separator === 'undefined' && limit === 0) {
2070 return [];
2071 }
2072 return strSplit(this, separator, limit);
2073 };
2074 }
2075
2076 var str_replace = StringPrototype.replace;
2077 var replaceReportsGroupsCorrectly = (function () {
2078 var groups = [];
2079 'x'.replace(/x(.)?/g, function (match, group) {
2080 pushCall(groups, group);
2081 });
2082 return groups.length === 1 && typeof groups[0] === 'undefined';
2083 }());
2084
2085 if (!replaceReportsGroupsCorrectly) {
2086 StringPrototype.replace = function replace(searchValue, replaceValue) {
2087 var isFn = isCallable(replaceValue);
2088 var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
2089 if (!isFn || !hasCapturingGroups) {
2090 return str_replace.call(this, searchValue, replaceValue);
2091 }
2092 var wrappedReplaceValue = function (match) {
2093 var length = arguments.length;
2094 var originalLastIndex = searchValue.lastIndex;
2095 searchValue.lastIndex = 0; // eslint-disable-line no-param-reassign
2096 var args = searchValue.exec(match) || [];
2097 searchValue.lastIndex = originalLastIndex; // eslint-disable-line no-param-reassign
2098 pushCall(args, arguments[length - 2], arguments[length - 1]);
2099 return replaceValue.apply(this, args);
2100 };
2101 return str_replace.call(this, searchValue, wrappedReplaceValue);
2102
2103 };
2104 }
2105
2106 // ECMA-262, 3rd B.2.3
2107 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
2108 // non-normative section suggesting uniform semantics and it should be
2109 // normalized across all browsers
2110 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
2111 var string_substr = StringPrototype.substr;
2112 var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
2113 defineProperties(StringPrototype, {
2114 substr: function substr(start, length) {
2115 var normalizedStart = start;
2116 if (start < 0) {
2117 normalizedStart = max(this.length + start, 0);
2118 }
2119 return string_substr.call(this, normalizedStart, length);
2120 }
2121 }, hasNegativeSubstrBug);
2122
2123 // ES5 15.5.4.20
2124 // whitespace from: http://es5.github.io/#x15.5.4.20
2125 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003'
2126 + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028'
2127 + '\u2029\uFEFF';
2128 var zeroWidth = '\u200b';
2129 var wsRegexChars = '[' + ws + ']';
2130 var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
2131 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
2132 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
2133 defineProperties(StringPrototype, {
2134 // http://blog.stevenlevithan.com/archives/faster-trim-javascript
2135 // http://perfectionkills.com/whitespace-deviations/
2136 trim: function trim() {
2137 if (typeof this === 'undefined' || this === null) {
2138 throw new TypeError("can't convert " + this + ' to object');
2139 }
2140 return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
2141 }
2142 }, hasTrimWhitespaceBug);
2143 var trim = call.bind(String.prototype.trim);
2144
2145 var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
2146 defineProperties(StringPrototype, {
2147 lastIndexOf: function lastIndexOf(searchString) {
2148 if (typeof this === 'undefined' || this === null) {
2149 throw new TypeError("can't convert " + this + ' to object');
2150 }
2151 var S = $String(this);
2152 var searchStr = $String(searchString);
2153 var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
2154 var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
2155 var start = min(max(pos, 0), S.length);
2156 var searchLen = searchStr.length;
2157 var k = start + searchLen;
2158 while (k > 0) {
2159 k = max(0, k - searchLen);
2160 var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
2161 if (index !== -1) {
2162 return k + index;
2163 }
2164 }
2165 return -1;
2166 }
2167 }, hasLastIndexBug);
2168
2169 var originalLastIndexOf = StringPrototype.lastIndexOf;
2170 defineProperties(StringPrototype, {
2171 lastIndexOf: function lastIndexOf(searchString) {
2172 return originalLastIndexOf.apply(this, arguments);
2173 }
2174 }, StringPrototype.lastIndexOf.length !== 1);
2175
2176 var hexRegex = /^[-+]?0[xX]/;
2177
2178 // ES-5 15.1.2.2
2179 // eslint-disable-next-line radix
2180 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
2181 // eslint-disable-next-line no-global-assign, no-implicit-globals
2182 parseInt = (function (origParseInt) {
2183 return function parseInt(str, radix) {
2184 var string = trim(String(str));
2185 var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
2186 return origParseInt(string, defaultedRadix);
2187 };
2188 }(parseInt));
2189 }
2190 // Edge 15-18
2191 var parseIntFailsToThrowOnBoxedSymbols = (function () {
2192 if (typeof Symbol !== 'function') {
2193 return false;
2194 }
2195 try {
2196 // eslint-disable-next-line radix
2197 parseInt(Object(Symbol.iterator));
2198 return true;
2199 } catch (e) { /**/ }
2200
2201 try {
2202 // eslint-disable-next-line radix
2203 parseInt(Symbol.iterator);
2204 return true;
2205 } catch (e) { /**/ }
2206
2207 return false;
2208 }());
2209 if (parseIntFailsToThrowOnBoxedSymbols) {
2210 var symbolValueOf = Symbol.prototype.valueOf;
2211 // eslint-disable-next-line no-global-assign, no-implicit-globals
2212 parseInt = (function (origParseInt) {
2213 return function parseInt(str, radix) {
2214 var isSym = typeof str === 'symbol';
2215 if (!isSym && str && typeof str === 'object') {
2216 try {
2217 symbolValueOf.call(str);
2218 isSym = true;
2219 } catch (e) { /**/ }
2220 }
2221 if (isSym) {
2222 // handle Symbols in node 8.3/8.4
2223 // eslint-disable-next-line no-implicit-coercion, no-unused-expressions
2224 '' + str; // jscs:ignore disallowImplicitTypeConversion
2225 }
2226 var string = trim(String(str));
2227 var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
2228 return origParseInt(string, defaultedRadix);
2229 };
2230 }(parseInt));
2231 }
2232
2233 // https://es5.github.io/#x15.1.2.3
2234 if (1 / parseFloat('-0') !== -Infinity) {
2235 // eslint-disable-next-line no-global-assign, no-implicit-globals, no-native-reassign
2236 parseFloat = (function (origParseFloat) {
2237 return function parseFloat(string) {
2238 var inputString = trim(String(string));
2239 var result = origParseFloat(inputString);
2240 return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
2241 };
2242 }(parseFloat));
2243 }
2244
2245 if (String(new RangeError('test')) !== 'RangeError: test') {
2246 var errorToStringShim = function toString() {
2247 if (typeof this === 'undefined' || this === null) {
2248 throw new TypeError("can't convert " + this + ' to object');
2249 }
2250 var name = this.name;
2251 if (typeof name === 'undefined') {
2252 name = 'Error';
2253 } else if (typeof name !== 'string') {
2254 name = $String(name);
2255 }
2256 var msg = this.message;
2257 if (typeof msg === 'undefined') {
2258 msg = '';
2259 } else if (typeof msg !== 'string') {
2260 msg = $String(msg);
2261 }
2262 if (!name) {
2263 return msg;
2264 }
2265 if (!msg) {
2266 return name;
2267 }
2268 return name + ': ' + msg;
2269 };
2270 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2271 Error.prototype.toString = errorToStringShim;
2272 }
2273
2274 if (supportsDescriptors) {
2275 var ensureNonEnumerable = function (obj, prop) {
2276 if (isEnum(obj, prop)) {
2277 var desc = Object.getOwnPropertyDescriptor(obj, prop);
2278 if (desc.configurable) {
2279 desc.enumerable = false;
2280 Object.defineProperty(obj, prop, desc);
2281 }
2282 }
2283 };
2284 ensureNonEnumerable(Error.prototype, 'message');
2285 if (Error.prototype.message !== '') {
2286 Error.prototype.message = '';
2287 }
2288 ensureNonEnumerable(Error.prototype, 'name');
2289 }
2290
2291 if (String(/a/mig) !== '/a/gim') {
2292 var regexToString = function toString() {
2293 var str = '/' + this.source + '/';
2294 if (this.global) {
2295 str += 'g';
2296 }
2297 if (this.ignoreCase) {
2298 str += 'i';
2299 }
2300 if (this.multiline) {
2301 str += 'm';
2302 }
2303 return str;
2304 };
2305 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2306 RegExp.prototype.toString = regexToString;
2307 }
2308}));