/*! * https://github.com/es-shims/es5-shim * @license es5-shim copyright 2009-2015 by contributors, mit license * see https://github.com/es-shims/es5-shim/blob/master/license */ // vim: ts=4 sts=4 sw=4 expandtab // add semicolon to prevent iife from being passed as argument to concatenated code. ; // umd (universal module definition) // see https://github.com/umdjs/umd/blob/master/templates/returnexports.js (function (root, factory) { 'use strict'; /* global define, exports, module */ if (typeof define === 'function' && define.amd) { // amd. register as an anonymous module. define(factory); } else if (typeof exports === 'object') { // node. does not work with strict commonjs, but // only commonjs-like enviroments that support module.exports, // like node. module.exports = factory(); } else { // browser globals (root is window) root.returnexports = factory(); } }(this, function () { /** * brings an environment as close to ecmascript 5 compliance * as is possible with the facilities of erstwhile engines. * * annotated es5: http://es5.github.com/ (specific links below) * es5 spec: http://www.ecma-international.org/publications/files/ecma-st/ecma-262.pdf * required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ */ // shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. this also holds a reference to known-good // functions. var $array = array; var arrayprototype = $array.prototype; var $object = object; var objectprototype = $object.prototype; var $function = function; var functionprototype = $function.prototype; var $string = string; var stringprototype = $string.prototype; var $number = number; var numberprototype = $number.prototype; var array_slice = arrayprototype.slice; var array_splice = arrayprototype.splice; var array_push = arrayprototype.push; var array_unshift = arrayprototype.unshift; var array_concat = arrayprototype.concat; var array_join = arrayprototype.join; var call = functionprototype.call; var apply = functionprototype.apply; var max = math.max; var min = math.min; // having a tostring local variable name breaks in opera so use to_string. var to_string = objectprototype.tostring; /* global symbol */ /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ var hastostringtag = typeof symbol === 'function' && typeof symbol.tostringtag === 'symbol'; 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; }; 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; }; 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; }; /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ /* inlined from http://npmjs.com/define-properties */ var supportsdescriptors = $object.defineproperty && (function () { try { var obj = {}; $object.defineproperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { // jscs:ignore disallowunusedvariables return false; } return obj.x === obj; } catch (e) { /* this is es3 */ return false; } }()); var defineproperties = (function (has) { // define configurable, writable, and non-enumerable props // if they don't exist. var defineproperty; if (supportsdescriptors) { defineproperty = function (object, name, method, forceassign) { if (!forceassign && (name in object)) { return; } $object.defineproperty(object, name, { configurable: true, enumerable: false, writable: true, value: method }); }; } else { defineproperty = function (object, name, method, forceassign) { if (!forceassign && (name in object)) { return; } object[name] = method; }; } return function defineproperties(object, map, forceassign) { for (var name in map) { if (has.call(map, name)) { defineproperty(object, name, map[name], forceassign); } } }; }(objectprototype.hasownproperty)); // // util // ====== // /* replaceable with https://npmjs.com/package/es-abstract /helpers/isprimitive */ var isprimitive = function isprimitive(input) { var type = typeof input; return input === null || (type !== 'object' && type !== 'function'); }; var isactualnan = $number.isnan || function isactualnan(x) { return x !== x; }; var es = { // es5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer /* replaceable with https://npmjs.com/package/es-abstract es5.tointeger */ tointeger: function tointeger(num) { var n = +num; if (isactualnan(n)) { n = 0; } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { n = (n > 0 || -1) * math.floor(math.abs(n)); } return n; }, /* replaceable with https://npmjs.com/package/es-abstract es5.toprimitive */ toprimitive: function toprimitive(input) { var val, valueof, tostr; if (isprimitive(input)) { return input; } valueof = input.valueof; if (iscallable(valueof)) { val = valueof.call(input); if (isprimitive(val)) { return val; } } tostr = input.tostring; if (iscallable(tostr)) { val = tostr.call(input); if (isprimitive(val)) { return val; } } throw new typeerror(); }, // es5 9.9 // http://es5.github.com/#x9.9 /* replaceable with https://npmjs.com/package/es-abstract es5.toobject */ toobject: function (o) { if (o == null) { // this matches both null and undefined throw new typeerror("can't convert " + o + ' to object'); } return $object(o); }, /* replaceable with https://npmjs.com/package/es-abstract es5.touint32 */ touint32: function touint32(x) { return x >>> 0; } }; // // function // ======== // // es-5 15.3.4.5 // http://es5.github.com/#x15.3.4.5 var empty = function empty() {}; defineproperties(functionprototype, { bind: function bind(that) { // .length is 1 // 1. let target be the this value. var target = this; // 2. if iscallable(target) is false, throw a typeerror exception. if (!iscallable(target)) { throw new typeerror('function.prototype.bind called on incompatible ' + target); } // 3. let a be a new (possibly empty) internal list of all of the // argument values provided after thisarg (arg1, arg2 etc), in order. // xxx slicedargs will stand in for "a" if used var args = array_slice.call(arguments, 1); // for normal call // 4. let f be a new native ecmascript object. // 11. set the [[prototype]] internal property of f to the standard // built-in function prototype object as specified in 15.3.3.1. // 12. set the [[call]] internal property of f as described in // 15.3.4.5.1. // 13. set the [[construct]] internal property of f as described in // 15.3.4.5.2. // 14. set the [[hasinstance]] internal property of f as described in // 15.3.4.5.3. var bound; var binder = function () { if (this instanceof bound) { // 15.3.4.5.2 [[construct]] // when the [[construct]] internal method of a function object, // f that was created using the bind function is called with a // list of arguments extraargs, the following steps are taken: // 1. let target be the value of f's [[targetfunction]] // internal property. // 2. if target has no [[construct]] internal method, a // typeerror exception is thrown. // 3. let boundargs be the value of f's [[boundargs]] internal // property. // 4. let args be a new list containing the same values as the // list boundargs in the same order followed by the same // values as the list extraargs in the same order. // 5. return the result of calling the [[construct]] internal // method of target providing args as the arguments. var result = apply.call( target, this, array_concat.call(args, array_slice.call(arguments)) ); if ($object(result) === result) { return result; } return this; } else { // 15.3.4.5.1 [[call]] // when the [[call]] internal method of a function object, f, // which was created using the bind function is called with a // this value and a list of arguments extraargs, the following // steps are taken: // 1. let boundargs be the value of f's [[boundargs]] internal // property. // 2. let boundthis be the value of f's [[boundthis]] internal // property. // 3. let target be the value of f's [[targetfunction]] internal // property. // 4. let args be a new list containing the same values as the // list boundargs in the same order followed by the same // values as the list extraargs in the same order. // 5. return the result of calling the [[call]] internal method // of target providing boundthis as the this value and // providing args as the arguments. // equiv: target.call(this, ...boundargs, ...args) return apply.call( target, that, array_concat.call(args, array_slice.call(arguments)) ); } }; // 15. if the [[class]] internal property of target is "function", then // a. let l be the length property of target minus the length of a. // b. set the length own property of f to either 0 or l, whichever is // larger. // 16. else set the length own property of f to 0. var boundlength = max(0, target.length - args.length); // 17. set the attributes of the length own property of f to the values // specified in 15.3.5.1. var boundargs = []; for (var i = 0; i < boundlength; i++) { array_push.call(boundargs, '$' + i); } // xxx build a dynamic function with desired amount of arguments is the only // way to set the length property of a function. // in environments where content security policies enabled (chrome extensions, // for ex.) all use of eval or function costructor throws an exception. // however in all of these environments function.prototype.bind exists // and so this code will never be executed. bound = $function('binder', 'return function (' + array_join.call(boundargs, ',') + '){ return binder.apply(this, arguments); }')(binder); if (target.prototype) { empty.prototype = target.prototype; bound.prototype = new empty(); // clean up dangling references. empty.prototype = null; } // todo // 18. set the [[extensible]] internal property of f to true. // todo // 19. let thrower be the [[throwtypeerror]] function object (13.2.3). // 20. call the [[defineownproperty]] internal method of f with // arguments "caller", propertydescriptor {[[get]]: thrower, [[set]]: // thrower, [[enumerable]]: false, [[configurable]]: false}, and // false. // 21. call the [[defineownproperty]] internal method of f with // arguments "arguments", propertydescriptor {[[get]]: thrower, // [[set]]: thrower, [[enumerable]]: false, [[configurable]]: false}, // and false. // todo // note function objects created using function.prototype.bind do not // have a prototype property or the [[code]], [[formalparameters]], and // [[scope]] internal properties. // xxx can't delete prototype in pure-js. // 22. return f. return bound; } }); // _please note: shortcuts are defined after `function.prototype.bind` as we // use it in defining shortcuts. var owns = call.bind(objectprototype.hasownproperty); var tostr = call.bind(objectprototype.tostring); var arrayslice = call.bind(array_slice); var arraysliceapply = apply.bind(array_slice); var strslice = call.bind(stringprototype.slice); var strsplit = call.bind(stringprototype.split); var strindexof = call.bind(stringprototype.indexof); var pushcall = call.bind(array_push); var isenum = call.bind(objectprototype.propertyisenumerable); var arraysort = call.bind(arrayprototype.sort); // // array // ===== // var isarray = $array.isarray || function isarray(obj) { return tostr(obj) === '[object array]'; }; // es5 15.4.4.12 // http://es5.github.com/#x15.4.4.13 // return len+argcount. // [bugfix, ielt8] // ie < 8 bug: [].unshift(0) === undefined but should be "1" var hasunshiftreturnvaluebug = [].unshift(0) !== 1; defineproperties(arrayprototype, { unshift: function () { array_unshift.apply(this, arguments); return this.length; } }, hasunshiftreturnvaluebug); // es5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/isarray defineproperties($array, { isarray: isarray }); // the iscallable() check in the array functions // has been replaced with a strict check on the // internal class of the object to trap cases where // the provided function was actually a regular // expression literal, which in v8 and // javascriptcore is a typeof "function". only in // v8 are regular expression literals permitted as // reduce parameters, so it is desirable in the // general case for the shim to match the more // strict and common behavior of rejecting regular // expressions. // es5 15.4.4.18 // http://es5.github.com/#x15.4.4.18 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/foreach // check failure of by-index access of string characters (ie < 9) // and failure of `0 in boxedstring` (rhino) var boxedstring = $object('a'); var splitstring = boxedstring[0] !== 'a' || !(0 in boxedstring); var properlyboxescontext = function properlyboxed(method) { // check node 0.6.21 bug where third parameter is not boxed var properlyboxesnonstrict = true; var properlyboxesstrict = true; var threwexception = false; if (method) { try { method.call('foo', function (_, __, context) { if (typeof context !== 'object') { properlyboxesnonstrict = false; } }); method.call([1], function () { 'use strict'; properlyboxesstrict = typeof this === 'string'; }, 'x'); } catch (e) { threwexception = true; } } return !!method && !threwexception && properlyboxesnonstrict && properlyboxesstrict; }; defineproperties(arrayprototype, { foreach: function foreach(callbackfn/*, thisarg*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var i = -1; var length = es.touint32(self.length); var t; if (arguments.length > 1) { t = arguments[1]; } // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.foreach callback must be a function'); } while (++i < length) { if (i in self) { // invoke the callback function with call, passing arguments: // context, property value, property key, thisarg object if (typeof t === 'undefined') { callbackfn(self[i], i, object); } else { callbackfn.call(t, self[i], i, object); } } } } }, !properlyboxescontext(arrayprototype.foreach)); // es5 15.4.4.19 // http://es5.github.com/#x15.4.4.19 // https://developer.mozilla.org/en/core_javascript_1.5_reference/objects/array/map defineproperties(arrayprototype, { map: function map(callbackfn/*, thisarg*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); var result = $array(length); var t; if (arguments.length > 1) { t = arguments[1]; } // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.map callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { if (typeof t === 'undefined') { result[i] = callbackfn(self[i], i, object); } else { result[i] = callbackfn.call(t, self[i], i, object); } } } return result; } }, !properlyboxescontext(arrayprototype.map)); // es5 15.4.4.20 // http://es5.github.com/#x15.4.4.20 // https://developer.mozilla.org/en/core_javascript_1.5_reference/objects/array/filter defineproperties(arrayprototype, { filter: function filter(callbackfn/*, thisarg*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); var result = []; var value; var t; if (arguments.length > 1) { t = arguments[1]; } // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.filter callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (typeof t === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(t, value, i, object)) { pushcall(result, value); } } } return result; } }, !properlyboxescontext(arrayprototype.filter)); // es5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/every defineproperties(arrayprototype, { every: function every(callbackfn/*, thisarg*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); var t; if (arguments.length > 1) { t = arguments[1]; } // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.every callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && !(typeof t === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(t, self[i], i, object))) { return false; } } return true; } }, !properlyboxescontext(arrayprototype.every)); // es5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/some defineproperties(arrayprototype, { some: function some(callbackfn/*, thisarg */) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); var t; if (arguments.length > 1) { t = arguments[1]; } // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.some callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && (typeof t === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(t, self[i], i, object))) { return true; } } return false; } }, !properlyboxescontext(arrayprototype.some)); // es5 15.4.4.21 // http://es5.github.com/#x15.4.4.21 // https://developer.mozilla.org/en/core_javascript_1.5_reference/objects/array/reduce var reducecoercestoobject = false; if (arrayprototype.reduce) { reducecoercestoobject = typeof arrayprototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineproperties(arrayprototype, { reduce: function reduce(callbackfn/*, initialvalue*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.reduce callback must be a function'); } // no value to return if no initial value and an empty array if (length === 0 && arguments.length === 1) { throw new typeerror('reduce of empty array with no initial value'); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } // if array contains no values, no initial value to return if (++i >= length) { throw new typeerror('reduce of empty array with no initial value'); } } while (true); } for (; i < length; i++) { if (i in self) { result = callbackfn(result, self[i], i, object); } } return result; } }, !reducecoercestoobject); // es5 15.4.4.22 // http://es5.github.com/#x15.4.4.22 // https://developer.mozilla.org/en/core_javascript_1.5_reference/objects/array/reduceright var reducerightcoercestoobject = false; if (arrayprototype.reduceright) { reducerightcoercestoobject = typeof arrayprototype.reduceright.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineproperties(arrayprototype, { reduceright: function reduceright(callbackfn/*, initial*/) { var object = es.toobject(this); var self = splitstring && isstring(this) ? strsplit(this, '') : object; var length = es.touint32(self.length); // if no callback function or if callback is not a callable function if (!iscallable(callbackfn)) { throw new typeerror('array.prototype.reduceright callback must be a function'); } // no value to return if no initial value, empty array if (length === 0 && arguments.length === 1) { throw new typeerror('reduceright of empty array with no initial value'); } var result; var i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } // if array contains no values, no initial value to return if (--i < 0) { throw new typeerror('reduceright of empty array with no initial value'); } } while (true); } if (i < 0) { return result; } do { if (i in self) { result = callbackfn(result, self[i], i, object); } } while (i--); return result; } }, !reducerightcoercestoobject); // es5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/indexof var hasfirefox2indexofbug = arrayprototype.indexof && [0, 1].indexof(1, 2) !== -1; defineproperties(arrayprototype, { indexof: function indexof(searchelement/*, fromindex */) { var self = splitstring && isstring(this) ? strsplit(this, '') : es.toobject(this); var length = es.touint32(self.length); if (length === 0) { return -1; } var i = 0; if (arguments.length > 1) { i = es.tointeger(arguments[1]); } // handle negative indices i = i >= 0 ? i : max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === searchelement) { return i; } } return -1; } }, hasfirefox2indexofbug); // es5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/javascript/reference/global_objects/array/lastindexof var hasfirefox2lastindexofbug = arrayprototype.lastindexof && [0, 1].lastindexof(0, -3) !== -1; defineproperties(arrayprototype, { lastindexof: function lastindexof(searchelement/*, fromindex */) { var self = splitstring && isstring(this) ? strsplit(this, '') : es.toobject(this); var length = es.touint32(self.length); if (length === 0) { return -1; } var i = length - 1; if (arguments.length > 1) { i = min(i, es.tointeger(arguments[1])); } // handle negative indices i = i >= 0 ? i : length - math.abs(i); for (; i >= 0; i--) { if (i in self && searchelement === self[i]) { return i; } } return -1; } }, hasfirefox2lastindexofbug); // es5 15.4.4.12 // http://es5.github.com/#x15.4.4.12 var splicenoopreturnsemptyarray = (function () { var a = [1, 2]; var result = a.splice(); return a.length === 2 && isarray(result) && result.length === 0; }()); defineproperties(arrayprototype, { // safari 5.0 bug where .splice() returns undefined splice: function splice(start, deletecount) { if (arguments.length === 0) { return []; } else { return array_splice.apply(this, arguments); } } }, !splicenoopreturnsemptyarray); var spliceworkswithemptyobject = (function () { var obj = {}; arrayprototype.splice.call(obj, 0, 0, 1); return obj.length === 1; }()); defineproperties(arrayprototype, { splice: function splice(start, deletecount) { if (arguments.length === 0) { return []; } var args = arguments; this.length = max(es.tointeger(this.length), 0); if (arguments.length > 0 && typeof deletecount !== 'number') { args = arrayslice(arguments); if (args.length < 2) { pushcall(args, this.length - start); } else { args[1] = es.tointeger(deletecount); } } return array_splice.apply(this, args); } }, !spliceworkswithemptyobject); var spliceworkswithlargesparsearrays = (function () { // per https://github.com/es-shims/es5-shim/issues/295 // safari 7/8 breaks with sparse arrays of size 1e5 or greater var arr = new $array(1e5); // note: the index must be 8 or larger or the test will false pass arr[8] = 'x'; arr.splice(1, 1); // note: this test must be defined *after* the indexof shim // per https://github.com/es-shims/es5-shim/issues/313 return arr.indexof('x') === 7; }()); var spliceworkswithsmallsparsearrays = (function () { // per https://github.com/es-shims/es5-shim/issues/295 // opera 12.15 breaks on this, no idea why. var n = 256; var arr = []; arr[n] = 'a'; arr.splice(n + 1, 0, 'b'); return arr[n] === 'a'; }()); defineproperties(arrayprototype, { splice: function splice(start, deletecount) { var o = es.toobject(this); var a = []; var len = es.touint32(o.length); var relativestart = es.tointeger(start); var actualstart = relativestart < 0 ? max((len + relativestart), 0) : min(relativestart, len); var actualdeletecount = min(max(es.tointeger(deletecount), 0), len - actualstart); var k = 0; var from; while (k < actualdeletecount) { from = $string(actualstart + k); if (owns(o, from)) { a[k] = o[from]; } k += 1; } var items = arrayslice(arguments, 2); var itemcount = items.length; var to; if (itemcount < actualdeletecount) { k = actualstart; var maxk = len - actualdeletecount; while (k < maxk) { from = $string(k + actualdeletecount); to = $string(k + itemcount); if (owns(o, from)) { o[to] = o[from]; } else { delete o[to]; } k += 1; } k = len; var mink = len - actualdeletecount + itemcount; while (k > mink) { delete o[k - 1]; k -= 1; } } else if (itemcount > actualdeletecount) { k = len - actualdeletecount; while (k > actualstart) { from = $string(k + actualdeletecount - 1); to = $string(k + itemcount - 1); if (owns(o, from)) { o[to] = o[from]; } else { delete o[to]; } k -= 1; } } k = actualstart; for (var i = 0; i < items.length; ++i) { o[k] = items[i]; k += 1; } o.length = len - actualdeletecount + itemcount; return a; } }, !spliceworkswithlargesparsearrays || !spliceworkswithsmallsparsearrays); var originaljoin = arrayprototype.join; var hasstringjoinbug; try { hasstringjoinbug = array.prototype.join.call('123', ',') !== '1,2,3'; } catch (e) { hasstringjoinbug = true; } if (hasstringjoinbug) { defineproperties(arrayprototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originaljoin.call(isstring(this) ? strsplit(this, '') : this, sep); } }, hasstringjoinbug); } var hasjoinundefinedbug = [1, 2].join(undefined) !== '1,2'; if (hasjoinundefinedbug) { defineproperties(arrayprototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originaljoin.call(this, sep); } }, hasjoinundefinedbug); } var pushshim = function push(item) { var o = es.toobject(this); var n = es.touint32(o.length); var i = 0; while (i < arguments.length) { o[n + i] = arguments[i]; i += 1; } o.length = n + i; return n + i; }; var pushisnotgeneric = (function () { var obj = {}; var result = array.prototype.push.call(obj, undefined); return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0); }()); defineproperties(arrayprototype, { push: function push(item) { if (isarray(this)) { return array_push.apply(this, arguments); } return pushshim.apply(this, arguments); } }, pushisnotgeneric); // this fixes a very weird bug in opera 10.6 when pushing `undefined var pushundefinedisweird = (function () { var arr = []; var result = arr.push(undefined); return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0); }()); defineproperties(arrayprototype, { push: pushshim }, pushundefinedisweird); // es5 15.2.3.14 // http://es5.github.io/#x15.4.4.10 // fix boxed string bug defineproperties(arrayprototype, { slice: function (start, end) { var arr = isstring(this) ? strsplit(this, '') : this; return arraysliceapply(arr, arguments); } }, splitstring); var sortignoresnonfunctions = (function () { try { [1, 2].sort(null); [1, 2].sort({}); return true; } catch (e) {} return false; }()); var sortthrowsonregex = (function () { // this is a problem in firefox 4, in which `typeof /11289/a/ === 'function'` try { [1, 2].sort(/11289/a/); return false; } catch (e) {} return true; }()); var sortignoresundefined = (function () { // applies in ie 8, for one. try { [1, 2].sort(undefined); return true; } catch (e) {} return false; }()); defineproperties(arrayprototype, { sort: function sort(comparefn) { if (typeof comparefn === 'undefined') { return arraysort(this); } if (!iscallable(comparefn)) { throw new typeerror('array.prototype.sort callback must be a function'); } return arraysort(this, comparefn); } }, sortignoresnonfunctions || !sortignoresundefined || !sortthrowsonregex); // // object // ====== // // es5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation var hasdontenumbug = !isenum({ 'tostring': null }, 'tostring'); var hasprotoenumbug = isenum(function () {}, 'prototype'); var hasstringenumbug = !owns('x', '0'); var equalsconstructorprototype = function (o) { var ctor = o.constructor; return ctor && ctor.prototype === o; }; var blacklistedkeys = { $window: true, $console: true, $parent: true, $self: true, $frame: true, $frames: true, $frameelement: true, $webkitindexeddb: true, $webkitstorageinfo: true, $external: true }; var hasautomationequalitybug = (function () { /* globals window */ if (typeof window === 'undefined') { return false; } for (var k in window) { try { if (!blacklistedkeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') { equalsconstructorprototype(window[k]); } } catch (e) { return true; } } return false; }()); var equalsconstructorprototypeifnotbuggy = function (object) { if (typeof window === 'undefined' || !hasautomationequalitybug) { return equalsconstructorprototype(object); } try { return equalsconstructorprototype(object); } catch (e) { return false; } }; var dontenums = [ 'tostring', 'tolocalestring', 'valueof', 'hasownproperty', 'isprototypeof', 'propertyisenumerable', 'constructor' ]; var dontenumslength = dontenums.length; // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js // can be replaced with require('is-arguments') if we ever use a build process instead var isstandardarguments = function isarguments(value) { return tostr(value) === '[object arguments]'; }; var islegacyarguments = function isarguments(value) { return value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && !isarray(value) && iscallable(value.callee); }; var isarguments = isstandardarguments(arguments) ? isstandardarguments : islegacyarguments; defineproperties($object, { keys: function keys(object) { var isfn = iscallable(object); var isargs = isarguments(object); var isobject = object !== null && typeof object === 'object'; var isstr = isobject && isstring(object); if (!isobject && !isfn && !isargs) { throw new typeerror('object.keys called on a non-object'); } var thekeys = []; var skipproto = hasprotoenumbug && isfn; if ((isstr && hasstringenumbug) || isargs) { for (var i = 0; i < object.length; ++i) { pushcall(thekeys, $string(i)); } } if (!isargs) { for (var name in object) { if (!(skipproto && name === 'prototype') && owns(object, name)) { pushcall(thekeys, $string(name)); } } } if (hasdontenumbug) { var skipconstructor = equalsconstructorprototypeifnotbuggy(object); for (var j = 0; j < dontenumslength; j++) { var dontenum = dontenums[j]; if (!(skipconstructor && dontenum === 'constructor') && owns(object, dontenum)) { pushcall(thekeys, dontenum); } } } return thekeys; } }); var keysworkswitharguments = $object.keys && (function () { // safari 5.0 bug return $object.keys(arguments).length === 2; }(1, 2)); var keyshasargumentslengthbug = $object.keys && (function () { var argkeys = $object.keys(arguments); return arguments.length !== 1 || argkeys.length !== 1 || argkeys[0] !== 1; }(1)); var originalkeys = $object.keys; defineproperties($object, { keys: function keys(object) { if (isarguments(object)) { return originalkeys(arrayslice(object)); } else { return originalkeys(object); } } }, !keysworkswitharguments || keyshasargumentslengthbug); // // date // ==== // var hasnegativemonthyearbug = new date(-3509827329600292).getutcmonth() !== 0; var anegativetestdate = new date(-1509842289600292); var apositivetestdate = new date(1449662400000); var hastoutcstringformatbug = anegativetestdate.toutcstring() !== 'mon, 01 jan -45875 11:59:59 gmt'; var hastodatestringformatbug; var hastostringformatbug; var timezoneoffset = anegativetestdate.gettimezoneoffset(); if (timezoneoffset < -720) { hastodatestringformatbug = anegativetestdate.todatestring() !== 'tue jan 02 -45875'; hastostringformatbug = !(/^thu dec 10 2015 \d\d:\d\d:\d\d gmt[-\+]\d\d\d\d(?: |$)/).test(apositivetestdate.tostring()); } else { hastodatestringformatbug = anegativetestdate.todatestring() !== 'mon jan 01 -45875'; hastostringformatbug = !(/^wed dec 09 2015 \d\d:\d\d:\d\d gmt[-\+]\d\d\d\d(?: |$)/).test(apositivetestdate.tostring()); } var originalgetfullyear = call.bind(date.prototype.getfullyear); var originalgetmonth = call.bind(date.prototype.getmonth); var originalgetdate = call.bind(date.prototype.getdate); var originalgetutcfullyear = call.bind(date.prototype.getutcfullyear); var originalgetutcmonth = call.bind(date.prototype.getutcmonth); var originalgetutcdate = call.bind(date.prototype.getutcdate); var originalgetutcday = call.bind(date.prototype.getutcday); var originalgetutchours = call.bind(date.prototype.getutchours); var originalgetutcminutes = call.bind(date.prototype.getutcminutes); var originalgetutcseconds = call.bind(date.prototype.getutcseconds); var originalgetutcmilliseconds = call.bind(date.prototype.getutcmilliseconds); var dayname = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; var monthname = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; var daysinmonth = function daysinmonth(month, year) { return originalgetdate(new date(year, month, 0)); }; defineproperties(date.prototype, { getfullyear: function getfullyear() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetfullyear(this); if (year < 0 && originalgetmonth(this) > 11) { return year + 1; } return year; }, getmonth: function getmonth() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetfullyear(this); var month = originalgetmonth(this); if (year < 0 && month > 11) { return 0; } return month; }, getdate: function getdate() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetfullyear(this); var month = originalgetmonth(this); var date = originalgetdate(this); if (year < 0 && month > 11) { if (month === 12) { return date; } var days = daysinmonth(0, year + 1); return (days - date) + 1; } return date; }, getutcfullyear: function getutcfullyear() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetutcfullyear(this); if (year < 0 && originalgetutcmonth(this) > 11) { return year + 1; } return year; }, getutcmonth: function getutcmonth() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetutcfullyear(this); var month = originalgetutcmonth(this); if (year < 0 && month > 11) { return 0; } return month; }, getutcdate: function getutcdate() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var year = originalgetutcfullyear(this); var month = originalgetutcmonth(this); var date = originalgetutcdate(this); if (year < 0 && month > 11) { if (month === 12) { return date; } var days = daysinmonth(0, year + 1); return (days - date) + 1; } return date; } }, hasnegativemonthyearbug); defineproperties(date.prototype, { toutcstring: function toutcstring() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var day = originalgetutcday(this); var date = originalgetutcdate(this); var month = originalgetutcmonth(this); var year = originalgetutcfullyear(this); var hour = originalgetutchours(this); var minute = originalgetutcminutes(this); var second = originalgetutcseconds(this); return dayname[day] + ', ' + (date < 10 ? '0' + date : date) + ' ' + monthname[month] + ' ' + year + ' ' + (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute) + ':' + (second < 10 ? '0' + second : second) + ' gmt'; } }, hasnegativemonthyearbug || hastoutcstringformatbug); // opera 12 has `,` defineproperties(date.prototype, { todatestring: function todatestring() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var day = this.getday(); var date = this.getdate(); var month = this.getmonth(); var year = this.getfullyear(); return dayname[day] + ' ' + monthname[month] + ' ' + (date < 10 ? '0' + date : date) + ' ' + year; } }, hasnegativemonthyearbug || hastodatestringformatbug); // can't use defineproperties here because of tostring enumeration issue in ie <= 8 if (hasnegativemonthyearbug || hastostringformatbug) { date.prototype.tostring = function tostring() { if (!this || !(this instanceof date)) { throw new typeerror('this is not a date object.'); } var day = this.getday(); var date = this.getdate(); var month = this.getmonth(); var year = this.getfullyear(); var hour = this.gethours(); var minute = this.getminutes(); var second = this.getseconds(); var timezoneoffset = this.gettimezoneoffset(); var hoursoffset = math.floor(math.abs(timezoneoffset) / 60); var minutesoffset = math.floor(math.abs(timezoneoffset) % 60); return dayname[day] + ' ' + monthname[month] + ' ' + (date < 10 ? '0' + date : date) + ' ' + year + ' ' + (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute) + ':' + (second < 10 ? '0' + second : second) + ' gmt' + (timezoneoffset > 0 ? '-' : '+') + (hoursoffset < 10 ? '0' + hoursoffset : hoursoffset) + (minutesoffset < 10 ? '0' + minutesoffset : minutesoffset); }; if (supportsdescriptors) { $object.defineproperty(date.prototype, 'tostring', { configurable: true, enumerable: false, writable: true }); } } // es5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 // this function returns a string value represent the instance in time // represented by this date object. the format of the string is the date time // string format defined in 15.9.1.15. all fields are present in the string. // the time zone is always utc, denoted by the suffix z. if the time value of // this object is not a finite number a rangeerror exception is thrown. var negativedate = -62198755200000; var negativeyearstring = '-000001'; var hasnegativedatebug = date.prototype.toisostring && new date(negativedate).toisostring().indexof(negativeyearstring) === -1; var hassafari51datebug = date.prototype.toisostring && new date(-1).toisostring() !== '1969-12-31t23:59:59.999z'; var gettime = call.bind(date.prototype.gettime); defineproperties(date.prototype, { toisostring: function toisostring() { if (!isfinite(this) || !isfinite(gettime(this))) { // adope photoshop requires the second check. throw new rangeerror('date.prototype.toisostring called on non-finite value.'); } var year = originalgetutcfullyear(this); var month = originalgetutcmonth(this); // see https://github.com/es-shims/es5-shim/issues/111 year += math.floor(month / 12); month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. var result = [month + 1, originalgetutcdate(this), originalgetutchours(this), originalgetutcminutes(this), originalgetutcseconds(this)]; year = ( (year < 0 ? '-' : (year > 9999 ? '+' : '')) + strslice('00000' + math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); for (var i = 0; i < result.length; ++i) { // pad months, days, hours, minutes, and seconds to have two digits. result[i] = strslice('00' + result[i], -2); } // pad milliseconds to have three digits. return ( year + '-' + arrayslice(result, 0, 2).join('-') + 't' + arrayslice(result, 2).join(':') + '.' + strslice('000' + originalgetutcmilliseconds(this), -3) + 'z' ); } }, hasnegativedatebug || hassafari51datebug); // es5 15.9.5.44 // http://es5.github.com/#x15.9.5.44 // this function provides a string representation of a date object for use by // json.stringify (15.12.3). var datetojsonissupported = (function () { try { return date.prototype.tojson && new date(nan).tojson() === null && new date(negativedate).tojson().indexof(negativeyearstring) !== -1 && date.prototype.tojson.call({ // generic toisostring: function () { return true; } }); } catch (e) { return false; } }()); if (!datetojsonissupported) { date.prototype.tojson = function tojson(key) { // when the tojson method is called with argument key, the following // steps are taken: // 1. let o be the result of calling toobject, giving it the this // value as its argument. // 2. let tv be es.toprimitive(o, hint number). var o = $object(this); var tv = es.toprimitive(o); // 3. if tv is a number and is not finite, return null. if (typeof tv === 'number' && !isfinite(tv)) { return null; } // 4. let toiso be the result of calling the [[get]] internal method of // o with argument "toisostring". var toiso = o.toisostring; // 5. if iscallable(toiso) is false, throw a typeerror exception. if (!iscallable(toiso)) { throw new typeerror('toisostring property is not callable'); } // 6. return the result of calling the [[call]] internal method of // toiso with o as the this value and an empty argument list. return toiso.call(o); // note 1 the argument is ignored. // note 2 the tojson function is intentionally generic; it does not // require that its this value be a date object. therefore, it can be // transferred to other kinds of objects for use as a method. however, // it does require that any such object have a toisostring method. an // object is free to use the argument key to filter its // stringification. }; } // es5 15.9.4.2 // http://es5.github.com/#x15.9.4.2 // based on work shared by daniel friesen (dantman) // http://gist.github.com/303249 var supportsextendedyears = date.parse('+033658-09-27t01:46:40.000z') === 1e15; 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')); var doesnotparsey2knewyear = isnan(date.parse('2000-01-01t00:00:00.000z')); if (doesnotparsey2knewyear || acceptsinvaliddates || !supportsextendedyears) { // xxx global assignment won't work in embeddings that use // an alternate object for the context. /* global date: true */ /* eslint-disable no-undef */ var maxsafeunsigned32bit = math.pow(2, 31) - 1; var hassafarisignedintbug = isactualnan(new date(1970, 0, 1, 0, 0, 0, maxsafeunsigned32bit + 1).gettime()); /* eslint-disable no-implicit-globals */ date = (function (nativedate) { /* eslint-enable no-implicit-globals */ /* eslint-enable no-undef */ // date.length === 7 var dateshim = function date(y, m, d, h, m, s, ms) { var length = arguments.length; var date; if (this instanceof nativedate) { var seconds = s; var millis = ms; if (hassafarisignedintbug && length >= 7 && ms > maxsafeunsigned32bit) { // work around a safari 8/9 bug where it treats the seconds as signed var mstoshift = math.floor(ms / maxsafeunsigned32bit) * maxsafeunsigned32bit; var stoshift = math.floor(mstoshift / 1e3); seconds += stoshift; millis -= stoshift * 1e3; } date = length === 1 && $string(y) === y ? // isstring(y) // we explicitly pass it through parse: new nativedate(dateshim.parse(y)) : // we have to manually make calls depending on argument // length here length >= 7 ? new nativedate(y, m, d, h, m, seconds, millis) : length >= 6 ? new nativedate(y, m, d, h, m, seconds) : length >= 5 ? new nativedate(y, m, d, h, m) : length >= 4 ? new nativedate(y, m, d, h) : length >= 3 ? new nativedate(y, m, d) : length >= 2 ? new nativedate(y, m) : length >= 1 ? new nativedate(y instanceof nativedate ? +y : y) : new nativedate(); } else { date = nativedate.apply(this, arguments); } if (!isprimitive(date)) { // prevent mixups with unfixed date object defineproperties(date, { constructor: dateshim }, true); } return date; }; // 15.9.1.15 date time string format. var isodateexpression = new regexp('^' + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture '(?:' + // capture hours:minutes:seconds.milliseconds 't(\\d{2})' + // hours capture ':(\\d{2})' + // minutes capture '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture ')?' + '(' + // capture utc offset component 'z|' + // utc capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture ')' + ')?)?)?)?' + '$'); var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; var dayfrommonth = function dayfrommonth(year, month) { var t = month > 1 ? 1 : 0; return ( months[month] + math.floor((year - 1969 + t) / 4) - math.floor((year - 1901 + t) / 100) + math.floor((year - 1601 + t) / 400) + 365 * (year - 1970) ); }; var toutc = function toutc(t) { var s = 0; var ms = t; if (hassafarisignedintbug && ms > maxsafeunsigned32bit) { // work around a safari 8/9 bug where it treats the seconds as signed var mstoshift = math.floor(ms / maxsafeunsigned32bit) * maxsafeunsigned32bit; var stoshift = math.floor(mstoshift / 1e3); s += stoshift; ms -= stoshift * 1e3; } return $number(new nativedate(1970, 0, 1, 0, 0, s, ms)); }; // copy any custom methods a 3rd party library may have added for (var key in nativedate) { if (owns(nativedate, key)) { dateshim[key] = nativedate[key]; } } // copy "native" methods explicitly; they may be non-enumerable defineproperties(dateshim, { now: nativedate.now, utc: nativedate.utc }, true); dateshim.prototype = nativedate.prototype; defineproperties(dateshim.prototype, { constructor: dateshim }, true); // upgrade date.parse to handle simplified iso 8601 strings var parseshim = function parse(string) { var match = isodateexpression.exec(string); if (match) { // parse months, days, hours, minutes, seconds, and milliseconds // provide default values if necessary // parse the utc offset component var year = $number(match[1]), month = $number(match[2] || 1) - 1, day = $number(match[3] || 1) - 1, hour = $number(match[4] || 0), minute = $number(match[5] || 0), second = $number(match[6] || 0), millisecond = math.floor($number(match[7] || 0) * 1000), // when time zone is missed, local offset should be used // (es 5.1 bug) // see https://bugs.ecmascript.org/show_bug.cgi?id=112 islocaltime = boolean(match[4] && !match[8]), signoffset = match[9] === '-' ? 1 : -1, houroffset = $number(match[10] || 0), minuteoffset = $number(match[11] || 0), result; var hasminutesorsecondsormilliseconds = minute > 0 || second > 0 || millisecond > 0; if ( hour < (hasminutesorsecondsormilliseconds ? 24 : 25) && minute < 60 && second < 60 && millisecond < 1000 && month > -1 && month < 12 && houroffset < 24 && minuteoffset < 60 && // detect invalid offsets day > -1 && day < (dayfrommonth(year, month + 1) - dayfrommonth(year, month)) ) { result = ( (dayfrommonth(year, month) + day) * 24 + hour + houroffset * signoffset ) * 60; result = ( (result + minute + minuteoffset * signoffset) * 60 + second ) * 1000 + millisecond; if (islocaltime) { result = toutc(result); } if (-8.64e15 <= result && result <= 8.64e15) { return result; } } return nan; } return nativedate.parse.apply(this, arguments); }; defineproperties(dateshim, { parse: parseshim }); return dateshim; }(date)); /* global date: false */ } // es5 15.9.4.4 // http://es5.github.com/#x15.9.4.4 if (!date.now) { date.now = function now() { return new date().gettime(); }; } // // number // ====== // // es5.1 15.7.4.5 // http://es5.github.com/#x15.7.4.5 var hastofixedbugs = numberprototype.tofixed && ( (0.00008).tofixed(3) !== '0.000' || (0.9).tofixed(0) !== '1' || (1.255).tofixed(2) !== '1.25' || (1000000000000000128).tofixed(0) !== '1000000000000000128' ); var tofixedhelpers = { base: 1e7, size: 6, data: [0, 0, 0, 0, 0, 0], multiply: function multiply(n, c) { var i = -1; var c2 = c; while (++i < tofixedhelpers.size) { c2 += n * tofixedhelpers.data[i]; tofixedhelpers.data[i] = c2 % tofixedhelpers.base; c2 = math.floor(c2 / tofixedhelpers.base); } }, divide: function divide(n) { var i = tofixedhelpers.size; var c = 0; while (--i >= 0) { c += tofixedhelpers.data[i]; tofixedhelpers.data[i] = math.floor(c / n); c = (c % n) * tofixedhelpers.base; } }, numtostring: function numtostring() { var i = tofixedhelpers.size; var s = ''; while (--i >= 0) { if (s !== '' || i === 0 || tofixedhelpers.data[i] !== 0) { var t = $string(tofixedhelpers.data[i]); if (s === '') { s = t; } else { s += strslice('0000000', 0, 7 - t.length) + t; } } } return s; }, pow: function pow(x, n, acc) { return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); }, log: function log(x) { var n = 0; var x2 = x; while (x2 >= 4096) { n += 12; x2 /= 4096; } while (x2 >= 2) { n += 1; x2 /= 2; } return n; } }; var tofixedshim = function tofixed(fractiondigits) { var f, x, s, m, e, z, j, k; // test for nan and round fractiondigits down f = $number(fractiondigits); f = isactualnan(f) ? 0 : math.floor(f); if (f < 0 || f > 20) { throw new rangeerror('number.tofixed called with invalid number of decimals'); } x = $number(this); if (isactualnan(x)) { return 'nan'; } // if it is too big or small, return the string value of the number if (x <= -1e21 || x >= 1e21) { return $string(x); } s = ''; if (x < 0) { s = '-'; x = -x; } m = '0'; if (x > 1e-21) { // 1e-21 < x < 1e21 // -70 < log2(x) < 70 e = tofixedhelpers.log(x * tofixedhelpers.pow(2, 69, 1)) - 69; z = (e < 0 ? x * tofixedhelpers.pow(2, -e, 1) : x / tofixedhelpers.pow(2, e, 1)); z *= 0x10000000000000; // math.pow(2, 52); e = 52 - e; // -18 < e < 122 // x = z / 2 ^ e if (e > 0) { tofixedhelpers.multiply(0, z); j = f; while (j >= 7) { tofixedhelpers.multiply(1e7, 0); j -= 7; } tofixedhelpers.multiply(tofixedhelpers.pow(10, j, 1), 0); j = e - 1; while (j >= 23) { tofixedhelpers.divide(1 << 23); j -= 23; } tofixedhelpers.divide(1 << j); tofixedhelpers.multiply(1, 1); tofixedhelpers.divide(2); m = tofixedhelpers.numtostring(); } else { tofixedhelpers.multiply(0, z); tofixedhelpers.multiply(1 << (-e), 0); m = tofixedhelpers.numtostring() + strslice('0.00000000000000000000', 2, 2 + f); } } if (f > 0) { k = m.length; if (k <= f) { m = s + strslice('0.0000000000000000000', 0, f - k + 2) + m; } else { m = s + strslice(m, 0, k - f) + '.' + strslice(m, k - f); } } else { m = s + m; } return m; }; defineproperties(numberprototype, { tofixed: tofixedshim }, hastofixedbugs); var hastoprecisionundefinedbug = (function () { try { return 1.0.toprecision(undefined) === '1'; } catch (e) { return true; } }()); var originaltoprecision = numberprototype.toprecision; defineproperties(numberprototype, { toprecision: function toprecision(precision) { return typeof precision === 'undefined' ? originaltoprecision.call(this) : originaltoprecision.call(this, precision); } }, hastoprecisionundefinedbug); // // string // ====== // // es5 15.5.4.14 // http://es5.github.com/#x15.5.4.14 // [bugfix, ie lt 9, firefox 4, konqueror, opera, obscure browsers] // many browsers do not split properly with regular expressions or they // do not perform the split correctly under obscure conditions. // see http://blog.stevenlevithan.com/archives/cross-browser-split // i've tested in many browsers and this seems to cover the deviant ones: // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not // [undefined, "t", undefined, "e", ...] // ''.split(/.?/) should be [], not [""] // '.'.split(/()()/) should be ["."], not ["", "", "."] if ( 'ab'.split(/(?:ab)*/).length !== 2 || '.'.split(/(.?)(.?)/).length !== 4 || 'tesst'.split(/(s)*/)[1] === 't' || 'test'.split(/(?:)/, -1).length !== 4 || ''.split(/.?/).length || '.'.split(/()()/).length > 1 ) { (function () { var compliantexecnpcg = typeof (/()??/).exec('')[1] === 'undefined'; // npcg: nonparticipating capturing group var maxsafe32bitint = math.pow(2, 32) - 1; stringprototype.split = function (separator, limit) { var string = string(this); if (typeof separator === 'undefined' && limit === 0) { return []; } // if `separator` is not a regex, use native split if (!isregex(separator)) { return strsplit(this, separator, limit); } var output = []; var flags = (separator.ignorecase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + // in es6 (separator.sticky ? 'y' : ''), // firefox 3+ and es6 lastlastindex = 0, // make `global` and avoid `lastindex` issues by working with a copy separator2, match, lastindex, lastlength; var separatorcopy = new regexp(separator.source, flags + 'g'); if (!compliantexecnpcg) { // doesn't need flags gy, but they don't hurt separator2 = new regexp('^' + separatorcopy.source + '$(?!\\s)', flags); } /* values for `limit`, per the spec: * if undefined: 4294967295 // maxsafe32bitint * if 0, infinity, or nan: 0 * if positive number: limit = math.floor(limit); if (limit > 4294967295) limit -= 4294967296; * if negative number: 4294967296 - math.floor(math.abs(limit)) * if other: type-convert, then use the above rules */ var splitlimit = typeof limit === 'undefined' ? maxsafe32bitint : es.touint32(limit); match = separatorcopy.exec(string); while (match) { // `separatorcopy.lastindex` is not reliable cross-browser lastindex = match.index + match[0].length; if (lastindex > lastlastindex) { pushcall(output, strslice(string, lastlastindex, match.index)); // fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantexecnpcg && match.length > 1) { /* eslint-disable no-loop-func */ match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (typeof arguments[i] === 'undefined') { match[i] = void 0; } } }); /* eslint-enable no-loop-func */ } if (match.length > 1 && match.index < string.length) { array_push.apply(output, arrayslice(match, 1)); } lastlength = match[0].length; lastlastindex = lastindex; if (output.length >= splitlimit) { break; } } if (separatorcopy.lastindex === match.index) { separatorcopy.lastindex++; // avoid an infinite loop } match = separatorcopy.exec(string); } if (lastlastindex === string.length) { if (lastlength || !separatorcopy.test('')) { pushcall(output, ''); } } else { pushcall(output, strslice(string, lastlastindex)); } return output.length > splitlimit ? arrayslice(output, 0, splitlimit) : output; }; }()); // [bugfix, chrome] // if separator is undefined, then the result array contains just one string, // which is the this value (converted to a string). if limit is not undefined, // then the output array is truncated so that it contains no more than limit // elements. // "0".split(undefined, 0) -> [] } else if ('0'.split(void 0, 0).length) { stringprototype.split = function split(separator, limit) { if (typeof separator === 'undefined' && limit === 0) { return []; } return strsplit(this, separator, limit); }; } var str_replace = stringprototype.replace; var replacereportsgroupscorrectly = (function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { pushcall(groups, group); }); return groups.length === 1 && typeof groups[0] === 'undefined'; }()); if (!replacereportsgroupscorrectly) { stringprototype.replace = function replace(searchvalue, replacevalue) { var isfn = iscallable(replacevalue); var hascapturinggroups = isregex(searchvalue) && (/\)[*?]/).test(searchvalue.source); if (!isfn || !hascapturinggroups) { return str_replace.call(this, searchvalue, replacevalue); } else { var wrappedreplacevalue = function (match) { var length = arguments.length; var originallastindex = searchvalue.lastindex; searchvalue.lastindex = 0; var args = searchvalue.exec(match) || []; searchvalue.lastindex = originallastindex; pushcall(args, arguments[length - 2], arguments[length - 1]); return replacevalue.apply(this, args); }; return str_replace.call(this, searchvalue, wrappedreplacevalue); } }; } // ecma-262, 3rd b.2.3 // not an ecmascript standard, although ecmascript 3rd edition has a // non-normative section suggesting uniform semantics and it should be // normalized across all browsers // [bugfix, ie lt 9] ie < 9 substr() with negative value not working in ie var string_substr = stringprototype.substr; var hasnegativesubstrbug = ''.substr && '0b'.substr(-1) !== 'b'; defineproperties(stringprototype, { substr: function substr(start, length) { var normalizedstart = start; if (start < 0) { normalizedstart = max(this.length + start, 0); } return string_substr.call(this, normalizedstart, length); } }, hasnegativesubstrbug); // es5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 var ws = '\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028' + '\u2029\ufeff'; var zerowidth = '\u200b'; var wsregexchars = '[' + ws + ']'; var trimbeginregexp = new regexp('^' + wsregexchars + wsregexchars + '*'); var trimendregexp = new regexp(wsregexchars + wsregexchars + '*$'); var hastrimwhitespacebug = stringprototype.trim && (ws.trim() || !zerowidth.trim()); defineproperties(stringprototype, { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ trim: function trim() { if (typeof this === 'undefined' || this === null) { throw new typeerror("can't convert " + this + ' to object'); } return $string(this).replace(trimbeginregexp, '').replace(trimendregexp, ''); } }, hastrimwhitespacebug); var trim = call.bind(string.prototype.trim); var haslastindexbug = stringprototype.lastindexof && 'abcあい'.lastindexof('あい', 2) !== -1; defineproperties(stringprototype, { lastindexof: function lastindexof(searchstring) { if (typeof this === 'undefined' || this === null) { throw new typeerror("can't convert " + this + ' to object'); } var s = $string(this); var searchstr = $string(searchstring); var numpos = arguments.length > 1 ? $number(arguments[1]) : nan; var pos = isactualnan(numpos) ? infinity : es.tointeger(numpos); var start = min(max(pos, 0), s.length); var searchlen = searchstr.length; var k = start + searchlen; while (k > 0) { k = max(0, k - searchlen); var index = strindexof(strslice(s, k, start + searchlen), searchstr); if (index !== -1) { return k + index; } } return -1; } }, haslastindexbug); var originallastindexof = stringprototype.lastindexof; defineproperties(stringprototype, { lastindexof: function lastindexof(searchstring) { return originallastindexof.apply(this, arguments); } }, stringprototype.lastindexof.length !== 1); // es-5 15.1.2.2 /* eslint-disable radix */ if (parseint(ws + '08') !== 8 || parseint(ws + '0x16') !== 22) { /* eslint-enable radix */ /* global parseint: true */ parseint = (function (origparseint) { var hexregex = /^[\-+]?0[xx]/; return function parseint(str, radix) { var string = trim(string(str)); var defaultedradix = $number(radix) || (hexregex.test(string) ? 16 : 10); return origparseint(string, defaultedradix); }; }(parseint)); } // https://es5.github.io/#x15.1.2.3 if (1 / parsefloat('-0') !== -infinity) { /* global parsefloat: true */ parsefloat = (function (origparsefloat) { return function parsefloat(string) { var inputstring = trim(string(string)); var result = origparsefloat(inputstring); return result === 0 && strslice(inputstring, 0, 1) === '-' ? -0 : result; }; }(parsefloat)); } if (string(new rangeerror('test')) !== 'rangeerror: test') { var errortostringshim = function tostring() { if (typeof this === 'undefined' || this === null) { throw new typeerror("can't convert " + this + ' to object'); } var name = this.name; if (typeof name === 'undefined') { name = 'error'; } else if (typeof name !== 'string') { name = $string(name); } var msg = this.message; if (typeof msg === 'undefined') { msg = ''; } else if (typeof msg !== 'string') { msg = $string(msg); } if (!name) { return msg; } if (!msg) { return name; } return name + ': ' + msg; }; // can't use defineproperties here because of tostring enumeration issue in ie <= 8 error.prototype.tostring = errortostringshim; } if (supportsdescriptors) { var ensurenonenumerable = function (obj, prop) { if (isenum(obj, prop)) { var desc = object.getownpropertydescriptor(obj, prop); if (desc.configurable) { desc.enumerable = false; object.defineproperty(obj, prop, desc); } } }; ensurenonenumerable(error.prototype, 'message'); if (error.prototype.message !== '') { error.prototype.message = ''; } ensurenonenumerable(error.prototype, 'name'); } if (string(/11289/a/mig) !== '/11289/a/gim') { var regextostring = function tostring() { var str = '/' + this.source + '/'; if (this.global) { str += 'g'; } if (this.ignorecase) { str += 'i'; } if (this.multiline) { str += 'm'; } return str; }; // can't use defineproperties here because of tostring enumeration issue in ie <= 8 regexp.prototype.tostring = regextostring; } }));