agenda-libre-ruby/public/webshims/shims/es6.js
2014-08-01 01:38:33 +02:00

1884 lines
55 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ES6-shim 0.8.0 (c) 2013 Paul Miller (paulmillr.com)
// ES6-shim may be freely distributed under the MIT license.
// For more details and documentation:
// https://github.com/paulmillr/es6-shim/
webshim.register('es6', function($, webshim, window, document, undefined){
'use strict';
var isCallableWithoutNew = function(func) {
try { func(); }
catch (e) { return false; }
return true;
};
var supportsSubclassing = function(C, f) {
/* jshint proto:true */
try {
var Sub = function() { C.apply(this, arguments); };
if (!Sub.__proto__) { return false; /* skip test on IE < 11 */ }
Object.setPrototypeOf(Sub, C);
Sub.prototype = Object.create(C.prototype, {
constructor: { value: C }
});
return f(Sub);
} catch (e) {
return false;
}
};
var arePropertyDescriptorsSupported = function() {
try {
Object.defineProperty({}, 'x', {});
return true;
} catch (e) { /* this is IE 8. */
return false;
}
};
var startsWithRejectsRegex = function() {
var rejectsRegex = false;
if (String.prototype.startsWith) {
try {
'/a/'.startsWith(/a/);
} catch (e) { /* this is spec compliant */
rejectsRegex = true;
}
}
return rejectsRegex;
};
/*jshint evil: true */
var getGlobal = new Function('return this;');
/*jshint evil: false */
var main = function() {
var globals = getGlobal();
var global_isFinite = globals.isFinite;
var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
var startsWithIsCompliant = startsWithRejectsRegex();
var _slice = Array.prototype.slice;
var _indexOf = String.prototype.indexOf;
var _toString = Object.prototype.toString;
var _hasOwnProperty = Object.prototype.hasOwnProperty;
var ArrayIterator; // make our implementation private
// Define configurable, writable and non-enumerable props
// if they dont exist.
var defineProperties = function(object, map) {
Object.keys(map).forEach(function(name) {
var method = map[name];
if (name in object) return;
if (supportsDescriptors) {
Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
writable: true,
value: method
});
} else {
object[name] = method;
}
});
};
// Simple shim for Object.create on ES3 browsers
// (unlike real shim, no attempt to support `prototype === null`)
var create = Object.create || function(prototype, properties) {
function Type() {}
Type.prototype = prototype;
var object = new Type();
if (typeof properties !== "undefined") {
defineProperties(object, properties);
}
return object;
};
// This is a private name in the es6 spec, equal to '[Symbol.iterator]'
// we're going to use an arbitrary _-prefixed name to make our shims
// work properly with each other, even though we don't have full Iterator
// support. That is, `Array.from(map.keys())` will work, but we don't
// pretend to export a "real" Iterator interface.
var $iterator$ = (typeof Symbol === 'object' && Symbol.iterator) ||
'_es6shim_iterator_';
// Firefox ships a partial implementation using the name @@iterator.
// https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
// So use that name if we detect it.
if (globals.Set && typeof new globals.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var addIterator = function(prototype, impl) {
if (!impl) { impl = function iterator() { return this; }; }
var o = {};
o[$iterator$] = impl;
defineProperties(prototype, o);
};
// 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 isArguments = function isArguments(value) {
var str = _toString.call(value);
var result = str === '[object Arguments]';
if (!result) {
result = str !== '[object Array]' &&
value !== null &&
typeof value === 'object' &&
typeof value.length === 'number' &&
value.length >= 0 &&
_toString.call(value.callee) === '[object Function]';
}
return result;
};
var emulateES6construct = function(o) {
if (!ES.TypeIsObject(o)) throw new TypeError('bad object');
// es5 approximation to es6 subclass semantics: in es6, 'new Foo'
// would invoke Foo.@@create to allocation/initialize the new object.
// In es5 we just get the plain object. So if we detect an
// uninitialized object, invoke o.constructor.@@create
if (!o._es6construct) {
if (o.constructor && ES.IsCallable(o.constructor['@@create'])) {
o = o.constructor['@@create'](o);
}
defineProperties(o, { _es6construct: true });
}
return o;
};
var ES = {
CheckObjectCoercible: function(x, optMessage) {
/* jshint eqnull:true */
if (x == null)
throw new TypeError(optMessage || ('Cannot call method on ' + x));
return x;
},
TypeIsObject: function(x) {
/* jshint eqnull:true */
// this is expensive when it returns false; use this function
// when you expect it to return true in the common case.
return x != null && Object(x) === x;
},
ToObject: function(o, optMessage) {
return Object(ES.CheckObjectCoercible(o, optMessage));
},
IsCallable: function(x) {
return typeof x === 'function' &&
// some versions of IE say that typeof /abc/ === 'function'
_toString.call(x) === '[object Function]';
},
ToInt32: function(x) {
return x >> 0;
},
ToUint32: function(x) {
return x >>> 0;
},
ToInteger: function(value) {
var number = +value;
if (Number.isNaN(number)) return 0;
if (number === 0 || !Number.isFinite(number)) return number;
return Math.sign(number) * Math.floor(Math.abs(number));
},
ToLength: function(value) {
var len = ES.ToInteger(value);
if (len <= 0) return 0; // includes converting -0 to +0
if (len > Number.MAX_SAFE_INTEGER) return Number.MAX_SAFE_INTEGER;
return len;
},
SameValue: function(a, b) {
if (a === b) {
// 0 === -0, but they are not identical.
if (a === 0) return 1 / a === 1 / b;
return true;
}
return Number.isNaN(a) && Number.isNaN(b);
},
SameValueZero: function(a, b) {
// same as SameValue except for SameValueZero(+0, -0) == true
return (a === b) || (Number.isNaN(a) && Number.isNaN(b));
},
IsIterable: function(o) {
return ES.TypeIsObject(o) &&
(o[$iterator$] !== undefined || isArguments(o));
},
GetIterator: function(o) {
if (isArguments(o)) {
// special case support for `arguments`
return new ArrayIterator(o, "value");
}
var it = o[$iterator$]();
if (!ES.TypeIsObject(it)) {
throw new TypeError('bad iterator');
}
return it;
},
IteratorNext: function(it) {
var result = (arguments.length > 1) ? it.next(arguments[1]) : it.next();
if (!ES.TypeIsObject(result)) {
throw new TypeError('bad iterator');
}
return result;
},
Construct: function(C, args) {
// CreateFromConstructor
var obj;
if (ES.IsCallable(C['@@create'])) {
obj = C['@@create']();
} else {
// OrdinaryCreateFromConstructor
obj = create(C.prototype || null);
}
// Mark that we've used the es6 construct path
// (see emulateES6construct)
defineProperties(obj, { _es6construct: true });
// Call the constructor.
var result = C.apply(obj, args);
return ES.TypeIsObject(result) ? result : obj;
}
};
var numberConversion = (function () {
// from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js#L176-L266
// with permission and license, per https://twitter.com/inexorabletash/status/372206509540659200
function roundToEven(n) {
var w = Math.floor(n), f = n - w;
if (f < 0.5) {
return w;
}
if (f > 0.5) {
return w + 1;
}
return w % 2 ? w + 1 : w;
}
function packIEEE754(v, ebits, fbits) {
var bias = (1 << (ebits - 1)) - 1,
s, e, f, ln,
i, bits, str, bytes;
// Compute sign, exponent, fraction
if (v !== v) {
// NaN
// http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
e = (1 << ebits) - 1;
f = Math.pow(2, fbits - 1);
s = 0;
} else if (v === Infinity || v === -Infinity) {
e = (1 << ebits) - 1;
f = 0;
s = (v < 0) ? 1 : 0;
} else if (v === 0) {
e = 0;
f = 0;
s = (1 / v === -Infinity) ? 1 : 0;
} else {
s = v < 0;
v = Math.abs(v);
if (v >= Math.pow(2, 1 - bias)) {
e = Math.min(Math.floor(Math.log(v) / Math.LN2), 1023);
f = roundToEven(v / Math.pow(2, e) * Math.pow(2, fbits));
if (f / Math.pow(2, fbits) >= 2) {
e = e + 1;
f = 1;
}
if (e > bias) {
// Overflow
e = (1 << ebits) - 1;
f = 0;
} else {
// Normal
e = e + bias;
f = f - Math.pow(2, fbits);
}
} else {
// Subnormal
e = 0;
f = roundToEven(v / Math.pow(2, 1 - bias - fbits));
}
}
// Pack sign, exponent, fraction
bits = [];
for (i = fbits; i; i -= 1) {
bits.push(f % 2 ? 1 : 0);
f = Math.floor(f / 2);
}
for (i = ebits; i; i -= 1) {
bits.push(e % 2 ? 1 : 0);
e = Math.floor(e / 2);
}
bits.push(s ? 1 : 0);
bits.reverse();
str = bits.join('');
// Bits to bytes
bytes = [];
while (str.length) {
bytes.push(parseInt(str.substring(0, 8), 2));
str = str.substring(8);
}
return bytes;
}
function unpackIEEE754(bytes, ebits, fbits) {
// Bytes to bits
var bits = [], i, j, b, str,
bias, s, e, f;
for (i = bytes.length; i; i -= 1) {
b = bytes[i - 1];
for (j = 8; j; j -= 1) {
bits.push(b % 2 ? 1 : 0);
b = b >> 1;
}
}
bits.reverse();
str = bits.join('');
// Unpack sign, exponent, fraction
bias = (1 << (ebits - 1)) - 1;
s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
e = parseInt(str.substring(1, 1 + ebits), 2);
f = parseInt(str.substring(1 + ebits), 2);
// Produce number
if (e === (1 << ebits) - 1) {
return f !== 0 ? NaN : s * Infinity;
} else if (e > 0) {
// Normalized
return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));
} else if (f !== 0) {
// Denormalized
return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits));
} else {
return s < 0 ? -0 : 0;
}
}
function unpackFloat64(b) { return unpackIEEE754(b, 11, 52); }
function packFloat64(v) { return packIEEE754(v, 11, 52); }
function unpackFloat32(b) { return unpackIEEE754(b, 8, 23); }
function packFloat32(v) { return packIEEE754(v, 8, 23); }
var conversions = {
toFloat32: function (num) { return unpackFloat32(packFloat32(num)); }
};
if (typeof Float32Array !== 'undefined') {
var float32array = new Float32Array(1);
conversions.toFloat32 = function (num) {
float32array[0] = num;
return float32array[0];
};
}
return conversions;
}());
defineProperties(String, {
fromCodePoint: function() {
var points = _slice.call(arguments, 0, arguments.length);
var result = [];
var next;
for (var i = 0, length = points.length; i < length; i++) {
next = Number(points[i]);
if (!ES.SameValue(next, ES.ToInteger(next)) ||
next < 0 || next > 0x10FFFF) {
throw new RangeError('Invalid code point ' + next);
}
if (next < 0x10000) {
result.push(String.fromCharCode(next));
} else {
next -= 0x10000;
result.push(String.fromCharCode((next >> 10) + 0xD800));
result.push(String.fromCharCode((next % 0x400) + 0xDC00));
}
}
return result.join('');
},
raw: function(callSite) { // raw.length===1
var substitutions = _slice.call(arguments, 1, arguments.length);
var cooked = ES.ToObject(callSite, 'bad callSite');
var rawValue = cooked.raw;
var raw = ES.ToObject(rawValue, 'bad raw value');
var len = Object.keys(raw).length;
var literalsegments = ES.ToLength(len);
if (literalsegments === 0) {
return '';
}
var stringElements = [];
var nextIndex = 0;
var nextKey, next, nextSeg, nextSub;
while (nextIndex < literalsegments) {
nextKey = String(nextIndex);
next = raw[nextKey];
nextSeg = String(next);
stringElements.push(nextSeg);
if (nextIndex + 1 >= literalsegments) {
break;
}
next = substitutions[nextKey];
if (next === undefined) {
break;
}
nextSub = String(next);
stringElements.push(nextSub);
nextIndex++;
}
return stringElements.join('');
}
});
var StringShims = {
// Fast repeat, uses the `Exponentiation by squaring` algorithm.
// Perf: http://jsperf.com/string-repeat2/2
repeat: (function() {
var repeat = function(s, times) {
if (times < 1) return '';
if (times % 2) return repeat(s, times - 1) + s;
var half = repeat(s, times / 2);
return half + half;
};
return function(times) {
var thisStr = String(ES.CheckObjectCoercible(this));
times = ES.ToInteger(times);
if (times < 0 || times === Infinity) {
throw new RangeError('Invalid String#repeat value');
}
return repeat(thisStr, times);
};
})(),
startsWith: function(searchStr) {
var thisStr = String(ES.CheckObjectCoercible(this));
if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "startsWith" with a regex');
searchStr = String(searchStr);
var startArg = arguments.length > 1 ? arguments[1] : undefined;
var start = Math.max(ES.ToInteger(startArg), 0);
return thisStr.slice(start, start + searchStr.length) === searchStr;
},
endsWith: function(searchStr) {
var thisStr = String(ES.CheckObjectCoercible(this));
if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "endsWith" with a regex');
searchStr = String(searchStr);
var thisLen = thisStr.length;
var posArg = arguments.length > 1 ? arguments[1] : undefined;
var pos = posArg === undefined ? thisLen : ES.ToInteger(posArg);
var end = Math.min(Math.max(pos, 0), thisLen);
return thisStr.slice(end - searchStr.length, end) === searchStr;
},
contains: function(searchString) {
var position = arguments.length > 1 ? arguments[1] : undefined;
// Somehow this trick makes method 100% compat with the spec.
return _indexOf.call(this, searchString, position) !== -1;
},
codePointAt: function(pos) {
var thisStr = String(ES.CheckObjectCoercible(this));
var position = ES.ToInteger(pos);
var length = thisStr.length;
if (position < 0 || position >= length) return undefined;
var first = thisStr.charCodeAt(position);
var isEnd = (position + 1 === length);
if (first < 0xD800 || first > 0xDBFF || isEnd) return first;
var second = thisStr.charCodeAt(position + 1);
if (second < 0xDC00 || second > 0xDFFF) return first;
return ((first - 0xD800) * 1024) + (second - 0xDC00) + 0x10000;
}
};
defineProperties(String.prototype, StringShims);
var hasStringTrimBug = '\u0085'.trim().length !== 1;
if (hasStringTrimBug) {
var originalStringTrim = String.prototype.trim;
delete String.prototype.trim;
// whitespace from: http://es5.github.io/#x15.5.4.20
// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
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'
].join('');
var trimBeginRegexp = new RegExp('^[' + ws + '][' + ws + ']*');
var trimEndRegexp = new RegExp('[' + ws + '][' + ws + ']*$');
defineProperties(String.prototype, {
trim: function() {
if (this === undefined || this === null) {
throw new TypeError("can't convert " + this + " to object");
}
return String(this)
.replace(trimBeginRegexp, "")
.replace(trimEndRegexp, "");
}
});
}
// see https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator
var StringIterator = function(s) {
this._s = String(ES.CheckObjectCoercible(s));
this._i = 0;
};
StringIterator.prototype.next = function() {
var s = this._s, i = this._i;
if (s === undefined || i >= s.length) {
this._s = undefined;
return { value: undefined, done: true };
}
var first = s.charCodeAt(i), second, len;
if (first < 0xD800 || first > 0xDBFF || (i+1) == s.length) {
len = 1;
} else {
second = s.charCodeAt(i+1);
len = (second < 0xDC00 || second > 0xDFFF) ? 1 : 2;
}
this._i = i + len;
return { value: s.substr(i, len), done: false };
};
addIterator(StringIterator.prototype);
addIterator(String.prototype, function() {
return new StringIterator(this);
});
if (!startsWithIsCompliant) {
// Firefox has a noncompliant startsWith implementation
String.prototype.startsWith = StringShims.startsWith;
String.prototype.endsWith = StringShims.endsWith;
}
defineProperties(Array, {
from: function(iterable) {
var mapFn = arguments.length > 1 ? arguments[1] : undefined;
var thisArg = arguments.length > 2 ? arguments[2] : undefined;
var list = ES.ToObject(iterable, 'bad iterable');
if (mapFn !== undefined && !ES.IsCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
var usingIterator = ES.IsIterable(list);
// does the spec really mean that Arrays should use ArrayIterator?
// https://bugs.ecmascript.org/show_bug.cgi?id=2416
//if (Array.isArray(list)) { usingIterator=false; }
var length = usingIterator ? 0 : ES.ToLength(list.length);
var result = ES.IsCallable(this) ? Object(usingIterator ? new this() : new this(length)) : new Array(length);
var it = usingIterator ? ES.GetIterator(list) : null;
var value;
for (var i = 0; usingIterator || (i < length); i++) {
if (usingIterator) {
value = ES.IteratorNext(it);
if (value.done) {
length = i;
break;
}
value = value.value;
} else {
value = list[i];
}
if (mapFn) {
result[i] = thisArg ? mapFn.call(thisArg, value, i) : mapFn(value, i);
} else {
result[i] = value;
}
}
result.length = length;
return result;
},
of: function() {
return Array.from(arguments);
}
});
// Our ArrayIterator is private; see
// https://github.com/paulmillr/es6-shim/issues/252
ArrayIterator = function(array, kind) {
this.i = 0;
this.array = array;
this.kind = kind;
};
defineProperties(ArrayIterator.prototype, {
next: function() {
var i = this.i, array = this.array;
if (i === undefined || this.kind === undefined) {
throw new TypeError('Not an ArrayIterator');
}
if (array!==undefined) {
var len = ES.ToLength(array.length);
for (; i < len; i++) {
var kind = this.kind;
var retval;
if (kind === "key") {
retval = i;
} else if (kind === "value") {
retval = array[i];
} else if (kind === "entry") {
retval = [i, array[i]];
}
this.i = i + 1;
return { value: retval, done: false };
}
}
this.array = undefined;
return { value: undefined, done: true };
}
});
addIterator(ArrayIterator.prototype);
defineProperties(Array.prototype, {
copyWithin: function(target, start) {
var end = arguments[2]; // copyWithin.length must be 2
var o = ES.ToObject(this);
var len = ES.ToLength(o.length);
target = ES.ToInteger(target);
start = ES.ToInteger(start);
var to = target < 0 ? Math.max(len + target, 0) : Math.min(target, len);
var from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
end = (end===undefined) ? len : ES.ToInteger(end);
var fin = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
var count = Math.min(fin - from, len - to);
var direction = 1;
if (from < to && to < (from + count)) {
direction = -1;
from += count - 1;
to += count - 1;
}
while (count > 0) {
if (_hasOwnProperty.call(o, from)) {
o[to] = o[from];
} else {
delete o[from];
}
from += direction;
to += direction;
count -= 1;
}
return o;
},
fill: function(value) {
var start = arguments[1], end = arguments[2]; // fill.length===1
var O = ES.ToObject(this);
var len = ES.ToLength(O.length);
start = ES.ToInteger(start===undefined ? 0 : start);
end = ES.ToInteger(end===undefined ? len : end);
var relativeStart = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
for (var i = relativeStart; i < len && i < end; ++i) {
O[i] = value;
}
return O;
},
find: function(predicate) {
var list = ES.ToObject(this);
var length = ES.ToLength(list.length);
if (!ES.IsCallable(predicate)) {
throw new TypeError('Array#find: predicate must be a function');
}
var thisArg = arguments[1];
for (var i = 0, value; i < length; i++) {
if (i in list) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) return value;
}
}
return undefined;
},
findIndex: function(predicate) {
var list = ES.ToObject(this);
var length = ES.ToLength(list.length);
if (!ES.IsCallable(predicate)) {
throw new TypeError('Array#findIndex: predicate must be a function');
}
var thisArg = arguments[1];
for (var i = 0; i < length; i++) {
if (i in list) {
if (predicate.call(thisArg, list[i], i, list)) return i;
}
}
return -1;
},
keys: function() {
return new ArrayIterator(this, "key");
},
values: function() {
return new ArrayIterator(this, "value");
},
entries: function() {
return new ArrayIterator(this, "entry");
}
});
addIterator(Array.prototype, function() { return this.values(); });
// Chrome defines keys/values/entries on Array, but doesn't give us
// any way to identify its iterator. So add our own shimmed field.
if (Object.getPrototypeOf) {
addIterator(Object.getPrototypeOf([].values()));
}
var maxSafeInteger = Math.pow(2, 53) - 1;
defineProperties(Number, {
MAX_SAFE_INTEGER: maxSafeInteger,
MIN_SAFE_INTEGER: -maxSafeInteger,
EPSILON: 2.220446049250313e-16,
parseInt: globals.parseInt,
parseFloat: globals.parseFloat,
isFinite: function(value) {
return typeof value === 'number' && global_isFinite(value);
},
isInteger: function(value) {
return typeof value === 'number' &&
!Number.isNaN(value) &&
Number.isFinite(value) &&
ES.ToInteger(value) === value;
},
isSafeInteger: function(value) {
return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
},
isNaN: function(value) {
// NaN !== NaN, but they are identical.
// NaNs are the only non-reflexive value, i.e., if x !== x,
// then x is NaN.
// isNaN is broken: it converts its argument to number, so
// isNaN('foo') => true
return value !== value;
}
});
if (supportsDescriptors) {
defineProperties(Object, {
getPropertyDescriptor: function(subject, name) {
var pd = Object.getOwnPropertyDescriptor(subject, name);
var proto = Object.getPrototypeOf(subject);
while (pd === undefined && proto !== null) {
pd = Object.getOwnPropertyDescriptor(proto, name);
proto = Object.getPrototypeOf(proto);
}
return pd;
},
getPropertyNames: function(subject) {
var result = Object.getOwnPropertyNames(subject);
var proto = Object.getPrototypeOf(subject);
var addProperty = function(property) {
if (result.indexOf(property) === -1) {
result.push(property);
}
};
while (proto !== null) {
Object.getOwnPropertyNames(proto).forEach(addProperty);
proto = Object.getPrototypeOf(proto);
}
return result;
}
});
defineProperties(Object, {
// 19.1.3.1
assign: function(target, source) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}
return Array.prototype.reduce.call(arguments, function(target, source) {
if (!ES.TypeIsObject(source)) {
throw new TypeError('source must be an object');
}
return Object.keys(source).reduce(function(target, key) {
target[key] = source[key];
return target;
}, target);
});
},
getOwnPropertyKeys: function(subject) {
return Object.keys(subject);
},
is: function(a, b) {
return ES.SameValue(a, b);
},
// 19.1.3.9
// shim from https://gist.github.com/WebReflection/5593554
setPrototypeOf: (function(Object, magic) {
var set;
var checkArgs = function(O, proto) {
if (!ES.TypeIsObject(O)) {
throw new TypeError('cannot set prototype on a non-object');
}
if (!(proto===null || ES.TypeIsObject(proto))) {
throw new TypeError('can only set prototype to an object or null'+proto);
}
};
var setPrototypeOf = function(O, proto) {
checkArgs(O, proto);
set.call(O, proto);
return O;
};
try {
// this works already in Firefox and Safari
set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set;
set.call({}, null);
} catch (e) {
if (Object.prototype !== {}[magic]) {
// IE < 11 cannot be shimmed
return;
}
// probably Chrome or some old Mobile stock browser
set = function(proto) {
this[magic] = proto;
};
// please note that this will **not** work
// in those browsers that do not inherit
// __proto__ by mistake from Object.prototype
// in these cases we should probably throw an error
// or at least be informed about the issue
setPrototypeOf.polyfill = setPrototypeOf(
setPrototypeOf({}, null),
Object.prototype
) instanceof Object;
// setPrototypeOf.polyfill === true means it works as meant
// setPrototypeOf.polyfill === false means it's not 100% reliable
// setPrototypeOf.polyfill === undefined
// or
// setPrototypeOf.polyfill == null means it's not a polyfill
// which means it works as expected
// we can even delete Object.prototype.__proto__;
}
return setPrototypeOf;
})(Object, '__proto__')
});
}
// Workaround bug in Opera 12 where setPrototypeOf(x, null) doesn't work,
// but Object.create(null) does.
if (Object.setPrototypeOf && Object.getPrototypeOf &&
Object.getPrototypeOf(Object.setPrototypeOf({}, null)) !== null &&
Object.getPrototypeOf(Object.create(null)) === null) {
(function() {
var FAKENULL = Object.create(null);
var gpo = Object.getPrototypeOf, spo = Object.setPrototypeOf;
Object.getPrototypeOf = function(o) {
var result = gpo(o);
return result === FAKENULL ? null : result;
};
Object.setPrototypeOf = function(o, p) {
if (p === null) { p = FAKENULL; }
return spo(o, p);
};
Object.setPrototypeOf.polyfill = false;
})();
}
try {
Object.keys('foo');
} catch (e) {
var originalObjectKeys = Object.keys;
Object.keys = function (obj) {
return originalObjectKeys(ES.ToObject(obj));
};
}
var MathShims = {
acosh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value < 1) return NaN;
if (value === 1) return 0;
if (value === Infinity) return value;
return Math.log(value + Math.sqrt(value * value - 1));
},
asinh: function(value) {
value = Number(value);
if (value === 0 || !global_isFinite(value)) {
return value;
}
return value < 0 ? -Math.asinh(-value) : Math.log(value + Math.sqrt(value * value + 1));
},
atanh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value < -1 || value > 1) {
return NaN;
}
if (value === -1) return -Infinity;
if (value === 1) return Infinity;
if (value === 0) return value;
return 0.5 * Math.log((1 + value) / (1 - value));
},
cbrt: function(value) {
value = Number(value);
if (value === 0) return value;
var negate = value < 0, result;
if (negate) value = -value;
result = Math.pow(value, 1/3);
return negate ? -result : result;
},
clz32: function(value) {
// See https://bugs.ecmascript.org/show_bug.cgi?id=2465
value = Number(value);
if (Number.isNaN(value)) return NaN;
var number = ES.ToUint32(value);
if (number === 0) {
return 32;
}
return 32 - (number).toString(2).length;
},
cosh: function(value) {
value = Number(value);
if (value === 0) return 1; // +0 or -0
if (Number.isNaN(value)) return NaN;
if (!global_isFinite(value)) return Infinity;
if (value < 0) value = -value;
if (value > 21) return Math.exp(value) / 2;
return (Math.exp(value) + Math.exp(-value)) / 2;
},
expm1: function(value) {
value = Number(value);
if (value === -Infinity) return -1;
if (!global_isFinite(value) || value === 0) return value;
return Math.exp(value) - 1;
},
hypot: function(x, y) {
var anyNaN = false;
var allZero = true;
var anyInfinity = false;
var numbers = [];
Array.prototype.every.call(arguments, function(arg) {
var num = Number(arg);
if (Number.isNaN(num)) anyNaN = true;
else if (num === Infinity || num === -Infinity) anyInfinity = true;
else if (num !== 0) allZero = false;
if (anyInfinity) {
return false;
} else if (!anyNaN) {
numbers.push(Math.abs(num));
}
return true;
});
if (anyInfinity) return Infinity;
if (anyNaN) return NaN;
if (allZero) return 0;
numbers.sort(function (a, b) { return b - a; });
var largest = numbers[0];
var divided = numbers.map(function (number) { return number / largest; });
var sum = divided.reduce(function (sum, number) { return sum += number * number; }, 0);
return largest * Math.sqrt(sum);
},
log2: function(value) {
return Math.log(value) * Math.LOG2E;
},
log10: function(value) {
return Math.log(value) * Math.LOG10E;
},
log1p: function(value) {
value = Number(value);
if (value < -1 || Number.isNaN(value)) return NaN;
if (value === 0 || value === Infinity) return value;
if (value === -1) return -Infinity;
var result = 0;
var n = 50;
if (value < 0 || value > 1) return Math.log(1 + value);
for (var i = 1; i < n; i++) {
if ((i % 2) === 0) {
result -= Math.pow(value, i) / i;
} else {
result += Math.pow(value, i) / i;
}
}
return result;
},
sign: function(value) {
var number = +value;
if (number === 0) return number;
if (Number.isNaN(number)) return number;
return number < 0 ? -1 : 1;
},
sinh: function(value) {
value = Number(value);
if (!global_isFinite(value) || value === 0) return value;
return (Math.exp(value) - Math.exp(-value)) / 2;
},
tanh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value === 0) return value;
if (value === Infinity) return 1;
if (value === -Infinity) return -1;
return (Math.exp(value) - Math.exp(-value)) / (Math.exp(value) + Math.exp(-value));
},
trunc: function(value) {
var number = Number(value);
return number < 0 ? -Math.floor(-number) : Math.floor(number);
},
imul: function(x, y) {
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
var ah = (x >>> 16) & 0xffff;
var al = x & 0xffff;
var bh = (y >>> 16) & 0xffff;
var bl = y & 0xffff;
// the shift by 0 fixes the sign on the high part
// the final |0 converts the unsigned value into a signed value
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
},
fround: function(x) {
if (x === 0 || x === Infinity || x === -Infinity || Number.isNaN(x)) {
return x;
}
var num = Number(x);
return numberConversion.toFloat32(num);
}
};
defineProperties(Math, MathShims);
if (Math.imul(0xffffffff, 5) !== -5) {
// Safari 6.1, at least, reports "0" for this value
Math.imul = MathShims.imul;
}
// Promises
// Simplest possible implementation; use a 3rd-party library if you
// want the best possible speed and/or long stack traces.
var PromiseShim = (function() {
var Promise, Promise$prototype;
ES.IsPromise = function(promise) {
if (!ES.TypeIsObject(promise)) {
return false;
}
if (!promise._promiseConstructor) {
// _promiseConstructor is a bit more unique than _status, so we'll
// check that instead of the [[PromiseStatus]] internal field.
return false;
}
if (promise._status === undefined) {
return false; // uninitialized
}
return true;
};
// "PromiseCapability" in the spec is what most promise implementations
// call a "deferred".
var PromiseCapability = function(C) {
if (!ES.IsCallable(C)) {
throw new TypeError('bad promise constructor');
}
var capability = this;
var resolver = function(resolve, reject) {
capability.resolve = resolve;
capability.reject = reject;
};
capability.promise = ES.Construct(C, [resolver]);
// see https://bugs.ecmascript.org/show_bug.cgi?id=2478
if (!capability.promise._es6construct) {
throw new TypeError('bad promise constructor');
}
if (!(ES.IsCallable(capability.resolve) &&
ES.IsCallable(capability.reject))) {
throw new TypeError('bad promise constructor');
}
};
// find an appropriate setImmediate-alike
var setTimeout = globals.setTimeout;
var makeZeroTimeout;
if (typeof window !== 'undefined' && ES.IsCallable(window.postMessage)) {
makeZeroTimeout = function() {
// from http://dbaron.org/log/20100309-faster-timeouts
var timeouts = [];
var messageName = "zero-timeout-message";
var setZeroTimeout = function(fn) {
timeouts.push(fn);
window.postMessage(messageName, "*");
};
var handleMessage = function(event) {
if (event.source == window && event.data == messageName) {
event.stopPropagation();
if (timeouts.length === 0) { return; }
var fn = timeouts.shift();
fn();
}
};
window.addEventListener("message", handleMessage, true);
return setZeroTimeout;
};
}
var makePromiseAsap = function() {
// An efficient task-scheduler based on a pre-existing Promise
// implementation, which we can use even if we override the
// global Promise below (in order to workaround bugs)
// https://github.com/Raynos/observ-hash/issues/2#issuecomment-35857671
var P = globals.Promise;
return P && P.resolve && function(task) {
return P.resolve().then(task);
};
};
var enqueue = ES.IsCallable(globals.setImmediate) ?
globals.setImmediate.bind(globals) :
typeof process === 'object' && process.nextTick ? process.nextTick :
makePromiseAsap() ||
(ES.IsCallable(makeZeroTimeout) ? makeZeroTimeout() :
function(task) { setTimeout(task, 0); }); // fallback
var triggerPromiseReactions = function(reactions, x) {
reactions.forEach(function(reaction) {
enqueue(function() {
// PromiseReactionTask
var handler = reaction.handler;
var capability = reaction.capability;
var resolve = capability.resolve;
var reject = capability.reject;
try {
var result = handler(x);
if (result === capability.promise) {
throw new TypeError('self resolution');
}
var updateResult =
updatePromiseFromPotentialThenable(result, capability);
if (!updateResult) {
resolve(result);
}
} catch (e) {
reject(e);
}
});
});
};
var updatePromiseFromPotentialThenable = function(x, capability) {
if (!ES.TypeIsObject(x)) {
return false;
}
var resolve = capability.resolve;
var reject = capability.reject;
try {
var then = x.then; // only one invocation of accessor
if (!ES.IsCallable(then)) { return false; }
then.call(x, resolve, reject);
} catch(e) {
reject(e);
}
return true;
};
var promiseResolutionHandler = function(promise, onFulfilled, onRejected){
return function(x) {
if (x === promise) {
return onRejected(new TypeError('self resolution'));
}
var C = promise._promiseConstructor;
var capability = new PromiseCapability(C);
var updateResult = updatePromiseFromPotentialThenable(x, capability);
if (updateResult) {
return capability.promise.then(onFulfilled, onRejected);
} else {
return onFulfilled(x);
}
};
};
Promise = function(resolver) {
var promise = this;
promise = emulateES6construct(promise);
if (!promise._promiseConstructor) {
// we use _promiseConstructor as a stand-in for the internal
// [[PromiseStatus]] field; it's a little more unique.
throw new TypeError('bad promise');
}
if (promise._status !== undefined) {
throw new TypeError('promise already initialized');
}
// see https://bugs.ecmascript.org/show_bug.cgi?id=2482
if (!ES.IsCallable(resolver)) {
throw new TypeError('not a valid resolver');
}
promise._status = 'unresolved';
promise._resolveReactions = [];
promise._rejectReactions = [];
var resolve = function(resolution) {
if (promise._status !== 'unresolved') { return; }
var reactions = promise._resolveReactions;
promise._result = resolution;
promise._resolveReactions = undefined;
promise._rejectReactions = undefined;
promise._status = 'has-resolution';
triggerPromiseReactions(reactions, resolution);
};
var reject = function(reason) {
if (promise._status !== 'unresolved') { return; }
var reactions = promise._rejectReactions;
promise._result = reason;
promise._resolveReactions = undefined;
promise._rejectReactions = undefined;
promise._status = 'has-rejection';
triggerPromiseReactions(reactions, reason);
};
try {
resolver(resolve, reject);
} catch (e) {
reject(e);
}
return promise;
};
Promise$prototype = Promise.prototype;
defineProperties(Promise, {
'@@create': function(obj) {
var constructor = this;
// AllocatePromise
// The `obj` parameter is a hack we use for es5
// compatibility.
var prototype = constructor.prototype || Promise$prototype;
obj = obj || create(prototype);
defineProperties(obj, {
_status: undefined,
_result: undefined,
_resolveReactions: undefined,
_rejectReactions: undefined,
_promiseConstructor: undefined
});
obj._promiseConstructor = constructor;
return obj;
}
});
var _promiseAllResolver = function(index, values, capability, remaining) {
var done = false;
return function(x) {
if (done) { return; } // protect against being called multiple times
done = true;
values[index] = x;
if ((--remaining.count) === 0) {
var resolve = capability.resolve;
resolve(values); // call w/ this===undefined
}
};
};
Promise.all = function(iterable) {
var C = this;
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
try {
if (!ES.IsIterable(iterable)) {
throw new TypeError('bad iterable');
}
var it = ES.GetIterator(iterable);
var values = [], remaining = { count: 1 };
for (var index = 0; ; index++) {
var next = ES.IteratorNext(it);
if (next.done) {
break;
}
var nextPromise = C.resolve(next.value);
var resolveElement = _promiseAllResolver(
index, values, capability, remaining
);
remaining.count++;
nextPromise.then(resolveElement, capability.reject);
}
if ((--remaining.count) === 0) {
resolve(values); // call w/ this===undefined
}
} catch (e) {
reject(e);
}
return capability.promise;
};
Promise.race = function(iterable) {
var C = this;
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
try {
if (!ES.IsIterable(iterable)) {
throw new TypeError('bad iterable');
}
var it = ES.GetIterator(iterable);
while (true) {
var next = ES.IteratorNext(it);
if (next.done) {
// If iterable has no items, resulting promise will never
// resolve; see:
// https://github.com/domenic/promises-unwrapping/issues/75
// https://bugs.ecmascript.org/show_bug.cgi?id=2515
break;
}
var nextPromise = C.resolve(next.value);
nextPromise.then(resolve, reject);
}
} catch (e) {
reject(e);
}
return capability.promise;
};
Promise.reject = function(reason) {
var C = this;
var capability = new PromiseCapability(C);
var reject = capability.reject;
reject(reason); // call with this===undefined
return capability.promise;
};
Promise.resolve = function(v) {
var C = this;
if (ES.IsPromise(v)) {
var constructor = v._promiseConstructor;
if (constructor === C) { return v; }
}
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
resolve(v); // call with this===undefined
return capability.promise;
};
Promise.prototype['catch'] = function( onRejected ) {
return this.then(undefined, onRejected);
};
Promise.prototype.then = function( onFulfilled, onRejected ) {
var promise = this;
if (!ES.IsPromise(promise)) { throw new TypeError('not a promise'); }
// this.constructor not this._promiseConstructor; see
// https://bugs.ecmascript.org/show_bug.cgi?id=2513
var C = this.constructor;
var capability = new PromiseCapability(C);
if (!ES.IsCallable(onRejected)) {
onRejected = function(e) { throw e; };
}
if (!ES.IsCallable(onFulfilled)) {
onFulfilled = function(x) { return x; };
}
var resolutionHandler =
promiseResolutionHandler(promise, onFulfilled, onRejected);
var resolveReaction =
{ capability: capability, handler: resolutionHandler };
var rejectReaction =
{ capability: capability, handler: onRejected };
switch (promise._status) {
case 'unresolved':
promise._resolveReactions.push(resolveReaction);
promise._rejectReactions.push(rejectReaction);
break;
case 'has-resolution':
triggerPromiseReactions([resolveReaction], promise._result);
break;
case 'has-rejection':
triggerPromiseReactions([rejectReaction], promise._result);
break;
default:
throw new TypeError('unexpected');
}
return capability.promise;
};
return Promise;
})();
// export the Promise constructor.
defineProperties(globals, { Promise: PromiseShim });
// In Chrome 33 (and thereabouts) Promise is defined, but the
// implementation is buggy in a number of ways. Let's check subclassing
// support to see if we have a buggy implementation.
var promiseSupportsSubclassing = supportsSubclassing(globals.Promise, function(S) {
return S.resolve(42) instanceof S;
});
var promiseIgnoresNonFunctionThenCallbacks = (function () {
try {
globals.Promise.reject(42).then(null, 5).then(null, function () {});
return true;
} catch (ex) {
return false;
}
}());
if (!promiseSupportsSubclassing || !promiseIgnoresNonFunctionThenCallbacks) {
globals.Promise = PromiseShim;
}
// Map and Set require a true ES5 environment
if (supportsDescriptors) {
var fastkey = function fastkey(key) {
var type = typeof key;
if (type === 'string') {
return '$' + key;
} else if (type === 'number') {
// note that -0 will get coerced to "0" when used as a property key
return key;
}
return null;
};
var emptyObject = function emptyObject() {
// accomodate some older not-quite-ES5 browsers
return Object.create ? Object.create(null) : {};
};
var collectionShims = {
Map: (function() {
var empty = {};
function MapEntry(key, value) {
this.key = key;
this.value = value;
this.next = null;
this.prev = null;
}
MapEntry.prototype.isRemoved = function() {
return this.key === empty;
};
function MapIterator(map, kind) {
this.head = map._head;
this.i = this.head;
this.kind = kind;
}
MapIterator.prototype = {
next: function() {
var i = this.i, kind = this.kind, head = this.head, result;
if (this.i === undefined) {
return { value: undefined, done: true };
}
while (i.isRemoved() && i !== head) {
// back up off of removed entries
i = i.prev;
}
// advance to next unreturned element.
while (i.next !== head) {
i = i.next;
if (!i.isRemoved()) {
if (kind === "key") {
result = i.key;
} else if (kind === "value") {
result = i.value;
} else {
result = [i.key, i.value];
}
this.i = i;
return { value: result, done: false };
}
}
// once the iterator is done, it is done forever.
this.i = undefined;
return { value: undefined, done: true };
}
};
addIterator(MapIterator.prototype);
function Map() {
var map = this;
map = emulateES6construct(map);
if (!map._es6map) {
throw new TypeError('bad map');
}
var head = new MapEntry(null, null);
// circular doubly-linked list.
head.next = head.prev = head;
defineProperties(map, {
'_head': head,
'_storage': emptyObject(),
'_size': 0
});
// Optionally initialize map from iterable
var iterable = arguments[0];
if (iterable !== undefined && iterable !== null) {
var it = ES.GetIterator(iterable);
var adder = map.set;
if (!ES.IsCallable(adder)) { throw new TypeError('bad map'); }
while (true) {
var next = ES.IteratorNext(it);
if (next.done) { break; }
var nextItem = next.value;
if (!ES.TypeIsObject(nextItem)) {
throw new TypeError('expected iterable of pairs');
}
adder.call(map, nextItem[0], nextItem[1]);
}
}
return map;
}
var Map$prototype = Map.prototype;
defineProperties(Map, {
'@@create': function(obj) {
var constructor = this;
var prototype = constructor.prototype || Map$prototype;
obj = obj || create(prototype);
defineProperties(obj, { _es6map: true });
return obj;
}
});
Object.defineProperty(Map.prototype, 'size', {
configurable: true,
enumerable: false,
get: function() {
if (typeof this._size === 'undefined') {
throw new TypeError('size method called on incompatible Map');
}
return this._size;
}
});
defineProperties(Map.prototype, {
get: function(key) {
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
var entry = this._storage[fkey];
return entry ? entry.value : undefined;
}
var head = this._head, i = head;
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
return i.value;
}
}
return undefined;
},
has: function(key) {
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
return typeof this._storage[fkey] !== 'undefined';
}
var head = this._head, i = head;
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
return true;
}
}
return false;
},
set: function(key, value) {
var head = this._head, i = head, entry;
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
if (typeof this._storage[fkey] !== 'undefined') {
this._storage[fkey].value = value;
return;
} else {
entry = this._storage[fkey] = new MapEntry(key, value);
i = head.prev;
// fall through
}
}
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
i.value = value;
return;
}
}
entry = entry || new MapEntry(key, value);
if (ES.SameValue(-0, key)) {
entry.key = +0; // coerce -0 to +0 in entry
}
entry.next = this._head;
entry.prev = this._head.prev;
entry.prev.next = entry;
entry.next.prev = entry;
this._size += 1;
},
'delete': function(key) {
var head = this._head, i = head;
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
if (typeof this._storage[fkey] === 'undefined') {
return false;
}
i = this._storage[fkey].prev;
delete this._storage[fkey];
// fall through
}
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
i.key = i.value = empty;
i.prev.next = i.next;
i.next.prev = i.prev;
this._size -= 1;
return true;
}
}
return false;
},
clear: function() {
this._size = 0;
this._storage = emptyObject();
var head = this._head, i = head, p = i.next;
while ((i = p) !== head) {
i.key = i.value = empty;
p = i.next;
i.next = i.prev = head;
}
head.next = head.prev = head;
},
keys: function() {
return new MapIterator(this, "key");
},
values: function() {
return new MapIterator(this, "value");
},
entries: function() {
return new MapIterator(this, "key+value");
},
forEach: function(callback) {
var context = arguments.length > 1 ? arguments[1] : null;
var it = this.entries();
for (var entry = it.next(); !entry.done; entry = it.next()) {
callback.call(context, entry.value[1], entry.value[0], this);
}
}
});
addIterator(Map.prototype, function() { return this.entries(); });
return Map;
})(),
Set: (function() {
// Creating a Map is expensive. To speed up the common case of
// Sets containing only string or numeric keys, we use an object
// as backing storage and lazily create a full Map only when
// required.
var SetShim = function Set() {
var set = this;
set = emulateES6construct(set);
if (!set._es6set) {
throw new TypeError('bad set');
}
defineProperties(set, {
'[[SetData]]': null,
'_storage': emptyObject()
});
// Optionally initialize map from iterable
var iterable = arguments[0];
if (iterable !== undefined && iterable !== null) {
var it = ES.GetIterator(iterable);
var adder = set.add;
if (!ES.IsCallable(adder)) { throw new TypeError('bad set'); }
while (true) {
var next = ES.IteratorNext(it);
if (next.done) { break; }
var nextItem = next.value;
adder.call(set, nextItem);
}
}
return set;
};
var Set$prototype = SetShim.prototype;
defineProperties(SetShim, {
'@@create': function(obj) {
var constructor = this;
var prototype = constructor.prototype || Set$prototype;
obj = obj || create(prototype);
defineProperties(obj, { _es6set: true });
return obj;
}
});
// Switch from the object backing storage to a full Map.
var ensureMap = function ensureMap(set) {
if (!set['[[SetData]]']) {
var m = set['[[SetData]]'] = new collectionShims.Map();
Object.keys(set._storage).forEach(function(k) {
// fast check for leading '$'
if (k.charCodeAt(0) === 36) {
k = k.substring(1);
} else {
k = +k;
}
m.set(k, k);
});
set._storage = null; // free old backing storage
}
};
Object.defineProperty(SetShim.prototype, 'size', {
configurable: true,
enumerable: false,
get: function() {
if (typeof this._storage === 'undefined') {
// https://github.com/paulmillr/es6-shim/issues/176
throw new TypeError('size method called on incompatible Set');
}
ensureMap(this);
return this['[[SetData]]'].size;
}
});
defineProperties(SetShim.prototype, {
has: function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
return !!this._storage[fkey];
}
ensureMap(this);
return this['[[SetData]]'].has(key);
},
add: function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
this._storage[fkey]=true;
return;
}
ensureMap(this);
return this['[[SetData]]'].set(key, key);
},
'delete': function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
delete this._storage[fkey];
return;
}
ensureMap(this);
return this['[[SetData]]']['delete'](key);
},
clear: function() {
if (this._storage) {
this._storage = emptyObject();
return;
}
return this['[[SetData]]'].clear();
},
keys: function() {
ensureMap(this);
return this['[[SetData]]'].keys();
},
values: function() {
ensureMap(this);
return this['[[SetData]]'].values();
},
entries: function() {
ensureMap(this);
return this['[[SetData]]'].entries();
},
forEach: function(callback) {
var context = arguments.length > 1 ? arguments[1] : null;
var entireSet = this;
ensureMap(this);
this['[[SetData]]'].forEach(function(value, key) {
callback.call(context, key, key, entireSet);
});
}
});
addIterator(SetShim.prototype, function() { return this.values(); });
return SetShim;
})()
};
defineProperties(globals, collectionShims);
if (globals.Map || globals.Set) {
/*
- In Firefox < 23, Map#size is a function.
- In all current Firefox, Set#entries/keys/values & Map#clear do not exist
- https://bugzilla.mozilla.org/show_bug.cgi?id=869996
- In Firefox 24, Map and Set do not implement forEach
- In Firefox 25 at least, Map and Set are callable without "new"
*/
if (
typeof globals.Map.prototype.clear !== 'function' ||
new globals.Set().size !== 0 ||
new globals.Map().size !== 0 ||
typeof globals.Map.prototype.keys !== 'function' ||
typeof globals.Set.prototype.keys !== 'function' ||
typeof globals.Map.prototype.forEach !== 'function' ||
typeof globals.Set.prototype.forEach !== 'function' ||
isCallableWithoutNew(globals.Map) ||
isCallableWithoutNew(globals.Set) ||
!supportsSubclassing(globals.Map, function(M) {
return (new M([])) instanceof M;
})
) {
globals.Map = collectionShims.Map;
globals.Set = collectionShims.Set;
}
}
// Shim incomplete iterator implementations.
addIterator(Object.getPrototypeOf((new globals.Map()).keys()));
addIterator(Object.getPrototypeOf((new globals.Set()).keys()));
}
};
main(); // CommonJS and <script>
});