es5-shim.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314
  1. // Copyright 2009-2012 by contributors, MIT License
  2. // vim: ts=4 sts=4 sw=4 expandtab
  3. // Module systems magic dance
  4. (function (definition) {
  5. // RequireJS
  6. if (typeof define == "function") {
  7. define(definition);
  8. // YUI3
  9. } else if (typeof YUI == "function") {
  10. YUI.add("es5", definition);
  11. // CommonJS and <script>
  12. } else {
  13. definition();
  14. }
  15. })(function () {
  16. /**
  17. * Brings an environment as close to ECMAScript 5 compliance
  18. * as is possible with the facilities of erstwhile engines.
  19. *
  20. * Annotated ES5: http://es5.github.com/ (specific links below)
  21. * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  22. * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
  23. */
  24. //
  25. // Function
  26. // ========
  27. //
  28. // ES-5 15.3.4.5
  29. // http://es5.github.com/#x15.3.4.5
  30. function Empty() {}
  31. if (!Function.prototype.bind) {
  32. Function.prototype.bind = function bind(that) { // .length is 1
  33. // 1. Let Target be the this value.
  34. var target = this;
  35. // 2. If IsCallable(Target) is false, throw a TypeError exception.
  36. if (typeof target != "function") {
  37. throw new TypeError("Function.prototype.bind called on incompatible " + target);
  38. }
  39. // 3. Let A be a new (possibly empty) internal list of all of the
  40. // argument values provided after thisArg (arg1, arg2 etc), in order.
  41. // XXX slicedArgs will stand in for "A" if used
  42. var args = _Array_slice_.call(arguments, 1); // for normal call
  43. // 4. Let F be a new native ECMAScript object.
  44. // 11. Set the [[Prototype]] internal property of F to the standard
  45. // built-in Function prototype object as specified in 15.3.3.1.
  46. // 12. Set the [[Call]] internal property of F as described in
  47. // 15.3.4.5.1.
  48. // 13. Set the [[Construct]] internal property of F as described in
  49. // 15.3.4.5.2.
  50. // 14. Set the [[HasInstance]] internal property of F as described in
  51. // 15.3.4.5.3.
  52. var bound = function () {
  53. if (this instanceof bound) {
  54. // 15.3.4.5.2 [[Construct]]
  55. // When the [[Construct]] internal method of a function object,
  56. // F that was created using the bind function is called with a
  57. // list of arguments ExtraArgs, the following steps are taken:
  58. // 1. Let target be the value of F's [[TargetFunction]]
  59. // internal property.
  60. // 2. If target has no [[Construct]] internal method, a
  61. // TypeError exception is thrown.
  62. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  63. // property.
  64. // 4. Let args be a new list containing the same values as the
  65. // list boundArgs in the same order followed by the same
  66. // values as the list ExtraArgs in the same order.
  67. // 5. Return the result of calling the [[Construct]] internal
  68. // method of target providing args as the arguments.
  69. var result = target.apply(
  70. this,
  71. args.concat(_Array_slice_.call(arguments))
  72. );
  73. if (Object(result) === result) {
  74. return result;
  75. }
  76. return this;
  77. } else {
  78. // 15.3.4.5.1 [[Call]]
  79. // When the [[Call]] internal method of a function object, F,
  80. // which was created using the bind function is called with a
  81. // this value and a list of arguments ExtraArgs, the following
  82. // steps are taken:
  83. // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  84. // property.
  85. // 2. Let boundThis be the value of F's [[BoundThis]] internal
  86. // property.
  87. // 3. Let target be the value of F's [[TargetFunction]] internal
  88. // property.
  89. // 4. Let args be a new list containing the same values as the
  90. // list boundArgs in the same order followed by the same
  91. // values as the list ExtraArgs in the same order.
  92. // 5. Return the result of calling the [[Call]] internal method
  93. // of target providing boundThis as the this value and
  94. // providing args as the arguments.
  95. // equiv: target.call(this, ...boundArgs, ...args)
  96. return target.apply(
  97. that,
  98. args.concat(_Array_slice_.call(arguments))
  99. );
  100. }
  101. };
  102. if(target.prototype) {
  103. Empty.prototype = target.prototype;
  104. bound.prototype = new Empty();
  105. // Clean up dangling references.
  106. Empty.prototype = null;
  107. }
  108. // XXX bound.length is never writable, so don't even try
  109. //
  110. // 15. If the [[Class]] internal property of Target is "Function", then
  111. // a. Let L be the length property of Target minus the length of A.
  112. // b. Set the length own property of F to either 0 or L, whichever is
  113. // larger.
  114. // 16. Else set the length own property of F to 0.
  115. // 17. Set the attributes of the length own property of F to the values
  116. // specified in 15.3.5.1.
  117. // TODO
  118. // 18. Set the [[Extensible]] internal property of F to true.
  119. // TODO
  120. // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  121. // 20. Call the [[DefineOwnProperty]] internal method of F with
  122. // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  123. // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  124. // false.
  125. // 21. Call the [[DefineOwnProperty]] internal method of F with
  126. // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  127. // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  128. // and false.
  129. // TODO
  130. // NOTE Function objects created using Function.prototype.bind do not
  131. // have a prototype property or the [[Code]], [[FormalParameters]], and
  132. // [[Scope]] internal properties.
  133. // XXX can't delete prototype in pure-js.
  134. // 22. Return F.
  135. return bound;
  136. };
  137. }
  138. // Shortcut to an often accessed properties, in order to avoid multiple
  139. // dereference that costs universally.
  140. // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  141. // us it in defining shortcuts.
  142. var call = Function.prototype.call;
  143. var prototypeOfArray = Array.prototype;
  144. var prototypeOfObject = Object.prototype;
  145. var _Array_slice_ = prototypeOfArray.slice;
  146. // Having a toString local variable name breaks in Opera so use _toString.
  147. var _toString = call.bind(prototypeOfObject.toString);
  148. var owns = call.bind(prototypeOfObject.hasOwnProperty);
  149. // If JS engine supports accessors creating shortcuts.
  150. var defineGetter;
  151. var defineSetter;
  152. var lookupGetter;
  153. var lookupSetter;
  154. var supportsAccessors;
  155. if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
  156. defineGetter = call.bind(prototypeOfObject.__defineGetter__);
  157. defineSetter = call.bind(prototypeOfObject.__defineSetter__);
  158. lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
  159. lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
  160. }
  161. //
  162. // Array
  163. // =====
  164. //
  165. // ES5 15.4.4.12
  166. // http://es5.github.com/#x15.4.4.12
  167. // Default value for second param
  168. // [bugfix, ielt9, old browsers]
  169. // IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12"
  170. if ([1,2].splice(0).length != 2) {
  171. var array_splice = Array.prototype.splice;
  172. if(function() { // test IE < 9 to splice bug - see issue #138
  173. function makeArray(l) {
  174. var a = [];
  175. while (l--) {
  176. a.unshift(l)
  177. }
  178. return a
  179. }
  180. var array = []
  181. , lengthBefore
  182. ;
  183. array.splice.bind(array, 0, 0).apply(null, makeArray(20));
  184. array.splice.bind(array, 0, 0).apply(null, makeArray(26));
  185. lengthBefore = array.length; //20
  186. array.splice(5, 0, "XXX"); // add one element
  187. if(lengthBefore + 1 == array.length) {
  188. return true;// has right splice implementation without bugs
  189. }
  190. // else {
  191. // IE8 bug
  192. // }
  193. }()) {//IE 6/7
  194. Array.prototype.splice = function(start, deleteCount) {
  195. if (!arguments.length) {
  196. return [];
  197. } else {
  198. return array_splice.apply(this, [
  199. start === void 0 ? 0 : start,
  200. deleteCount === void 0 ? (this.length - start) : deleteCount
  201. ].concat(_Array_slice_.call(arguments, 2)))
  202. }
  203. };
  204. }
  205. else {//IE8
  206. Array.prototype.splice = function(start, deleteCount) {
  207. var result
  208. , args = _Array_slice_.call(arguments, 2)
  209. , addElementsCount = args.length
  210. ;
  211. if(!arguments.length) {
  212. return [];
  213. }
  214. if(start === void 0) { // default
  215. start = 0;
  216. }
  217. if(deleteCount === void 0) { // default
  218. deleteCount = this.length - start;
  219. }
  220. if(addElementsCount > 0) {
  221. if(deleteCount <= 0) {
  222. if(start == this.length) { // tiny optimisation #1
  223. this.push.apply(this, args);
  224. return [];
  225. }
  226. if(start == 0) { // tiny optimisation #2
  227. this.unshift.apply(this, args);
  228. return [];
  229. }
  230. }
  231. // Array.prototype.splice implementation
  232. result = _Array_slice_.call(this, start, start + deleteCount);// delete part
  233. args.push.apply(args, _Array_slice_.call(this, start + deleteCount, this.length));// right part
  234. args.unshift.apply(args, _Array_slice_.call(this, 0, start));// left part
  235. // delete all items from this array and replace it to 'left part' + _Array_slice_.call(arguments, 2) + 'right part'
  236. args.unshift(0, this.length);
  237. array_splice.apply(this, args);
  238. return result;
  239. }
  240. return array_splice.call(this, start, deleteCount);
  241. }
  242. }
  243. }
  244. // ES5 15.4.4.12
  245. // http://es5.github.com/#x15.4.4.13
  246. // Return len+argCount.
  247. // [bugfix, ielt8]
  248. // IE < 8 bug: [].unshift(0) == undefined but should be "1"
  249. if ([].unshift(0) != 1) {
  250. var array_unshift = Array.prototype.unshift;
  251. Array.prototype.unshift = function() {
  252. array_unshift.apply(this, arguments);
  253. return this.length;
  254. };
  255. }
  256. // ES5 15.4.3.2
  257. // http://es5.github.com/#x15.4.3.2
  258. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  259. if (!Array.isArray) {
  260. Array.isArray = function isArray(obj) {
  261. return _toString(obj) == "[object Array]";
  262. };
  263. }
  264. // The IsCallable() check in the Array functions
  265. // has been replaced with a strict check on the
  266. // internal class of the object to trap cases where
  267. // the provided function was actually a regular
  268. // expression literal, which in V8 and
  269. // JavaScriptCore is a typeof "function". Only in
  270. // V8 are regular expression literals permitted as
  271. // reduce parameters, so it is desirable in the
  272. // general case for the shim to match the more
  273. // strict and common behavior of rejecting regular
  274. // expressions.
  275. // ES5 15.4.4.18
  276. // http://es5.github.com/#x15.4.4.18
  277. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  278. // Check failure of by-index access of string characters (IE < 9)
  279. // and failure of `0 in boxedString` (Rhino)
  280. var boxedString = Object("a"),
  281. splitString = boxedString[0] != "a" || !(0 in boxedString);
  282. if (!Array.prototype.forEach) {
  283. Array.prototype.forEach = function forEach(fun /*, thisp*/) {
  284. var object = toObject(this),
  285. self = splitString && _toString(this) == "[object String]" ?
  286. this.split("") :
  287. object,
  288. thisp = arguments[1],
  289. i = -1,
  290. length = self.length >>> 0;
  291. // If no callback function or if callback is not a callable function
  292. if (_toString(fun) != "[object Function]") {
  293. throw new TypeError(); // TODO message
  294. }
  295. while (++i < length) {
  296. if (i in self) {
  297. // Invoke the callback function with call, passing arguments:
  298. // context, property value, property key, thisArg object
  299. // context
  300. fun.call(thisp, self[i], i, object);
  301. }
  302. }
  303. };
  304. }
  305. // ES5 15.4.4.19
  306. // http://es5.github.com/#x15.4.4.19
  307. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  308. if (!Array.prototype.map) {
  309. Array.prototype.map = function map(fun /*, thisp*/) {
  310. var object = toObject(this),
  311. self = splitString && _toString(this) == "[object String]" ?
  312. this.split("") :
  313. object,
  314. length = self.length >>> 0,
  315. result = Array(length),
  316. thisp = arguments[1];
  317. // If no callback function or if callback is not a callable function
  318. if (_toString(fun) != "[object Function]") {
  319. throw new TypeError(fun + " is not a function");
  320. }
  321. for (var i = 0; i < length; i++) {
  322. if (i in self)
  323. result[i] = fun.call(thisp, self[i], i, object);
  324. }
  325. return result;
  326. };
  327. }
  328. // ES5 15.4.4.20
  329. // http://es5.github.com/#x15.4.4.20
  330. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  331. if (!Array.prototype.filter) {
  332. Array.prototype.filter = function filter(fun /*, thisp */) {
  333. var object = toObject(this),
  334. self = splitString && _toString(this) == "[object String]" ?
  335. this.split("") :
  336. object,
  337. length = self.length >>> 0,
  338. result = [],
  339. value,
  340. thisp = arguments[1];
  341. // If no callback function or if callback is not a callable function
  342. if (_toString(fun) != "[object Function]") {
  343. throw new TypeError(fun + " is not a function");
  344. }
  345. for (var i = 0; i < length; i++) {
  346. if (i in self) {
  347. value = self[i];
  348. if (fun.call(thisp, value, i, object)) {
  349. result.push(value);
  350. }
  351. }
  352. }
  353. return result;
  354. };
  355. }
  356. // ES5 15.4.4.16
  357. // http://es5.github.com/#x15.4.4.16
  358. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  359. if (!Array.prototype.every) {
  360. Array.prototype.every = function every(fun /*, thisp */) {
  361. var object = toObject(this),
  362. self = splitString && _toString(this) == "[object String]" ?
  363. this.split("") :
  364. object,
  365. length = self.length >>> 0,
  366. thisp = arguments[1];
  367. // If no callback function or if callback is not a callable function
  368. if (_toString(fun) != "[object Function]") {
  369. throw new TypeError(fun + " is not a function");
  370. }
  371. for (var i = 0; i < length; i++) {
  372. if (i in self && !fun.call(thisp, self[i], i, object)) {
  373. return false;
  374. }
  375. }
  376. return true;
  377. };
  378. }
  379. // ES5 15.4.4.17
  380. // http://es5.github.com/#x15.4.4.17
  381. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  382. if (!Array.prototype.some) {
  383. Array.prototype.some = function some(fun /*, thisp */) {
  384. var object = toObject(this),
  385. self = splitString && _toString(this) == "[object String]" ?
  386. this.split("") :
  387. object,
  388. length = self.length >>> 0,
  389. thisp = arguments[1];
  390. // If no callback function or if callback is not a callable function
  391. if (_toString(fun) != "[object Function]") {
  392. throw new TypeError(fun + " is not a function");
  393. }
  394. for (var i = 0; i < length; i++) {
  395. if (i in self && fun.call(thisp, self[i], i, object)) {
  396. return true;
  397. }
  398. }
  399. return false;
  400. };
  401. }
  402. // ES5 15.4.4.21
  403. // http://es5.github.com/#x15.4.4.21
  404. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  405. if (!Array.prototype.reduce) {
  406. Array.prototype.reduce = function reduce(fun /*, initial*/) {
  407. var object = toObject(this),
  408. self = splitString && _toString(this) == "[object String]" ?
  409. this.split("") :
  410. object,
  411. length = self.length >>> 0;
  412. // If no callback function or if callback is not a callable function
  413. if (_toString(fun) != "[object Function]") {
  414. throw new TypeError(fun + " is not a function");
  415. }
  416. // no value to return if no initial value and an empty array
  417. if (!length && arguments.length == 1) {
  418. throw new TypeError("reduce of empty array with no initial value");
  419. }
  420. var i = 0;
  421. var result;
  422. if (arguments.length >= 2) {
  423. result = arguments[1];
  424. } else {
  425. do {
  426. if (i in self) {
  427. result = self[i++];
  428. break;
  429. }
  430. // if array contains no values, no initial value to return
  431. if (++i >= length) {
  432. throw new TypeError("reduce of empty array with no initial value");
  433. }
  434. } while (true);
  435. }
  436. for (; i < length; i++) {
  437. if (i in self) {
  438. result = fun.call(void 0, result, self[i], i, object);
  439. }
  440. }
  441. return result;
  442. };
  443. }
  444. // ES5 15.4.4.22
  445. // http://es5.github.com/#x15.4.4.22
  446. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  447. if (!Array.prototype.reduceRight) {
  448. Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
  449. var object = toObject(this),
  450. self = splitString && _toString(this) == "[object String]" ?
  451. this.split("") :
  452. object,
  453. length = self.length >>> 0;
  454. // If no callback function or if callback is not a callable function
  455. if (_toString(fun) != "[object Function]") {
  456. throw new TypeError(fun + " is not a function");
  457. }
  458. // no value to return if no initial value, empty array
  459. if (!length && arguments.length == 1) {
  460. throw new TypeError("reduceRight of empty array with no initial value");
  461. }
  462. var result, i = length - 1;
  463. if (arguments.length >= 2) {
  464. result = arguments[1];
  465. } else {
  466. do {
  467. if (i in self) {
  468. result = self[i--];
  469. break;
  470. }
  471. // if array contains no values, no initial value to return
  472. if (--i < 0) {
  473. throw new TypeError("reduceRight of empty array with no initial value");
  474. }
  475. } while (true);
  476. }
  477. if (i < 0) {
  478. return result;
  479. }
  480. do {
  481. if (i in this) {
  482. result = fun.call(void 0, result, self[i], i, object);
  483. }
  484. } while (i--);
  485. return result;
  486. };
  487. }
  488. // ES5 15.4.4.14
  489. // http://es5.github.com/#x15.4.4.14
  490. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  491. if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
  492. Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
  493. var self = splitString && _toString(this) == "[object String]" ?
  494. this.split("") :
  495. toObject(this),
  496. length = self.length >>> 0;
  497. if (!length) {
  498. return -1;
  499. }
  500. var i = 0;
  501. if (arguments.length > 1) {
  502. i = toInteger(arguments[1]);
  503. }
  504. // handle negative indices
  505. i = i >= 0 ? i : Math.max(0, length + i);
  506. for (; i < length; i++) {
  507. if (i in self && self[i] === sought) {
  508. return i;
  509. }
  510. }
  511. return -1;
  512. };
  513. }
  514. // ES5 15.4.4.15
  515. // http://es5.github.com/#x15.4.4.15
  516. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  517. if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
  518. Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
  519. var self = splitString && _toString(this) == "[object String]" ?
  520. this.split("") :
  521. toObject(this),
  522. length = self.length >>> 0;
  523. if (!length) {
  524. return -1;
  525. }
  526. var i = length - 1;
  527. if (arguments.length > 1) {
  528. i = Math.min(i, toInteger(arguments[1]));
  529. }
  530. // handle negative indices
  531. i = i >= 0 ? i : length - Math.abs(i);
  532. for (; i >= 0; i--) {
  533. if (i in self && sought === self[i]) {
  534. return i;
  535. }
  536. }
  537. return -1;
  538. };
  539. }
  540. //
  541. // Object
  542. // ======
  543. //
  544. // ES5 15.2.3.14
  545. // http://es5.github.com/#x15.2.3.14
  546. if (!Object.keys) {
  547. // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  548. var hasDontEnumBug = true,
  549. dontEnums = [
  550. "toString",
  551. "toLocaleString",
  552. "valueOf",
  553. "hasOwnProperty",
  554. "isPrototypeOf",
  555. "propertyIsEnumerable",
  556. "constructor"
  557. ],
  558. dontEnumsLength = dontEnums.length;
  559. for (var key in {"toString": null}) {
  560. hasDontEnumBug = false;
  561. }
  562. Object.keys = function keys(object) {
  563. if (
  564. (typeof object != "object" && typeof object != "function") ||
  565. object === null
  566. ) {
  567. throw new TypeError("Object.keys called on a non-object");
  568. }
  569. var keys = [];
  570. for (var name in object) {
  571. if (owns(object, name)) {
  572. keys.push(name);
  573. }
  574. }
  575. if (hasDontEnumBug) {
  576. for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
  577. var dontEnum = dontEnums[i];
  578. if (owns(object, dontEnum)) {
  579. keys.push(dontEnum);
  580. }
  581. }
  582. }
  583. return keys;
  584. };
  585. }
  586. //
  587. // Date
  588. // ====
  589. //
  590. // ES5 15.9.5.43
  591. // http://es5.github.com/#x15.9.5.43
  592. // This function returns a String value represent the instance in time
  593. // represented by this Date object. The format of the String is the Date Time
  594. // string format defined in 15.9.1.15. All fields are present in the String.
  595. // The time zone is always UTC, denoted by the suffix Z. If the time value of
  596. // this object is not a finite Number a RangeError exception is thrown.
  597. var negativeDate = -62198755200000,
  598. negativeYearString = "-000001";
  599. if (
  600. !Date.prototype.toISOString ||
  601. (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)
  602. ) {
  603. Date.prototype.toISOString = function toISOString() {
  604. var result, length, value, year, month;
  605. if (!isFinite(this)) {
  606. throw new RangeError("Date.prototype.toISOString called on non-finite value.");
  607. }
  608. year = this.getUTCFullYear();
  609. month = this.getUTCMonth();
  610. // see https://github.com/kriskowal/es5-shim/issues/111
  611. year += Math.floor(month / 12);
  612. month = (month % 12 + 12) % 12;
  613. // the date time string format is specified in 15.9.1.15.
  614. result = [month + 1, this.getUTCDate(),
  615. this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
  616. year = (
  617. (year < 0 ? "-" : (year > 9999 ? "+" : "")) +
  618. ("00000" + Math.abs(year))
  619. .slice(0 <= year && year <= 9999 ? -4 : -6)
  620. );
  621. length = result.length;
  622. while (length--) {
  623. value = result[length];
  624. // pad months, days, hours, minutes, and seconds to have two
  625. // digits.
  626. if (value < 10) {
  627. result[length] = "0" + value;
  628. }
  629. }
  630. // pad milliseconds to have three digits.
  631. return (
  632. year + "-" + result.slice(0, 2).join("-") +
  633. "T" + result.slice(2).join(":") + "." +
  634. ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
  635. );
  636. };
  637. }
  638. // ES5 15.9.5.44
  639. // http://es5.github.com/#x15.9.5.44
  640. // This function provides a String representation of a Date object for use by
  641. // JSON.stringify (15.12.3).
  642. var dateToJSONIsSupported = false;
  643. try {
  644. dateToJSONIsSupported = (
  645. Date.prototype.toJSON &&
  646. new Date(NaN).toJSON() === null &&
  647. new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
  648. Date.prototype.toJSON.call({ // generic
  649. toISOString: function () {
  650. return true;
  651. }
  652. })
  653. );
  654. } catch (e) {
  655. }
  656. if (!dateToJSONIsSupported) {
  657. Date.prototype.toJSON = function toJSON(key) {
  658. // When the toJSON method is called with argument key, the following
  659. // steps are taken:
  660. // 1. Let O be the result of calling ToObject, giving it the this
  661. // value as its argument.
  662. // 2. Let tv be toPrimitive(O, hint Number).
  663. var o = Object(this),
  664. tv = toPrimitive(o),
  665. toISO;
  666. // 3. If tv is a Number and is not finite, return null.
  667. if (typeof tv === "number" && !isFinite(tv)) {
  668. return null;
  669. }
  670. // 4. Let toISO be the result of calling the [[Get]] internal method of
  671. // O with argument "toISOString".
  672. toISO = o.toISOString;
  673. // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  674. if (typeof toISO != "function") {
  675. throw new TypeError("toISOString property is not callable");
  676. }
  677. // 6. Return the result of calling the [[Call]] internal method of
  678. // toISO with O as the this value and an empty argument list.
  679. return toISO.call(o);
  680. // NOTE 1 The argument is ignored.
  681. // NOTE 2 The toJSON function is intentionally generic; it does not
  682. // require that its this value be a Date object. Therefore, it can be
  683. // transferred to other kinds of objects for use as a method. However,
  684. // it does require that any such object have a toISOString method. An
  685. // object is free to use the argument key to filter its
  686. // stringification.
  687. };
  688. }
  689. // ES5 15.9.4.2
  690. // http://es5.github.com/#x15.9.4.2
  691. // based on work shared by Daniel Friesen (dantman)
  692. // http://gist.github.com/303249
  693. if (!Date.parse || "Date.parse is buggy") {
  694. // XXX global assignment won't work in embeddings that use
  695. // an alternate object for the context.
  696. Date = (function(NativeDate) {
  697. // Date.length === 7
  698. function Date(Y, M, D, h, m, s, ms) {
  699. var length = arguments.length;
  700. if (this instanceof NativeDate) {
  701. var date = length == 1 && String(Y) === Y ? // isString(Y)
  702. // We explicitly pass it through parse:
  703. new NativeDate(Date.parse(Y)) :
  704. // We have to manually make calls depending on argument
  705. // length here
  706. length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
  707. length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
  708. length >= 5 ? new NativeDate(Y, M, D, h, m) :
  709. length >= 4 ? new NativeDate(Y, M, D, h) :
  710. length >= 3 ? new NativeDate(Y, M, D) :
  711. length >= 2 ? new NativeDate(Y, M) :
  712. length >= 1 ? new NativeDate(Y) :
  713. new NativeDate();
  714. // Prevent mixups with unfixed Date object
  715. date.constructor = Date;
  716. return date;
  717. }
  718. return NativeDate.apply(this, arguments);
  719. };
  720. // 15.9.1.15 Date Time String Format.
  721. var isoDateExpression = new RegExp("^" +
  722. "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign +
  723. // 6-digit extended year
  724. "(?:-(\\d{2})" + // optional month capture
  725. "(?:-(\\d{2})" + // optional day capture
  726. "(?:" + // capture hours:minutes:seconds.milliseconds
  727. "T(\\d{2})" + // hours capture
  728. ":(\\d{2})" + // minutes capture
  729. "(?:" + // optional :seconds.milliseconds
  730. ":(\\d{2})" + // seconds capture
  731. "(?:(\\.\\d{1,}))?" + // milliseconds capture
  732. ")?" +
  733. "(" + // capture UTC offset component
  734. "Z|" + // UTC capture
  735. "(?:" + // offset specifier +/-hours:minutes
  736. "([-+])" + // sign capture
  737. "(\\d{2})" + // hours offset capture
  738. ":(\\d{2})" + // minutes offset capture
  739. ")" +
  740. ")?)?)?)?" +
  741. "$");
  742. var months = [
  743. 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
  744. ];
  745. function dayFromMonth(year, month) {
  746. var t = month > 1 ? 1 : 0;
  747. return (
  748. months[month] +
  749. Math.floor((year - 1969 + t) / 4) -
  750. Math.floor((year - 1901 + t) / 100) +
  751. Math.floor((year - 1601 + t) / 400) +
  752. 365 * (year - 1970)
  753. );
  754. }
  755. // Copy any custom methods a 3rd party library may have added
  756. for (var key in NativeDate) {
  757. Date[key] = NativeDate[key];
  758. }
  759. // Copy "native" methods explicitly; they may be non-enumerable
  760. Date.now = NativeDate.now;
  761. Date.UTC = NativeDate.UTC;
  762. Date.prototype = NativeDate.prototype;
  763. Date.prototype.constructor = Date;
  764. // Upgrade Date.parse to handle simplified ISO 8601 strings
  765. Date.parse = function parse(string) {
  766. var match = isoDateExpression.exec(string);
  767. if (match) {
  768. // parse months, days, hours, minutes, seconds, and milliseconds
  769. // provide default values if necessary
  770. // parse the UTC offset component
  771. var year = Number(match[1]),
  772. month = Number(match[2] || 1) - 1,
  773. day = Number(match[3] || 1) - 1,
  774. hour = Number(match[4] || 0),
  775. minute = Number(match[5] || 0),
  776. second = Number(match[6] || 0),
  777. millisecond = Math.floor(Number(match[7] || 0) * 1000),
  778. // When time zone is missed, local offset should be used
  779. // (ES 5.1 bug)
  780. // see https://bugs.ecmascript.org/show_bug.cgi?id=112
  781. offset = !match[4] || match[8] ?
  782. 0 : Number(new NativeDate(1970, 0)),
  783. signOffset = match[9] === "-" ? 1 : -1,
  784. hourOffset = Number(match[10] || 0),
  785. minuteOffset = Number(match[11] || 0),
  786. result;
  787. if (
  788. hour < (
  789. minute > 0 || second > 0 || millisecond > 0 ?
  790. 24 : 25
  791. ) &&
  792. minute < 60 && second < 60 && millisecond < 1000 &&
  793. month > -1 && month < 12 && hourOffset < 24 &&
  794. minuteOffset < 60 && // detect invalid offsets
  795. day > -1 &&
  796. day < (
  797. dayFromMonth(year, month + 1) -
  798. dayFromMonth(year, month)
  799. )
  800. ) {
  801. result = (
  802. (dayFromMonth(year, month) + day) * 24 +
  803. hour +
  804. hourOffset * signOffset
  805. ) * 60;
  806. result = (
  807. (result + minute + minuteOffset * signOffset) * 60 +
  808. second
  809. ) * 1000 + millisecond + offset;
  810. if (-8.64e15 <= result && result <= 8.64e15) {
  811. return result;
  812. }
  813. }
  814. return NaN;
  815. }
  816. return NativeDate.parse.apply(this, arguments);
  817. };
  818. return Date;
  819. })(Date);
  820. }
  821. // ES5 15.9.4.4
  822. // http://es5.github.com/#x15.9.4.4
  823. if (!Date.now) {
  824. Date.now = function now() {
  825. return new Date().getTime();
  826. };
  827. }
  828. //
  829. // Number
  830. // ======
  831. //
  832. // ES5.1 15.7.4.5
  833. // http://es5.github.com/#x15.7.4.5
  834. if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") {
  835. // Hide these variables and functions
  836. (function () {
  837. var base, size, data, i;
  838. base = 1e7;
  839. size = 6;
  840. data = [0, 0, 0, 0, 0, 0];
  841. function multiply(n, c) {
  842. var i = -1;
  843. while (++i < size) {
  844. c += n * data[i];
  845. data[i] = c % base;
  846. c = Math.floor(c / base);
  847. }
  848. }
  849. function divide(n) {
  850. var i = size, c = 0;
  851. while (--i >= 0) {
  852. c += data[i];
  853. data[i] = Math.floor(c / n);
  854. c = (c % n) * base;
  855. }
  856. }
  857. function toString() {
  858. var i = size;
  859. var s = '';
  860. while (--i >= 0) {
  861. if (s !== '' || i === 0 || data[i] !== 0) {
  862. var t = String(data[i]);
  863. if (s === '') {
  864. s = t;
  865. } else {
  866. s += '0000000'.slice(0, 7 - t.length) + t;
  867. }
  868. }
  869. }
  870. return s;
  871. }
  872. function pow(x, n, acc) {
  873. return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
  874. }
  875. function log(x) {
  876. var n = 0;
  877. while (x >= 4096) {
  878. n += 12;
  879. x /= 4096;
  880. }
  881. while (x >= 2) {
  882. n += 1;
  883. x /= 2;
  884. }
  885. return n;
  886. }
  887. Number.prototype.toFixed = function (fractionDigits) {
  888. var f, x, s, m, e, z, j, k;
  889. // Test for NaN and round fractionDigits down
  890. f = Number(fractionDigits);
  891. f = f !== f ? 0 : Math.floor(f);
  892. if (f < 0 || f > 20) {
  893. throw new RangeError("Number.toFixed called with invalid number of decimals");
  894. }
  895. x = Number(this);
  896. // Test for NaN
  897. if (x !== x) {
  898. return "NaN";
  899. }
  900. // If it is too big or small, return the string value of the number
  901. if (x <= -1e21 || x >= 1e21) {
  902. return String(x);
  903. }
  904. s = "";
  905. if (x < 0) {
  906. s = "-";
  907. x = -x;
  908. }
  909. m = "0";
  910. if (x > 1e-21) {
  911. // 1e-21 < x < 1e21
  912. // -70 < log2(x) < 70
  913. e = log(x * pow(2, 69, 1)) - 69;
  914. z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1));
  915. z *= 0x10000000000000; // Math.pow(2, 52);
  916. e = 52 - e;
  917. // -18 < e < 122
  918. // x = z / 2 ^ e
  919. if (e > 0) {
  920. multiply(0, z);
  921. j = f;
  922. while (j >= 7) {
  923. multiply(1e7, 0);
  924. j -= 7;
  925. }
  926. multiply(pow(10, j, 1), 0);
  927. j = e - 1;
  928. while (j >= 23) {
  929. divide(1 << 23);
  930. j -= 23;
  931. }
  932. divide(1 << j);
  933. multiply(1, 1);
  934. divide(2);
  935. m = toString();
  936. } else {
  937. multiply(0, z);
  938. multiply(1 << (-e), 0);
  939. m = toString() + '0.00000000000000000000'.slice(2, 2 + f);
  940. }
  941. }
  942. if (f > 0) {
  943. k = m.length;
  944. if (k <= f) {
  945. m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
  946. } else {
  947. m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
  948. }
  949. } else {
  950. m = s + m;
  951. }
  952. return m;
  953. }
  954. }());
  955. }
  956. //
  957. // String
  958. // ======
  959. //
  960. // ES5 15.5.4.14
  961. // http://es5.github.com/#x15.5.4.14
  962. // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
  963. // Many browsers do not split properly with regular expressions or they
  964. // do not perform the split correctly under obscure conditions.
  965. // See http://blog.stevenlevithan.com/archives/cross-browser-split
  966. // I've tested in many browsers and this seems to cover the deviant ones:
  967. // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
  968. // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
  969. // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
  970. // [undefined, "t", undefined, "e", ...]
  971. // ''.split(/.?/) should be [], not [""]
  972. // '.'.split(/()()/) should be ["."], not ["", "", "."]
  973. var string_split = String.prototype.split;
  974. if (
  975. 'ab'.split(/(?:ab)*/).length !== 2 ||
  976. '.'.split(/(.?)(.?)/).length !== 4 ||
  977. 'tesst'.split(/(s)*/)[1] === "t" ||
  978. ''.split(/.?/).length === 0 ||
  979. '.'.split(/()()/).length > 1
  980. ) {
  981. (function () {
  982. var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group
  983. String.prototype.split = function (separator, limit) {
  984. var string = this;
  985. if (separator === void 0 && limit === 0)
  986. return [];
  987. // If `separator` is not a regex, use native split
  988. if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
  989. return string_split.apply(this, arguments);
  990. }
  991. var output = [],
  992. flags = (separator.ignoreCase ? "i" : "") +
  993. (separator.multiline ? "m" : "") +
  994. (separator.extended ? "x" : "") + // Proposed for ES6
  995. (separator.sticky ? "y" : ""), // Firefox 3+
  996. lastLastIndex = 0,
  997. // Make `global` and avoid `lastIndex` issues by working with a copy
  998. separator = new RegExp(separator.source, flags + "g"),
  999. separator2, match, lastIndex, lastLength;
  1000. string += ""; // Type-convert
  1001. if (!compliantExecNpcg) {
  1002. // Doesn't need flags gy, but they don't hurt
  1003. separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
  1004. }
  1005. /* Values for `limit`, per the spec:
  1006. * If undefined: 4294967295 // Math.pow(2, 32) - 1
  1007. * If 0, Infinity, or NaN: 0
  1008. * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
  1009. * If negative number: 4294967296 - Math.floor(Math.abs(limit))
  1010. * If other: Type-convert, then use the above rules
  1011. */
  1012. limit = limit === void 0 ?
  1013. -1 >>> 0 : // Math.pow(2, 32) - 1
  1014. limit >>> 0; // ToUint32(limit)
  1015. while (match = separator.exec(string)) {
  1016. // `separator.lastIndex` is not reliable cross-browser
  1017. lastIndex = match.index + match[0].length;
  1018. if (lastIndex > lastLastIndex) {
  1019. output.push(string.slice(lastLastIndex, match.index));
  1020. // Fix browsers whose `exec` methods don't consistently return `undefined` for
  1021. // nonparticipating capturing groups
  1022. if (!compliantExecNpcg && match.length > 1) {
  1023. match[0].replace(separator2, function () {
  1024. for (var i = 1; i < arguments.length - 2; i++) {
  1025. if (arguments[i] === void 0) {
  1026. match[i] = void 0;
  1027. }
  1028. }
  1029. });
  1030. }
  1031. if (match.length > 1 && match.index < string.length) {
  1032. Array.prototype.push.apply(output, match.slice(1));
  1033. }
  1034. lastLength = match[0].length;
  1035. lastLastIndex = lastIndex;
  1036. if (output.length >= limit) {
  1037. break;
  1038. }
  1039. }
  1040. if (separator.lastIndex === match.index) {
  1041. separator.lastIndex++; // Avoid an infinite loop
  1042. }
  1043. }
  1044. if (lastLastIndex === string.length) {
  1045. if (lastLength || !separator.test("")) {
  1046. output.push("");
  1047. }
  1048. } else {
  1049. output.push(string.slice(lastLastIndex));
  1050. }
  1051. return output.length > limit ? output.slice(0, limit) : output;
  1052. };
  1053. }());
  1054. // [bugfix, chrome]
  1055. // If separator is undefined, then the result array contains just one String,
  1056. // which is the this value (converted to a String). If limit is not undefined,
  1057. // then the output array is truncated so that it contains no more than limit
  1058. // elements.
  1059. // "0".split(undefined, 0) -> []
  1060. } else if ("0".split(void 0, 0).length) {
  1061. String.prototype.split = function(separator, limit) {
  1062. if (separator === void 0 && limit === 0) return [];
  1063. return string_split.apply(this, arguments);
  1064. }
  1065. }
  1066. // ECMA-262, 3rd B.2.3
  1067. // Note an ECMAScript standart, although ECMAScript 3rd Edition has a
  1068. // non-normative section suggesting uniform semantics and it should be
  1069. // normalized across all browsers
  1070. // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
  1071. if("".substr && "0b".substr(-1) !== "b") {
  1072. var string_substr = String.prototype.substr;
  1073. /**
  1074. * Get the substring of a string
  1075. * @param {integer} start where to start the substring
  1076. * @param {integer} length how many characters to return
  1077. * @return {string}
  1078. */
  1079. String.prototype.substr = function(start, length) {
  1080. return string_substr.call(
  1081. this,
  1082. start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
  1083. length
  1084. );
  1085. }
  1086. }
  1087. // ES5 15.5.4.20
  1088. // http://es5.github.com/#x15.5.4.20
  1089. var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
  1090. "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
  1091. "\u2029\uFEFF";
  1092. if (!String.prototype.trim || ws.trim()) {
  1093. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  1094. // http://perfectionkills.com/whitespace-deviations/
  1095. ws = "[" + ws + "]";
  1096. var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
  1097. trimEndRegexp = new RegExp(ws + ws + "*$");
  1098. String.prototype.trim = function trim() {
  1099. if (this === void 0 || this === null) {
  1100. throw new TypeError("can't convert "+this+" to object");
  1101. }
  1102. return String(this)
  1103. .replace(trimBeginRegexp, "")
  1104. .replace(trimEndRegexp, "");
  1105. };
  1106. }
  1107. //
  1108. // Util
  1109. // ======
  1110. //
  1111. // ES5 9.4
  1112. // http://es5.github.com/#x9.4
  1113. // http://jsperf.com/to-integer
  1114. function toInteger(n) {
  1115. n = +n;
  1116. if (n !== n) { // isNaN
  1117. n = 0;
  1118. } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
  1119. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  1120. }
  1121. return n;
  1122. }
  1123. function isPrimitive(input) {
  1124. var type = typeof input;
  1125. return (
  1126. input === null ||
  1127. type === "undefined" ||
  1128. type === "boolean" ||
  1129. type === "number" ||
  1130. type === "string"
  1131. );
  1132. }
  1133. function toPrimitive(input) {
  1134. var val, valueOf, toString;
  1135. if (isPrimitive(input)) {
  1136. return input;
  1137. }
  1138. valueOf = input.valueOf;
  1139. if (typeof valueOf === "function") {
  1140. val = valueOf.call(input);
  1141. if (isPrimitive(val)) {
  1142. return val;
  1143. }
  1144. }
  1145. toString = input.toString;
  1146. if (typeof toString === "function") {
  1147. val = toString.call(input);
  1148. if (isPrimitive(val)) {
  1149. return val;
  1150. }
  1151. }
  1152. throw new TypeError();
  1153. }
  1154. // ES5 9.9
  1155. // http://es5.github.com/#x9.9
  1156. var toObject = function (o) {
  1157. if (o == null) { // this matches both null and undefined
  1158. throw new TypeError("can't convert "+o+" to object");
  1159. }
  1160. return Object(o);
  1161. };
  1162. });