]> git.openstreetmap.org Git - rails.git/commitdiff
Replace augment.js with conditional polyfills for ES5 and ES6
authorTom Hughes <tom@compton.nu>
Wed, 30 Jan 2019 12:02:06 +0000 (12:02 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 30 Jan 2019 12:11:57 +0000 (12:11 +0000)
Vendorfile
app/assets/javascripts/application.js
app/views/layouts/_head.html.erb
config/initializers/assets.rb
vendor/assets/augment.js/augment.js [deleted file]
vendor/assets/polyfill/es5.js [new file with mode: 0644]
vendor/assets/polyfill/es6.js [new file with mode: 0644]

index c4128262340b1819928e3369768144687a70b104..22a6ae422b4355efb15e4edbb5fa8bea337a6cc1 100644 (file)
@@ -67,6 +67,11 @@ folder 'vendor/assets' do
     end
   end
 
+  folder 'polyfill' do
+    file 'es5.js', 'https://polyfill.io/v3/polyfill.js?features=es5&flags=gated,always'
+    file 'es6.js', 'https://polyfill.io/v3/polyfill.js?features=es6&flags=gated,always'
+  end
+
   folder 'javascripts' do
     file 'html5shiv.js', 'https://raw.githubusercontent.com/aFarkas/html5shiv/master/src/html5shiv.js'
     file 'bowser.js', 'https://github.com/lancedikson/bowser/releases/download/1.9.4/bowser.js'
index 654b01680847f0668d38db7cec1c639cfb493f65..ebb0ff5808b65c6cd7d287d7e9dd40a2c83757aa 100644 (file)
@@ -5,7 +5,6 @@
 //= require jquery.throttle-debounce
 //= require bootstrap.tooltip
 //= require bootstrap.dropdown
-//= require augment
 //= require osm
 //= require leaflet
 //= require leaflet.osm
index c06b01ed1989574ea8acece3c5e96e6f5e6a2707..8c6b246d80b145f8fd3cd31102fa3219cc3fb346 100644 (file)
@@ -2,6 +2,8 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
   <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
   <%= javascript_include_tag "html5shiv" unless browser.html5? %>
+  <%= javascript_include_tag "es5" unless browser.es5? %>
+  <%= javascript_include_tag "es6" unless browser.es6? %>
   <%= javascript_include_tag "application" %>
   <%= javascript_include_tag "i18n/" + I18n.locale.to_s %>
   <%= stylesheet_link_tag "screen-#{dir}", :media => "screen" %>
index 7bd35daf6acaa08322599b59b6589ac68461ae4c..4193fe482e777cb5ddb5f241cd48c700bf062f5b 100644 (file)
@@ -20,7 +20,7 @@ Rails.application.config.assets.precompile += %w[leaflet-all.css leaflet.ie.css]
 Rails.application.config.assets.precompile += %w[id.js id.css]
 Rails.application.config.assets.precompile += %w[embed.js embed.css]
 Rails.application.config.assets.precompile += %w[errors.css]
-Rails.application.config.assets.precompile += %w[html5shiv.js]
+Rails.application.config.assets.precompile += %w[html5shiv.js es5.js es6.js]
 Rails.application.config.assets.precompile += %w[images/marker-*.png img/*-handle.png]
 Rails.application.config.assets.precompile += %w[swfobject.js expressInstall.swf]
 Rails.application.config.assets.precompile += %w[potlatch2.swf]
diff --git a/vendor/assets/augment.js/augment.js b/vendor/assets/augment.js/augment.js
deleted file mode 100644 (file)
index 33f0390..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-// augment.js JavaScript 1.8.5 methods for all, version: 0.4.2
-// using snippets from Mozilla - https://developer.mozilla.org/en/JavaScript
-// (c) 2011 Oliver Nightingale
-//
-//  Released under MIT license.
-//
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
-if (!Array.prototype.every) {
-  Array.prototype.every = function(fun /*, thisp */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    var thisp = arguments[1];
-    for (var i = 0; i < len; i++) {
-      if (i in t && !fun.call(thisp, t[i], i, t))
-        return false;
-    }
-
-    return true;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
-if (!Array.prototype.filter) {
-  Array.prototype.filter = function(fun /*, thisp */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    var res = [];
-    var thisp = arguments[1];
-    for (var i = 0; i < len; i++) {
-      if (i in t) {
-        var val = t[i]; // in case fun mutates this
-        if (fun.call(thisp, val, i, t))
-          res.push(val);
-      }
-    }
-
-    return res;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
-if (!Array.prototype.forEach) {
-  Array.prototype.forEach = function(fun /*, thisp */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    var thisp = arguments[1];
-    for (var i = 0; i < len; i++) {
-      if (i in t)
-        fun.call(thisp, t[i], i, t);
-    }
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
-if (!Array.prototype.indexOf) {
-  Array.prototype.indexOf = function(searchElement /*, fromIndex */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (len === 0)
-      return -1;
-
-    var n = 0;
-    if (arguments.length > 0) {
-      n = Number(arguments[1]);
-      if (n !== n) // shortcut for verifying if it's NaN
-        n = 0;
-      else if (n !== 0 && n !== (Infinity) && n !== -(Infinity))
-        n = (n > 0 || -1) * Math.floor(Math.abs(n));
-    }
-
-    if (n >= len)
-      return -1;
-
-    var k = n >= 0
-          ? n
-          : Math.max(len - Math.abs(n), 0);
-
-    for (; k < len; k++) {
-      if (k in t && t[k] === searchElement)
-        return k;
-    }
-    return -1;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
-Array.isArray = Array.isArray || function(o) { return Object.prototype.toString.call(o) === '[object Array]'; };
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
-if (!Array.prototype.lastIndexOf) {
-  Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (len === 0)
-      return -1;
-
-    var n = len;
-    if (arguments.length > 1) {
-      n = Number(arguments[1]);
-      if (n !== n)
-        n = 0;
-      else if (n !== 0 && n !== (Infinity) && n !== -(Infinity))
-        n = (n > 0 || -1) * Math.floor(Math.abs(n));
-    }
-
-    var k = n >= 0
-          ? Math.min(n, len - 1)
-          : len - Math.abs(n);
-
-    for (; k >= 0; k--) {
-      if (k in t && t[k] === searchElement)
-        return k;
-    }
-    return -1;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
-if (!Array.prototype.map) {
-  Array.prototype.map = function(fun /*, thisp */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    var res = new Array(len);
-    var thisp = arguments[1];
-    for (var i = 0; i < len; i++) {
-      if (i in t)
-        res[i] = fun.call(thisp, t[i], i, t);
-    }
-
-    return res;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
-if (!Array.prototype.reduce) {
-  Array.prototype.reduce = function(fun /*, initialValue */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    // no value to return if no initial value and an empty array
-    if (len == 0 && arguments.length == 1)
-      throw new TypeError();
-
-    var k = 0;
-    var accumulator;
-    if (arguments.length >= 2) {
-      accumulator = arguments[1];
-    } else {
-      do {
-        if (k in t) {
-          accumulator = t[k++];
-          break;
-        }
-
-        // if array contains no values, no initial value to return
-        if (++k >= len)
-          throw new TypeError();
-      }
-      while (true);
-    }
-
-    while (k < len) {
-      if (k in t)
-        accumulator = fun.call(undefined, accumulator, t[k], k, t);
-      k++;
-    }
-
-    return accumulator;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/ReduceRight
-if (!Array.prototype.reduceRight) {
-  Array.prototype.reduceRight = function(callbackfn /*, initialValue */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof callbackfn !== "function")
-      throw new TypeError();
-
-    // no value to return if no initial value, empty array
-    if (len === 0 && arguments.length === 1)
-      throw new TypeError();
-
-    var k = len - 1;
-    var accumulator;
-    if (arguments.length >= 2) {
-      accumulator = arguments[1];
-    } else {
-      do {
-        if (k in this) {
-          accumulator = this[k--];
-          break;
-        }
-
-        // if array contains no values, no initial value to return
-        if (--k < 0)
-          throw new TypeError();
-      }
-      while (true);
-    }
-
-    while (k >= 0) {
-      if (k in t)
-        accumulator = callbackfn.call(undefined, accumulator, t[k], k, t);
-      k--;
-    }
-
-    return accumulator;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
-if (!Array.prototype.some) {
-  Array.prototype.some = function(fun /*, thisp */) {
-    "use strict";
-
-    if (this === void 0 || this === null)
-      throw new TypeError();
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== "function")
-      throw new TypeError();
-
-    var thisp = arguments[1];
-    for (var i = 0; i < len; i++) {
-      if (i in t && fun.call(thisp, t[i], i, t))
-        return true;
-    }
-
-    return false;
-  };
-}
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now
-if (!Date.now) {
-  Date.now = function now () {
-    return +new Date();
-  };
-}
-if (!Date.prototype.toISOString) {
-  Date.prototype.toISOString = (function () {
-
-    var pad = function (n, length) {
-      length = length || 2
-      return (n = n + "", n.length === length) ? n : pad("0" + n, length);
-    }
-
-    return function () {
-      var year = this.getUTCFullYear()
-      year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6);
-
-      var date = [year, pad(this.getUTCMonth() + 1), pad(this.getUTCDate())].join("-")
-      var time = [pad(this.getUTCHours()), pad(this.getUTCMinutes()), pad(this.getUTCSeconds())].join(":") + "." + pad(this.getUTCMilliseconds(), 3)
-      return [date, time].join("T") + "Z"
-    }
-  })()
-};
-if (!Date.prototype.toJSON) {
-  Date.prototype.toJSON = Date.prototype.toJSON
-};
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
-if (!Function.prototype.bind ) {
-
-  Function.prototype.bind = function(obj) {
-
-    if (typeof this !== 'function') throw new TypeError ("Function.prototype.bind - what is trying to be bound is not callable")
-
-    var slice = Array.prototype.slice,
-        args = slice.call(arguments, 1), 
-        self = this, 
-        nop = function () {}, 
-        bound = function () {
-
-          if (nop.prototype && this instanceof nop) {
-            var result = self.apply(new nop, args.concat(slice.call(arguments)))
-            return (Object(result) === result) ? result : self
-          } else {
-            return self.apply(obj, args.concat(slice.call(arguments)))
-          };
-        };
-
-    nop.prototype = self.prototype;
-
-    bound.prototype = new nop();
-
-    return bound;
-  };
-}
-;(function () { "use strict"
-
-  var ensureIsObject = function (param) {
-    if (param !== Object(param)) throw new TypeError('Object.getPrototypeOf called on non-object');
-  }
-
-  if (!Object.getPrototypeOf) {
-    if (typeof "test".__proto__ === "object") {
-      Object.getPrototypeOf = function (obj) {
-        ensureIsObject(obj)
-        return obj.__proto__
-      }
-    } else {
-      Object.getPrototypeOf = function (obj) {
-        ensureIsObject(obj)
-        return obj.constructor.prototype
-      }
-    };
-  };
-})();
-// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
-if (!Object.keys) {
-  Object.keys = (function () {
-    var hasOwnProperty = Object.prototype.hasOwnProperty,
-        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
-        dontEnums = [
-          'toString',
-          'toLocaleString',
-          'valueOf',
-          'hasOwnProperty',
-          'isPrototypeOf',
-          'propertyIsEnumerable',
-          'constructor'
-        ],
-        dontEnumsLength = dontEnums.length
-
-    return function (obj) {
-      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object')
-
-      var result = []
-
-      for (var prop in obj) {
-        if (hasOwnProperty.call(obj, prop)) result.push(prop)
-      }
-
-      if (hasDontEnumBug) {
-        for (var i=0; i < dontEnumsLength; i++) {
-          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i])
-        }
-      }
-      return result
-    }
-  })()
-};if (!String.prototype.trim) {
-  String.prototype.trim = (function () {
-
-    var trimLeft  = /^\s+/,
-        trimRight = /\s+$/
-
-    return function () {
-      return this.replace(trimLeft, "").replace(trimRight, "")
-    }
-  })()
-};
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
-// https://tc39.github.io/ecma262/#sec-array.prototype.findindex
-if (!Array.prototype.findIndex) {
-  Object.defineProperty(Array.prototype, 'findIndex', {
-    value: function(predicate) {
-     // 1. Let O be ? ToObject(this value).
-      if (this == null) {
-        throw new TypeError('"this" is null or not defined');
-      }
-
-      var o = Object(this);
-
-      // 2. Let len be ? ToLength(? Get(O, "length")).
-      var len = o.length >>> 0;
-
-      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
-      if (typeof predicate !== 'function') {
-        throw new TypeError('predicate must be a function');
-      }
-
-      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
-      var thisArg = arguments[1];
-
-      // 5. Let k be 0.
-      var k = 0;
-
-      // 6. Repeat, while k < len
-      while (k < len) {
-        // a. Let Pk be ! ToString(k).
-        // b. Let kValue be ? Get(O, Pk).
-        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
-        // d. If testResult is true, return k.
-        var kValue = o[k];
-        if (predicate.call(thisArg, kValue, k, o)) {
-          return k;
-        }
-        // e. Increase k by 1.
-        k++;
-      }
-
-      // 7. Return -1.
-      return -1;
-    },
-    configurable: true,
-    writable: true
-  });
-}
diff --git a/vendor/assets/polyfill/es5.js b/vendor/assets/polyfill/es5.js
new file mode 100644 (file)
index 0000000..f16f7cc
--- /dev/null
@@ -0,0 +1,1821 @@
+/* Polyfill service v3.27.1
+ * For detailed credits and licence information see https://github.com/financial-times/polyfill-service.
+ * 
+ * Features requested: es5
+ * 
+ * - Object.defineProperty, License: CC0 (required by "es5", "Object.defineProperties", "Object.create", "_ESAbstract.CreateMethodProperty", "Array.isArray", "Array.prototype.every", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "Function.prototype.bind", "Object.freeze", "Object.getOwnPropertyDescriptor", "Object.getOwnPropertyNames", "Object.getPrototypeOf", "String.prototype.trim", "_ESAbstract.CreateDataProperty", "_ESAbstract.CreateDataPropertyOrThrow", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate")
+ * - _ESAbstract.CreateMethodProperty, License: CC0 (required by "Array.isArray", "es5", "Array.prototype.every", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "Function.prototype.bind", "Object.create", "Object.defineProperties", "Object.freeze", "Object.getOwnPropertyDescriptor", "Object.getOwnPropertyNames", "Object.getPrototypeOf", "String.prototype.trim")
+ * - _ESAbstract.IsArray, License: CC0 (required by "Array.isArray", "es5", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Array.prototype.map")
+ * - Array.isArray, License: CC0 (required by "es5")
+ * - _ESAbstract.ToObject, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "Object.defineProperties", "Object.create", "_ESAbstract.GetV", "_ESAbstract.GetMethod", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "String.prototype.trim", "_ESAbstract.IsConstructor", "_ESAbstract.ArraySpeciesCreate")
+ * - _ESAbstract.ToInteger, License: CC0 (required by "Array.prototype.indexOf", "es5", "Array.prototype.lastIndexOf", "_ESAbstract.ToLength", "Array.prototype.every", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some")
+ * - _ESAbstract.ToLength, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some")
+ * - _ESAbstract.Get, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "Object.defineProperties", "Object.create", "_ESAbstract.ArraySpeciesCreate", "_ESAbstract.OrdinaryToPrimitive", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "String.prototype.trim", "_ESAbstract.GetPrototypeFromConstructor", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct")
+ * - _ESAbstract.IsCallable, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "Function.prototype.bind", "_ESAbstract.GetMethod", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "String.prototype.trim", "_ESAbstract.IsConstructor", "_ESAbstract.ArraySpeciesCreate", "_ESAbstract.OrdinaryToPrimitive")
+ * - _ESAbstract.Call, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "String.prototype.trim", "_ESAbstract.OrdinaryToPrimitive")
+ * - _ESAbstract.GetV, License: CC0 (required by "_ESAbstract.GetMethod", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim", "_ESAbstract.IsConstructor", "_ESAbstract.ArraySpeciesCreate")
+ * - _ESAbstract.GetMethod, License: CC0 (required by "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim", "_ESAbstract.IsConstructor", "_ESAbstract.ArraySpeciesCreate")
+ * - _ESAbstract.Type, License: CC0 (required by "Object.create", "es5", "Object.defineProperties", "_ESAbstract.ToString", "Array.prototype.every", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim", "_ESAbstract.ArraySpeciesCreate", "_ESAbstract.ToPrimitive", "_ESAbstract.IsConstructor", "_ESAbstract.OrdinaryToPrimitive", "_ESAbstract.GetPrototypeFromConstructor", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct")
+ * - _ESAbstract.OrdinaryToPrimitive, License: CC0 (required by "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim")
+ * - _ESAbstract.ToPrimitive, License: CC0 (required by "_ESAbstract.ToString", "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim")
+ * - _ESAbstract.ToString, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some", "String.prototype.trim")
+ * - _ESAbstract.HasProperty, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.prototype.some")
+ * - _ESAbstract.ToBoolean, License: CC0 (required by "Array.prototype.every", "es5", "Array.prototype.filter", "Array.prototype.some")
+ * - Array.prototype.every, License: CC0 (required by "es5")
+ * - _ESAbstract.ArrayCreate, License: CC0 (required by "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - _ESAbstract.IsConstructor, License: CC0 (required by "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "es5", "Array.prototype.map", "_ESAbstract.Construct")
+ * - _ESAbstract.GetPrototypeFromConstructor, License: CC0 (required by "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - Object.keys, License: MIT (required by "es5", "Object.defineProperties", "Object.create")
+ * - Function.prototype.bind, License: MIT (required by "es5", "Object.getOwnPropertyDescriptor", "Object.defineProperties", "Object.create", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Array.prototype.map")
+ * - Object.getOwnPropertyDescriptor, License: CC0 (required by "es5", "Object.defineProperties", "Object.create")
+ * - Object.defineProperties, License: CC0 (required by "es5", "Object.create")
+ * - Object.create, License: CC0 (required by "es5", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Array.prototype.map")
+ * - Object.getPrototypeOf, License: CC0 (required by "es5", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Array.prototype.map")
+ * - _ESAbstract.OrdinaryCreateFromConstructor, License: CC0 (required by "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - _ESAbstract.Construct, License: CC0 (required by "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - _ESAbstract.ArraySpeciesCreate, License: CC0 (required by "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - _ESAbstract.CreateDataProperty, License: CC0 (required by "_ESAbstract.CreateDataPropertyOrThrow", "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - _ESAbstract.CreateDataPropertyOrThrow, License: CC0 (required by "Array.prototype.filter", "es5", "Array.prototype.map")
+ * - Array.prototype.filter, License: CC0 (required by "es5")
+ * - Array.prototype.forEach, License: CC0 (required by "es5")
+ * - Array.prototype.indexOf, License: CC0 (required by "es5")
+ * - Array.prototype.lastIndexOf, License: CC0 (required by "es5")
+ * - Array.prototype.map, License: CC0 (required by "es5")
+ * - Array.prototype.reduce, License: CC0 (required by "es5")
+ * - Array.prototype.reduceRight, License: CC0 (required by "es5")
+ * - Array.prototype.some, License: CC0 (required by "es5")
+ * - Date.now, License: CC0 (required by "es5")
+ * - Date.prototype.toISOString, License: CC0 (required by "es5")
+ * - Object.freeze, License: CC0 (required by "es5")
+ * - Object.getOwnPropertyNames, License: CC0 (required by "es5")
+ * - _ESAbstract.RequireObjectCoercible, License: CC0 (required by "String.prototype.trim", "es5")
+ * - String.prototype.trim, License: CC0 (required by "es5") */
+
+(function(undefined) {
+if (!(// In IE8, defineProperty could only act on DOM elements, so full support
+// for the feature requires the ability to set a property on an arbitrary object
+'defineProperty' in Object && (function() {
+       try {
+               var a = {};
+               Object.defineProperty(a, 'test', {value:42});
+               return true;
+       } catch(e) {
+               return false
+       }
+}()))) {
+
+// Object.defineProperty
+(function (nativeDefineProperty) {
+
+       var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__');
+       var ERR_ACCESSORS_NOT_SUPPORTED = 'Getters & setters cannot be defined on this javascript engine';
+       var ERR_VALUE_ACCESSORS = 'A property cannot both have accessors and be writable or have a value';
+
+       // Polyfill.io - This does not use CreateMethodProperty because our CreateMethodProperty function uses Object.defineProperty.
+       Object['defineProperty'] = function defineProperty(object, property, descriptor) {
+
+               // Where native support exists, assume it
+               if (nativeDefineProperty && (object === window || object === document || object === Element.prototype || object instanceof Element)) {
+                       return nativeDefineProperty(object, property, descriptor);
+               }
+
+               if (object === null || !(object instanceof Object || typeof object === 'object')) {
+                       throw new TypeError('Object.defineProperty called on non-object');
+               }
+
+               if (!(descriptor instanceof Object)) {
+                       throw new TypeError('Property description must be an object');
+               }
+
+               var propertyString = String(property);
+               var hasValueOrWritable = 'value' in descriptor || 'writable' in descriptor;
+               var getterType = 'get' in descriptor && typeof descriptor.get;
+               var setterType = 'set' in descriptor && typeof descriptor.set;
+
+               // handle descriptor.get
+               if (getterType) {
+                       if (getterType !== 'function') {
+                               throw new TypeError('Getter must be a function');
+                       }
+                       if (!supportsAccessors) {
+                               throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
+                       }
+                       if (hasValueOrWritable) {
+                               throw new TypeError(ERR_VALUE_ACCESSORS);
+                       }
+                       Object.__defineGetter__.call(object, propertyString, descriptor.get);
+               } else {
+                       object[propertyString] = descriptor.value;
+               }
+
+               // handle descriptor.set
+               if (setterType) {
+                       if (setterType !== 'function') {
+                               throw new TypeError('Setter must be a function');
+                       }
+                       if (!supportsAccessors) {
+                               throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
+                       }
+                       if (hasValueOrWritable) {
+                               throw new TypeError(ERR_VALUE_ACCESSORS);
+                       }
+                       Object.__defineSetter__.call(object, propertyString, descriptor.set);
+               }
+
+               // OK to define value unconditionally - if a getter has been specified as well, an error would be thrown above
+               if ('value' in descriptor) {
+                       object[propertyString] = descriptor.value;
+               }
+
+               return object;
+       };
+}(Object.defineProperty));
+
+}
+
+
+// _ESAbstract.CreateMethodProperty
+// 7.3.5. CreateMethodProperty ( O, P, V )
+function CreateMethodProperty(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let newDesc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
+       var newDesc = {
+               value: V,
+               writable: true,
+               enumerable: false,
+               configurable: true
+       };
+       // 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
+       Object.defineProperty(O, P, newDesc);
+}
+
+// _ESAbstract.IsArray
+// 7.2.2. IsArray ( argument )
+function IsArray(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       // 2. If argument is an Array exotic object, return true.
+       // 3. If argument is a Proxy exotic object, then
+               // a. If argument.[[ProxyHandler]] is null, throw a TypeError exception.
+               // b. Let target be argument.[[ProxyTarget]].
+               // c. Return ? IsArray(target).
+       // 4. Return false.
+
+       // Polyfill.io - We can skip all the above steps and check the string returned from Object.prototype.toString().
+       return Object.prototype.toString.call(argument) === '[object Array]';
+}
+if (!('isArray' in Array)) {
+
+// Array.isArray
+/* global CreateMethodProperty, IsArray */
+// 22.1.2.2. Array.isArray ( arg )
+CreateMethodProperty(Array, 'isArray', function isArray(arg) {
+       // 1. Return ? IsArray(arg).
+       return IsArray(arg);
+});
+
+}
+
+
+// _ESAbstract.ToObject
+// 7.1.13 ToObject ( argument )
+// The abstract operation ToObject converts argument to a value of type Object according to Table 12:
+// Table 12: ToObject Conversions
+/*
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Argument Type | Result                                                                                                                             |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Undefined     | Throw a TypeError exception.                                                                                                       |
+| Null          | Throw a TypeError exception.                                                                                                       |
+| Boolean       | Return a new Boolean object whose [[BooleanData]] internal slot is set to argument. See 19.3 for a description of Boolean objects. |
+| Number        | Return a new Number object whose [[NumberData]] internal slot is set to argument. See 20.1 for a description of Number objects.    |
+| String        | Return a new String object whose [[StringData]] internal slot is set to argument. See 21.1 for a description of String objects.    |
+| Symbol        | Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 19.4 for a description of Symbol objects.    |
+| Object        | Return argument.                                                                                                                   |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+*/
+function ToObject(argument) { // eslint-disable-line no-unused-vars
+       if (argument === null || argument === undefined) {
+               throw TypeError();
+       }
+  return Object(argument);
+}
+
+// _ESAbstract.ToInteger
+// 7.1.4. ToInteger ( argument )
+function ToInteger(argument) { // eslint-disable-line no-unused-vars
+       // 1. Let number be ? ToNumber(argument).
+       var number = Number(argument);
+       // 2. If number is NaN, return +0.
+       if (isNaN(number)) {
+               return 0;
+       }
+       // 3. If number is +0, -0, +∞, or -∞, return number.
+       if (1/number === Infinity || 1/number === -Infinity || number === Infinity || number === -Infinity) {
+               return number;
+       }
+       // 4. Return the number value that is the same sign as number and whose magnitude is floor(abs(number)).
+       return ((number < 0) ? -1 : 1) * Math.floor(Math.abs(number));
+}
+
+// _ESAbstract.ToLength
+/* global ToInteger */
+// 7.1.15. ToLength ( argument )
+function ToLength(argument) { // eslint-disable-line no-unused-vars
+       // 1. Let len be ? ToInteger(argument).
+       var len = ToInteger(argument);
+       // 2. If len ≤ +0, return +0.
+       if (len <= 0) {
+               return 0;
+       }
+       // 3. Return min(len, 253-1).
+       return Math.min(len, Math.pow(2, 53) -1);
+}
+
+// _ESAbstract.Get
+// 7.3.1. Get ( O, P )
+function Get(O, P) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Return ? O.[[Get]](P, O).
+       return O[P];
+}
+
+// _ESAbstract.IsCallable
+// 7.2.3. IsCallable ( argument )
+function IsCallable(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       // 2. If argument has a [[Call]] internal method, return true.
+       // 3. Return false.
+
+       // Polyfill.io - Only function objects have a [[Call]] internal method. This means we can simplify this function to check that the argument has a type of function.
+       return typeof argument === 'function';
+}
+
+// _ESAbstract.Call
+/* global IsCallable */
+// 7.3.12. Call ( F, V [ , argumentsList ] )
+function Call(F, V /* [, argumentsList] */) { // eslint-disable-line no-unused-vars
+       // 1. If argumentsList is not present, set argumentsList to a new empty List.
+       var argumentsList = arguments.length > 2 ? arguments[2] : [];
+       // 2. If IsCallable(F) is false, throw a TypeError exception.
+       if (IsCallable(F) === false) {
+               throw new TypeError(Object.prototype.toString.call(F) + 'is not a function.');
+       }
+       // 3. Return ? F.[[Call]](V, argumentsList).
+       return F.apply(V, argumentsList);
+}
+
+// _ESAbstract.GetV
+/* global ToObject */
+// 7.3.2 GetV (V, P)
+function GetV(v, p) { // eslint-disable-line no-unused-vars
+       // 1. Assert: IsPropertyKey(P) is true.
+       // 2. Let O be ? ToObject(V).
+       var o = ToObject(v);
+       // 3. Return ? O.[[Get]](P, V).
+       return o[p];
+}
+
+// _ESAbstract.GetMethod
+/* global GetV, IsCallable */
+// 7.3.9. GetMethod ( V, P )
+function GetMethod(V, P) { // eslint-disable-line no-unused-vars
+       // 1. Assert: IsPropertyKey(P) is true.
+       // 2. Let func be ? GetV(V, P).
+       var func = GetV(V, P);
+       // 3. If func is either undefined or null, return undefined.
+       if (func === null || func === undefined) {
+               return undefined;
+       }
+       // 4. If IsCallable(func) is false, throw a TypeError exception.
+       if (IsCallable(func) === false) {
+               throw new TypeError('Method not callable: ' + P);
+       }
+       // 5. Return func.
+       return func;
+}
+
+// _ESAbstract.Type
+// "Type(x)" is used as shorthand for "the type of x"...
+function Type(x) { // eslint-disable-line no-unused-vars
+       switch (typeof x) {
+               case 'undefined':
+                       return 'undefined';
+               case 'boolean':
+                       return 'boolean';
+               case 'number':
+                       return 'number';
+               case 'string':
+                       return 'string';
+               case 'symbol':
+                       return 'symbol';
+               default:
+                       // typeof null is 'object'
+                       if (x === null) return 'null';
+                       // Polyfill.io - This is here because a Symbol polyfill will have a typeof `object`.
+                       if ('Symbol' in this && x instanceof this.Symbol) return 'symbol';
+                       return 'object';
+       }
+}
+
+// _ESAbstract.OrdinaryToPrimitive
+/* global Get, IsCallable, Call, Type */
+// 7.1.1.1. OrdinaryToPrimitive ( O, hint )
+function OrdinaryToPrimitive(O, hint) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: Type(hint) is String and its value is either "string" or "number".
+       // 3. If hint is "string", then
+       if (hint === 'string') {
+               // a. Let methodNames be « "toString", "valueOf" ».
+               var methodNames = ['toString', 'valueOf'];
+               // 4. Else,
+       } else {
+               // a. Let methodNames be « "valueOf", "toString" ».
+               methodNames = ['valueOf', 'toString'];
+       }
+       // 5. For each name in methodNames in List order, do
+       for (var i = 0; i < methodNames.length; ++i) {
+               var name = methodNames[i];
+               // a. Let method be ? Get(O, name).
+               var method = Get(O, name);
+               // b. If IsCallable(method) is true, then
+               if (IsCallable(method)) {
+                       // i. Let result be ? Call(method, O).
+                       var result = Call(method, O);
+                       // ii. If Type(result) is not Object, return result.
+                       if (Type(result) !== 'object') {
+                               return result;
+                       }
+               }
+       }
+       // 6. Throw a TypeError exception.
+       throw new TypeError('Cannot convert to primitive.');
+}
+
+// _ESAbstract.ToPrimitive
+/* global Type, GetMethod, Call, OrdinaryToPrimitive */
+// 7.1.1. ToPrimitive ( input [ , PreferredType ] )
+function ToPrimitive(input /* [, PreferredType] */) { // eslint-disable-line no-unused-vars
+       var PreferredType = arguments.length > 1 ? arguments[1] : undefined;
+       // 1. Assert: input is an ECMAScript language value.
+       // 2. If Type(input) is Object, then
+       if (Type(input) === 'object') {
+               // a. If PreferredType is not present, let hint be "default".
+               if (arguments.length < 2) {
+                       var hint = 'default';
+                       // b. Else if PreferredType is hint String, let hint be "string".
+               } else if (PreferredType === String) {
+                       hint = 'string';
+                       // c. Else PreferredType is hint Number, let hint be "number".
+               } else if (PreferredType === Number) {
+                       hint = 'number';
+               }
+               // d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+               var exoticToPrim = typeof this.Symbol === 'function' && typeof this.Symbol.toPrimitive === 'symbol' ? GetMethod(input, this.Symbol.toPrimitive) : undefined;
+               // e. If exoticToPrim is not undefined, then
+               if (exoticToPrim !== undefined) {
+                       // i. Let result be ? Call(exoticToPrim, input, « hint »).
+                       var result = Call(exoticToPrim, input, [hint]);
+                       // ii. If Type(result) is not Object, return result.
+                       if (Type(result) !== 'object') {
+                               return result;
+                       }
+                       // iii. Throw a TypeError exception.
+                       throw new TypeError('Cannot convert exotic object to primitive.');
+               }
+               // f. If hint is "default", set hint to "number".
+               if (hint === 'default') {
+                       hint = 'number';
+               }
+               // g. Return ? OrdinaryToPrimitive(input, hint).
+               return OrdinaryToPrimitive(input, hint);
+       }
+       // 3. Return input
+       return input;
+}
+
+// _ESAbstract.ToString
+/* global Type, ToPrimitive */
+// 7.1.12. ToString ( argument )
+// The abstract operation ToString converts argument to a value of type String according to Table 11:
+// Table 11: ToString Conversions
+/*
+|---------------|--------------------------------------------------------|
+| Argument Type | Result                                                 |
+|---------------|--------------------------------------------------------|
+| Undefined     | Return "undefined".                                    |
+|---------------|--------------------------------------------------------|
+| Null         | Return "null".                                         |
+|---------------|--------------------------------------------------------|
+| Boolean       | If argument is true, return "true".                    |
+|               | If argument is false, return "false".                  |
+|---------------|--------------------------------------------------------|
+| Number        | Return NumberToString(argument).                       |
+|---------------|--------------------------------------------------------|
+| String        | Return argument.                                       |
+|---------------|--------------------------------------------------------|
+| Symbol        | Throw a TypeError exception.                           |
+|---------------|--------------------------------------------------------|
+| Object        | Apply the following steps:                             |
+|               | Let primValue be ? ToPrimitive(argument, hint String). |
+|               | Return ? ToString(primValue).                          |
+|---------------|--------------------------------------------------------|
+*/
+function ToString(argument) { // eslint-disable-line no-unused-vars
+       switch(Type(argument)) {
+               case 'symbol':
+                       throw new TypeError('Cannot convert a Symbol value to a string');
+                       break;
+               case 'object':
+                       var primValue = ToPrimitive(argument, 'string');
+                       return ToString(primValue);
+               default:
+                       return String(argument);
+       }
+}
+
+// _ESAbstract.HasProperty
+// 7.3.10. HasProperty ( O, P )
+function HasProperty(O, P) { // eslint-disable-line no-unused-vars
+       // Assert: Type(O) is Object.
+       // Assert: IsPropertyKey(P) is true.
+       // Return ? O.[[HasProperty]](P).
+       return P in O;
+}
+
+// _ESAbstract.ToBoolean
+// 7.1.2. ToBoolean ( argument )
+// The abstract operation ToBoolean converts argument to a value of type Boolean according to Table 9:
+/*
+--------------------------------------------------------------------------------------------------------------
+| Argument Type | Result                                                                                     |
+--------------------------------------------------------------------------------------------------------------
+| Undefined     | Return false.                                                                              |
+| Null          | Return false.                                                                              |
+| Boolean       | Return argument.                                                                           |
+| Number        | If argument is +0, -0, or NaN, return false; otherwise return true.                        |
+| String        | If argument is the empty String (its length is zero), return false; otherwise return true. |
+| Symbol        | Return true.                                                                               |
+| Object        | Return true.                                                                               |
+--------------------------------------------------------------------------------------------------------------
+*/
+function ToBoolean(argument) { // eslint-disable-line no-unused-vars
+       return Boolean(argument);
+}
+if (!('every' in Array.prototype)) {
+
+// Array.prototype.every
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToBoolean, ToLength, ToObject, ToString */
+// 22.1.3.5. Array.prototype.every ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'every', function every(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let testResult be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
+                       var testResult = ToBoolean(Call(callbackfn, T, [kValue, k, O]));
+                       // iii. If testResult is false, return false.
+                       if (testResult === false) {
+                               return false;
+                       }
+               }
+               // d. Increase k by 1.
+               var k = k + 1;
+       }
+       // 7. Return true.
+       return true;
+});
+
+}
+
+
+// _ESAbstract.ArrayCreate
+// 9.4.2.2. ArrayCreate ( length [ , proto ] )
+function ArrayCreate(length /* [, proto] */) { // eslint-disable-line no-unused-vars
+       // 1. Assert: length is an integer Number ≥ 0.
+       // 2. If length is -0, set length to +0.
+       if (1 / length === -Infinity) {
+               length = 0;
+       }
+       // 3. If length>2^32-1, throw a RangeError exception.
+       if (length > (Math.pow(2, 32) - 1)) {
+               throw new RangeError('Invalid array length');
+       }
+       // 4. If proto is not present, set proto to the intrinsic object %ArrayPrototype%.
+       // 5. Let A be a newly created Array exotic object.
+       var A = [];
+       // 6. Set A's essential internal methods except for [[DefineOwnProperty]] to the default ordinary object definitions specified in 9.1.
+       // 7. Set A.[[DefineOwnProperty]] as specified in 9.4.2.1.
+       // 8. Set A.[[Prototype]] to proto.
+       // 9. Set A.[[Extensible]] to true.
+       // 10. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
+       A.length = length;
+       // 11. Return A.
+       return A;
+}
+
+// _ESAbstract.IsConstructor
+/* global Type */
+// 7.2.4. IsConstructor ( argument )
+function IsConstructor(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       if (Type(argument) !== 'object') {
+               return false;
+       }
+       // 2. If argument has a [[Construct]] internal method, return true.
+       // 3. Return false.
+
+       // Polyfill.io - `new argument` is the only way  to truly test if a function is a constructor.
+       // We choose to not use`new argument` because the argument could have side effects when called.
+       // Instead we check to see if the argument is a function and if it has a prototype.
+       // Arrow functions do not have a [[Construct]] internal method, nor do they have a prototype.
+       return typeof argument === 'function' && !!argument.prototype;
+}
+
+// _ESAbstract.GetPrototypeFromConstructor
+/* global Get, Type */
+// 9.1.14. GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
+function GetPrototypeFromConstructor(constructor, intrinsicDefaultProto) { // eslint-disable-line no-unused-vars
+       // 1. Assert: intrinsicDefaultProto is a String value that is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object.
+       // 2. Assert: IsCallable(constructor) is true.
+       // 3. Let proto be ? Get(constructor, "prototype").
+       var proto = Get(constructor, "prototype");
+       // 4. If Type(proto) is not Object, then
+       if (Type(proto) !== 'object') {
+               // a. Let realm be ? GetFunctionRealm(constructor).
+               // b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
+               proto = intrinsicDefaultProto;
+       }
+       // 5. Return proto.
+       return proto;
+}
+if (!('keys' in Object && (function () {
+       // Safari 5.0 bug where Object.keys doesn't work with arguments
+       return (Object.keys(arguments)).length === 2;
+}(1, 2)) && (function () {
+       try {
+               // In ES6 Object.keys works on all object except `null` and `undefined`.
+               Object.keys('');
+               return true;
+       } catch (e) {
+               return false;
+       }
+}()))) {
+
+// Object.keys
+Object.keys = (function() {
+       'use strict';
+
+       // modified from https://github.com/es-shims/object-keys
+
+       var has = Object.prototype.hasOwnProperty;
+       var toStr = Object.prototype.toString;
+       var isEnumerable = Object.prototype.propertyIsEnumerable;
+       var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
+       var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
+       var dontEnums = [
+               'toString',
+               'toLocaleString',
+               'valueOf',
+               'hasOwnProperty',
+               'isPrototypeOf',
+               'propertyIsEnumerable',
+               'constructor'
+       ];
+       var equalsConstructorPrototype = function (o) {
+               var ctor = o.constructor;
+               return ctor && ctor.prototype === o;
+       };
+       var excludedKeys = {
+               $console: true,
+               $external: true,
+               $frame: true,
+               $frameElement: true,
+               $frames: true,
+               $innerHeight: true,
+               $innerWidth: true,
+               $outerHeight: true,
+               $outerWidth: true,
+               $pageXOffset: true,
+               $pageYOffset: true,
+               $parent: true,
+               $scrollLeft: true,
+               $scrollTop: true,
+               $scrollX: true,
+               $scrollY: true,
+               $self: true,
+               $webkitIndexedDB: true,
+               $webkitStorageInfo: true,
+               $window: true
+       };
+       var hasAutomationEqualityBug = (function () {
+               /* global window */
+               if (typeof window === 'undefined') { return false; }
+               for (var k in window) {
+                       try {
+                               if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
+                                       try {
+                                               equalsConstructorPrototype(window[k]);
+                                       } catch (e) {
+                                               return true;
+                                       }
+                               }
+                       } catch (e) {
+                               return true;
+                       }
+               }
+               return false;
+       }());
+       var equalsConstructorPrototypeIfNotBuggy = function (o) {
+               /* global window */
+               if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+                       return equalsConstructorPrototype(o);
+               }
+               try {
+                       return equalsConstructorPrototype(o);
+               } catch (e) {
+                       return false;
+               }
+       };
+
+       function isArgumentsObject(value) {
+               var str = toStr.call(value);
+               var isArgs = str === '[object Arguments]';
+               if (!isArgs) {
+                       isArgs = str !== '[object Array]' &&
+                               value !== null &&
+                               typeof value === 'object' &&
+                               typeof value.length === 'number' &&
+                               value.length >= 0 &&
+                               toStr.call(value.callee) === '[object Function]';
+               }
+               return isArgs;
+       }
+
+       return function keys(object) {
+               var isFunction = toStr.call(object) === '[object Function]';
+               var isArguments = isArgumentsObject(object);
+               var isString = toStr.call(object) === '[object String]';
+               var theKeys = [];
+
+               if (object === undefined || object === null) {
+                       throw new TypeError('Cannot convert undefined or null to object');
+               }
+
+               var skipProto = hasProtoEnumBug && isFunction;
+               if (isString && object.length > 0 && !has.call(object, 0)) {
+                       for (var i = 0; i < object.length; ++i) {
+                               theKeys.push(String(i));
+                       }
+               }
+
+               if (isArguments && object.length > 0) {
+                       for (var j = 0; j < object.length; ++j) {
+                               theKeys.push(String(j));
+                       }
+               } else {
+                       for (var name in object) {
+                               if (!(skipProto && name === 'prototype') && has.call(object, name)) {
+                                       theKeys.push(String(name));
+                               }
+                       }
+               }
+
+               if (hasDontEnumBug) {
+                       var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+
+                       for (var k = 0; k < dontEnums.length; ++k) {
+                               if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
+                                       theKeys.push(dontEnums[k]);
+                               }
+                       }
+               }
+               return theKeys;
+       };
+}());
+
+}
+
+if (!('bind' in Function.prototype)) {
+
+// Function.prototype.bind
+/* global CreateMethodProperty, IsCallable */
+// 19.2.3.2. Function.prototype.bind ( thisArg, ...args )
+// https://github.com/es-shims/es5-shim/blob/d6d7ff1b131c7ba14c798cafc598bb6780d37d3b/es5-shim.js#L182
+CreateMethodProperty(Function.prototype, 'bind', function bind(that) { // .length is 1
+       // add necessary es5-shim utilities
+       var $Array = Array;
+       var $Object = Object;
+       var ArrayPrototype = $Array.prototype;
+       var Empty = function Empty() { };
+       var array_slice = ArrayPrototype.slice;
+       var array_concat = ArrayPrototype.concat;
+       var array_push = ArrayPrototype.push;
+       var max = Math.max;
+       // /add necessary es5-shim utilities
+
+       // 1. Let Target be the this value.
+       var target = this;
+       // 2. If IsCallable(Target) is false, throw a TypeError exception.
+       if (!IsCallable(target)) {
+               throw new TypeError('Function.prototype.bind called on incompatible ' + target);
+       }
+       // 3. Let A be a new (possibly empty) internal list of all of the
+       //   argument values provided after thisArg (arg1, arg2 etc), in order.
+       // XXX slicedArgs will stand in for "A" if used
+       var args = array_slice.call(arguments, 1); // for normal call
+       // 4. Let F be a new native ECMAScript object.
+       // 11. Set the [[Prototype]] internal property of F to the standard
+       //   built-in Function prototype object as specified in 15.3.3.1.
+       // 12. Set the [[Call]] internal property of F as described in
+       //   15.3.4.5.1.
+       // 13. Set the [[Construct]] internal property of F as described in
+       //   15.3.4.5.2.
+       // 14. Set the [[HasInstance]] internal property of F as described in
+       //   15.3.4.5.3.
+       var bound;
+       var binder = function () {
+
+               if (this instanceof bound) {
+                       // 15.3.4.5.2 [[Construct]]
+                       // When the [[Construct]] internal method of a function object,
+                       // F that was created using the bind function is called with a
+                       // list of arguments ExtraArgs, the following steps are taken:
+                       // 1. Let target be the value of F's [[TargetFunction]]
+                       //   internal property.
+                       // 2. If target has no [[Construct]] internal method, a
+                       //   TypeError exception is thrown.
+                       // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
+                       //   property.
+                       // 4. Let args be a new list containing the same values as the
+                       //   list boundArgs in the same order followed by the same
+                       //   values as the list ExtraArgs in the same order.
+                       // 5. Return the result of calling the [[Construct]] internal
+                       //   method of target providing args as the arguments.
+
+                       var result = target.apply(
+                               this,
+                               array_concat.call(args, array_slice.call(arguments))
+                       );
+                       if ($Object(result) === result) {
+                               return result;
+                       }
+                       return this;
+
+               } else {
+                       // 15.3.4.5.1 [[Call]]
+                       // When the [[Call]] internal method of a function object, F,
+                       // which was created using the bind function is called with a
+                       // this value and a list of arguments ExtraArgs, the following
+                       // steps are taken:
+                       // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+                       //   property.
+                       // 2. Let boundThis be the value of F's [[BoundThis]] internal
+                       //   property.
+                       // 3. Let target be the value of F's [[TargetFunction]] internal
+                       //   property.
+                       // 4. Let args be a new list containing the same values as the
+                       //   list boundArgs in the same order followed by the same
+                       //   values as the list ExtraArgs in the same order.
+                       // 5. Return the result of calling the [[Call]] internal method
+                       //   of target providing boundThis as the this value and
+                       //   providing args as the arguments.
+
+                       // equiv: target.call(this, ...boundArgs, ...args)
+                       return target.apply(
+                               that,
+                               array_concat.call(args, array_slice.call(arguments))
+                       );
+
+               }
+
+       };
+
+       // 15. If the [[Class]] internal property of Target is "Function", then
+       //     a. Let L be the length property of Target minus the length of A.
+       //     b. Set the length own property of F to either 0 or L, whichever is
+       //       larger.
+       // 16. Else set the length own property of F to 0.
+
+       var boundLength = max(0, target.length - args.length);
+
+       // 17. Set the attributes of the length own property of F to the values
+       //   specified in 15.3.5.1.
+       var boundArgs = [];
+       for (var i = 0; i < boundLength; i++) {
+               array_push.call(boundArgs, '$' + i);
+       }
+
+       // XXX Build a dynamic function with desired amount of arguments is the only
+       // way to set the length property of a function.
+       // In environments where Content Security Policies enabled (Chrome extensions,
+       // for ex.) all use of eval or Function costructor throws an exception.
+       // However in all of these environments Function.prototype.bind exists
+       // and so this code will never be executed.
+       bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
+
+       if (target.prototype) {
+               Empty.prototype = target.prototype;
+               bound.prototype = new Empty();
+               // Clean up dangling references.
+               Empty.prototype = null;
+       }
+
+       // TODO
+       // 18. Set the [[Extensible]] internal property of F to true.
+
+       // TODO
+       // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
+       // 20. Call the [[DefineOwnProperty]] internal method of F with
+       //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
+       //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
+       //   false.
+       // 21. Call the [[DefineOwnProperty]] internal method of F with
+       //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
+       //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
+       //   and false.
+
+       // TODO
+       // NOTE Function objects created using Function.prototype.bind do not
+       // have a prototype property or the [[Code]], [[FormalParameters]], and
+       // [[Scope]] internal properties.
+       // XXX can't delete prototype in pure-js.
+
+       // 22. Return F.
+       return bound;
+});
+
+}
+
+if (!('getOwnPropertyDescriptor' in Object && typeof Object.getOwnPropertyDescriptor === 'function' && (function() {
+    try {
+       var object = {};
+        object.test = 0;
+        return Object.getOwnPropertyDescriptor(
+            object,
+            "test"
+        ).value === 0;
+    } catch (exception) {
+        return false
+    }
+}()))) {
+
+// Object.getOwnPropertyDescriptor
+/* global CreateMethodProperty */
+(function () {
+       var call = Function.prototype.call;
+       var prototypeOfObject = Object.prototype;
+       var owns = call.bind(prototypeOfObject.hasOwnProperty);
+
+       var lookupGetter;
+       var lookupSetter;
+       var supportsAccessors;
+       if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
+           lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
+           lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
+       }
+       function doesGetOwnPropertyDescriptorWork(object) {
+           try {
+               object.sentinel = 0;
+               return Object.getOwnPropertyDescriptor(
+                   object,
+                   "sentinel"
+               ).value === 0;
+           } catch (exception) {
+               // returns falsy
+           }
+       }
+       // check whether getOwnPropertyDescriptor works if it's given. Otherwise,
+       // shim partially.
+       if (Object.defineProperty) {
+           var getOwnPropertyDescriptorWorksOnObject =
+               doesGetOwnPropertyDescriptorWork({});
+           var getOwnPropertyDescriptorWorksOnDom = typeof document == "undefined" ||
+               doesGetOwnPropertyDescriptorWork(document.createElement("div"));
+           if (!getOwnPropertyDescriptorWorksOnDom ||
+               !getOwnPropertyDescriptorWorksOnObject
+           ) {
+               var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;
+           }
+       }
+
+       if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
+           var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object: ";
+
+           CreateMethodProperty(Object, 'getOwnPropertyDescriptor', function getOwnPropertyDescriptor(object, property) {
+               if ((typeof object != "object" && typeof object != "function") || object === null) {
+                   throw new TypeError(ERR_NON_OBJECT + object);
+               }
+
+               // make a valiant attempt to use the real getOwnPropertyDescriptor
+               // for I8's DOM elements.
+               if (getOwnPropertyDescriptorFallback) {
+                   try {
+                       return getOwnPropertyDescriptorFallback.call(Object, object, property);
+                   } catch (exception) {
+                       // try the shim if the real one doesn't work
+                   }
+               }
+
+               // If object does not owns property return undefined immediately.
+               if (!owns(object, property)) {
+                   return;
+               }
+
+               // If object has a property then it's for sure both `enumerable` and
+               // `configurable`.
+               var descriptor = { enumerable: true, configurable: true };
+
+               // If JS engine supports accessor properties then property may be a
+               // getter or setter.
+               if (supportsAccessors) {
+                   // Unfortunately `__lookupGetter__` will return a getter even
+                   // if object has own non getter property along with a same named
+                   // inherited getter. To avoid misbehavior we temporary remove
+                   // `__proto__` so that `__lookupGetter__` will return getter only
+                   // if it's owned by an object.
+                   var prototype = object.__proto__;
+                   object.__proto__ = prototypeOfObject;
+
+                   var getter = lookupGetter(object, property);
+                   var setter = lookupSetter(object, property);
+
+                   // Once we have getter and setter we can put values back.
+                   object.__proto__ = prototype;
+
+                   if (getter || setter) {
+                       if (getter) {
+                           descriptor.get = getter;
+                       }
+                       if (setter) {
+                           descriptor.set = setter;
+                       }
+                       // If it was accessor property we're done and return here
+                       // in order to avoid adding `value` to the descriptor.
+                       return descriptor;
+                   }
+               }
+
+               // If we got this far we know that object has an own property that is
+               // not an accessor so we set it as a value and return descriptor.
+               descriptor.value = object[property];
+                       descriptor.writable = true;
+               return descriptor;
+           });
+       }
+}());
+
+}
+
+if (!('defineProperties' in Object)) {
+
+// Object.defineProperties
+/* global CreateMethodProperty, Get, ToObject, Type */
+// 19.1.2.3. Object.defineProperties ( O, Properties )
+CreateMethodProperty(Object, 'defineProperties', function defineProperties(O, Properties) {
+       // 1. If Type(O) is not Object, throw a TypeError exception.
+       if (Type(O) !== 'object') {
+               throw new TypeError('Object.defineProperties called on non-object');
+       }
+       // 2. Let props be ? ToObject(Properties).
+       var props = ToObject(Properties);
+       // 3. Let keys be ? props.[[OwnPropertyKeys]]().
+       /*
+               Polyfill.io - This step in our polyfill is not complying with the specification.
+               [[OwnPropertyKeys]] is meant to return ALL keys, including non-enumerable and symbols.
+               TODO: When we have Reflect.ownKeys, use that instead as it is the userland equivalent of [[OwnPropertyKeys]].
+       */
+       var keys = Object.keys(props);
+       // 4. Let descriptors be a new empty List.
+       var descriptors = [];
+       // 5. For each element nextKey of keys in List order, do
+       for (var i = 0; i < keys.length; i++) {
+               var nextKey = keys[i];
+               // a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
+               var propDesc = Object.getOwnPropertyDescriptor(props, nextKey);
+               // b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
+               if (propDesc !== undefined && propDesc.enumerable) {
+                       // i. Let descObj be ? Get(props, nextKey).
+                       var descObj = Get(props, nextKey);
+                       // ii. Let desc be ? ToPropertyDescriptor(descObj).
+                       // Polyfill.io - We skip this step because Object.defineProperty deals with it.
+                       // TODO: Implement this step?
+                       var desc = descObj;
+                       // iii. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
+                       descriptors.push([nextKey, desc]);
+               }
+       }
+       // 6. For each pair from descriptors in list order, do
+       for (var i = 0; i < descriptors.length; i++){
+               // a. Let P be the first element of pair.
+               var P = descriptors[i][0];
+               // b. Let desc be the second element of pair.
+               var desc = descriptors[i][1];
+               // c. Perform ? DefinePropertyOrThrow(O, P, desc).
+               Object.defineProperty(O, P, desc);
+       }
+       // 7. Return O.
+       return O;
+});
+
+}
+
+if (!('create' in Object)) {
+
+// Object.create
+/* global CreateMethodProperty, Type */
+CreateMethodProperty(Object, 'create', function create(O, properties) {
+       // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
+       if (Type(O) !== 'object' && Type(O) !== 'null') {
+               throw new TypeError('Object prototype may only be an Object or null');
+       }
+       // 2. Let obj be ObjectCreate(O).
+       var obj = new Function('e', 'function Object() {}Object.prototype=e;return new Object')(O);
+
+       obj.constructor.prototype = O;
+
+       // 3. If Properties is not undefined, then
+       if (1 in arguments) {
+               // a. Return ? ObjectDefineProperties(obj, Properties).
+               return Object.defineProperties(obj, properties);
+       }
+
+       return obj;
+});
+
+}
+
+if (!('getPrototypeOf' in Object)) {
+
+// Object.getPrototypeOf
+/* global CreateMethodProperty */
+// Based on: https://github.com/es-shims/es5-shim/blob/master/es5-sham.js
+
+// https://github.com/es-shims/es5-shim/issues#issue/2
+// http://ejohn.org/blog/objectgetprototypeof/
+// recommended by fschaefer on github
+//
+// sure, and webreflection says ^_^
+// ... this will nerever possibly return null
+// ... Opera Mini breaks here with infinite loops
+CreateMethodProperty(Object, 'getPrototypeOf', function getPrototypeOf(object) {
+       if (object !== Object(object)) {
+               throw new TypeError('Object.getPrototypeOf called on non-object');
+       }
+       var proto = object.__proto__;
+       if (proto || proto === null) {
+               return proto;
+       } else if (typeof object.constructor == 'function' && object instanceof object.constructor) {
+    return object.constructor.prototype;
+  } else if (object instanceof Object) {
+               return Object.prototype;
+       } else {
+               // Correctly return null for Objects created with `Object.create(null)`
+               // (shammed or native) or `{ __proto__: null}`.  Also returns null for
+               // cross-realm objects on browsers that lack `__proto__` support (like
+               // IE <11), but that's the best we can do.
+               return null;
+       }
+});
+
+}
+
+
+// _ESAbstract.OrdinaryCreateFromConstructor
+/* global GetPrototypeFromConstructor */
+// 9.1.13. OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
+function OrdinaryCreateFromConstructor(constructor, intrinsicDefaultProto) { // eslint-disable-line no-unused-vars
+       var internalSlotsList = arguments[2] || {};
+       // 1. Assert: intrinsicDefaultProto is a String value that is this specification's name of an intrinsic object.
+       // The corresponding object must be an intrinsic that is intended to be used as the[[Prototype]] value of an object.
+
+       // 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
+       var proto = GetPrototypeFromConstructor(constructor, intrinsicDefaultProto);
+
+       // 3. Return ObjectCreate(proto, internalSlotsList).
+       // Polyfill.io - We do not pass internalSlotsList to Object.create because Object.create does not use the default ordinary object definitions specified in 9.1.
+       var obj = Object.create(proto);
+       for (var name in internalSlotsList) {
+               if (Object.prototype.hasOwnProperty.call(internalSlotsList, name)) {
+                       Object.defineProperty(obj, name, {
+                               configurable: true,
+                               enumerable: false,
+                               writable: true,
+                               value: internalSlotsList[name]
+                       });
+               }
+       }
+       return obj;
+}
+
+// _ESAbstract.Construct
+/* global IsConstructor, OrdinaryCreateFromConstructor, Call */
+// 7.3.13. Construct ( F [ , argumentsList [ , newTarget ]] )
+function Construct(F /* [ , argumentsList [ , newTarget ]] */) { // eslint-disable-line no-unused-vars
+       // 1. If newTarget is not present, set newTarget to F.
+       var newTarget = arguments.length > 2 ? arguments[2] : F;
+
+       // 2. If argumentsList is not present, set argumentsList to a new empty List.
+       var argumentsList = arguments.length > 1 ? arguments[1] : [];
+
+       // 3. Assert: IsConstructor(F) is true.
+       if (!IsConstructor(F)) {
+               throw new TypeError('F must be a constructor.');
+       }
+
+       // 4. Assert: IsConstructor(newTarget) is true.
+       if (!IsConstructor(newTarget)) {
+               throw new TypeError('newTarget must be a constructor.');
+       }
+
+       // 5. Return ? F.[[Construct]](argumentsList, newTarget).
+       // Polyfill.io - If newTarget is the same as F, it is equivalent to new F(...argumentsList).
+       if (newTarget === F) {
+               return new (Function.prototype.bind.apply(F, [null].concat(argumentsList)))();
+       } else {
+               // Polyfill.io - This is mimicking section 9.2.2 step 5.a.
+               var obj = OrdinaryCreateFromConstructor(newTarget, Object.prototype);
+               return Call(F, obj, argumentsList);
+       }
+}
+
+// _ESAbstract.ArraySpeciesCreate
+/* global IsArray, ArrayCreate, Get, Type, IsConstructor, Construct */
+// 9.4.2.3. ArraySpeciesCreate ( originalArray, length )
+function ArraySpeciesCreate(originalArray, length) { // eslint-disable-line no-unused-vars
+       // 1. Assert: length is an integer Number ≥ 0.
+       // 2. If length is -0, set length to +0.
+       if (1/length === -Infinity) {
+               length = 0;
+       }
+
+       // 3. Let isArray be ? IsArray(originalArray).
+       var isArray = IsArray(originalArray);
+
+       // 4. If isArray is false, return ? ArrayCreate(length).
+       if (isArray === false) {
+               return ArrayCreate(length);
+       }
+
+       // 5. Let C be ? Get(originalArray, "constructor").
+       var C = Get(originalArray, 'constructor');
+
+       // Polyfill.io - We skip this section as not sure how to make a cross-realm normal Array, a same-realm Array.
+       // 6. If IsConstructor(C) is true, then
+       // if (IsConstructor(C)) {
+               // a. Let thisRealm be the current Realm Record.
+               // b. Let realmC be ? GetFunctionRealm(C).
+               // c. If thisRealm and realmC are not the same Realm Record, then
+                       // i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
+       // }
+       // 7. If Type(C) is Object, then
+       if (Type(C) === 'object') {
+               // a. Set C to ? Get(C, @@species).
+               C = 'Symbol' in this && 'species' in this.Symbol ? Get(C, this.Symbol.species) : undefined;
+               // b. If C is null, set C to undefined.
+               if (C === null) {
+                       C = undefined;
+               }
+       }
+       // 8. If C is undefined, return ? ArrayCreate(length).
+       if (C === undefined) {
+               return ArrayCreate(length);
+       }
+       // 9. If IsConstructor(C) is false, throw a TypeError exception.
+       if (!IsConstructor(C)) {
+               throw new TypeError('C must be a constructor');
+       }
+       // 10. Return ? Construct(C, « length »).
+       return Construct(C, [length]);
+}
+
+// _ESAbstract.CreateDataProperty
+// 7.3.4. CreateDataProperty ( O, P, V )
+// NOTE
+// This abstract operation creates a property whose attributes are set to the same defaults used for properties created by the ECMAScript language assignment operator.
+// Normally, the property will not already exist. If it does exist and is not configurable or if O is not extensible, [[DefineOwnProperty]] will return false.
+function CreateDataProperty(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let newDesc be the PropertyDescriptor{ [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
+       var newDesc = {
+               value: V,
+               writable: true,
+               enumerable: true,
+               configurable: true
+       };
+       // 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
+       try {
+               Object.defineProperty(O, P, newDesc);
+               return true;
+       } catch (e) {
+               return false;
+       }
+}
+
+// _ESAbstract.CreateDataPropertyOrThrow
+/* global CreateDataProperty */
+// 7.3.6. CreateDataPropertyOrThrow ( O, P, V )
+function CreateDataPropertyOrThrow(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let success be ? CreateDataProperty(O, P, V).
+       var success = CreateDataProperty(O, P, V);
+       // 4. If success is false, throw a TypeError exception.
+       if (!success) {
+               throw new TypeError('Cannot assign value `' + Object.prototype.toString.call(V) + '` to property `' + Object.prototype.toString.call(P) + '` on object `' + Object.prototype.toString.call(O) + '`');
+       }
+       // 5. Return success.
+       return success;
+}
+if (!('filter' in Array.prototype)) {
+
+// Array.prototype.filter
+/* global CreateMethodProperty, ToObject, ToLength, Get, IsCallable, ArraySpeciesCreate, ToString, HasProperty, ToBoolean, Call, CreateDataPropertyOrThrow */
+// 22.1.3.7. Array.prototype.filter ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'filter', function filter(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let A be ? ArraySpeciesCreate(O, 0).
+       var A = ArraySpeciesCreate(O, 0);
+       // 6. Let k be 0.
+       var k = 0;
+       // 7. Let to be 0.
+       var to = 0;
+       // 8. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let selected be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
+                       var selected = ToBoolean(Call(callbackfn, T, [kValue, k, O]));
+                       // iii. If selected is true, then
+                       if (selected) {
+                               // 1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(to), kValue)
+                               CreateDataPropertyOrThrow(A, ToString(to), kValue);
+                               // 2. Increase to by 1.
+                               to = to + 1;
+                       }
+
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 9. Return A.
+       return A;
+});
+
+}
+
+if (!('forEach' in Array.prototype)) {
+
+// Array.prototype.forEach
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+// 22.1.3.10. Array.prototype.forEach ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'forEach', function forEach(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // Polyfill.io - If O is a String object, split it into an array in order to iterate correctly.
+       // We will use arrayLike in place of O when we are iterating through the list.
+       var arraylike = O instanceof String ? O.split('') : O;
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(arraylike, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(arraylike, Pk);
+                       // ii. Perform ? Call(callbackfn, T, « kValue, k, O »).
+                       Call(callbackfn, T, [kValue, k, O]);
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 7. Return undefined.
+       return undefined;
+});
+
+}
+
+if (!('indexOf' in Array.prototype)) {
+
+// Array.prototype.indexOf
+/* global CreateMethodProperty, Get, HasProperty, ToInteger, ToLength, ToObject, ToString */
+// 22.1.3.12. Array.prototype.indexOf ( searchElement [ , fromIndex ] )
+CreateMethodProperty(Array.prototype, 'indexOf', function indexOf(searchElement /* [ , fromIndex ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If len is 0, return -1.
+       if (len === 0) {
+               return -1;
+       }
+       // 4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.)
+       var n = ToInteger(arguments[1]);
+       // 5. If n ≥ len, return -1.
+       if (n >= len) {
+               return -1;
+       }
+       // 6. If n ≥ 0, then
+       if (n >= 0) {
+               // a. If n is -0, let k be +0; else let k be n.
+               var k = n === -0 ? 0 : n;
+               // 7. Else n < 0,
+       } else {
+               // a. Let k be len + n.
+               var k = len + n;
+               // b. If k < 0, let k be 0.
+               if (k < 0) {
+                       k = 0;
+               }
+       }
+       // 8. Repeat, while k < len
+       while (k < len) {
+               // a. Let kPresent be ? HasProperty(O, ! ToString(k)).
+               var kPresent = HasProperty(O, ToString(k));
+               // b. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let elementK be ? Get(O, ! ToString(k)).
+                       var elementK = Get(O, ToString(k));
+                       // ii. Let same be the result of performing Strict Equality Comparison searchElement === elementK.
+                       var same = searchElement === elementK;
+                       // iii. If same is true, return k.
+                       if (same) {
+                               return k;
+                       }
+               }
+               // c. Increase k by 1.
+               k = k + 1;
+       }
+       // 9. Return -1.
+       return -1;
+});
+
+}
+
+if (!('lastIndexOf' in Array.prototype)) {
+
+// Array.prototype.lastIndexOf
+/* global CreateMethodProperty, Get, HasProperty, ToInteger, ToLength, ToObject, ToString */
+// 22.1.3.15. Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
+CreateMethodProperty(Array.prototype, 'lastIndexOf', function lastIndexOf(searchElement /* [ , fromIndex ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If len is 0, return -1.
+       if (len === 0) {
+               return -1;
+       }
+       // 4. If fromIndex is present, let n be ? ToInteger(fromIndex); else let n be len-1.
+       var n = arguments.length > 1 ? ToInteger(arguments[1]) : len - 1;
+       // 5. If n ≥ 0, then
+       if (n >= 0) {
+               // a. If n is -0, let k be +0; else let k be min(n, len - 1).
+               var k = n === -0 ? 0 : Math.min(n, len - 1);
+               // 6. Else n < 0,
+       } else {
+               // a. Let k be len + n.
+               k = len + n;
+       }
+       // 7. Repeat, while k ≥ 0
+       while (k >= 0) {
+               // a. Let kPresent be ? HasProperty(O, ! ToString(k)).
+               var kPresent = HasProperty(O, ToString(k));
+               // b. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let elementK be ? Get(O, ! ToString(k)).
+                       var elementK = Get(O, ToString(k));
+                       // ii. Let same be the result of performing Strict Equality Comparison searchElement === elementK.
+                       var same = searchElement === elementK;
+                       // iii. If same is true, return k.
+                       if (same) {
+                               return k;
+                       }
+               }
+               // c. Decrease k by 1.
+               k = k - 1;
+       }
+       // 9. Return -1.
+       return -1;
+});
+
+}
+
+if (!('map' in Array.prototype)) {
+
+// Array.prototype.map
+/* global ArraySpeciesCreate, Call, CreateDataPropertyOrThrow, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+/* global CreateMethodProperty, ToObject, ToLength, Get, ArraySpeciesCreate, ToString, HasProperty, Call, CreateDataPropertyOrThrow */
+// 22.1.3.16. Array.prototype.map ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'map', function map(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let A be ? ArraySpeciesCreate(O, len).
+       var A = ArraySpeciesCreate(O, len);
+       // 6. Let k be 0.
+       var k = 0;
+       // 7. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let mappedValue be ? Call(callbackfn, T, « kValue, k, O »).
+                       var mappedValue = Call(callbackfn, T, [kValue, k, O]);
+                       // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
+                       CreateDataPropertyOrThrow(A, Pk, mappedValue);
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 8. Return A.
+       return A;
+});
+
+}
+
+if (!('reduce' in Array.prototype)) {
+
+// Array.prototype.reduce
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+// 22.1.3.19. Array.prototype.reduce ( callbackfn [ , initialValue ] )
+CreateMethodProperty(Array.prototype, 'reduce', function reduce(callbackfn /* [ , initialValue ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // Polyfill.io - If O is a String object, split it into an array in order to iterate correctly.
+       // We will use arrayLike in place of O when we are iterating through the list.
+       var arraylike = O instanceof String ? O.split('') : O;
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(arraylike, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If len is 0 and initialValue is not present, throw a TypeError exception.
+       var initialValue = arguments.length > 1 ? arguments[1] : undefined;
+       if (len === 0 && arguments.length < 2) {
+               throw new TypeError('Reduce of empty array with no initial value');
+       }
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Let accumulator be undefined.
+       var accumulator = undefined;
+       // 7. If initialValue is present, then
+       if (arguments.length > 1) {
+               // a. Set accumulator to initialValue.
+               accumulator = initialValue;
+               // 8. Else initialValue is not present,
+       } else {
+               // a. Let kPresent be false.
+               var kPresent = false;
+               // b. Repeat, while kPresent is false and k < len
+               while (kPresent === false && k < len) {
+                       // i. Let Pk be ! ToString(k).
+                       var Pk = ToString(k);
+                       // ii. Let kPresent be ? HasProperty(O, Pk).
+                       var kPresent = HasProperty(arraylike, Pk);
+                       // iii. If kPresent is true, then
+                       if (kPresent) {
+                               // 1. Set accumulator to ? Get(O, Pk).
+                               var accumulator = Get(arraylike, Pk);
+                       }
+                       // iv. Increase k by 1.
+                       k = k + 1;
+               }
+               // c. If kPresent is false, throw a TypeError exception.
+               if (kPresent === false) {
+                       throw new TypeError('Reduce of empty array with no initial value');
+               }
+       }
+       // 9. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(arraylike, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(arraylike, Pk);
+                       // ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, k, O »).
+                       accumulator = Call(callbackfn, undefined, [accumulator, kValue, k, O]);
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 10. Return accumulator.
+       return accumulator;
+});
+
+}
+
+if (!('reduceRight' in Array.prototype)) {
+
+// Array.prototype.reduceRight
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+// 22.1.3.20. Array.prototype.reduceRight ( callbackfn [ , initialValue ] )
+CreateMethodProperty(Array.prototype, 'reduceRight', function reduceRight(callbackfn /* [ , initialValue ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // Polyfill.io - If O is a String object, split it into an array in order to iterate correctly.
+       // We will use arrayLike in place of O when we are iterating through the list.
+       var arraylike = O instanceof String ? O.split('') : O;
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(arraylike, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If len is 0 and initialValue is not present, throw a TypeError exception.
+       var initialValue = arguments.length > 1 ? arguments[1] : undefined;
+       if (len === 0 && arguments.length < 2) {
+               throw new TypeError('Reduce of empty array with no initial value');
+       }
+       // 5. Let k be len-1.
+       var k = len - 1;
+       // 6. Let accumulator be undefined.
+       var accumulator = undefined;
+       // 7. If initialValue is present, then
+       if (arguments.length > 1) {
+               // a. Set accumulator to initialValue.
+               accumulator = initialValue;
+               // 8.Else initialValue is not present,
+       } else {
+               // a. Let kPresent be false.
+               var kPresent = false;
+               // b. Repeat, while kPresent is false and k ≥ 0
+               while (kPresent === false && k >= 0) {
+                       // i. Let Pk be ! ToString(k).
+                       var Pk = ToString(k);
+                       // ii. Let kPresent be ? HasProperty(O, Pk).
+                       var kPresent = HasProperty(arraylike, Pk);
+                       // iii. If kPresent is true, then
+                       if (kPresent) {
+                               // 1. Set accumulator to ? Get(O, Pk).
+                               accumulator = Get(arraylike, Pk);
+                       }
+                       // iv. Decrease k by 1.
+                       k = k - 1;
+               }
+               // c. If kPresent is false, throw a TypeError exception.
+               if (kPresent === false) {
+                       throw new TypeError('Reduce of empty array with no initial value');
+               }
+       }
+       // 9. Repeat, while k ≥ 0
+       while (k >= 0) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(arraylike, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(arraylike, Pk);
+                       // ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, k, O »).
+                       accumulator = Call(callbackfn, undefined, [accumulator, kValue, k, O]);
+               }
+               // d. Decrease k by 1.
+               k = k - 1;
+       }
+       // 10 Return accumulator.
+       return accumulator;
+});
+
+}
+
+if (!('some' in Array.prototype)) {
+
+// Array.prototype.some
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToBoolean, ToLength, ToObject, ToString */
+// 22.1.3.24. Array.prototype.some ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'some', function some(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let testResult be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
+                       var testResult = ToBoolean(Call(callbackfn, T, [kValue, k, O]));
+                       // iii. If testResult is true, return true.
+                       if (testResult) {
+                               return true;
+                       }
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 7. Return false.
+       return false;
+});
+
+}
+
+if (!('Date' in this && 'now' in this.Date && 'getTime' in this.Date.prototype)) {
+
+// Date.now
+Date.now = function now() {
+       return new Date().getTime();
+};
+
+}
+
+if (!('Date' in this && 'toISOString' in Date.prototype)) {
+
+// Date.prototype.toISOString
+Date.prototype.toISOString = function toISOString() {
+       var date = this;
+
+       function pad(str, len) {
+               var pad = "0000";
+               str = '' + str;
+               return pad.substr(0, len - str.length) + str;
+       }
+
+       var y = date.getUTCFullYear(),
+       m = pad(date.getUTCMonth() + 1, 2),
+       d = pad(date.getUTCDate(), 2),
+       h = pad(date.getUTCHours(), 2),
+       i = pad(date.getUTCMinutes(), 2),
+       s = pad(date.getUTCSeconds(), 2),
+       ms = pad(date.getUTCMilliseconds(), 3);
+
+       return y +'-'+ m +'-'+ d + 'T' + h +':'+ i +':'+ s +'.'+ ms +'Z';
+};
+
+}
+
+if (!('freeze' in Object)) {
+
+// Object.freeze
+/* global CreateMethodProperty */
+// 19.1.2.6. Object.freeze ( O )
+CreateMethodProperty(Object, 'freeze', function freeze(O) {
+       // This feature cannot be implemented fully as a polyfill.
+       // We choose to silently fail which allows "securable" code
+       // to "gracefully" degrade to working but insecure code.
+       return O;
+});
+
+}
+
+if (!('getOwnPropertyNames' in Object)) {
+
+// Object.getOwnPropertyNames
+/* global CreateMethodProperty */
+
+var toString = ({}).toString;
+var split = ''.split;
+
+CreateMethodProperty(Object, 'getOwnPropertyNames', function getOwnPropertyNames(object) {
+       var buffer = [];
+       var key;
+
+       // Non-enumerable properties cannot be discovered but can be checked for by name.
+       // Define those used internally by JS to allow an incomplete solution
+       var commonProps = ['length', "name", "arguments", "caller", "prototype", "observe", "unobserve"];
+
+       if (typeof object === 'undefined' || object === null) {
+               throw new TypeError('Cannot convert undefined or null to object');
+       }
+
+       // Polyfill.io fallback for non-array-like strings which exist in some ES3 user-agents (IE 8)
+       object = toString.call(object) == '[object String]' ? split.call(object, '') : Object(object);
+
+       // Enumerable properties only
+       for (key in object) {
+               if (Object.prototype.hasOwnProperty.call(object, key)) {
+                       buffer.push(key);
+               }
+       }
+
+       // Check for and add the common non-enumerable properties
+       for (var i=0, s=commonProps.length; i<s; i++) {
+               if (commonProps[i] in object) buffer.push(commonProps[i]);
+       }
+
+       return buffer;
+});
+
+}
+
+
+// _ESAbstract.RequireObjectCoercible
+// 7.2.1. RequireObjectCoercible ( argument )
+// The abstract operation ToObject converts argument to a value of type Object according to Table 12:
+// Table 12: ToObject Conversions
+/*
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Argument Type | Result                                                                                                                             |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Undefined     | Throw a TypeError exception.                                                                                                       |
+| Null          | Throw a TypeError exception.                                                                                                       |
+| Boolean       | Return argument.                                                                                                                   |
+| Number        | Return argument.                                                                                                                   |
+| String        | Return argument.                                                                                                                   |
+| Symbol        | Return argument.                                                                                                                   |
+| Object        | Return argument.                                                                                                                   |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+*/
+function RequireObjectCoercible(argument) { // eslint-disable-line no-unused-vars
+       if (argument === null || argument === undefined) {
+               throw TypeError();
+       }
+  return argument;
+}
+if (!('trim' in String.prototype)) {
+
+// String.prototype.trim
+/* global CreateMethodProperty, RequireObjectCoercible, ToString */
+// 21.1.3.27. String.prototype.trim ( )
+CreateMethodProperty(String.prototype, 'trim', function trim() {
+       // 1. Let O be ? RequireObjectCoercible(this value).
+       var O = RequireObjectCoercible(this);
+       // 2. Let S be ? ToString(O).
+       var S = ToString(O);
+       // 3. Let T be the String value that is a copy of S with both leading and trailing white space removed. The definition of white space is the union of WhiteSpace and LineTerminator. When determining whether a Unicode code point is in Unicode general category “Space_Separator” (“Zs”), code unit sequences are interpreted as UTF-16 encoded code point sequences as specified in 6.1.4.
+       var T = String.prototype.replace.call(S, /^[\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]+|[\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]+$/g, '');
+       // 4. Return T.
+       return T;
+});
+
+}
+
+})
+.call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
diff --git a/vendor/assets/polyfill/es6.js b/vendor/assets/polyfill/es6.js
new file mode 100644 (file)
index 0000000..ae2436e
--- /dev/null
@@ -0,0 +1,6658 @@
+/* Polyfill service v3.27.1
+ * For detailed credits and licence information see https://github.com/financial-times/polyfill-service.
+ * 
+ * Features requested: es6
+ * 
+ * - _ESAbstract.IsCallable, License: CC0 (required by "Array.from", "es6", "Array.prototype.find", "Array.prototype.findIndex", "Map", "Set", "WeakMap", "WeakSet", "_ESAbstract.GetMethod", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map", "Function.prototype.bind", "_ESAbstract.Construct", "Array.of", "Object.getOwnPropertyDescriptor", "Object.assign", "_ESAbstract.OrdinaryToPrimitive", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.fill", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith")
+ * - Object.defineProperty, License: CC0 (required by "Function.name", "es6", "Map", "Array.from", "Number.Epsilon", "Number.MAX_SAFE_INTEGER", "Number.MIN_SAFE_INTEGER", "Object.setPrototypeOf", "RegExp.prototype.flags", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Symbol", "WeakMap", "WeakSet", "_ESAbstract.CreateMethodProperty", "Array.of", "Array.prototype.copyWithin", "Array.prototype.entries", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "Array.prototype.keys", "Array.prototype.values", "Math.acosh", "Math.asinh", "Math.atanh", "Math.cbrt", "Math.clz32", "Math.cosh", "Math.expm1", "Math.fround", "Math.hypot", "Math.imul", "Math.log10", "Math.log1p", "Math.log2", "Math.sign", "Math.sinh", "Math.tanh", "Math.trunc", "Number.isFinite", "Number.isInteger", "Number.isNaN", "Number.isSafeInteger", "Number.parseFloat", "Number.parseInt", "Object.assign", "Object.is", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "_ArrayIterator", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_StringIterator", "_ESAbstract.CreateDataProperty", "_ESAbstract.CreateDataPropertyOrThrow", "_ESAbstract.CreateIterResultObject", "_Iterator", "Object.defineProperties", "Object.create", "_ESAbstract.GetIterator")
+ * - _ESAbstract.CreateMethodProperty, License: CC0 (required by "Array.from", "es6", "Array.of", "Array.prototype.@@iterator", "Array.prototype.copyWithin", "Array.prototype.entries", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "Array.prototype.keys", "Array.prototype.values", "Map", "Math.acosh", "Math.asinh", "Math.atanh", "Math.cbrt", "Math.clz32", "Math.cosh", "Math.expm1", "Math.fround", "Math.hypot", "Math.imul", "Math.log10", "Math.log1p", "Math.log2", "Math.sign", "Math.sinh", "Math.tanh", "Math.trunc", "Number.isFinite", "Number.isInteger", "Number.isNaN", "Number.isSafeInteger", "Number.parseFloat", "Number.parseInt", "Object.assign", "Object.is", "Object.setPrototypeOf", "Set", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "WeakMap", "WeakSet", "Array.isArray", "Object.create", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_ESAbstract.GetIterator", "_ArrayIterator", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Object.getOwnPropertyDescriptor", "Array.prototype.forEach", "Object.getPrototypeOf", "Object.getOwnPropertyNames", "Array.prototype.filter", "Array.prototype.map", "Object.freeze", "Function.prototype.bind", "Object.defineProperties", "_Iterator", "_StringIterator")
+ * - _ESAbstract.ToObject, License: CC0 (required by "Array.from", "es6", "Array.prototype.entries", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator", "Object.assign", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map", "_ESAbstract.GetV", "_ESAbstract.GetMethod", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "Object.defineProperties", "Object.create", "_ArrayIterator", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "_Iterator", "_StringIterator")
+ * - _ESAbstract.GetV, License: CC0 (required by "_ESAbstract.GetMethod", "Array.from", "es6", "Map", "Set", "_ESAbstract.GetIterator", "WeakMap", "WeakSet")
+ * - _ESAbstract.GetMethod, License: CC0 (required by "Array.from", "es6", "Map", "Set", "_ESAbstract.IsConstructor", "Array.of", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "_ESAbstract.IteratorClose", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith")
+ * - _ESAbstract.ToInteger, License: CC0 (required by "Array.prototype.copyWithin", "es6", "Array.prototype.fill", "Number.isInteger", "Number.isSafeInteger", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "_ESAbstract.ToLength", "Array.from", "Array.prototype.find", "Array.prototype.findIndex")
+ * - _ESAbstract.ToLength, License: CC0 (required by "Array.from", "es6", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map")
+ * - _ESAbstract.Get, License: CC0 (required by "Array.from", "es6", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "Object.assign", "RegExp.prototype.flags", "WeakMap", "WeakSet", "_ESAbstract.IteratorValue", "Map", "Set", "_ESAbstract.IteratorComplete", "_ESAbstract.IteratorStep", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_ESAbstract.IsRegExp", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.startsWith", "Array.prototype.filter", "Array.prototype.map", "_ESAbstract.GetPrototypeFromConstructor", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "Object.defineProperties", "Object.create", "_ESAbstract.GetIterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_Iterator", "_StringIterator", "_ESAbstract.ArraySpeciesCreate", "_ESAbstract.OrdinaryToPrimitive", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "String.prototype.codePointAt", "String.prototype.repeat")
+ * - _ESAbstract.HasProperty, License: CC0 (required by "Array.prototype.copyWithin", "es6", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map")
+ * - _ESAbstract.Call, License: CC0 (required by "Array.from", "es6", "Array.prototype.find", "Array.prototype.findIndex", "WeakMap", "WeakSet", "_ESAbstract.GetIterator", "Map", "Set", "_ESAbstract.IteratorClose", "_ESAbstract.IteratorNext", "_ESAbstract.IteratorStep", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map", "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.of", "Array.prototype.fill", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "_ESAbstract.OrdinaryToPrimitive")
+ * - _ESAbstract.Type, License: CC0 (required by "Map", "es6", "Array.from", "Number.isFinite", "Number.isInteger", "Number.isNaN", "Number.isSafeInteger", "RegExp.prototype.flags", "WeakMap", "WeakSet", "_ESAbstract.IsConstructor", "Array.of", "_ESAbstract.GetIterator", "Set", "_ESAbstract.IteratorClose", "_ESAbstract.ToString", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "_ESAbstract.IteratorValue", "_ESAbstract.CreateIterResultObject", "_ESAbstract.IteratorComplete", "_ESAbstract.IteratorStep", "_ESAbstract.IteratorNext", "_ESAbstract.SameValueZero", "Object.create", "Object.setPrototypeOf", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "_ESAbstract.SameValue", "Object.is", "_ESAbstract.IsRegExp", "_ESAbstract.ToPrimitive", "_ESAbstract.GetPrototypeFromConstructor", "Object.defineProperties", "_Iterator", "_StringIterator", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Array.prototype.map", "_ESAbstract.OrdinaryToPrimitive")
+ * - _ESAbstract.OrdinaryToPrimitive, License: CC0 (required by "_ESAbstract.ToPrimitive", "_ESAbstract.ToString", "Array.from", "es6", "Array.of", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith")
+ * - _ESAbstract.ToPrimitive, License: CC0 (required by "_ESAbstract.ToString", "Array.from", "es6", "Array.of", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith")
+ * - _ESAbstract.ToString, License: CC0 (required by "Array.from", "es6", "Array.of", "Array.prototype.fill", "Array.prototype.find", "Array.prototype.findIndex", "String.prototype.@@iterator", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith", "Array.prototype.forEach", "Object.setPrototypeOf", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.filter", "Array.prototype.map")
+ * - Array.prototype.forEach, License: CC0 (required by "Object.setPrototypeOf", "es6", "Symbol", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - _ESAbstract.IsArray, License: CC0 (required by "WeakMap", "es6", "WeakSet", "Array.isArray", "Map", "Array.from", "Set", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - _ESAbstract.ArrayCreate, License: CC0 (required by "Array.from", "es6", "Array.of", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - _ESAbstract.IsConstructor, License: CC0 (required by "Array.from", "es6", "Array.of", "_ESAbstract.Construct", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - _ESAbstract.GetPrototypeFromConstructor, License: CC0 (required by "_ESAbstract.OrdinaryCreateFromConstructor", "Map", "es6", "Array.from", "Set", "WeakMap", "WeakSet", "_ESAbstract.Construct", "Array.of")
+ * - Object.keys, License: MIT (required by "Object.assign", "es6", "Symbol", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Object.defineProperties", "Object.create", "Object.setPrototypeOf", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "_Iterator", "_StringIterator")
+ * - Function.prototype.bind, License: MIT (required by "_ESAbstract.Construct", "Array.from", "es6", "Array.of", "Object.getOwnPropertyDescriptor", "Object.assign", "Object.setPrototypeOf", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_Iterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_StringIterator")
+ * - Object.getOwnPropertyDescriptor, License: CC0 (required by "Object.assign", "es6", "Object.setPrototypeOf", "Symbol", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Object.defineProperties", "Object.create", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "_Iterator", "_StringIterator")
+ * - Object.defineProperties, License: CC0 (required by "Object.create", "Map", "es6", "Array.from", "Object.setPrototypeOf", "Set", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "_Iterator", "_StringIterator")
+ * - Object.create, License: CC0 (required by "Map", "es6", "Array.from", "Object.setPrototypeOf", "Set", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "_ESAbstract.GetIterator", "WeakMap", "WeakSet", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_ESAbstract.OrdinaryCreateFromConstructor", "_ESAbstract.Construct", "Array.of", "_StringIterator")
+ * - Object.getPrototypeOf, License: CC0 (required by "Object.setPrototypeOf", "es6", "_ESAbstract.OrdinaryCreateFromConstructor", "Map", "Array.from", "Set", "WeakMap", "WeakSet", "_ESAbstract.Construct", "Array.of")
+ * - _ESAbstract.OrdinaryCreateFromConstructor, License: CC0 (required by "Map", "es6", "Array.from", "Set", "WeakMap", "WeakSet", "_ESAbstract.Construct", "Array.of")
+ * - _ESAbstract.Construct, License: CC0 (required by "Array.from", "es6", "Array.of", "_ESAbstract.ArraySpeciesCreate", "Array.prototype.filter", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - _ESAbstract.ArraySpeciesCreate, License: CC0 (required by "Array.prototype.filter", "Symbol", "es6", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - _ESAbstract.ToBoolean, License: CC0 (required by "Array.prototype.find", "es6", "Array.prototype.findIndex", "RegExp.prototype.flags", "_ESAbstract.IteratorComplete", "Map", "Array.from", "Set", "_ESAbstract.IteratorStep", "WeakMap", "WeakSet", "_ESAbstract.IsRegExp", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.startsWith", "Array.prototype.filter", "Symbol", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - _ESAbstract.CreateDataProperty, License: CC0 (required by "_ESAbstract.CreateDataPropertyOrThrow", "Array.from", "es6", "Array.of", "_ESAbstract.CreateIterResultObject", "Map", "Set")
+ * - _ESAbstract.CreateDataPropertyOrThrow, License: CC0 (required by "Array.from", "es6", "Array.of", "Array.prototype.filter", "Symbol", "Map", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "Array.prototype.map")
+ * - Array.prototype.filter, License: CC0 (required by "Symbol", "es6", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - Array.prototype.map, License: CC0 (required by "Symbol", "es6", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - Object.getOwnPropertyNames, License: CC0 (required by "Object.setPrototypeOf", "es6", "Symbol", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - Object.freeze, License: CC0 (required by "Symbol", "es6", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables")
+ * - Symbol, License: MIT (required by "es6", "Map", "Array.from", "Set", "Symbol.hasInstance", "Symbol.isConcatSpreadable", "Symbol.iterator", "Array.prototype.@@iterator", "String.prototype.@@iterator", "Symbol.match", "Symbol.replace", "Symbol.search", "Symbol.species", "Symbol.split", "Symbol.toPrimitive", "Symbol.toStringTag", "Symbol.unscopables", "WeakMap", "WeakSet", "_Iterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_StringIterator")
+ * - Symbol.iterator, License: MIT (required by "es6", "Array.from", "Array.prototype.@@iterator", "Map", "Set", "String.prototype.@@iterator", "_Iterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "_StringIterator")
+ * - _ESAbstract.GetIterator, License: CC0 (required by "Array.from", "es6", "Map", "Set", "WeakMap", "WeakSet")
+ * - _ESAbstract.IteratorClose, License: CC0 (required by "Array.from", "es6", "Map", "Set", "WeakMap", "WeakSet")
+ * - _ESAbstract.IteratorNext, License: CC0 (required by "Map", "es6", "Array.from", "Set", "_ESAbstract.IteratorStep", "WeakMap", "WeakSet")
+ * - _ESAbstract.IteratorComplete, License: CC0 (required by "Map", "es6", "Array.from", "Set", "_ESAbstract.IteratorStep", "WeakMap", "WeakSet")
+ * - _ESAbstract.IteratorStep, License: CC0 (required by "Array.from", "es6", "Map", "Set", "WeakMap", "WeakSet")
+ * - _ESAbstract.IteratorValue, License: CC0 (required by "Array.from", "es6", "Map", "Set", "WeakMap", "WeakSet")
+ * - _ESAbstract.CreateIterResultObject, License: CC0 (required by "Map", "es6", "Array.from", "Set")
+ * - _ESAbstract.SameValueNonNumber, License: CC0 (required by "_ESAbstract.SameValueZero", "Map", "es6", "Array.from", "Set", "WeakSet", "_ESAbstract.SameValue", "Object.is", "WeakMap")
+ * - _ESAbstract.SameValueZero, License: CC0 (required by "Map", "es6", "Array.from", "Set", "WeakSet")
+ * - Array.isArray, License: CC0 (required by "Map", "es6", "Array.from", "Set", "WeakMap")
+ * - Symbol.species, License: MIT (required by "es6", "Map", "Array.from", "Set")
+ * - Map, License: CC0 (required by "es6", "Array.from")
+ * - Set, License: CC0 (required by "es6", "Array.from")
+ * - Array.from, License: CC0 (required by "es6")
+ * - Array.of, License: CC0 (required by "es6")
+ * - Object.assign, License: CC0 (required by "es6", "_Iterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator", "_StringIterator", "String.prototype.@@iterator")
+ * - Symbol.toStringTag, License: MIT (required by "es6", "_Iterator", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator", "_StringIterator", "String.prototype.@@iterator")
+ * - _Iterator, License: MIT (required by "_ArrayIterator", "Array.prototype.entries", "es6", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator", "_StringIterator", "String.prototype.@@iterator")
+ * - Object.setPrototypeOf, License: MIT (required by "es6", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator", "_StringIterator", "String.prototype.@@iterator")
+ * - _ESAbstract.RequireObjectCoercible, License: CC0 (required by "String.prototype.@@iterator", "es6", "String.prototype.codePointAt", "String.prototype.endsWith", "String.prototype.includes", "String.prototype.repeat", "String.prototype.startsWith")
+ * - _ESAbstract.IsRegExp, License: CC0 (required by "String.prototype.endsWith", "es6", "String.prototype.includes", "String.prototype.startsWith")
+ * - String.prototype.includes, License: CC0 (required by "es6", "_ArrayIterator", "Array.prototype.entries", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator")
+ * - _ArrayIterator, License: MIT (required by "Array.prototype.entries", "es6", "Array.prototype.keys", "Array.prototype.values", "Array.prototype.@@iterator")
+ * - Array.prototype.values, License: MIT (required by "es6", "Array.prototype.@@iterator")
+ * - Array.prototype.@@iterator, License: CC0 (required by "es6")
+ * - Array.prototype.copyWithin, License: MIT (required by "es6")
+ * - Array.prototype.entries, License: CC0 (required by "es6")
+ * - Array.prototype.fill, License: CC0 (required by "es6")
+ * - Array.prototype.find, License: CC0 (required by "es6")
+ * - Array.prototype.findIndex, License: CC0 (required by "es6")
+ * - Array.prototype.keys, License: CC0 (required by "es6")
+ * - Function.name, License: MIT (required by "es6")
+ * - Math.acosh, License: CC0 (required by "es6")
+ * - Math.asinh, License: CC0 (required by "es6")
+ * - Math.atanh, License: CC0 (required by "es6")
+ * - Math.cbrt, License: CC0 (required by "es6")
+ * - _ESAbstract.ToUint32, License: CC0 (required by "Math.clz32", "es6", "Math.imul")
+ * - Math.clz32, License: CC0 (required by "es6")
+ * - Math.cosh, License: CC0 (required by "es6")
+ * - Math.expm1, License: CC0 (required by "es6")
+ * - _TypedArray, License: Copyright 2010, Linden Research, Inc. Copyright 2014, Joshua Bell. (required by "Math.fround", "es6")
+ * - Math.fround, License: CC0 (required by "es6")
+ * - Math.hypot, License: CC0 (required by "es6")
+ * - Math.imul, License: CC0 (required by "es6")
+ * - Math.log10, License: CC0 (required by "es6")
+ * - Math.log1p, License: CC0 (required by "es6")
+ * - Math.log2, License: CC0 (required by "es6")
+ * - Math.sign, License: CC0 (required by "es6")
+ * - Math.sinh, License: CC0 (required by "es6")
+ * - Math.tanh, License: CC0 (required by "es6")
+ * - Math.trunc, License: CC0 (required by "es6")
+ * - Number.Epsilon, License: MIT (required by "es6")
+ * - Number.MAX_SAFE_INTEGER, License: MIT (required by "es6")
+ * - Number.MIN_SAFE_INTEGER, License: MIT (required by "es6")
+ * - Number.isFinite, License: MIT (required by "es6")
+ * - Number.isInteger, License: MIT (required by "es6")
+ * - Number.isNaN, License: MIT (required by "es6")
+ * - Number.isSafeInteger, License: MIT (required by "es6")
+ * - Number.parseFloat, License: MIT (required by "es6")
+ * - Number.parseInt, License: MIT (required by "es6")
+ * - _ESAbstract.SameValue, License: CC0 (required by "Object.is", "es6", "WeakMap")
+ * - Object.is, License: CC0 (required by "es6")
+ * - Promise, License: MIT (required by "es6")
+ * - RegExp.prototype.flags, License: MIT (required by "es6")
+ * - _StringIterator, License: MIT (required by "String.prototype.@@iterator", "es6")
+ * - String.prototype.@@iterator, License: CC0 (required by "es6")
+ * - _ESAbstract.UTF16Decode, License: CC0 (required by "String.prototype.codePointAt", "es6")
+ * - String.prototype.codePointAt, License: MIT (required by "es6")
+ * - String.prototype.endsWith, License: CC0 (required by "es6")
+ * - String.prototype.repeat, License: CC0 (required by "es6")
+ * - String.prototype.startsWith, License: CC0 (required by "es6")
+ * - Symbol.hasInstance, License: MIT (required by "es6")
+ * - Symbol.isConcatSpreadable, License: MIT (required by "es6")
+ * - Symbol.match, License: MIT (required by "es6")
+ * - Symbol.replace, License: MIT (required by "es6")
+ * - Symbol.search, License: MIT (required by "es6")
+ * - Symbol.split, License: MIT (required by "es6")
+ * - Symbol.toPrimitive, License: MIT (required by "es6")
+ * - Symbol.unscopables, License: MIT (required by "es6")
+ * - WeakMap, License: CC0 (required by "es6")
+ * - WeakSet, License: CC0 (required by "es6") */
+
+(function(undefined) {
+
+// _ESAbstract.IsCallable
+// 7.2.3. IsCallable ( argument )
+function IsCallable(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       // 2. If argument has a [[Call]] internal method, return true.
+       // 3. Return false.
+
+       // Polyfill.io - Only function objects have a [[Call]] internal method. This means we can simplify this function to check that the argument has a type of function.
+       return typeof argument === 'function';
+}
+if (!(// In IE8, defineProperty could only act on DOM elements, so full support
+// for the feature requires the ability to set a property on an arbitrary object
+'defineProperty' in Object && (function() {
+       try {
+               var a = {};
+               Object.defineProperty(a, 'test', {value:42});
+               return true;
+       } catch(e) {
+               return false
+       }
+}()))) {
+
+// Object.defineProperty
+(function (nativeDefineProperty) {
+
+       var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__');
+       var ERR_ACCESSORS_NOT_SUPPORTED = 'Getters & setters cannot be defined on this javascript engine';
+       var ERR_VALUE_ACCESSORS = 'A property cannot both have accessors and be writable or have a value';
+
+       // Polyfill.io - This does not use CreateMethodProperty because our CreateMethodProperty function uses Object.defineProperty.
+       Object['defineProperty'] = function defineProperty(object, property, descriptor) {
+
+               // Where native support exists, assume it
+               if (nativeDefineProperty && (object === window || object === document || object === Element.prototype || object instanceof Element)) {
+                       return nativeDefineProperty(object, property, descriptor);
+               }
+
+               if (object === null || !(object instanceof Object || typeof object === 'object')) {
+                       throw new TypeError('Object.defineProperty called on non-object');
+               }
+
+               if (!(descriptor instanceof Object)) {
+                       throw new TypeError('Property description must be an object');
+               }
+
+               var propertyString = String(property);
+               var hasValueOrWritable = 'value' in descriptor || 'writable' in descriptor;
+               var getterType = 'get' in descriptor && typeof descriptor.get;
+               var setterType = 'set' in descriptor && typeof descriptor.set;
+
+               // handle descriptor.get
+               if (getterType) {
+                       if (getterType !== 'function') {
+                               throw new TypeError('Getter must be a function');
+                       }
+                       if (!supportsAccessors) {
+                               throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
+                       }
+                       if (hasValueOrWritable) {
+                               throw new TypeError(ERR_VALUE_ACCESSORS);
+                       }
+                       Object.__defineGetter__.call(object, propertyString, descriptor.get);
+               } else {
+                       object[propertyString] = descriptor.value;
+               }
+
+               // handle descriptor.set
+               if (setterType) {
+                       if (setterType !== 'function') {
+                               throw new TypeError('Setter must be a function');
+                       }
+                       if (!supportsAccessors) {
+                               throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
+                       }
+                       if (hasValueOrWritable) {
+                               throw new TypeError(ERR_VALUE_ACCESSORS);
+                       }
+                       Object.__defineSetter__.call(object, propertyString, descriptor.set);
+               }
+
+               // OK to define value unconditionally - if a getter has been specified as well, an error would be thrown above
+               if ('value' in descriptor) {
+                       object[propertyString] = descriptor.value;
+               }
+
+               return object;
+       };
+}(Object.defineProperty));
+
+}
+
+
+// _ESAbstract.CreateMethodProperty
+// 7.3.5. CreateMethodProperty ( O, P, V )
+function CreateMethodProperty(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let newDesc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
+       var newDesc = {
+               value: V,
+               writable: true,
+               enumerable: false,
+               configurable: true
+       };
+       // 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
+       Object.defineProperty(O, P, newDesc);
+}
+
+// _ESAbstract.ToObject
+// 7.1.13 ToObject ( argument )
+// The abstract operation ToObject converts argument to a value of type Object according to Table 12:
+// Table 12: ToObject Conversions
+/*
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Argument Type | Result                                                                                                                             |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Undefined     | Throw a TypeError exception.                                                                                                       |
+| Null          | Throw a TypeError exception.                                                                                                       |
+| Boolean       | Return a new Boolean object whose [[BooleanData]] internal slot is set to argument. See 19.3 for a description of Boolean objects. |
+| Number        | Return a new Number object whose [[NumberData]] internal slot is set to argument. See 20.1 for a description of Number objects.    |
+| String        | Return a new String object whose [[StringData]] internal slot is set to argument. See 21.1 for a description of String objects.    |
+| Symbol        | Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 19.4 for a description of Symbol objects.    |
+| Object        | Return argument.                                                                                                                   |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+*/
+function ToObject(argument) { // eslint-disable-line no-unused-vars
+       if (argument === null || argument === undefined) {
+               throw TypeError();
+       }
+  return Object(argument);
+}
+
+// _ESAbstract.GetV
+/* global ToObject */
+// 7.3.2 GetV (V, P)
+function GetV(v, p) { // eslint-disable-line no-unused-vars
+       // 1. Assert: IsPropertyKey(P) is true.
+       // 2. Let O be ? ToObject(V).
+       var o = ToObject(v);
+       // 3. Return ? O.[[Get]](P, V).
+       return o[p];
+}
+
+// _ESAbstract.GetMethod
+/* global GetV, IsCallable */
+// 7.3.9. GetMethod ( V, P )
+function GetMethod(V, P) { // eslint-disable-line no-unused-vars
+       // 1. Assert: IsPropertyKey(P) is true.
+       // 2. Let func be ? GetV(V, P).
+       var func = GetV(V, P);
+       // 3. If func is either undefined or null, return undefined.
+       if (func === null || func === undefined) {
+               return undefined;
+       }
+       // 4. If IsCallable(func) is false, throw a TypeError exception.
+       if (IsCallable(func) === false) {
+               throw new TypeError('Method not callable: ' + P);
+       }
+       // 5. Return func.
+       return func;
+}
+
+// _ESAbstract.ToInteger
+// 7.1.4. ToInteger ( argument )
+function ToInteger(argument) { // eslint-disable-line no-unused-vars
+       // 1. Let number be ? ToNumber(argument).
+       var number = Number(argument);
+       // 2. If number is NaN, return +0.
+       if (isNaN(number)) {
+               return 0;
+       }
+       // 3. If number is +0, -0, +∞, or -∞, return number.
+       if (1/number === Infinity || 1/number === -Infinity || number === Infinity || number === -Infinity) {
+               return number;
+       }
+       // 4. Return the number value that is the same sign as number and whose magnitude is floor(abs(number)).
+       return ((number < 0) ? -1 : 1) * Math.floor(Math.abs(number));
+}
+
+// _ESAbstract.ToLength
+/* global ToInteger */
+// 7.1.15. ToLength ( argument )
+function ToLength(argument) { // eslint-disable-line no-unused-vars
+       // 1. Let len be ? ToInteger(argument).
+       var len = ToInteger(argument);
+       // 2. If len ≤ +0, return +0.
+       if (len <= 0) {
+               return 0;
+       }
+       // 3. Return min(len, 253-1).
+       return Math.min(len, Math.pow(2, 53) -1);
+}
+
+// _ESAbstract.Get
+// 7.3.1. Get ( O, P )
+function Get(O, P) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Return ? O.[[Get]](P, O).
+       return O[P];
+}
+
+// _ESAbstract.HasProperty
+// 7.3.10. HasProperty ( O, P )
+function HasProperty(O, P) { // eslint-disable-line no-unused-vars
+       // Assert: Type(O) is Object.
+       // Assert: IsPropertyKey(P) is true.
+       // Return ? O.[[HasProperty]](P).
+       return P in O;
+}
+
+// _ESAbstract.Call
+/* global IsCallable */
+// 7.3.12. Call ( F, V [ , argumentsList ] )
+function Call(F, V /* [, argumentsList] */) { // eslint-disable-line no-unused-vars
+       // 1. If argumentsList is not present, set argumentsList to a new empty List.
+       var argumentsList = arguments.length > 2 ? arguments[2] : [];
+       // 2. If IsCallable(F) is false, throw a TypeError exception.
+       if (IsCallable(F) === false) {
+               throw new TypeError(Object.prototype.toString.call(F) + 'is not a function.');
+       }
+       // 3. Return ? F.[[Call]](V, argumentsList).
+       return F.apply(V, argumentsList);
+}
+
+// _ESAbstract.Type
+// "Type(x)" is used as shorthand for "the type of x"...
+function Type(x) { // eslint-disable-line no-unused-vars
+       switch (typeof x) {
+               case 'undefined':
+                       return 'undefined';
+               case 'boolean':
+                       return 'boolean';
+               case 'number':
+                       return 'number';
+               case 'string':
+                       return 'string';
+               case 'symbol':
+                       return 'symbol';
+               default:
+                       // typeof null is 'object'
+                       if (x === null) return 'null';
+                       // Polyfill.io - This is here because a Symbol polyfill will have a typeof `object`.
+                       if ('Symbol' in this && x instanceof this.Symbol) return 'symbol';
+                       return 'object';
+       }
+}
+
+// _ESAbstract.OrdinaryToPrimitive
+/* global Get, IsCallable, Call, Type */
+// 7.1.1.1. OrdinaryToPrimitive ( O, hint )
+function OrdinaryToPrimitive(O, hint) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: Type(hint) is String and its value is either "string" or "number".
+       // 3. If hint is "string", then
+       if (hint === 'string') {
+               // a. Let methodNames be « "toString", "valueOf" ».
+               var methodNames = ['toString', 'valueOf'];
+               // 4. Else,
+       } else {
+               // a. Let methodNames be « "valueOf", "toString" ».
+               methodNames = ['valueOf', 'toString'];
+       }
+       // 5. For each name in methodNames in List order, do
+       for (var i = 0; i < methodNames.length; ++i) {
+               var name = methodNames[i];
+               // a. Let method be ? Get(O, name).
+               var method = Get(O, name);
+               // b. If IsCallable(method) is true, then
+               if (IsCallable(method)) {
+                       // i. Let result be ? Call(method, O).
+                       var result = Call(method, O);
+                       // ii. If Type(result) is not Object, return result.
+                       if (Type(result) !== 'object') {
+                               return result;
+                       }
+               }
+       }
+       // 6. Throw a TypeError exception.
+       throw new TypeError('Cannot convert to primitive.');
+}
+
+// _ESAbstract.ToPrimitive
+/* global Type, GetMethod, Call, OrdinaryToPrimitive */
+// 7.1.1. ToPrimitive ( input [ , PreferredType ] )
+function ToPrimitive(input /* [, PreferredType] */) { // eslint-disable-line no-unused-vars
+       var PreferredType = arguments.length > 1 ? arguments[1] : undefined;
+       // 1. Assert: input is an ECMAScript language value.
+       // 2. If Type(input) is Object, then
+       if (Type(input) === 'object') {
+               // a. If PreferredType is not present, let hint be "default".
+               if (arguments.length < 2) {
+                       var hint = 'default';
+                       // b. Else if PreferredType is hint String, let hint be "string".
+               } else if (PreferredType === String) {
+                       hint = 'string';
+                       // c. Else PreferredType is hint Number, let hint be "number".
+               } else if (PreferredType === Number) {
+                       hint = 'number';
+               }
+               // d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+               var exoticToPrim = typeof this.Symbol === 'function' && typeof this.Symbol.toPrimitive === 'symbol' ? GetMethod(input, this.Symbol.toPrimitive) : undefined;
+               // e. If exoticToPrim is not undefined, then
+               if (exoticToPrim !== undefined) {
+                       // i. Let result be ? Call(exoticToPrim, input, « hint »).
+                       var result = Call(exoticToPrim, input, [hint]);
+                       // ii. If Type(result) is not Object, return result.
+                       if (Type(result) !== 'object') {
+                               return result;
+                       }
+                       // iii. Throw a TypeError exception.
+                       throw new TypeError('Cannot convert exotic object to primitive.');
+               }
+               // f. If hint is "default", set hint to "number".
+               if (hint === 'default') {
+                       hint = 'number';
+               }
+               // g. Return ? OrdinaryToPrimitive(input, hint).
+               return OrdinaryToPrimitive(input, hint);
+       }
+       // 3. Return input
+       return input;
+}
+
+// _ESAbstract.ToString
+/* global Type, ToPrimitive */
+// 7.1.12. ToString ( argument )
+// The abstract operation ToString converts argument to a value of type String according to Table 11:
+// Table 11: ToString Conversions
+/*
+|---------------|--------------------------------------------------------|
+| Argument Type | Result                                                 |
+|---------------|--------------------------------------------------------|
+| Undefined     | Return "undefined".                                    |
+|---------------|--------------------------------------------------------|
+| Null         | Return "null".                                         |
+|---------------|--------------------------------------------------------|
+| Boolean       | If argument is true, return "true".                    |
+|               | If argument is false, return "false".                  |
+|---------------|--------------------------------------------------------|
+| Number        | Return NumberToString(argument).                       |
+|---------------|--------------------------------------------------------|
+| String        | Return argument.                                       |
+|---------------|--------------------------------------------------------|
+| Symbol        | Throw a TypeError exception.                           |
+|---------------|--------------------------------------------------------|
+| Object        | Apply the following steps:                             |
+|               | Let primValue be ? ToPrimitive(argument, hint String). |
+|               | Return ? ToString(primValue).                          |
+|---------------|--------------------------------------------------------|
+*/
+function ToString(argument) { // eslint-disable-line no-unused-vars
+       switch(Type(argument)) {
+               case 'symbol':
+                       throw new TypeError('Cannot convert a Symbol value to a string');
+                       break;
+               case 'object':
+                       var primValue = ToPrimitive(argument, 'string');
+                       return ToString(primValue);
+               default:
+                       return String(argument);
+       }
+}
+if (!('forEach' in Array.prototype)) {
+
+// Array.prototype.forEach
+/* global Call, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+// 22.1.3.10. Array.prototype.forEach ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'forEach', function forEach(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // Polyfill.io - If O is a String object, split it into an array in order to iterate correctly.
+       // We will use arrayLike in place of O when we are iterating through the list.
+       var arraylike = O instanceof String ? O.split('') : O;
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(arraylike, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(arraylike, Pk);
+                       // ii. Perform ? Call(callbackfn, T, « kValue, k, O »).
+                       Call(callbackfn, T, [kValue, k, O]);
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 7. Return undefined.
+       return undefined;
+});
+
+}
+
+
+// _ESAbstract.IsArray
+// 7.2.2. IsArray ( argument )
+function IsArray(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       // 2. If argument is an Array exotic object, return true.
+       // 3. If argument is a Proxy exotic object, then
+               // a. If argument.[[ProxyHandler]] is null, throw a TypeError exception.
+               // b. Let target be argument.[[ProxyTarget]].
+               // c. Return ? IsArray(target).
+       // 4. Return false.
+
+       // Polyfill.io - We can skip all the above steps and check the string returned from Object.prototype.toString().
+       return Object.prototype.toString.call(argument) === '[object Array]';
+}
+
+// _ESAbstract.ArrayCreate
+// 9.4.2.2. ArrayCreate ( length [ , proto ] )
+function ArrayCreate(length /* [, proto] */) { // eslint-disable-line no-unused-vars
+       // 1. Assert: length is an integer Number ≥ 0.
+       // 2. If length is -0, set length to +0.
+       if (1 / length === -Infinity) {
+               length = 0;
+       }
+       // 3. If length>2^32-1, throw a RangeError exception.
+       if (length > (Math.pow(2, 32) - 1)) {
+               throw new RangeError('Invalid array length');
+       }
+       // 4. If proto is not present, set proto to the intrinsic object %ArrayPrototype%.
+       // 5. Let A be a newly created Array exotic object.
+       var A = [];
+       // 6. Set A's essential internal methods except for [[DefineOwnProperty]] to the default ordinary object definitions specified in 9.1.
+       // 7. Set A.[[DefineOwnProperty]] as specified in 9.4.2.1.
+       // 8. Set A.[[Prototype]] to proto.
+       // 9. Set A.[[Extensible]] to true.
+       // 10. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
+       A.length = length;
+       // 11. Return A.
+       return A;
+}
+
+// _ESAbstract.IsConstructor
+/* global Type */
+// 7.2.4. IsConstructor ( argument )
+function IsConstructor(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       if (Type(argument) !== 'object') {
+               return false;
+       }
+       // 2. If argument has a [[Construct]] internal method, return true.
+       // 3. Return false.
+
+       // Polyfill.io - `new argument` is the only way  to truly test if a function is a constructor.
+       // We choose to not use`new argument` because the argument could have side effects when called.
+       // Instead we check to see if the argument is a function and if it has a prototype.
+       // Arrow functions do not have a [[Construct]] internal method, nor do they have a prototype.
+       return typeof argument === 'function' && !!argument.prototype;
+}
+
+// _ESAbstract.GetPrototypeFromConstructor
+/* global Get, Type */
+// 9.1.14. GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
+function GetPrototypeFromConstructor(constructor, intrinsicDefaultProto) { // eslint-disable-line no-unused-vars
+       // 1. Assert: intrinsicDefaultProto is a String value that is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object.
+       // 2. Assert: IsCallable(constructor) is true.
+       // 3. Let proto be ? Get(constructor, "prototype").
+       var proto = Get(constructor, "prototype");
+       // 4. If Type(proto) is not Object, then
+       if (Type(proto) !== 'object') {
+               // a. Let realm be ? GetFunctionRealm(constructor).
+               // b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
+               proto = intrinsicDefaultProto;
+       }
+       // 5. Return proto.
+       return proto;
+}
+if (!('keys' in Object && (function () {
+       // Safari 5.0 bug where Object.keys doesn't work with arguments
+       return (Object.keys(arguments)).length === 2;
+}(1, 2)) && (function () {
+       try {
+               // In ES6 Object.keys works on all object except `null` and `undefined`.
+               Object.keys('');
+               return true;
+       } catch (e) {
+               return false;
+       }
+}()))) {
+
+// Object.keys
+Object.keys = (function() {
+       'use strict';
+
+       // modified from https://github.com/es-shims/object-keys
+
+       var has = Object.prototype.hasOwnProperty;
+       var toStr = Object.prototype.toString;
+       var isEnumerable = Object.prototype.propertyIsEnumerable;
+       var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
+       var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
+       var dontEnums = [
+               'toString',
+               'toLocaleString',
+               'valueOf',
+               'hasOwnProperty',
+               'isPrototypeOf',
+               'propertyIsEnumerable',
+               'constructor'
+       ];
+       var equalsConstructorPrototype = function (o) {
+               var ctor = o.constructor;
+               return ctor && ctor.prototype === o;
+       };
+       var excludedKeys = {
+               $console: true,
+               $external: true,
+               $frame: true,
+               $frameElement: true,
+               $frames: true,
+               $innerHeight: true,
+               $innerWidth: true,
+               $outerHeight: true,
+               $outerWidth: true,
+               $pageXOffset: true,
+               $pageYOffset: true,
+               $parent: true,
+               $scrollLeft: true,
+               $scrollTop: true,
+               $scrollX: true,
+               $scrollY: true,
+               $self: true,
+               $webkitIndexedDB: true,
+               $webkitStorageInfo: true,
+               $window: true
+       };
+       var hasAutomationEqualityBug = (function () {
+               /* global window */
+               if (typeof window === 'undefined') { return false; }
+               for (var k in window) {
+                       try {
+                               if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
+                                       try {
+                                               equalsConstructorPrototype(window[k]);
+                                       } catch (e) {
+                                               return true;
+                                       }
+                               }
+                       } catch (e) {
+                               return true;
+                       }
+               }
+               return false;
+       }());
+       var equalsConstructorPrototypeIfNotBuggy = function (o) {
+               /* global window */
+               if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+                       return equalsConstructorPrototype(o);
+               }
+               try {
+                       return equalsConstructorPrototype(o);
+               } catch (e) {
+                       return false;
+               }
+       };
+
+       function isArgumentsObject(value) {
+               var str = toStr.call(value);
+               var isArgs = str === '[object Arguments]';
+               if (!isArgs) {
+                       isArgs = str !== '[object Array]' &&
+                               value !== null &&
+                               typeof value === 'object' &&
+                               typeof value.length === 'number' &&
+                               value.length >= 0 &&
+                               toStr.call(value.callee) === '[object Function]';
+               }
+               return isArgs;
+       }
+
+       return function keys(object) {
+               var isFunction = toStr.call(object) === '[object Function]';
+               var isArguments = isArgumentsObject(object);
+               var isString = toStr.call(object) === '[object String]';
+               var theKeys = [];
+
+               if (object === undefined || object === null) {
+                       throw new TypeError('Cannot convert undefined or null to object');
+               }
+
+               var skipProto = hasProtoEnumBug && isFunction;
+               if (isString && object.length > 0 && !has.call(object, 0)) {
+                       for (var i = 0; i < object.length; ++i) {
+                               theKeys.push(String(i));
+                       }
+               }
+
+               if (isArguments && object.length > 0) {
+                       for (var j = 0; j < object.length; ++j) {
+                               theKeys.push(String(j));
+                       }
+               } else {
+                       for (var name in object) {
+                               if (!(skipProto && name === 'prototype') && has.call(object, name)) {
+                                       theKeys.push(String(name));
+                               }
+                       }
+               }
+
+               if (hasDontEnumBug) {
+                       var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+
+                       for (var k = 0; k < dontEnums.length; ++k) {
+                               if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
+                                       theKeys.push(dontEnums[k]);
+                               }
+                       }
+               }
+               return theKeys;
+       };
+}());
+
+}
+
+if (!('bind' in Function.prototype)) {
+
+// Function.prototype.bind
+/* global CreateMethodProperty, IsCallable */
+// 19.2.3.2. Function.prototype.bind ( thisArg, ...args )
+// https://github.com/es-shims/es5-shim/blob/d6d7ff1b131c7ba14c798cafc598bb6780d37d3b/es5-shim.js#L182
+CreateMethodProperty(Function.prototype, 'bind', function bind(that) { // .length is 1
+       // add necessary es5-shim utilities
+       var $Array = Array;
+       var $Object = Object;
+       var ArrayPrototype = $Array.prototype;
+       var Empty = function Empty() { };
+       var array_slice = ArrayPrototype.slice;
+       var array_concat = ArrayPrototype.concat;
+       var array_push = ArrayPrototype.push;
+       var max = Math.max;
+       // /add necessary es5-shim utilities
+
+       // 1. Let Target be the this value.
+       var target = this;
+       // 2. If IsCallable(Target) is false, throw a TypeError exception.
+       if (!IsCallable(target)) {
+               throw new TypeError('Function.prototype.bind called on incompatible ' + target);
+       }
+       // 3. Let A be a new (possibly empty) internal list of all of the
+       //   argument values provided after thisArg (arg1, arg2 etc), in order.
+       // XXX slicedArgs will stand in for "A" if used
+       var args = array_slice.call(arguments, 1); // for normal call
+       // 4. Let F be a new native ECMAScript object.
+       // 11. Set the [[Prototype]] internal property of F to the standard
+       //   built-in Function prototype object as specified in 15.3.3.1.
+       // 12. Set the [[Call]] internal property of F as described in
+       //   15.3.4.5.1.
+       // 13. Set the [[Construct]] internal property of F as described in
+       //   15.3.4.5.2.
+       // 14. Set the [[HasInstance]] internal property of F as described in
+       //   15.3.4.5.3.
+       var bound;
+       var binder = function () {
+
+               if (this instanceof bound) {
+                       // 15.3.4.5.2 [[Construct]]
+                       // When the [[Construct]] internal method of a function object,
+                       // F that was created using the bind function is called with a
+                       // list of arguments ExtraArgs, the following steps are taken:
+                       // 1. Let target be the value of F's [[TargetFunction]]
+                       //   internal property.
+                       // 2. If target has no [[Construct]] internal method, a
+                       //   TypeError exception is thrown.
+                       // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
+                       //   property.
+                       // 4. Let args be a new list containing the same values as the
+                       //   list boundArgs in the same order followed by the same
+                       //   values as the list ExtraArgs in the same order.
+                       // 5. Return the result of calling the [[Construct]] internal
+                       //   method of target providing args as the arguments.
+
+                       var result = target.apply(
+                               this,
+                               array_concat.call(args, array_slice.call(arguments))
+                       );
+                       if ($Object(result) === result) {
+                               return result;
+                       }
+                       return this;
+
+               } else {
+                       // 15.3.4.5.1 [[Call]]
+                       // When the [[Call]] internal method of a function object, F,
+                       // which was created using the bind function is called with a
+                       // this value and a list of arguments ExtraArgs, the following
+                       // steps are taken:
+                       // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+                       //   property.
+                       // 2. Let boundThis be the value of F's [[BoundThis]] internal
+                       //   property.
+                       // 3. Let target be the value of F's [[TargetFunction]] internal
+                       //   property.
+                       // 4. Let args be a new list containing the same values as the
+                       //   list boundArgs in the same order followed by the same
+                       //   values as the list ExtraArgs in the same order.
+                       // 5. Return the result of calling the [[Call]] internal method
+                       //   of target providing boundThis as the this value and
+                       //   providing args as the arguments.
+
+                       // equiv: target.call(this, ...boundArgs, ...args)
+                       return target.apply(
+                               that,
+                               array_concat.call(args, array_slice.call(arguments))
+                       );
+
+               }
+
+       };
+
+       // 15. If the [[Class]] internal property of Target is "Function", then
+       //     a. Let L be the length property of Target minus the length of A.
+       //     b. Set the length own property of F to either 0 or L, whichever is
+       //       larger.
+       // 16. Else set the length own property of F to 0.
+
+       var boundLength = max(0, target.length - args.length);
+
+       // 17. Set the attributes of the length own property of F to the values
+       //   specified in 15.3.5.1.
+       var boundArgs = [];
+       for (var i = 0; i < boundLength; i++) {
+               array_push.call(boundArgs, '$' + i);
+       }
+
+       // XXX Build a dynamic function with desired amount of arguments is the only
+       // way to set the length property of a function.
+       // In environments where Content Security Policies enabled (Chrome extensions,
+       // for ex.) all use of eval or Function costructor throws an exception.
+       // However in all of these environments Function.prototype.bind exists
+       // and so this code will never be executed.
+       bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
+
+       if (target.prototype) {
+               Empty.prototype = target.prototype;
+               bound.prototype = new Empty();
+               // Clean up dangling references.
+               Empty.prototype = null;
+       }
+
+       // TODO
+       // 18. Set the [[Extensible]] internal property of F to true.
+
+       // TODO
+       // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
+       // 20. Call the [[DefineOwnProperty]] internal method of F with
+       //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
+       //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
+       //   false.
+       // 21. Call the [[DefineOwnProperty]] internal method of F with
+       //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
+       //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
+       //   and false.
+
+       // TODO
+       // NOTE Function objects created using Function.prototype.bind do not
+       // have a prototype property or the [[Code]], [[FormalParameters]], and
+       // [[Scope]] internal properties.
+       // XXX can't delete prototype in pure-js.
+
+       // 22. Return F.
+       return bound;
+});
+
+}
+
+if (!('getOwnPropertyDescriptor' in Object && typeof Object.getOwnPropertyDescriptor === 'function' && (function() {
+    try {
+       var object = {};
+        object.test = 0;
+        return Object.getOwnPropertyDescriptor(
+            object,
+            "test"
+        ).value === 0;
+    } catch (exception) {
+        return false
+    }
+}()))) {
+
+// Object.getOwnPropertyDescriptor
+/* global CreateMethodProperty */
+(function () {
+       var call = Function.prototype.call;
+       var prototypeOfObject = Object.prototype;
+       var owns = call.bind(prototypeOfObject.hasOwnProperty);
+
+       var lookupGetter;
+       var lookupSetter;
+       var supportsAccessors;
+       if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
+           lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
+           lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
+       }
+       function doesGetOwnPropertyDescriptorWork(object) {
+           try {
+               object.sentinel = 0;
+               return Object.getOwnPropertyDescriptor(
+                   object,
+                   "sentinel"
+               ).value === 0;
+           } catch (exception) {
+               // returns falsy
+           }
+       }
+       // check whether getOwnPropertyDescriptor works if it's given. Otherwise,
+       // shim partially.
+       if (Object.defineProperty) {
+           var getOwnPropertyDescriptorWorksOnObject =
+               doesGetOwnPropertyDescriptorWork({});
+           var getOwnPropertyDescriptorWorksOnDom = typeof document == "undefined" ||
+               doesGetOwnPropertyDescriptorWork(document.createElement("div"));
+           if (!getOwnPropertyDescriptorWorksOnDom ||
+               !getOwnPropertyDescriptorWorksOnObject
+           ) {
+               var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;
+           }
+       }
+
+       if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
+           var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object: ";
+
+           CreateMethodProperty(Object, 'getOwnPropertyDescriptor', function getOwnPropertyDescriptor(object, property) {
+               if ((typeof object != "object" && typeof object != "function") || object === null) {
+                   throw new TypeError(ERR_NON_OBJECT + object);
+               }
+
+               // make a valiant attempt to use the real getOwnPropertyDescriptor
+               // for I8's DOM elements.
+               if (getOwnPropertyDescriptorFallback) {
+                   try {
+                       return getOwnPropertyDescriptorFallback.call(Object, object, property);
+                   } catch (exception) {
+                       // try the shim if the real one doesn't work
+                   }
+               }
+
+               // If object does not owns property return undefined immediately.
+               if (!owns(object, property)) {
+                   return;
+               }
+
+               // If object has a property then it's for sure both `enumerable` and
+               // `configurable`.
+               var descriptor = { enumerable: true, configurable: true };
+
+               // If JS engine supports accessor properties then property may be a
+               // getter or setter.
+               if (supportsAccessors) {
+                   // Unfortunately `__lookupGetter__` will return a getter even
+                   // if object has own non getter property along with a same named
+                   // inherited getter. To avoid misbehavior we temporary remove
+                   // `__proto__` so that `__lookupGetter__` will return getter only
+                   // if it's owned by an object.
+                   var prototype = object.__proto__;
+                   object.__proto__ = prototypeOfObject;
+
+                   var getter = lookupGetter(object, property);
+                   var setter = lookupSetter(object, property);
+
+                   // Once we have getter and setter we can put values back.
+                   object.__proto__ = prototype;
+
+                   if (getter || setter) {
+                       if (getter) {
+                           descriptor.get = getter;
+                       }
+                       if (setter) {
+                           descriptor.set = setter;
+                       }
+                       // If it was accessor property we're done and return here
+                       // in order to avoid adding `value` to the descriptor.
+                       return descriptor;
+                   }
+               }
+
+               // If we got this far we know that object has an own property that is
+               // not an accessor so we set it as a value and return descriptor.
+               descriptor.value = object[property];
+                       descriptor.writable = true;
+               return descriptor;
+           });
+       }
+}());
+
+}
+
+if (!('defineProperties' in Object)) {
+
+// Object.defineProperties
+/* global CreateMethodProperty, Get, ToObject, Type */
+// 19.1.2.3. Object.defineProperties ( O, Properties )
+CreateMethodProperty(Object, 'defineProperties', function defineProperties(O, Properties) {
+       // 1. If Type(O) is not Object, throw a TypeError exception.
+       if (Type(O) !== 'object') {
+               throw new TypeError('Object.defineProperties called on non-object');
+       }
+       // 2. Let props be ? ToObject(Properties).
+       var props = ToObject(Properties);
+       // 3. Let keys be ? props.[[OwnPropertyKeys]]().
+       /*
+               Polyfill.io - This step in our polyfill is not complying with the specification.
+               [[OwnPropertyKeys]] is meant to return ALL keys, including non-enumerable and symbols.
+               TODO: When we have Reflect.ownKeys, use that instead as it is the userland equivalent of [[OwnPropertyKeys]].
+       */
+       var keys = Object.keys(props);
+       // 4. Let descriptors be a new empty List.
+       var descriptors = [];
+       // 5. For each element nextKey of keys in List order, do
+       for (var i = 0; i < keys.length; i++) {
+               var nextKey = keys[i];
+               // a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
+               var propDesc = Object.getOwnPropertyDescriptor(props, nextKey);
+               // b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
+               if (propDesc !== undefined && propDesc.enumerable) {
+                       // i. Let descObj be ? Get(props, nextKey).
+                       var descObj = Get(props, nextKey);
+                       // ii. Let desc be ? ToPropertyDescriptor(descObj).
+                       // Polyfill.io - We skip this step because Object.defineProperty deals with it.
+                       // TODO: Implement this step?
+                       var desc = descObj;
+                       // iii. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
+                       descriptors.push([nextKey, desc]);
+               }
+       }
+       // 6. For each pair from descriptors in list order, do
+       for (var i = 0; i < descriptors.length; i++){
+               // a. Let P be the first element of pair.
+               var P = descriptors[i][0];
+               // b. Let desc be the second element of pair.
+               var desc = descriptors[i][1];
+               // c. Perform ? DefinePropertyOrThrow(O, P, desc).
+               Object.defineProperty(O, P, desc);
+       }
+       // 7. Return O.
+       return O;
+});
+
+}
+
+if (!('create' in Object)) {
+
+// Object.create
+/* global CreateMethodProperty, Type */
+CreateMethodProperty(Object, 'create', function create(O, properties) {
+       // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
+       if (Type(O) !== 'object' && Type(O) !== 'null') {
+               throw new TypeError('Object prototype may only be an Object or null');
+       }
+       // 2. Let obj be ObjectCreate(O).
+       var obj = new Function('e', 'function Object() {}Object.prototype=e;return new Object')(O);
+
+       obj.constructor.prototype = O;
+
+       // 3. If Properties is not undefined, then
+       if (1 in arguments) {
+               // a. Return ? ObjectDefineProperties(obj, Properties).
+               return Object.defineProperties(obj, properties);
+       }
+
+       return obj;
+});
+
+}
+
+if (!('getPrototypeOf' in Object)) {
+
+// Object.getPrototypeOf
+/* global CreateMethodProperty */
+// Based on: https://github.com/es-shims/es5-shim/blob/master/es5-sham.js
+
+// https://github.com/es-shims/es5-shim/issues#issue/2
+// http://ejohn.org/blog/objectgetprototypeof/
+// recommended by fschaefer on github
+//
+// sure, and webreflection says ^_^
+// ... this will nerever possibly return null
+// ... Opera Mini breaks here with infinite loops
+CreateMethodProperty(Object, 'getPrototypeOf', function getPrototypeOf(object) {
+       if (object !== Object(object)) {
+               throw new TypeError('Object.getPrototypeOf called on non-object');
+       }
+       var proto = object.__proto__;
+       if (proto || proto === null) {
+               return proto;
+       } else if (typeof object.constructor == 'function' && object instanceof object.constructor) {
+    return object.constructor.prototype;
+  } else if (object instanceof Object) {
+               return Object.prototype;
+       } else {
+               // Correctly return null for Objects created with `Object.create(null)`
+               // (shammed or native) or `{ __proto__: null}`.  Also returns null for
+               // cross-realm objects on browsers that lack `__proto__` support (like
+               // IE <11), but that's the best we can do.
+               return null;
+       }
+});
+
+}
+
+
+// _ESAbstract.OrdinaryCreateFromConstructor
+/* global GetPrototypeFromConstructor */
+// 9.1.13. OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
+function OrdinaryCreateFromConstructor(constructor, intrinsicDefaultProto) { // eslint-disable-line no-unused-vars
+       var internalSlotsList = arguments[2] || {};
+       // 1. Assert: intrinsicDefaultProto is a String value that is this specification's name of an intrinsic object.
+       // The corresponding object must be an intrinsic that is intended to be used as the[[Prototype]] value of an object.
+
+       // 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
+       var proto = GetPrototypeFromConstructor(constructor, intrinsicDefaultProto);
+
+       // 3. Return ObjectCreate(proto, internalSlotsList).
+       // Polyfill.io - We do not pass internalSlotsList to Object.create because Object.create does not use the default ordinary object definitions specified in 9.1.
+       var obj = Object.create(proto);
+       for (var name in internalSlotsList) {
+               if (Object.prototype.hasOwnProperty.call(internalSlotsList, name)) {
+                       Object.defineProperty(obj, name, {
+                               configurable: true,
+                               enumerable: false,
+                               writable: true,
+                               value: internalSlotsList[name]
+                       });
+               }
+       }
+       return obj;
+}
+
+// _ESAbstract.Construct
+/* global IsConstructor, OrdinaryCreateFromConstructor, Call */
+// 7.3.13. Construct ( F [ , argumentsList [ , newTarget ]] )
+function Construct(F /* [ , argumentsList [ , newTarget ]] */) { // eslint-disable-line no-unused-vars
+       // 1. If newTarget is not present, set newTarget to F.
+       var newTarget = arguments.length > 2 ? arguments[2] : F;
+
+       // 2. If argumentsList is not present, set argumentsList to a new empty List.
+       var argumentsList = arguments.length > 1 ? arguments[1] : [];
+
+       // 3. Assert: IsConstructor(F) is true.
+       if (!IsConstructor(F)) {
+               throw new TypeError('F must be a constructor.');
+       }
+
+       // 4. Assert: IsConstructor(newTarget) is true.
+       if (!IsConstructor(newTarget)) {
+               throw new TypeError('newTarget must be a constructor.');
+       }
+
+       // 5. Return ? F.[[Construct]](argumentsList, newTarget).
+       // Polyfill.io - If newTarget is the same as F, it is equivalent to new F(...argumentsList).
+       if (newTarget === F) {
+               return new (Function.prototype.bind.apply(F, [null].concat(argumentsList)))();
+       } else {
+               // Polyfill.io - This is mimicking section 9.2.2 step 5.a.
+               var obj = OrdinaryCreateFromConstructor(newTarget, Object.prototype);
+               return Call(F, obj, argumentsList);
+       }
+}
+
+// _ESAbstract.ArraySpeciesCreate
+/* global IsArray, ArrayCreate, Get, Type, IsConstructor, Construct */
+// 9.4.2.3. ArraySpeciesCreate ( originalArray, length )
+function ArraySpeciesCreate(originalArray, length) { // eslint-disable-line no-unused-vars
+       // 1. Assert: length is an integer Number ≥ 0.
+       // 2. If length is -0, set length to +0.
+       if (1/length === -Infinity) {
+               length = 0;
+       }
+
+       // 3. Let isArray be ? IsArray(originalArray).
+       var isArray = IsArray(originalArray);
+
+       // 4. If isArray is false, return ? ArrayCreate(length).
+       if (isArray === false) {
+               return ArrayCreate(length);
+       }
+
+       // 5. Let C be ? Get(originalArray, "constructor").
+       var C = Get(originalArray, 'constructor');
+
+       // Polyfill.io - We skip this section as not sure how to make a cross-realm normal Array, a same-realm Array.
+       // 6. If IsConstructor(C) is true, then
+       // if (IsConstructor(C)) {
+               // a. Let thisRealm be the current Realm Record.
+               // b. Let realmC be ? GetFunctionRealm(C).
+               // c. If thisRealm and realmC are not the same Realm Record, then
+                       // i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
+       // }
+       // 7. If Type(C) is Object, then
+       if (Type(C) === 'object') {
+               // a. Set C to ? Get(C, @@species).
+               C = 'Symbol' in this && 'species' in this.Symbol ? Get(C, this.Symbol.species) : undefined;
+               // b. If C is null, set C to undefined.
+               if (C === null) {
+                       C = undefined;
+               }
+       }
+       // 8. If C is undefined, return ? ArrayCreate(length).
+       if (C === undefined) {
+               return ArrayCreate(length);
+       }
+       // 9. If IsConstructor(C) is false, throw a TypeError exception.
+       if (!IsConstructor(C)) {
+               throw new TypeError('C must be a constructor');
+       }
+       // 10. Return ? Construct(C, « length »).
+       return Construct(C, [length]);
+}
+
+// _ESAbstract.ToBoolean
+// 7.1.2. ToBoolean ( argument )
+// The abstract operation ToBoolean converts argument to a value of type Boolean according to Table 9:
+/*
+--------------------------------------------------------------------------------------------------------------
+| Argument Type | Result                                                                                     |
+--------------------------------------------------------------------------------------------------------------
+| Undefined     | Return false.                                                                              |
+| Null          | Return false.                                                                              |
+| Boolean       | Return argument.                                                                           |
+| Number        | If argument is +0, -0, or NaN, return false; otherwise return true.                        |
+| String        | If argument is the empty String (its length is zero), return false; otherwise return true. |
+| Symbol        | Return true.                                                                               |
+| Object        | Return true.                                                                               |
+--------------------------------------------------------------------------------------------------------------
+*/
+function ToBoolean(argument) { // eslint-disable-line no-unused-vars
+       return Boolean(argument);
+}
+
+// _ESAbstract.CreateDataProperty
+// 7.3.4. CreateDataProperty ( O, P, V )
+// NOTE
+// This abstract operation creates a property whose attributes are set to the same defaults used for properties created by the ECMAScript language assignment operator.
+// Normally, the property will not already exist. If it does exist and is not configurable or if O is not extensible, [[DefineOwnProperty]] will return false.
+function CreateDataProperty(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let newDesc be the PropertyDescriptor{ [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
+       var newDesc = {
+               value: V,
+               writable: true,
+               enumerable: true,
+               configurable: true
+       };
+       // 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
+       try {
+               Object.defineProperty(O, P, newDesc);
+               return true;
+       } catch (e) {
+               return false;
+       }
+}
+
+// _ESAbstract.CreateDataPropertyOrThrow
+/* global CreateDataProperty */
+// 7.3.6. CreateDataPropertyOrThrow ( O, P, V )
+function CreateDataPropertyOrThrow(O, P, V) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(O) is Object.
+       // 2. Assert: IsPropertyKey(P) is true.
+       // 3. Let success be ? CreateDataProperty(O, P, V).
+       var success = CreateDataProperty(O, P, V);
+       // 4. If success is false, throw a TypeError exception.
+       if (!success) {
+               throw new TypeError('Cannot assign value `' + Object.prototype.toString.call(V) + '` to property `' + Object.prototype.toString.call(P) + '` on object `' + Object.prototype.toString.call(O) + '`');
+       }
+       // 5. Return success.
+       return success;
+}
+if (!('filter' in Array.prototype)) {
+
+// Array.prototype.filter
+/* global CreateMethodProperty, ToObject, ToLength, Get, IsCallable, ArraySpeciesCreate, ToString, HasProperty, ToBoolean, Call, CreateDataPropertyOrThrow */
+// 22.1.3.7. Array.prototype.filter ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'filter', function filter(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let A be ? ArraySpeciesCreate(O, 0).
+       var A = ArraySpeciesCreate(O, 0);
+       // 6. Let k be 0.
+       var k = 0;
+       // 7. Let to be 0.
+       var to = 0;
+       // 8. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let selected be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
+                       var selected = ToBoolean(Call(callbackfn, T, [kValue, k, O]));
+                       // iii. If selected is true, then
+                       if (selected) {
+                               // 1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(to), kValue)
+                               CreateDataPropertyOrThrow(A, ToString(to), kValue);
+                               // 2. Increase to by 1.
+                               to = to + 1;
+                       }
+
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 9. Return A.
+       return A;
+});
+
+}
+
+if (!('map' in Array.prototype)) {
+
+// Array.prototype.map
+/* global ArraySpeciesCreate, Call, CreateDataPropertyOrThrow, CreateMethodProperty, Get, HasProperty, IsCallable, ToLength, ToObject, ToString */
+/* global CreateMethodProperty, ToObject, ToLength, Get, ArraySpeciesCreate, ToString, HasProperty, Call, CreateDataPropertyOrThrow */
+// 22.1.3.16. Array.prototype.map ( callbackfn [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'map', function map(callbackfn /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
+       if (IsCallable(callbackfn) === false) {
+               throw new TypeError(callbackfn + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let A be ? ArraySpeciesCreate(O, len).
+       var A = ArraySpeciesCreate(O, len);
+       // 6. Let k be 0.
+       var k = 0;
+       // 7. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kPresent be ? HasProperty(O, Pk).
+               var kPresent = HasProperty(O, Pk);
+               // c. If kPresent is true, then
+               if (kPresent) {
+                       // i. Let kValue be ? Get(O, Pk).
+                       var kValue = Get(O, Pk);
+                       // ii. Let mappedValue be ? Call(callbackfn, T, « kValue, k, O »).
+                       var mappedValue = Call(callbackfn, T, [kValue, k, O]);
+                       // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
+                       CreateDataPropertyOrThrow(A, Pk, mappedValue);
+               }
+               // d. Increase k by 1.
+               k = k + 1;
+       }
+       // 8. Return A.
+       return A;
+});
+
+}
+
+if (!('getOwnPropertyNames' in Object)) {
+
+// Object.getOwnPropertyNames
+/* global CreateMethodProperty */
+
+var toString = ({}).toString;
+var split = ''.split;
+
+CreateMethodProperty(Object, 'getOwnPropertyNames', function getOwnPropertyNames(object) {
+       var buffer = [];
+       var key;
+
+       // Non-enumerable properties cannot be discovered but can be checked for by name.
+       // Define those used internally by JS to allow an incomplete solution
+       var commonProps = ['length', "name", "arguments", "caller", "prototype", "observe", "unobserve"];
+
+       if (typeof object === 'undefined' || object === null) {
+               throw new TypeError('Cannot convert undefined or null to object');
+       }
+
+       // Polyfill.io fallback for non-array-like strings which exist in some ES3 user-agents (IE 8)
+       object = toString.call(object) == '[object String]' ? split.call(object, '') : Object(object);
+
+       // Enumerable properties only
+       for (key in object) {
+               if (Object.prototype.hasOwnProperty.call(object, key)) {
+                       buffer.push(key);
+               }
+       }
+
+       // Check for and add the common non-enumerable properties
+       for (var i=0, s=commonProps.length; i<s; i++) {
+               if (commonProps[i] in object) buffer.push(commonProps[i]);
+       }
+
+       return buffer;
+});
+
+}
+
+if (!('freeze' in Object)) {
+
+// Object.freeze
+/* global CreateMethodProperty */
+// 19.1.2.6. Object.freeze ( O )
+CreateMethodProperty(Object, 'freeze', function freeze(O) {
+       // This feature cannot be implemented fully as a polyfill.
+       // We choose to silently fail which allows "securable" code
+       // to "gracefully" degrade to working but insecure code.
+       return O;
+});
+
+}
+
+if (!('Symbol' in this && this.Symbol.length === 0)) {
+
+// Symbol
+// A modification of https://github.com/WebReflection/get-own-property-symbols
+// (C) Andrea Giammarchi - MIT Licensed
+
+(function (Object, GOPS, global) {
+
+       var     setDescriptor;
+       var id = 0;
+       var random = '' + Math.random();
+       var prefix = '__\x01symbol:';
+       var prefixLength = prefix.length;
+       var internalSymbol = '__\x01symbol@@' + random;
+       var DP = 'defineProperty';
+       var DPies = 'defineProperties';
+       var GOPN = 'getOwnPropertyNames';
+       var GOPD = 'getOwnPropertyDescriptor';
+       var PIE = 'propertyIsEnumerable';
+       var ObjectProto = Object.prototype;
+       var hOP = ObjectProto.hasOwnProperty;
+       var pIE = ObjectProto[PIE];
+       var toString = ObjectProto.toString;
+       var concat = Array.prototype.concat;
+       var cachedWindowNames = typeof window === 'object' ? Object.getOwnPropertyNames(window) : [];
+       var nGOPN = Object[GOPN];
+       var gOPN = function getOwnPropertyNames (obj) {
+               if (toString.call(obj) === '[object Window]') {
+                       try {
+                               return nGOPN(obj);
+                       } catch (e) {
+                               // IE bug where layout engine calls userland gOPN for cross-domain `window` objects
+                               return concat.call([], cachedWindowNames);
+                       }
+               }
+               return nGOPN(obj);
+       };
+       var gOPD = Object[GOPD];
+       var create = Object.create;
+       var keys = Object.keys;
+       var freeze = Object.freeze || Object;
+       var defineProperty = Object[DP];
+       var $defineProperties = Object[DPies];
+       var descriptor = gOPD(Object, GOPN);
+       var addInternalIfNeeded = function (o, uid, enumerable) {
+               if (!hOP.call(o, internalSymbol)) {
+                       try {
+                               defineProperty(o, internalSymbol, {
+                                       enumerable: false,
+                                       configurable: false,
+                                       writable: false,
+                                       value: {}
+                               });
+                       } catch (e) {
+                               o[internalSymbol] = {};
+                       }
+               }
+               o[internalSymbol]['@@' + uid] = enumerable;
+       };
+       var createWithSymbols = function (proto, descriptors) {
+               var self = create(proto);
+               gOPN(descriptors).forEach(function (key) {
+                       if (propertyIsEnumerable.call(descriptors, key)) {
+                               $defineProperty(self, key, descriptors[key]);
+                       }
+               });
+               return self;
+       };
+       var copyAsNonEnumerable = function (descriptor) {
+               var newDescriptor = create(descriptor);
+               newDescriptor.enumerable = false;
+               return newDescriptor;
+       };
+       var get = function get(){};
+       var onlyNonSymbols = function (name) {
+               return name != internalSymbol &&
+                       !hOP.call(source, name);
+       };
+       var onlySymbols = function (name) {
+               return name != internalSymbol &&
+                       hOP.call(source, name);
+       };
+       var propertyIsEnumerable = function propertyIsEnumerable(key) {
+               var uid = '' + key;
+               return onlySymbols(uid) ? (
+                       hOP.call(this, uid) &&
+                       this[internalSymbol]['@@' + uid]
+               ) : pIE.call(this, key);
+       };
+       var setAndGetSymbol = function (uid) {
+               var descriptor = {
+                       enumerable: false,
+                       configurable: true,
+                       get: get,
+                       set: function (value) {
+                       setDescriptor(this, uid, {
+                               enumerable: false,
+                               configurable: true,
+                               writable: true,
+                               value: value
+                       });
+                       addInternalIfNeeded(this, uid, true);
+                       }
+               };
+               try {
+                       defineProperty(ObjectProto, uid, descriptor);
+               } catch (e) {
+                       ObjectProto[uid] = descriptor.value;
+               }
+               return freeze(source[uid] = defineProperty(
+                       Object(uid),
+                       'constructor',
+                       sourceConstructor
+               ));
+       };
+       var Symbol = function Symbol() {
+               var description = arguments[0];
+               if (this instanceof Symbol) {
+                       throw new TypeError('Symbol is not a constructor');
+               }
+               return setAndGetSymbol(
+                       prefix.concat(description || '', random, ++id)
+               );
+               };
+       var source = create(null);
+       var sourceConstructor = {value: Symbol};
+       var sourceMap = function (uid) {
+               return source[uid];
+               };
+       var $defineProperty = function defineProp(o, key, descriptor) {
+               var uid = '' + key;
+               if (onlySymbols(uid)) {
+                       setDescriptor(o, uid, descriptor.enumerable ?
+                               copyAsNonEnumerable(descriptor) : descriptor);
+                       addInternalIfNeeded(o, uid, !!descriptor.enumerable);
+               } else {
+                       defineProperty(o, key, descriptor);
+               }
+               return o;
+       };
+
+       var onlyInternalSymbols = function (obj) {
+               return function (name) {
+                       return hOP.call(obj, internalSymbol) && hOP.call(obj[internalSymbol], '@@' + name);
+               };
+       };
+       var $getOwnPropertySymbols = function getOwnPropertySymbols(o) {
+               return gOPN(o).filter(o === ObjectProto ? onlyInternalSymbols(o) : onlySymbols).map(sourceMap);
+               }
+       ;
+
+       descriptor.value = $defineProperty;
+       defineProperty(Object, DP, descriptor);
+
+       descriptor.value = $getOwnPropertySymbols;
+       defineProperty(Object, GOPS, descriptor);
+
+       descriptor.value = function getOwnPropertyNames(o) {
+               return gOPN(o).filter(onlyNonSymbols);
+       };
+       defineProperty(Object, GOPN, descriptor);
+
+       descriptor.value = function defineProperties(o, descriptors) {
+               var symbols = $getOwnPropertySymbols(descriptors);
+               if (symbols.length) {
+               keys(descriptors).concat(symbols).forEach(function (uid) {
+                       if (propertyIsEnumerable.call(descriptors, uid)) {
+                       $defineProperty(o, uid, descriptors[uid]);
+                       }
+               });
+               } else {
+               $defineProperties(o, descriptors);
+               }
+               return o;
+       };
+       defineProperty(Object, DPies, descriptor);
+
+       descriptor.value = propertyIsEnumerable;
+       defineProperty(ObjectProto, PIE, descriptor);
+
+       descriptor.value = Symbol;
+       defineProperty(global, 'Symbol', descriptor);
+
+       // defining `Symbol.for(key)`
+       descriptor.value = function (key) {
+               var uid = prefix.concat(prefix, key, random);
+               return uid in ObjectProto ? source[uid] : setAndGetSymbol(uid);
+       };
+       defineProperty(Symbol, 'for', descriptor);
+
+       // defining `Symbol.keyFor(symbol)`
+       descriptor.value = function (symbol) {
+               if (onlyNonSymbols(symbol))
+               throw new TypeError(symbol + ' is not a symbol');
+               return hOP.call(source, symbol) ?
+               symbol.slice(prefixLength * 2, -random.length) :
+               void 0
+               ;
+       };
+       defineProperty(Symbol, 'keyFor', descriptor);
+
+       descriptor.value = function getOwnPropertyDescriptor(o, key) {
+               var descriptor = gOPD(o, key);
+               if (descriptor && onlySymbols(key)) {
+               descriptor.enumerable = propertyIsEnumerable.call(o, key);
+               }
+               return descriptor;
+       };
+       defineProperty(Object, GOPD, descriptor);
+
+       descriptor.value = function (proto, descriptors) {
+               return arguments.length === 1 || typeof descriptors === "undefined" ?
+               create(proto) :
+               createWithSymbols(proto, descriptors);
+       };
+       defineProperty(Object, 'create', descriptor);
+
+       descriptor.value = function () {
+               var str = toString.call(this);
+               return (str === '[object String]' && onlySymbols(this)) ? '[object Symbol]' : str;
+       };
+       defineProperty(ObjectProto, 'toString', descriptor);
+
+
+       setDescriptor = function (o, key, descriptor) {
+               var protoDescriptor = gOPD(ObjectProto, key);
+               delete ObjectProto[key];
+               defineProperty(o, key, descriptor);
+               if (o !== ObjectProto) {
+                       defineProperty(ObjectProto, key, protoDescriptor);
+               }
+       };
+
+}(Object, 'getOwnPropertySymbols', this));
+
+}
+
+if (!('Symbol' in this && 'iterator' in this.Symbol)) {
+
+// Symbol.iterator
+/* global Symbol */
+Object.defineProperty(Symbol, 'iterator', { value: Symbol('iterator') });
+
+}
+
+
+// _ESAbstract.GetIterator
+/* global GetMethod, Symbol, Call, Type, GetV */
+// 7.4.1. GetIterator ( obj [ , method ] )
+// The abstract operation GetIterator with argument obj and optional argument method performs the following steps:
+function GetIterator(obj /*, method */) { // eslint-disable-line no-unused-vars
+       // 1. If method is not present, then
+               // a. Set method to ? GetMethod(obj, @@iterator).
+       var method = arguments.length > 1 ? arguments[1] : GetMethod(obj, Symbol.iterator);
+       // 2. Let iterator be ? Call(method, obj).
+       var iterator = Call(method, obj);
+       // 3. If Type(iterator) is not Object, throw a TypeError exception.
+       if (Type(iterator) !== 'object') {
+               throw new TypeError('bad iterator');
+       }
+       // 4. Let nextMethod be ? GetV(iterator, "next").
+       var nextMethod = GetV(iterator, "next");
+       // 5. Let iteratorRecord be Record {[[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false}.
+       var iteratorRecord = Object.create(null);
+       iteratorRecord['[[Iterator]]'] = iterator;
+       iteratorRecord['[[NextMethod]]'] = nextMethod;
+       iteratorRecord['[[Done]]'] = false;
+       // 6. Return iteratorRecord.
+       return iteratorRecord;
+}
+
+// _ESAbstract.IteratorClose
+/* global GetMethod, Type, Call */
+// 7.4.6. IteratorClose ( iteratorRecord, completion )
+function IteratorClose(iteratorRecord, completion) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(iteratorRecord.[[Iterator]]) is Object.
+       if (Type(iteratorRecord['[[Iterator]]']) !== 'object') {
+               throw new Error(Object.prototype.toString.call(iteratorRecord['[[Iterator]]']) + 'is not an Object.');
+       }
+       // 2. Assert: completion is a Completion Record.
+       // Polyfill.io - Ignoring this step as there is no way to check if something is a Completion Record in userland JavaScript.
+
+       // 3. Let iterator be iteratorRecord.[[Iterator]].
+       var iterator = iteratorRecord['[[Iterator]]'];
+       // 4. Let return be ? GetMethod(iterator, "return").
+       // Polyfill.io - We name it  returnMethod because return is a keyword and can not be used as an identifier (E.G. variable name, function name etc).
+       var returnMethod = GetMethod(iterator, "return");
+       // 5. If return is undefined, return Completion(completion).
+       if (returnMethod === undefined) {
+               return completion;
+       }
+       // 6. Let innerResult be Call(return, iterator, « »).
+       try {
+               var innerResult = Call(returnMethod, iterator);
+       } catch (error) {
+               var innerException = error;
+       }
+       // 7. If completion.[[Type]] is throw, return Completion(completion).
+       if (completion) {
+               return completion;
+       }
+       // 8. If innerResult.[[Type]] is throw, return Completion(innerResult).
+       if (innerException) {
+               throw innerException;
+       }
+       // 9. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
+       if (Type(innerResult) !== 'object') {
+               throw new TypeError("Iterator's return method returned a non-object.");
+       }
+       // 10. Return Completion(completion).
+       return completion;
+}
+
+// _ESAbstract.IteratorNext
+/* global Call, Type */
+// 7.4.2. IteratorNext ( iteratorRecord [ , value ] )
+function IteratorNext(iteratorRecord /* [, value] */) { // eslint-disable-line no-unused-vars
+       // 1. If value is not present, then
+       if (arguments.length < 2) {
+               // a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « »).
+               var result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]']);
+       // 2. Else,
+       } else {
+               // a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »).
+               result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]'], [arguments[1]]);
+       }
+       // 3. If Type(result) is not Object, throw a TypeError exception.
+       if (Type(result) !== 'object') {
+               throw new TypeError('bad iterator');
+       }
+       // 4. Return result.
+       return result;
+}
+
+// _ESAbstract.IteratorComplete
+/* global Type, ToBoolean, Get */
+// 7.4.3 IteratorComplete ( iterResult )
+function IteratorComplete(iterResult) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(iterResult) is Object.
+       if (Type(iterResult) !== 'object') {
+               throw new Error(Object.prototype.toString.call(iterResult) + 'is not an Object.');
+       }
+       // 2. Return ToBoolean(? Get(iterResult, "done")).
+       return ToBoolean(Get(iterResult, "done"));
+}
+
+// _ESAbstract.IteratorStep
+/* global IteratorNext, IteratorComplete */
+// 7.4.5. IteratorStep ( iteratorRecord )
+function IteratorStep(iteratorRecord) { // eslint-disable-line no-unused-vars
+       // 1. Let result be ? IteratorNext(iteratorRecord).
+       var result = IteratorNext(iteratorRecord);
+       // 2. Let done be ? IteratorComplete(result).
+       var done = IteratorComplete(result);
+       // 3. If done is true, return false.
+       if (done === true) {
+               return false;
+       }
+       // 4. Return result.
+       return result;
+}
+
+// _ESAbstract.IteratorValue
+/* global Type, Get */
+// 7.4.4 IteratorValue ( iterResult )
+function IteratorValue(iterResult) { // eslint-disable-line no-unused-vars
+       // Assert: Type(iterResult) is Object.
+       if (Type(iterResult) !== 'object') {
+               throw new Error(Object.prototype.toString.call(iterResult) + 'is not an Object.');
+       }
+       // Return ? Get(iterResult, "value").
+       return Get(iterResult, "value");
+}
+
+// _ESAbstract.CreateIterResultObject
+/* global Type, CreateDataProperty */
+// 7.4.7. CreateIterResultObject ( value, done )
+function CreateIterResultObject(value, done) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(done) is Boolean.
+       if (Type(done) !== 'boolean') {
+               throw new Error();
+       }
+       // 2. Let obj be ObjectCreate(%ObjectPrototype%).
+       var obj = {};
+       // 3. Perform CreateDataProperty(obj, "value", value).
+       CreateDataProperty(obj, "value", value);
+       // 4. Perform CreateDataProperty(obj, "done", done).
+       CreateDataProperty(obj, "done", done);
+       // 5. Return obj.
+       return obj;
+}
+
+// _ESAbstract.SameValueNonNumber
+// 7.2.12. SameValueNonNumber ( x, y )
+function SameValueNonNumber(x, y) { // eslint-disable-line no-unused-vars
+       // 1. Assert: Type(x) is not Number.
+       // 2. Assert: Type(x) is the same as Type(y).
+       // 3. If Type(x) is Undefined, return true.
+       // 4. If Type(x) is Null, return true.
+       // 5. If Type(x) is String, then
+               // a. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
+       // 6. If Type(x) is Boolean, then
+               // a. If x and y are both true or both false, return true; otherwise, return false.
+       // 7. If Type(x) is Symbol, then
+               // a. If x and y are both the same Symbol value, return true; otherwise, return false.
+       // 8. If x and y are the same Object value, return true. Otherwise, return false.
+
+       // Polyfill.io - We can skip all above steps because the === operator does it all for us.
+       return x === y;
+}
+
+// _ESAbstract.SameValueZero
+/* global Type, SameValueNonNumber */
+// 7.2.11. SameValueZero ( x, y )
+function SameValueZero (x, y) { // eslint-disable-line no-unused-vars
+       // 1. If Type(x) is different from Type(y), return false.
+       if (Type(x) !== Type(y)) {
+               return false;
+       }
+       // 2. If Type(x) is Number, then
+       if (Type(x) === 'number') {
+               // a. If x is NaN and y is NaN, return true.
+               if (isNaN(x) && isNaN(y)) {
+                       return true;
+               }
+               // b. If x is +0 and y is -0, return true.
+               if (1/x === Infinity && 1/y === -Infinity) {
+                       return true;
+               }
+               // c. If x is -0 and y is +0, return true.
+               if (1/x === -Infinity && 1/y === Infinity) {
+                       return true;
+               }
+               // d. If x is the same Number value as y, return true.
+               if (x === y) {
+                       return true;
+               }
+               // e. Return false.
+               return false;
+       }
+       // 3. Return SameValueNonNumber(x, y).
+       return SameValueNonNumber(x, y);
+}
+if (!('isArray' in Array)) {
+
+// Array.isArray
+/* global CreateMethodProperty, IsArray */
+// 22.1.2.2. Array.isArray ( arg )
+CreateMethodProperty(Array, 'isArray', function isArray(arg) {
+       // 1. Return ? IsArray(arg).
+       return IsArray(arg);
+});
+
+}
+
+if (!('Symbol' in this && 'species' in this.Symbol)) {
+
+// Symbol.species
+/* global Symbol */
+Object.defineProperty(Symbol, 'species', { value: Symbol('species') });
+
+}
+
+if (!('Map' in this && (function() {
+       try {
+               var m = new Map([[1, 1], [2, 2]]);
+               if (Map.length === 0) {
+                       if (m.size === 2) {
+                               if ('Symbol' in this && 'iterator' in Symbol && typeof m[Symbol.iterator] === 'function') {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       } catch (e) {
+               return false;
+       }
+}()))) {
+
+// Map
+/* global CreateIterResultObject, CreateMethodProperty, GetIterator, IsCallable, IteratorClose, IteratorStep, IteratorValue, OrdinaryCreateFromConstructor, SameValueZero, Type, Symbol */
+(function (global) {
+       var supportsGetters = (function () {
+               try {
+                       var a = {};
+                       Object.defineProperty(a, 't', {
+                               configurable: true,
+                               enumerable: false,
+                               get: function () {
+                                       return true;
+                               },
+                               set: undefined
+                       });
+                       return !!a.t;
+               } catch (e) {
+                       return false;
+               }
+       }());
+
+       // Deleted map items mess with iterator pointers, so rather than removing them mark them as deleted. Can't use undefined or null since those both valid keys so use a private symbol.
+       var undefMarker = Symbol('undef');
+       // 23.1.1.1 Map ( [ iterable ] )
+       var Map = function Map(/* iterable */) {
+               // 1. If NewTarget is undefined, throw a TypeError exception.
+               if (!(this instanceof Map)) {
+                       throw new TypeError('Constructor Map requires "new"');
+               }
+               // 2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%MapPrototype%", « [[MapData]] »).
+               var map = OrdinaryCreateFromConstructor(this, Map.prototype, {
+                       _keys: [],
+                       _values: [],
+                       _size: 0,
+                       _es6Map: true
+               });
+
+               // 3. Set map.[[MapData]] to a new empty List.
+               // Polyfill.io - This step was done as part of step two.
+
+               // Some old engines do not support ES5 getters/setters.  Since Map only requires these for the size property, we can fall back to setting the size property statically each time the size of the map changes.
+               if (!supportsGetters) {
+                       Object.defineProperty(map, 'size', {
+                               configurable: true,
+                               enumerable: false,
+                               writable: true,
+                               value: 0
+                       });
+               }
+
+               // 4. If iterable is not present, let iterable be undefined.
+               var iterable = arguments.length > 0 ? arguments[0] : undefined;
+
+               // 5. If iterable is either undefined or null, return map.
+               if (iterable === null || iterable === undefined) {
+                       return map;
+               }
+
+               // 6. Let adder be ? Get(map, "set").
+               var adder = map.set;
+
+               // 7. If IsCallable(adder) is false, throw a TypeError exception.
+               if (!IsCallable(adder)) {
+                       throw new TypeError("Map.prototype.set is not a function");
+               }
+
+               // 8. Let iteratorRecord be ? GetIterator(iterable).
+               try {
+                       var iteratorRecord = GetIterator(iterable);
+                       // 9. Repeat,
+                       while (true) {
+                               // a. Let next be ? IteratorStep(iteratorRecord).
+                               var next = IteratorStep(iteratorRecord);
+                               // b. If next is false, return map.
+                               if (next === false) {
+                                       return map;
+                               }
+                               // c. Let nextItem be ? IteratorValue(next).
+                               var nextItem = IteratorValue(next);
+                               // d. If Type(nextItem) is not Object, then
+                               if (Type(nextItem) !== 'object') {
+                                       // i. Let error be Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.
+                                       try {
+                                               throw new TypeError('Iterator value ' + nextItem + ' is not an entry object');
+                                       } catch (error) {
+                                               // ii. Return ? IteratorClose(iteratorRecord, error).
+                                               return IteratorClose(iteratorRecord, error);
+                                       }
+                               }
+                               try {
+                                       // Polyfill.io - The try catch accounts for steps: f, h, and j.
+
+                                       // e. Let k be Get(nextItem, "0").
+                                       var k = nextItem[0];
+                                       // f. If k is an abrupt completion, return ? IteratorClose(iteratorRecord, k).
+                                       // g. Let v be Get(nextItem, "1").
+                                       var v = nextItem[1];
+                                       // h. If v is an abrupt completion, return ? IteratorClose(iteratorRecord, v).
+                                       // i. Let status be Call(adder, map, « k.[[Value]], v.[[Value]] »).
+                                       adder.call(map, k, v);
+                               } catch (e) {
+                                       // j. If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).
+                                       return IteratorClose(iteratorRecord, e);
+                               }
+                       }
+               } catch (e) {
+                       // Polyfill.io - For user agents which do not have iteration methods on argument objects or arrays, we can special case those.
+                       if (Array.isArray(iterable) ||
+                               Object.prototype.toString.call(iterable) === '[object Arguments]' ||
+                               // IE 7 & IE 8 return '[object Object]' for the arguments object, we can detect by checking for the existence of the callee property
+                               (!!iterable.callee)) {
+                               var index;
+                               var length = iterable.length;
+                               for (index = 0; index < length; index++) {
+                                       adder.call(map, iterable[index][0], iterable[index][1]);
+                               }
+                       }
+               }
+               return map;
+       };
+
+       // 23.1.2.1. Map.prototype
+       // The initial value of Map.prototype is the intrinsic object %MapPrototype%.
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
+       Object.defineProperty(Map, 'prototype', {
+               configurable: false,
+               enumerable: false,
+               writable: false,
+               value: {}
+       });
+
+       // 23.1.2.2 get Map [ @@species ]
+       if (supportsGetters) {
+               Object.defineProperty(Map, Symbol.species, {
+                       configurable: true,
+                       enumerable: false,
+                       get: function () {
+                               // 1. Return the this value.
+                               return this;
+                       },
+                       set: undefined
+               });
+       } else {
+               CreateMethodProperty(Map, Symbol.species, Map);
+       }
+
+       // 23.1.3.1 Map.prototype.clear ( )
+       CreateMethodProperty(Map.prototype, 'clear', function clear() {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (Type(M) !== 'object') {
+                               throw new TypeError('Method Map.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 5. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // 5.a. Set p.[[Key]] to empty.
+                               M._keys[i] = undefMarker;
+                               // 5.b. Set p.[[Value]] to empty.
+                               M._values[i] = undefMarker;
+                       }
+                       this._size = 0;
+                       if (!supportsGetters) {
+                               this.size = this._size;
+                       }
+                       // 6. Return undefined.
+                       return undefined;
+               }
+       );
+
+       // 23.1.3.2. Map.prototype.constructor
+       CreateMethodProperty(Map.prototype, 'constructor', Map);
+
+       // 23.1.3.3. Map.prototype.delete ( key )
+       CreateMethodProperty(Map.prototype, 'delete', function (key) {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (Type(M) !== 'object') {
+                               throw new TypeError('Method Map.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 5. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
+                               if (M._keys[i] !== undefMarker && SameValueZero(M._keys[i], key)) {
+                                       // i. Set p.[[Key]] to empty.
+                                       this._keys[i] = undefMarker;
+                                       // ii. Set p.[[Value]] to empty.
+                                       this._values[i] = undefMarker;
+                                       this._size = --this._size;
+                                       if (!supportsGetters) {
+                                               this.size = this._size;
+                                       }
+                                       // iii. Return true.
+                                       return true;
+                               }
+                       }
+                       // 6. Return false.
+                       return false;
+               }
+       );
+
+       // 23.1.3.4. Map.prototype.entries ( )
+       CreateMethodProperty(Map.prototype, 'entries', function entries () {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. Return ? CreateMapIterator(M, "key+value").
+                       return CreateMapIterator(M, 'key+value');
+               }
+       );
+
+       // 23.1.3.5. Map.prototype.forEach ( callbackfn [ , thisArg ] )
+       CreateMethodProperty(Map.prototype, 'forEach', function (callbackFn) {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (Type(M) !== 'object') {
+                               throw new TypeError('Method Map.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
+                       if (!IsCallable(callbackFn)) {
+                               throw new TypeError(Object.prototype.toString.call(callbackFn) + ' is not a function.');
+                       }
+                       // 5. If thisArg is present, let T be thisArg; else let T be undefined.
+                       if (arguments[1]) {
+                               var T = arguments[1];
+                       }
+                       // 6. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 7. For each Record {[[Key]], [[Value]]} e that is an element of entries, in original key insertion order, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. If e.[[Key]] is not empty, then
+                               if (M._keys[i] !== undefMarker && M._values[i] !== undefMarker ) {
+                                       // i. Perform ? Call(callbackfn, T, « e.[[Value]], e.[[Key]], M »).
+                                       callbackFn.call(T, M._values[i], M._keys[i], M);
+                               }
+                       }
+                       // 8. Return undefined.
+                       return undefined;
+               }
+       );
+
+       // 23.1.3.6. Map.prototype.get ( key )
+       CreateMethodProperty(Map.prototype, 'get', function get(key) {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (Type(M) !== 'object') {
+                               throw new TypeError('Method Map.prototype.get called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.get called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 5. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return p.[[Value]].
+                               if (M._keys[i] !== undefMarker && SameValueZero(M._keys[i], key)) {
+                                       return M._values[i];
+                               }
+                       }
+                       // 6. Return undefined.
+                       return undefined;
+               });
+
+       // 23.1.3.7. Map.prototype.has ( key )
+       CreateMethodProperty(Map.prototype, 'has', function has (key) {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (typeof M !== 'object') {
+                               throw new TypeError('Method Map.prototype.has called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.has called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 5. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return true.
+                               if (M._keys[i] !== undefMarker && SameValueZero(M._keys[i], key)) {
+                                       return true;
+                               }
+                       }
+                       // 6. Return false.
+                       return false;
+               });
+
+       // 23.1.3.8. Map.prototype.keys ( )
+       CreateMethodProperty(Map.prototype, 'keys', function keys () {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. Return ? CreateMapIterator(M, "key").
+                       return CreateMapIterator(M, "key");
+               });
+
+       // 23.1.3.9. Map.prototype.set ( key, value )
+       CreateMethodProperty(Map.prototype, 'set', function set(key, value) {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. If Type(M) is not Object, throw a TypeError exception.
+                       if (Type(M) !== 'object') {
+                               throw new TypeError('Method Map.prototype.set called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                       if (M._es6Map !== true) {
+                               throw new TypeError('Method Map.prototype.set called on incompatible receiver ' + Object.prototype.toString.call(M));
+                       }
+                       // 4. Let entries be the List that is M.[[MapData]].
+                       var entries = M._keys;
+                       // 5. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
+                               if (M._keys[i] !== undefMarker && SameValueZero(M._keys[i], key)) {
+                                       // i. Set p.[[Value]] to value.
+                                       M._values[i] = value;
+                                       // Return M.
+                                       return M;
+                               }
+                       }
+                       // 6. If key is -0, let key be +0.
+                       if (1/key === -Infinity) {
+                               key = 0;
+                       }
+                       // 7. Let p be the Record {[[Key]]: key, [[Value]]: value}.
+                       var p = {};
+                       p['[[Key]]'] = key;
+                       p['[[Value]]'] = value;
+                       // 8. Append p as the last element of entries.
+                       M._keys.push(p['[[Key]]']);
+                       M._values.push(p['[[Value]]']);
+                       ++M._size;
+                       if (!supportsGetters) {
+                               M.size = M._size;
+                       }
+                       // 9. Return M.
+                       return M;
+               });
+
+       // 23.1.3.10. get Map.prototype.size
+       if (supportsGetters) {
+               Object.defineProperty(Map.prototype, 'size', {
+                       configurable: true,
+                       enumerable: false,
+                       get: function () {
+                               // 1. Let M be the this value.
+                               var M = this;
+                               // 2. If Type(M) is not Object, throw a TypeError exception.
+                               if (Type(M) !== 'object') {
+                                       throw new TypeError('Method Map.prototype.size called on incompatible receiver ' + Object.prototype.toString.call(M));
+                               }
+                               // 3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
+                               if (M._es6Map !== true) {
+                                       throw new TypeError('Method Map.prototype.size called on incompatible receiver ' + Object.prototype.toString.call(M));
+                               }
+                               // 4. Let entries be the List that is M.[[MapData]].
+                               var entries = M._keys;
+                               // 5. Let count be 0.
+                               var count = 0;
+                               // 6. For each Record {[[Key]], [[Value]]} p that is an element of entries, do
+                               for (var i = 0; i < entries.length; i++) {
+                                       // a. If p.[[Key]] is not empty, set count to count+1.
+                                       if (M._keys[i] !== undefMarker) {
+                                               count = count + 1;
+                                       }
+                               }
+                               // 7. Return count.
+                               return count;
+                       },
+                       set: undefined
+               });
+       }
+
+       // 23.1.3.11. Map.prototype.values ( )
+       CreateMethodProperty(Map.prototype, 'values', function values () {
+                       // 1. Let M be the this value.
+                       var M = this;
+                       // 2. Return ? CreateMapIterator(M, "value").
+                       return CreateMapIterator(M, 'value');
+               }
+       );
+
+       // 23.1.3.12. Map.prototype [ @@iterator ] ( )
+       // The initial value of the @@iterator property is the same function object as the initial value of the entries property.
+       CreateMethodProperty(Map.prototype, Symbol.iterator, Map.prototype.entries);
+
+       // 23.1.3.13. Map.prototype [ @@toStringTag ]
+       // The initial value of the @@toStringTag property is the String value "Map".
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+       // Polyfill.io - Safari 8 implements Map.name but as a non-configurable property, which means it would throw an error if we try and configure it here.
+       if (!('name' in Map)) {
+               // 19.2.4.2 name
+               Object.defineProperty(Map, 'name', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: false,
+                       value: 'Map'
+               });
+       }
+
+       // 23.1.5.1. CreateMapIterator ( map, kind )
+       function CreateMapIterator(map, kind) {
+               // 1. If Type(map) is not Object, throw a TypeError exception.
+               if (Type(map) !== 'object') {
+                       throw new TypeError('createMapIterator called on incompatible receiver ' + Object.prototype.toString.call(map));
+               }
+               // 2. If map does not have a [[MapData]] internal slot, throw a TypeError exception.
+               if (map._es6Map !== true) {
+                       throw new TypeError('createMapIterator called on incompatible receiver ' + Object.prototype.toString.call(map));
+               }
+               // 3. Let iterator be ObjectCreate(%MapIteratorPrototype%, « [[Map]], [[MapNextIndex]], [[MapIterationKind]] »).
+               var iterator = Object.create(MapIteratorPrototype);
+               // 4. Set iterator.[[Map]] to map.
+               Object.defineProperty(iterator, '[[Map]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: map
+               });
+               // 5. Set iterator.[[MapNextIndex]] to 0.
+               Object.defineProperty(iterator, '[[MapNextIndex]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: 0
+               });
+               // 6. Set iterator.[[MapIterationKind]] to kind.
+               Object.defineProperty(iterator, '[[MapIterationKind]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: kind
+               });
+               // 7. Return iterator.
+               return iterator;
+       }
+
+       // 23.1.5.2. The %MapIteratorPrototype% Object
+       var MapIteratorPrototype = {};
+       // Polyfill.io - We use this as a quick way to check if an object is a Map Iterator instance.
+       Object.defineProperty(MapIteratorPrototype, 'isMapIterator', {
+               configurable: false,
+               enumerable: false,
+               writable: false,
+               value: true
+       });
+
+       // 23.1.5.2.1. %MapIteratorPrototype%.next ( )
+       CreateMethodProperty(MapIteratorPrototype, 'next', function next() {
+                       // 1. Let O be the this value.
+                       var O = this;
+                       // 2. If Type(O) is not Object, throw a TypeError exception.
+                       if (Type(O) !== 'object') {
+                               throw new TypeError('Method %MapIteratorPrototype%.next called on incompatible receiver ' + Object.prototype.toString.call(O));
+                       }
+                       // 3. If O does not have all of the internal slots of a Map Iterator Instance (23.1.5.3), throw a TypeError exception.
+                       if (!O.isMapIterator) {
+                               throw new TypeError('Method %MapIteratorPrototype%.next called on incompatible receiver ' + Object.prototype.toString.call(O));
+                       }
+                       // 4. Let m be O.[[Map]].
+                       var m = O['[[Map]]'];
+                       // 5. Let index be O.[[MapNextIndex]].
+                       var index = O['[[MapNextIndex]]'];
+                       // 6. Let itemKind be O.[[MapIterationKind]].
+                       var itemKind = O['[[MapIterationKind]]'];
+                       // 7. If m is undefined, return CreateIterResultObject(undefined, true).
+                       if (m === undefined) {
+                               return CreateIterResultObject(undefined, true);
+                       }
+                       // 8. Assert: m has a [[MapData]] internal slot.
+                       if (!m._es6Map) {
+                               throw new Error(Object.prototype.toString.call(m) + ' has a [[MapData]] internal slot.');
+                       }
+                       // 9. Let entries be the List that is m.[[MapData]].
+                       var entries = m._keys;
+                       // 10. Let numEntries be the number of elements of entries.
+                       var numEntries = entries.length;
+                       // 11. NOTE: numEntries must be redetermined each time this method is evaluated.
+                       // 12. Repeat, while index is less than numEntries,
+                       while (index < numEntries) {
+                               // a. Let e be the Record {[[Key]], [[Value]]} that is the value of entries[index].
+                               var e = Object.create(null);
+                               e['[[Key]]'] = m._keys[index];
+                               e['[[Value]]'] = m._values[index];
+                               // b. Set index to index+1.
+                               index = index + 1;
+                               // c. Set O.[[MapNextIndex]] to index.
+                               O['[[MapNextIndex]]'] = index;
+                               // d. If e.[[Key]] is not empty, then
+                               if (e['[[Key]]'] !== undefMarker) {
+                                       // i. If itemKind is "key", let result be e.[[Key]].
+                                       if (itemKind === 'key') {
+                                               var result = e['[[Key]]'];
+                                               // ii. Else if itemKind is "value", let result be e.[[Value]].
+                                       } else if (itemKind === 'value') {
+                                               result = e['[[Value]]'];
+                                               // iii. Else,
+                                       } else {
+                                               // 1. Assert: itemKind is "key+value".
+                                               if (itemKind !== 'key+value') {
+                                                       throw new Error();
+                                               }
+                                               // 2. Let result be CreateArrayFromList(« e.[[Key]], e.[[Value]] »).
+                                               result = [
+                                                       e['[[Key]]'],
+                                                       e['[[Value]]']
+                                               ];
+                                       }
+                                       // iv. Return CreateIterResultObject(result, false).
+                                       return CreateIterResultObject(result, false);
+                               }
+                       }
+                       // 13. Set O.[[Map]] to undefined.
+                       O['[[Map]]'] = undefined;
+                       // 14. Return CreateIterResultObject(undefined, true).
+                       return CreateIterResultObject(undefined, true);
+               }
+       );
+
+       // 23.1.5.2.2 %MapIteratorPrototype% [ @@toStringTag ]
+       // The initial value of the @@toStringTag property is the String value "Map Iterator".
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+       CreateMethodProperty(MapIteratorPrototype, Symbol.iterator, function iterator() {
+                       return this;
+               }
+       );
+
+       // Export the object
+       try {
+               CreateMethodProperty(global, 'Map', Map);
+       } catch (e) {
+               // IE8 throws an error here if we set enumerable to false.
+               // More info on table 2: https://msdn.microsoft.com/en-us/library/dd229916(v=vs.85).aspx
+               global['Map'] = Map;
+       }
+}(this));
+
+}
+
+if (!('Set' in this && (function() {
+       try {
+               var s = new Set([1, 2]);
+               if (Set.length === 0) {
+                       if (s.size === 2) {
+                               if ('Symbol' in this && 'iterator' in Symbol && typeof s[Symbol.iterator] === 'function') {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       } catch (e) {
+               return false;
+       }
+}()))) {
+
+// Set
+/* global CreateIterResultObject, CreateMethodProperty, GetIterator, IsCallable, IteratorClose, IteratorStep, IteratorValue, OrdinaryCreateFromConstructor, SameValueZero, Symbol */
+(function (global) {
+       var supportsGetters = (function () {
+               try {
+                       var a = {};
+                       Object.defineProperty(a, 't', {
+                               configurable: true,
+                               enumerable: false,
+                               get: function () {
+                                       return true;
+                               },
+                               set: undefined
+                       });
+                       return !!a.t;
+               } catch (e) {
+                       return false;
+               }
+       }());
+
+       // Deleted set items mess with iterator pointers, so rather than removing them mark them as deleted. Can't use undefined or null since those both valid keys so use a private symbol.
+       var undefMarker = Symbol('undef');
+       // 23.2.1.1. Set ( [ iterable ] )
+       var Set = function Set(/* iterable */) {
+               // 1. If NewTarget is undefined, throw a TypeError exception.
+               if (!(this instanceof Set)) {
+                       throw new TypeError('Constructor Set requires "new"');
+               }
+               // 2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%SetPrototype%", « [[SetData]] »).
+               var set = OrdinaryCreateFromConstructor(this, Set.prototype, {
+                       _values: [],
+                       _size: 0,
+                       _es6Set: true
+               });
+
+               // 3. Set set.[[SetData]] to a new empty List.
+               // Polyfill.io - This step was done as part of step two.
+
+               // Some old engines do not support ES5 getters/setters.  Since Set only requires these for the size property, we can fall back to setting the size property statically each time the size of the set changes.
+               if (!supportsGetters) {
+                       Object.defineProperty(set, 'size', {
+                               configurable: true,
+                               enumerable: false,
+                               writable: true,
+                               value: 0
+                       });
+               }
+
+               // 4. If iterable is not present, let iterable be undefined.
+               var iterable = arguments.length > 0 ? arguments[0] : undefined;
+
+               // 5. If iterable is either undefined or null, return set.
+               if (iterable === null || iterable === undefined) {
+                       return set;
+               }
+
+               // 6. Let adder be ? Get(set, "add").
+               var adder = set.add;
+               // 7. If IsCallable(adder) is false, throw a TypeError exception.
+               if (!IsCallable(adder)) {
+                       throw new TypeError("Set.prototype.add is not a function");
+               }
+
+               try {
+                       // 8. Let iteratorRecord be ? GetIterator(iterable).
+                       var iteratorRecord = GetIterator(iterable);
+                       // 9. Repeat,
+                       while (true) {
+                               // a. Let next be ? IteratorStep(iteratorRecord).
+                               var next = IteratorStep(iteratorRecord);
+                               // b. If next is false, return set.
+                               if (next === false) {
+                                       return set;
+                               }
+                               // c. Let nextValue be ? IteratorValue(next).
+                               var nextValue = IteratorValue(next);
+                               // d. Let status be Call(adder, set, « nextValue.[[Value]] »).
+                               try {
+                                       adder.call(set, nextValue);
+                               } catch (e) {
+                                       // e. If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).
+                                       return IteratorClose(iteratorRecord, e);
+                               }
+                       }
+               } catch (e) {
+                       // Polyfill.io - For user agents which do not have iteration methods on argument objects or arrays, we can special case those.
+                       if (Array.isArray(iterable) ||
+                               Object.prototype.toString.call(iterable) === '[object Arguments]' ||
+                               // IE 7 & IE 8 return '[object Object]' for the arguments object, we can detect by checking for the existence of the callee property
+                               (!!iterable.callee)) {
+                               var index;
+                               var length = iterable.length;
+                               for (index = 0; index < length; index++) {
+                                       adder.call(set, iterable[index]);
+                               }
+                       }
+               }
+               return set;
+       };
+
+       // 23.2.2.1. Set.prototype
+       // The initial value of Set.prototype is the intrinsic %SetPrototype% object.
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
+       Object.defineProperty(Set, 'prototype', {
+               configurable: false,
+               enumerable: false,
+               writable: false,
+               value: {}
+       });
+
+       // 23.2.2.2 get Set [ @@species ]
+       if (supportsGetters) {
+               Object.defineProperty(Set, Symbol.species, {
+                       configurable: true,
+                       enumerable: false,
+                       get: function () {
+                               // 1. Return the this value.
+                               return this;
+                       },
+                       set: undefined
+               });
+       } else {
+               CreateMethodProperty(Set, Symbol.species, Set);
+       }
+
+       // 23.2.3.1. Set.prototype.add ( value )
+       CreateMethodProperty(Set.prototype, 'add', function add(value) {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. If Type(S) is not Object, throw a TypeError exception.
+                       if (typeof S !== 'object') {
+                               throw new TypeError('Method Set.prototype.add called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                       if (S._es6Set !== true) {
+                               throw new TypeError('Method Set.prototype.add called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 4. Let entries be the List that is S.[[SetData]].
+                       var entries = S._values;
+                       // 5. For each e that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               var e = entries[i];
+                               // a. If e is not empty and SameValueZero(e, value) is true, then
+                               if (e !== undefMarker && SameValueZero(e, value)) {
+                                       // i. Return S.
+                                       return S;
+                               }
+                       }
+                       // 6. If value is -0, let value be +0.
+                       if (1/value === -Infinity) {
+                               value = 0;
+                       }
+                       // 7. Append value as the last element of entries.
+                       S._values.push(value);
+
+                       this._size = ++this._size;
+                       if (!supportsGetters) {
+                               this.size = this._size;
+                       }
+                       // 8. Return S.
+                       return S;
+               });
+
+       // 23.2.3.2. Set.prototype.clear ( )
+       CreateMethodProperty(Set.prototype, 'clear', function clear() {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. If Type(S) is not Object, throw a TypeError exception.
+                       if (typeof S !== 'object') {
+                               throw new TypeError('Method Set.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                       if (S._es6Set !== true) {
+                               throw new TypeError('Method Set.prototype.clear called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 4. Let entries be the List that is S.[[SetData]].
+                       var entries = S._values;
+                       // 5. For each e that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               // a. Replace the element of entries whose value is e with an element whose value is empty.
+                               entries[i] = undefMarker;
+                       }
+                       this._size = 0;
+                       if (!supportsGetters) {
+                               this.size = this._size;
+                       }
+                       // 6. Return undefined.
+                       return undefined;
+               });
+
+       // 23.2.3.3. Set.prototype.constructor
+       CreateMethodProperty(Set.prototype, 'constructor', Set);
+
+       // 23.2.3.4. Set.prototype.delete ( value )
+       CreateMethodProperty(Set.prototype, 'delete', function (value) {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. If Type(S) is not Object, throw a TypeError exception.
+                       if (typeof S !== 'object') {
+                               throw new TypeError('Method Set.prototype.delete called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                       if (S._es6Set !== true) {
+                               throw new TypeError('Method Set.prototype.delete called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 4. Let entries be the List that is S.[[SetData]].
+                       var entries = S._values;
+                       // 5. For each e that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               var e = entries[i];
+                               // a. If e is not empty and SameValueZero(e, value) is true, then
+                               if (e !== undefMarker && SameValueZero(e, value)) {
+                                       // i. Replace the element of entries whose value is e with an element whose value is empty.
+                                       entries[i] = undefMarker;
+
+                                       this._size = --this._size;
+                                       if (!supportsGetters) {
+                                               this.size = this._size;
+                                       }
+                                       // ii. Return true.
+                                       return true;
+                               }
+                       }
+                       // 6. Return false.
+                       return false;
+               }
+       );
+
+       // 23.2.3.5. Set.prototype.entries ( )
+       CreateMethodProperty(Set.prototype, 'entries', function entries() {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. Return ? CreateSetIterator(S, "key+value").
+                       return CreateSetIterator(S, 'key+value');
+               }
+       );
+
+       // 23.2.3.6. Set.prototype.forEach ( callbackfn [ , thisArg ] )
+       CreateMethodProperty(Set.prototype, 'forEach', function forEach(callbackFn /*[ , thisArg ]*/) {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. If Type(S) is not Object, throw a TypeError exception.
+                       if (typeof S !== 'object') {
+                               throw new TypeError('Method Set.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                       if (S._es6Set !== true) {
+                               throw new TypeError('Method Set.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
+                       if (!IsCallable(callbackFn)) {
+                               throw new TypeError(Object.prototype.toString.call(callbackFn) + ' is not a function.');
+                       }
+                       // 5. If thisArg is present, let T be thisArg; else let T be undefined.
+                       if (arguments[1]) {
+                               var T = arguments[1];
+                       }
+                       // 6. Let entries be the List that is S.[[SetData]].
+                       var entries = S._values;
+                       // 7. For each e that is an element of entries, in original insertion order, do
+                       for (var i = 0; i < entries.length; i++) {
+                               var e = entries[i];
+                               // a. If e is not empty, then
+                               if (e !== undefMarker) {
+                                       // i. Perform ? Call(callbackfn, T, « e, e, S »).
+                                       callbackFn.call(T, e, e, S);
+                               }
+                       }
+                       // 8. Return undefined.
+                       return undefined;
+               }
+       );
+
+       // 23.2.3.7. Set.prototype.has ( value )
+       CreateMethodProperty(Set.prototype, 'has', function has(value) {
+                       // 1. Let S be the this value.
+                       var S = this;
+                       // 2. If Type(S) is not Object, throw a TypeError exception.
+                       if (typeof S !== 'object') {
+                               throw new TypeError('Method Set.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                       if (S._es6Set !== true) {
+                               throw new TypeError('Method Set.prototype.forEach called on incompatible receiver ' + Object.prototype.toString.call(S));
+                       }
+                       // 4. Let entries be the List that is S.[[SetData]].
+                       var entries = S._values;
+                       // 5. For each e that is an element of entries, do
+                       for (var i = 0; i < entries.length; i++) {
+                               var e = entries[i];
+                               // a. If e is not empty and SameValueZero(e, value) is true, return true.
+                               if (e !== undefMarker && SameValueZero(e, value)) {
+                                       return true;
+                               }
+                       }
+                       // 6. Return false.
+                       return false;
+               }
+       );
+
+       // Polyfill.io - We need to define Set.prototype.values before Set.prototype.keys because keys is a reference to values.
+       // 23.2.3.10. Set.prototype.values()
+       var values = function values() {
+               // 1. Let S be the this value.
+               var S = this;
+               // 2. Return ? CreateSetIterator(S, "value").
+               return CreateSetIterator(S, "value");
+       };
+       CreateMethodProperty(Set.prototype, 'values', values);
+
+       // 23.2.3.8 Set.prototype.keys ( )
+       // The initial value of the keys property is the same function object as the initial value of the values property.
+       CreateMethodProperty(Set.prototype, 'keys', values);
+
+       // 23.2.3.9. get Set.prototype.size
+       if (supportsGetters) {
+               Object.defineProperty(Set.prototype, 'size', {
+                       configurable: true,
+                       enumerable: false,
+                       get: function () {
+                               // 1. Let S be the this value.
+                               var S = this;
+                               // 2. If Type(S) is not Object, throw a TypeError exception.
+                               if (typeof S !== 'object') {
+                                       throw new TypeError('Method Set.prototype.size called on incompatible receiver ' + Object.prototype.toString.call(S));
+                               }
+                               // 3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
+                               if (S._es6Set !== true) {
+                                       throw new TypeError('Method Set.prototype.size called on incompatible receiver ' + Object.prototype.toString.call(S));
+                               }
+                               // 4. Let entries be the List that is S.[[SetData]].
+                               var entries = S._values;
+                               // 5. Let count be 0.
+                               var count = 0;
+                               // 6. For each e that is an element of entries, do
+                               for (var i = 0; i < entries.length; i++) {
+                                       var e = entries[i];
+                                       // a. If e is not empty, set count to count+1.
+                                       if (e !== undefMarker) {
+                                               count = count + 1;
+                                       }
+                               }
+                               // 7. Return count.
+                               return count;
+                       },
+                       set: undefined
+               });
+       }
+
+       // 23.2.3.11. Set.prototype [ @@iterator ] ( )
+       // The initial value of the @@iterator property is the same function object as the initial value of the values property.
+       CreateMethodProperty(Set.prototype, Symbol.iterator, values);
+
+       // 23.2.3.12. Set.prototype [ @@toStringTag ]
+       // The initial value of the @@toStringTag property is the String value "Set".
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+       // Polyfill.io - Safari 8 implements Set.name but as a non-configurable property, which means it would throw an error if we try and configure it here.
+       if (!('name' in Set)) {
+               // 19.2.4.2 name
+               Object.defineProperty(Set, 'name', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: false,
+                       value: 'Set'
+               });
+       }
+
+       // 23.2.5.1. CreateSetIterator ( set, kind )
+       function CreateSetIterator(set, kind) {
+               // 1. If Type(set) is not Object, throw a TypeError exception.
+               if (typeof set !== 'object') {
+                       throw new TypeError('createSetIterator called on incompatible receiver ' + Object.prototype.toString.call(set));
+               }
+               // 2. If set does not have a [[SetData]] internal slot, throw a TypeError exception.
+               if (set._es6Set !== true) {
+                       throw new TypeError('createSetIterator called on incompatible receiver ' + Object.prototype.toString.call(set));
+               }
+               // 3. Let iterator be ObjectCreate(%SetIteratorPrototype%, « [[IteratedSet]], [[SetNextIndex]], [[SetIterationKind]] »).
+               var iterator = Object.create(SetIteratorPrototype);
+               // 4. Set iterator.[[IteratedSet]] to set.
+               Object.defineProperty(iterator, '[[IteratedSet]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: set
+               });
+               // 5. Set iterator.[[SetNextIndex]] to 0.
+               Object.defineProperty(iterator, '[[SetNextIndex]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: 0
+               });
+               // 6. Set iterator.[[SetIterationKind]] to kind.
+               Object.defineProperty(iterator, '[[SetIterationKind]]', {
+                       configurable: true,
+                       enumerable: false,
+                       writable: true,
+                       value: kind
+               });
+               // 7. Return iterator.
+               return iterator;
+       }
+
+       // 23.2.5.2. The %SetIteratorPrototype% Object
+       var SetIteratorPrototype = {};
+       //Polyfill.io - We add this property to help us identify what is a set iterator.
+       Object.defineProperty(SetIteratorPrototype, 'isSetIterator', {
+               configurable: false,
+               enumerable: false,
+               writable: false,
+               value: true
+       });
+
+       // 23.2.5.2.1. %SetIteratorPrototype%.next ( )
+       CreateMethodProperty(SetIteratorPrototype, 'next', function next() {
+               // 1. Let O be the this value.
+               var O = this;
+               // 2. If Type(O) is not Object, throw a TypeError exception.
+               if (typeof O !== 'object') {
+                       throw new TypeError('Method %SetIteratorPrototype%.next called on incompatible receiver ' + Object.prototype.toString.call(O));
+               }
+               // 3. If O does not have all of the internal slots of a Set Iterator Instance (23.2.5.3), throw a TypeError exception.
+               if (!O.isSetIterator) {
+                       throw new TypeError('Method %SetIteratorPrototype%.next called on incompatible receiver ' + Object.prototype.toString.call(O));
+               }
+               // 4. Let s be O.[[IteratedSet]].
+               var s = O['[[IteratedSet]]'];
+               // 5. Let index be O.[[SetNextIndex]].
+               var index = O['[[SetNextIndex]]'];
+               // 6. Let itemKind be O.[[SetIterationKind]].
+               var itemKind = O['[[SetIterationKind]]'];
+               // 7. If s is undefined, return CreateIterResultObject(undefined, true).
+               if (s === undefined) {
+                       return CreateIterResultObject(undefined, true);
+               }
+               // 8. Assert: s has a [[SetData]] internal slot.
+               if (!s._es6Set) {
+                       throw new Error(Object.prototype.toString.call(s) + ' does not have [[SetData]] internal slot.');
+               }
+               // 9. Let entries be the List that is s.[[SetData]].
+               var entries = s._values;
+               // 10. Let numEntries be the number of elements of entries.
+               var numEntries = entries.length;
+               // 11. NOTE: numEntries must be redetermined each time this method is evaluated.
+               // 12. Repeat, while index is less than numEntries,
+               while (index < numEntries) {
+                       // a. Let e be entries[index].
+                       var e = entries[index];
+                       // b. Set index to index+1.
+                       index = index + 1;
+                       // c. Set O.[[SetNextIndex]] to index.
+                       O['[[SetNextIndex]]'] = index;
+                       // d. If e is not empty, then
+                       if (e !== undefMarker) {
+                               // i. If itemKind is "key+value", then
+                               if (itemKind === 'key+value') {
+                                       // 1. Return CreateIterResultObject(CreateArrayFromList(« e, e »), false).
+                                       return CreateIterResultObject([e, e], false);
+                               }
+                               // ii. Return CreateIterResultObject(e, false).
+                               return CreateIterResultObject(e, false);
+                       }
+               }
+               // 13. Set O.[[IteratedSet]] to undefined.
+               O['[[IteratedSet]]'] = undefined;
+               // 14. Return CreateIterResultObject(undefined, true).
+               return CreateIterResultObject(undefined, true);
+       });
+
+       // 23.2.5.2.2. %SetIteratorPrototype% [ @@toStringTag ]
+       // The initial value of the @@toStringTag property is the String value "Set Iterator".
+       // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+       CreateMethodProperty(SetIteratorPrototype, Symbol.iterator, function iterator() {
+                       return this;
+               }
+       );
+
+       // Export the object
+       try {
+               CreateMethodProperty(global, 'Set', Set);
+       } catch (e) {
+               // IE8 throws an error here if we set enumerable to false.
+               // More info on table 2: https://msdn.microsoft.com/en-us/library/dd229916(v=vs.85).aspx
+               global['Set'] = Set;
+       }
+
+}(this));
+
+}
+
+if (!('from' in Array && (function () {
+       try {
+               Array.from({ length: -Infinity });
+
+               return true;
+       } catch (e) {
+               return false;
+       }
+}()))) {
+
+// Array.from
+/* globals
+       IsCallable, GetMethod, Symbol, IsConstructor, Construct, ArrayCreate, GetIterator, IteratorClose,
+       ToString, IteratorStep, IteratorValue, Call, CreateDataPropertyOrThrow, ToObject, ToLength, Get, CreateMethodProperty
+*/
+(function () {
+       var toString = Object.prototype.toString;
+       var stringMatch = String.prototype.match;
+       // A cross-realm friendly way to detect if a value is a String object or literal.
+       function isString(value) {
+               if (typeof value === 'string') { return true; }
+               if (typeof value !== 'object') { return false; }
+               return toString.call(value) === '[object String]';
+       }
+
+       // 22.1.2.1. Array.from ( items [ , mapfn [ , thisArg ] ] )
+       CreateMethodProperty(Array, 'from', function from(items /* [ , mapfn [ , thisArg ] ] */) { // eslint-disable-line no-undef
+               // 1. Let C be the this value.
+               var C = this;
+               // 2. If mapfn is undefined, let mapping be false.
+               var mapfn = arguments.length > 1 ? arguments[1] : undefined;
+               if (mapfn === undefined) {
+                       var mapping = false;
+                       // 3. Else,
+               } else {
+                       // a. If IsCallable(mapfn) is false, throw a TypeError exception.
+                       if (IsCallable(mapfn) === false) {
+                               throw new TypeError(Object.prototype.toString.call(mapfn) + ' is not a function.');
+                       }
+                       // b. If thisArg is present, let T be thisArg; else let T be undefined.
+                       var thisArg = arguments.length > 2 ? arguments[2] : undefined;
+                       if (thisArg !== undefined) {
+                               var T = thisArg;
+                       } else {
+                               T = undefined;
+                       }
+                       // c. Let mapping be true.
+                       mapping = true;
+
+               }
+               // 4. Let usingIterator be ? GetMethod(items, @@iterator).
+               var usingIterator = GetMethod(items, Symbol.iterator);
+               // 5. If usingIterator is not undefined, then
+               if (usingIterator !== undefined) {
+                       // a. If IsConstructor(C) is true, then
+                       if (IsConstructor(C)) {
+                               // i. Let A be ? Construct(C).
+                               var A = Construct(C);
+                               // b. Else,
+                       } else {
+                               // i. Let A be ! ArrayCreate(0).
+                               A = ArrayCreate(0);
+                       }
+                       // c. Let iteratorRecord be ? GetIterator(items, usingIterator).
+                       var iteratorRecord = GetIterator(items, usingIterator);
+                       // d. Let k be 0.
+                       var k = 0;
+                       // e. Repeat,
+                       while (true) {
+                               // i. If k ≥ 2^53-1, then
+                               if (k >= (Math.pow(2, 53) - 1)) {
+                                       // 1. Let error be Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.
+                                       var error = new TypeError('Iteration count can not be greater than or equal 9007199254740991.');
+                                       // 2. Return ? IteratorClose(iteratorRecord, error).
+                                       return IteratorClose(iteratorRecord, error);
+                               }
+                               // ii. Let Pk be ! ToString(k).
+                               var Pk = ToString(k);
+                               // iii. Let next be ? IteratorStep(iteratorRecord).
+                               var next = IteratorStep(iteratorRecord);
+                               // iv. If next is false, then
+                               if (next === false) {
+                                       // 1. Perform ? Set(A, "length", k, true).
+                                       A["length"] = k;
+                                       // 2. Return A.
+                                       return A;
+                               }
+                               // v. Let nextValue be ? IteratorValue(next).
+                               var nextValue = IteratorValue(next);
+                               // vi. If mapping is true, then
+                               if (mapping) {
+                                       try {
+                                               // Polyfill.io - The try catch accounts for step 2.
+                                               // 1. Let mappedValue be Call(mapfn, T, « nextValue, k »).
+                                               var mappedValue = Call(mapfn, T, [nextValue, k]);
+                                               // 2. If mappedValue is an abrupt completion, return ? IteratorClose(iteratorRecord, mappedValue).
+                                               // 3. Let mappedValue be mappedValue.[[Value]].
+                                       } catch (e) {
+                                               return IteratorClose(iteratorRecord, e);
+                                       }
+
+                                       // vii. Else, let mappedValue be nextValue.
+                               } else {
+                                       mappedValue = nextValue;
+                               }
+                               try {
+                                       // Polyfill.io - The try catch accounts for step ix.
+                                       // viii. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
+                                       CreateDataPropertyOrThrow(A, Pk, mappedValue);
+                                       // ix. If defineStatus is an abrupt completion, return ? IteratorClose(iteratorRecord, defineStatus).
+                               } catch (e) {
+                                       return IteratorClose(iteratorRecord, e);
+                               }
+                               // x. Increase k by 1.
+                               k = k + 1;
+                       }
+               }
+               // 6. NOTE: items is not an Iterable so assume it is an array-like object.
+               // 7. Let arrayLike be ! ToObject(items).
+               // Polyfill.io - For Strings we need to split astral symbols into surrogate pairs.
+               if (isString(items)) {
+                       var arrayLike = stringMatch.call(items, /[\uD800-\uDBFF][\uDC00-\uDFFF]?|[^\uD800-\uDFFF]|./g) || [];
+               } else {
+                       arrayLike = ToObject(items);
+               }
+               // 8. Let len be ? ToLength(? Get(arrayLike, "length")).
+               var len = ToLength(Get(arrayLike, "length"));
+               // 9. If IsConstructor(C) is true, then
+               if (IsConstructor(C)) {
+                       // a. Let A be ? Construct(C, « len »).
+                       A = Construct(C, [len]);
+                       // 10. Else,
+               } else {
+                       // a. Let A be ? ArrayCreate(len).
+                       A = ArrayCreate(len);
+               }
+               // 11. Let k be 0.
+               k = 0;
+               // 12. Repeat, while k < len
+               while (k < len) {
+                       // a. Let Pk be ! ToString(k).
+                       Pk = ToString(k);
+                       // b. Let kValue be ? Get(arrayLike, Pk).
+                       var kValue = Get(arrayLike, Pk);
+                       // c. If mapping is true, then
+                       if (mapping === true) {
+                               // i. Let mappedValue be ? Call(mapfn, T, « kValue, k »).
+                               mappedValue = Call(mapfn, T, [kValue, k]);
+                               // d. Else, let mappedValue be kValue.
+                       } else {
+                               mappedValue = kValue;
+                       }
+                       // e. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
+                       CreateDataPropertyOrThrow(A, Pk, mappedValue);
+                       // f. Increase k by 1.
+                       k = k + 1;
+               }
+               // 13. Perform ? Set(A, "length", len, true).
+               A["length"] = len;
+               // 14. Return A.
+               return A;
+       });
+}());
+
+}
+
+if (!('of' in Array)) {
+
+// Array.of
+/* global ArrayCreate, Construct, CreateDataPropertyOrThrow, CreateMethodProperty, IsConstructor, ToString */
+// 22.1.2.3. Array.of ( ...items )
+CreateMethodProperty(Array, 'of', function of() {
+       // 1. Let len be the actual number of arguments passed to this function.
+       var len = arguments.length;
+       // 2. Let items be the List of arguments passed to this function.
+       var items = arguments;
+       // 3. Let C be the this value.
+       var C = this;
+       // 4. If IsConstructor(C) is true, then
+       if (IsConstructor(C)) {
+               // a. Let A be ? Construct(C, « len »).
+               var A = Construct(C, [len]);
+               // 5. Else,
+       } else {
+               // a. Let A be ? ArrayCreate(len).
+               var A = ArrayCreate(len);
+       }
+       // 6. Let k be 0.
+       var k = 0;
+       // 7. Repeat, while k < len
+       while (k < len) {
+               // a. Let kValue be items[k].
+               var kValue = items[k];
+               // b. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // c. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue).
+               CreateDataPropertyOrThrow(A, Pk, kValue);
+               // d. Increase k by 1.
+               var k = k + 1;
+
+       }
+       // 8. Perform ? Set(A, "length", len, true)
+       A["length"] = len;
+       // 9. Return A.
+       return A;
+});
+
+}
+
+if (!('assign' in Object)) {
+
+// Object.assign
+/* global CreateMethodProperty, Get, ToObject */
+// 19.1.2.1 Object.assign ( target, ...sources )
+CreateMethodProperty(Object, 'assign', function assign(target, source) { // eslint-disable-line no-unused-vars
+       // 1. Let to be ? ToObject(target).
+       var to = ToObject(target);
+
+       // 2. If only one argument was passed, return to.
+       if (arguments.length === 1) {
+               return to;
+       }
+
+       // 3. Let sources be the List of argument values starting with the second argument
+       var sources = Array.prototype.slice.call(arguments, 1);
+
+       // 4. For each element nextSource of sources, in ascending index order, do
+       var index1;
+       var index2;
+       var keys;
+       var from;
+       for (index1 = 0; index1 < sources.length; index1++) {
+               var nextSource = sources[index1];
+               // a. If nextSource is undefined or null, let keys be a new empty List.
+               if (nextSource === undefined || nextSource === null) {
+                       keys = [];
+                       // b. Else,
+               } else {
+                       // i. Let from be ! ToObject(nextSource).
+                       from = ToObject(nextSource);
+                       // ii. Let keys be ? from.[[OwnPropertyKeys]]().
+                       /*
+                               This step in our polyfill is not complying with the specification.
+                               [[OwnPropertyKeys]] is meant to return ALL keys, including non-enumerable and symbols.
+                               TODO: When we have Reflect.ownKeys, use that instead as it is the userland equivalent of [[OwnPropertyKeys]].
+                       */
+                       keys = Object.keys(from);
+               }
+
+               // c. For each element nextKey of keys in List order, do
+               for (index2 = 0; index2 < keys.length; index2++) {
+                       var nextKey = keys[index2];
+                       // i. Let desc be ? from.[[GetOwnProperty]](nextKey).
+                       var desc = Object.getOwnPropertyDescriptor(from, nextKey);
+                       // ii. If desc is not undefined and desc.[[Enumerable]] is true, then
+                       if (desc !== undefined && desc.enumerable) {
+                               // 1. Let propValue be ? Get(from, nextKey).
+                               var propValue = Get(from, nextKey);
+                               // 2. Perform ? Set(to, nextKey, propValue, true).
+                               to[nextKey] = propValue;
+                       }
+               }
+       }
+       // 5. Return to.
+       return to;
+});
+
+}
+
+if (!('Symbol' in this && 'toStringTag' in this.Symbol)) {
+
+// Symbol.toStringTag
+/* global Symbol */
+Object.defineProperty(Symbol, 'toStringTag', {
+       value: Symbol('toStringTag')
+});
+
+}
+
+
+// _Iterator
+/* global Symbol */
+// A modification of https://github.com/medikoo/es6-iterator
+// Copyright (C) 2013-2015 Mariusz Nowak (www.medikoo.com)
+
+var Iterator = (function () { // eslint-disable-line no-unused-vars
+       var clear = function () {
+               this.length = 0;
+               return this;
+       };
+       var callable = function (fn) {
+               if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
+               return fn;
+       };
+
+       var Iterator = function (list, context) {
+               if (!(this instanceof Iterator)) {
+                       return new Iterator(list, context);
+               }
+               Object.defineProperties(this, {
+                       __list__: {
+                               writable: true,
+                               value: list
+                       },
+                       __context__: {
+                               writable: true,
+                               value: context
+                       },
+                       __nextIndex__: {
+                               writable: true,
+                               value: 0
+                       }
+               });
+               if (!context) return;
+               callable(context.on);
+               context.on('_add', this._onAdd.bind(this));
+               context.on('_delete', this._onDelete.bind(this));
+               context.on('_clear', this._onClear.bind(this));
+       };
+
+       Object.defineProperties(Iterator.prototype, Object.assign({
+               constructor: {
+                       value: Iterator,
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _next: {
+                       value: function () {
+                               var i;
+                               if (!this.__list__) return;
+                               if (this.__redo__) {
+                                       i = this.__redo__.shift();
+                                       if (i !== undefined) return i;
+                               }
+                               if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++;
+                               this._unBind();
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               next: {
+                       value: function () {
+                               return this._createResult(this._next());
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _createResult: {
+                       value: function (i) {
+                               if (i === undefined) return {
+                                       done: true,
+                                       value: undefined
+                               };
+                               return {
+                                       done: false,
+                                       value: this._resolve(i)
+                               };
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _resolve: {
+                       value: function (i) {
+                               return this.__list__[i];
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _unBind: {
+                       value: function () {
+                               this.__list__ = null;
+                               delete this.__redo__;
+                               if (!this.__context__) return;
+                               this.__context__.off('_add', this._onAdd.bind(this));
+                               this.__context__.off('_delete', this._onDelete.bind(this));
+                               this.__context__.off('_clear', this._onClear.bind(this));
+                               this.__context__ = null;
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               toString: {
+                       value: function () {
+                               return '[object Iterator]';
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               }
+       }, {
+               _onAdd: {
+                       value: function (index) {
+                               if (index >= this.__nextIndex__) return;
+                               ++this.__nextIndex__;
+                               if (!this.__redo__) {
+                                       Object.defineProperty(this, '__redo__', {
+                                               value: [index],
+                                               configurable: true,
+                                               enumerable: false,
+                                               writable: false
+                                       });
+                                       return;
+                               }
+                               this.__redo__.forEach(function (redo, i) {
+                                       if (redo >= index) this.__redo__[i] = ++redo;
+                               }, this);
+                               this.__redo__.push(index);
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _onDelete: {
+                       value: function (index) {
+                               var i;
+                               if (index >= this.__nextIndex__) return;
+                               --this.__nextIndex__;
+                               if (!this.__redo__) return;
+                               i = this.__redo__.indexOf(index);
+                               if (i !== -1) this.__redo__.splice(i, 1);
+                               this.__redo__.forEach(function (redo, i) {
+                                       if (redo > index) this.__redo__[i] = --redo;
+                               }, this);
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _onClear: {
+                       value: function () {
+                               if (this.__redo__) clear.call(this.__redo__);
+                               this.__nextIndex__ = 0;
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               }
+       }));
+
+       Object.defineProperty(Iterator.prototype, Symbol.iterator, {
+               value: function () {
+                       return this;
+               },
+               configurable: true,
+               enumerable: false,
+               writable: true
+       });
+       Object.defineProperty(Iterator.prototype, Symbol.toStringTag, {
+               value: 'Iterator',
+               configurable: false,
+               enumerable: false,
+               writable: true
+       });
+
+       return Iterator;
+}());
+
+// Object.setPrototypeOf
+/* global CreateMethodProperty */
+// ES6-shim 0.16.0 (c) 2013-2014 Paul Miller (http://paulmillr.com)
+// ES6-shim may be freely distributed under the MIT license.
+// For more details and documentation:
+// https://github.com/paulmillr/es6-shim/
+
+ // NOTE:  This versions needs object ownership
+  //        because every promoted object needs to be reassigned
+  //        otherwise uncompatible browsers cannot work as expected
+  //
+  // NOTE:  This might need es5-shim or polyfills upfront
+  //        because it's based on ES5 API.
+  //        (probably just an IE <= 8 problem)
+  //
+  // NOTE:  nodejs is fine in version 0.8, 0.10, and future versions.
+(function () {
+       if (Object.setPrototypeOf) { return; }
+
+       /*jshint proto: true */
+       // @author    Andrea Giammarchi - @WebReflection
+
+       var getOwnPropertyNames = Object.getOwnPropertyNames;
+       var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+       var create = Object.create;
+       var defineProperty = Object.defineProperty;
+       var getPrototypeOf = Object.getPrototypeOf;
+       var objProto = Object.prototype;
+
+       var copyDescriptors = function (target, source) {
+               // define into target descriptors from source
+               getOwnPropertyNames(source).forEach(function (key) {
+                       defineProperty(
+                               target,
+                               key,
+                               getOwnPropertyDescriptor(source, key)
+                       );
+               });
+               return target;
+       };
+       // used as fallback when no promotion is possible
+       var createAndCopy = function setPrototypeOf(origin, proto) {
+               return copyDescriptors(create(proto), origin);
+       };
+       var set, sPOf;
+       try {
+               // this might fail for various reasons
+               // ignore if Chrome cought it at runtime
+               set = getOwnPropertyDescriptor(objProto, '__proto__').set;
+               set.call({}, null);
+               // setter not poisoned, it can promote
+               // Firefox, Chrome
+               sPOf = function setPrototypeOf(origin, proto) {
+                       set.call(origin, proto);
+                       return origin;
+               };
+       } catch (e) {
+               // do one or more feature detections
+               set = { __proto__: null };
+               // if proto does not work, needs to fallback
+               // some Opera, Rhino, ducktape
+               if (set instanceof Object) {
+                       sPOf = createAndCopy;
+               } else {
+                       // verify if null objects are buggy
+                       /* eslint-disable no-proto */
+                       set.__proto__ = objProto;
+                       /* eslint-enable no-proto */
+                       // if null objects are buggy
+                       // nodejs 0.8 to 0.10
+                       if (set instanceof Object) {
+                               sPOf = function setPrototypeOf(origin, proto) {
+                                       // use such bug to promote
+                                       /* eslint-disable no-proto */
+                                       origin.__proto__ = proto;
+                                       /* eslint-enable no-proto */
+                                       return origin;
+                               };
+                       } else {
+                               // try to use proto or fallback
+                               // Safari, old Firefox, many others
+                               sPOf = function setPrototypeOf(origin, proto) {
+                                       // if proto is not null
+                                       if (getPrototypeOf(origin)) {
+                                               // use __proto__ to promote
+                                               /* eslint-disable no-proto */
+                                               origin.__proto__ = proto;
+                                               /* eslint-enable no-proto */
+                                               return origin;
+                                       } else {
+                                               // otherwise unable to promote: fallback
+                                               return createAndCopy(origin, proto);
+                                       }
+                               };
+                       }
+               }
+       }
+       CreateMethodProperty(Object, 'setPrototypeOf', sPOf);
+}());
+
+// _ESAbstract.RequireObjectCoercible
+// 7.2.1. RequireObjectCoercible ( argument )
+// The abstract operation ToObject converts argument to a value of type Object according to Table 12:
+// Table 12: ToObject Conversions
+/*
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Argument Type | Result                                                                                                                             |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| Undefined     | Throw a TypeError exception.                                                                                                       |
+| Null          | Throw a TypeError exception.                                                                                                       |
+| Boolean       | Return argument.                                                                                                                   |
+| Number        | Return argument.                                                                                                                   |
+| String        | Return argument.                                                                                                                   |
+| Symbol        | Return argument.                                                                                                                   |
+| Object        | Return argument.                                                                                                                   |
+|----------------------------------------------------------------------------------------------------------------------------------------------------|
+*/
+function RequireObjectCoercible(argument) { // eslint-disable-line no-unused-vars
+       if (argument === null || argument === undefined) {
+               throw TypeError();
+       }
+  return argument;
+}
+
+// _ESAbstract.IsRegExp
+/* global Type, Get, ToBoolean */
+// 7.2.8. IsRegExp ( argument )
+function IsRegExp(argument) { // eslint-disable-line no-unused-vars
+       // 1. If Type(argument) is not Object, return false.
+       if (Type(argument) !== 'object') {
+               return false;
+       }
+       // 2. Let matcher be ? Get(argument, @@match).
+       var matcher = 'Symbol' in this && 'match' in this.Symbol ? Get(argument, this.Symbol.match) : undefined;
+       // 3. If matcher is not undefined, return ToBoolean(matcher).
+       if (matcher !== undefined) {
+               return ToBoolean(matcher);
+       }
+       // 4. If argument has a [[RegExpMatcher]] internal slot, return true.
+       try {
+               var lastIndex = argument.lastIndex;
+               argument.lastIndex = 0;
+               RegExp.prototype.exec.call(argument);
+               return true;
+       } catch (e) {} finally {
+               argument.lastIndex = lastIndex;
+       }
+       // 5. Return false.
+       return false;
+}
+if (!('includes' in String.prototype)) {
+
+// String.prototype.includes
+/* global CreateMethodProperty, IsRegExp, RequireObjectCoercible, ToInteger, ToString */
+// 21.1.3.7. String.prototype.includes ( searchString [ , position ] )
+CreateMethodProperty(String.prototype, 'includes', function includes(searchString /* [ , position ] */) {
+       'use strict';
+       var position = arguments.length > 1 ? arguments[1] : undefined;
+       // 1. Let O be ? RequireObjectCoercible(this value).
+       var O = RequireObjectCoercible(this);
+       // 2. Let S be ? ToString(O).
+       var S = ToString(O);
+       // 3. Let isRegExp be ? IsRegExp(searchString).
+       var isRegExp = IsRegExp(searchString);
+       // 4. If isRegExp is true, throw a TypeError exception.
+       if (isRegExp) {
+               throw new TypeError('First argument to String.prototype.includes must not be a regular expression');
+       }
+       // 5. Let searchStr be ? ToString(searchString).
+       var searchStr = ToString(searchString);
+       // 6. Let pos be ? ToInteger(position). (If position is undefined, this step produces the value 0.)
+       var pos = ToInteger(position);
+       // 7. Let len be the length of S.
+       var len = S.length;
+       // 8. Let start be min(max(pos, 0), len).
+       var start = Math.min(Math.max(pos, 0), len);
+       // 9. Let searchLen be the length of searchStr.
+       // var searchLength = searchStr.length;
+       // 10. If there exists any integer k not smaller than start such that k + searchLen is not greater than len, and for all nonnegative integers j less than searchLen, the code unit at index k+j within S is the same as the code unit at index j within searchStr, return true; but if there is no such integer k, return false.
+       return String.prototype.indexOf.call(S, searchStr, start) !== -1;
+});
+
+}
+
+
+// _ArrayIterator
+/* global Iterator */
+// A modification of https://github.com/medikoo/es6-iterator
+// Copyright (C) 2013-2015 Mariusz Nowak (www.medikoo.com)
+
+var ArrayIterator = (function() { // eslint-disable-line no-unused-vars
+
+       var ArrayIterator = function(arr, kind) {
+               if (!(this instanceof ArrayIterator)) return new ArrayIterator(arr, kind);
+               Iterator.call(this, arr);
+               if (!kind) kind = 'value';
+               else if (String.prototype.includes.call(kind, 'key+value')) kind = 'key+value';
+               else if (String.prototype.includes.call(kind, 'key')) kind = 'key';
+               else kind = 'value';
+               Object.defineProperty(this, '__kind__', {
+                       value: kind,
+                       configurable: false,
+                       enumerable: false,
+                       writable: false
+               });
+       };
+       if (Object.setPrototypeOf) Object.setPrototypeOf(ArrayIterator, Iterator.prototype);
+
+       ArrayIterator.prototype = Object.create(Iterator.prototype, {
+               constructor: {
+                       value: ArrayIterator,
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               _resolve: {
+                       value: function(i) {
+                               if (this.__kind__ === 'value') return this.__list__[i];
+                               if (this.__kind__ === 'key+value') return [i, this.__list__[i]];
+                               return i;
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               },
+               toString: {
+                       value: function() {
+                               return '[object Array Iterator]';
+                       },
+                       configurable: true,
+                       enumerable: false,
+                       writable: true
+               }
+       });
+
+       return ArrayIterator;
+}());
+if (!('values' in Array.prototype)) {
+
+// Array.prototype.values
+/* global CreateMethodProperty, Symbol, ToObject */
+// 22.1.3.30/ Array.prototype.values ( )
+// Polyfill.io - Firefox, Chrome and Opera have Array.prototype[Symbol.iterator], which is the exact same function as Array.prototype.values.
+if ('Symbol' in this && 'iterator' in Symbol && typeof Array.prototype[Symbol.iterator] === 'function') {
+       CreateMethodProperty(Array.prototype, 'values', Array.prototype[Symbol.iterator]);
+} else {
+       CreateMethodProperty(Array.prototype, 'values', function values () {
+               // 1. Let O be ? ToObject(this value).
+               var O = ToObject(this);
+               // 2. Return CreateArrayIterator(O, "value").
+               // TODO: Add CreateArrayIterator
+               return new ArrayIterator(O, 'value');
+       });
+}
+
+}
+
+if (!('Symbol' in this && 'iterator' in this.Symbol && !!Array.prototype[Symbol.iterator])) {
+
+// Array.prototype.@@iterator
+/* global Symbol, CreateMethodProperty */
+// 22.1.3.31. Array.prototype [ @@iterator ] ( )
+// The initial value of the @@iterator property is the same function object as the initial value of the  Array.prototype.values property.
+CreateMethodProperty(Array.prototype, Symbol.iterator, Array.prototype.values);
+
+}
+
+if (!('copyWithin' in Array.prototype && (function () {
+       try {
+               var Parent = function Parent() {};
+               Parent.prototype[0] = 'foo';
+               var sparse = new Parent();
+               sparse[1] = 1;
+               sparse[2] = 2;
+               sparse.length = 3;
+               var result = Array.prototype.copyWithin.call(sparse, 1, 0);
+               if (result['0'] && !Object.prototype.hasOwnProperty.call(result, '0') && Object.prototype.hasOwnProperty.call(result, '1') && result[0] === 'foo' && result[1] === 'foo' && result[2] === 1 && result.length === 3) {
+                       return true;
+               } else {
+                       return false;
+               }
+       } catch (err) {
+               return false;
+       }
+}()))) {
+
+// Array.prototype.copyWithin
+/* global CreateMethodProperty, HasProperty, ToInteger */
+// 22.1.3.3 Array.prototype.copyWithin ( target, start [ , end ] )
+CreateMethodProperty(Array.prototype, 'copyWithin', function copyWithin(target, start /* [ , end ] */ ) {
+       'use strict';
+       var end = arguments[2];
+
+       // 22.1.3.3.1 Let O be ? ToObject(this value).
+       if (this === null || this === undefined) {
+               throw new TypeError('Cannot call method on ' + this);
+       }
+
+       var o = Object(this);
+
+       // 22.1.3.3.2 Let len be ? ToLength(? Get(O, "length")).
+       var len = ToInteger(o.length);
+       if (len <= 0) {
+               len = 0;
+       }
+       if (len === Infinity) {
+               len = Math.pow(2, 53) - 1;
+       } else {
+               len = Math.min(len, Math.pow(2, 53) - 1);
+       }
+       len = Math.max(len, 0);
+
+       // 22.1.3.3.3 Let relativeTarget be ? ToInteger(target).
+       var relativeTarget = ToInteger(target);
+
+       // 22.1.3.3.4 If relativeTarget < 0, let to be max((len + relativeTarget), 0); else let to be min(relativeTarget, len).
+       var to;
+       if (relativeTarget < 0) {
+               to = Math.max(len + relativeTarget, 0);
+       } else {
+               to = Math.min(relativeTarget, len);
+       }
+
+       // 22.1.3.3.5 Let relativeStart be ? ToInteger(start).
+       var relativeStart = ToInteger(start);
+
+       // 22.1.3.3.6 If relativeStart < 0, let from be max((len + relativeStart), 0); else let from be min(relativeStart, len).
+       var from;
+       if (relativeStart < 0) {
+               from = Math.max(len + relativeStart, 0);
+       } else {
+               from = Math.min(relativeStart, len);
+       }
+
+       // 22.1.3.3.7 If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
+       var relativeEnd;
+       if (end === undefined) {
+               relativeEnd = len;
+       } else {
+               relativeEnd = ToInteger(end);
+       }
+
+       // 22.1.3.3.8 If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
+       var final;
+       if (relativeEnd < 0) {
+               final = Math.max(len + relativeEnd, 0);
+       } else {
+               final = Math.min(relativeEnd, len);
+       }
+
+       // 22.1.3.3.9 Let count be min(final-from, len-to).
+       var count = Math.min(final - from, len - to);
+
+       // 22.1.3.3.10 If from<to and to<from+count, then
+       var direction;
+       if (from < to && to < from + count) {
+               // 22.1.3.3.10.a Let direction be -1.
+               direction = -1;
+
+               // 22.1.3.3.10.b Let from be from + count - 1.
+               from = from + count - 1;
+
+               // 22.1.3.3.10.c Let to be to + count - 1.
+               to = to + count - 1;
+       } else {
+               // 22.1.3.3.11 Else,
+               // 22.1.3.3.11.a Let direction be 1.
+               direction = 1;
+       }
+
+       // 22.1.3.3.12 Repeat, while count > 0
+       while (count > 0) {
+               // 22.1.3.3.12.a Let fromKey be ! ToString(from).
+               var fromKey = String(from);
+               // 22.1.3.3.12.b Let toKey be ! ToString(to).
+               var toKey = String(to);
+               // 22.1.3.3.12.c Let fromPresent be ? HasProperty(O, fromKey).
+               var fromPresent = HasProperty(o, fromKey);
+               // 22.1.3.3.12.d If fromPresent is true, then
+               if (fromPresent) {
+                       // 22.1.3.3.12.d.i Let fromVal be ? Get(O, fromKey).
+                       var fromVal = o[fromKey];
+                       // 22.1.3.3.12.d.ii Perform ? Set(O, toKey, fromVal, true).
+                       o[toKey] = fromVal;
+               } else {
+                       // 22.1.3.3.12.e Else fromPresent is false,
+                       // 22.1.3.3.12.e.i Perform ? DeletePropertyOrThrow(O, toKey).
+                       delete o[toKey];
+               }
+               // 22.1.3.3.12.f Let from be from + direction.
+               from = from + direction;
+               // 22.1.3.3.12.g Let to be to + direction.
+               to = to + direction;
+               // 22.1.3.3.12.h Let count be count - 1.
+               count = count - 1;
+       }
+       // 22.1.3.3.13 Return O.
+       return o;
+});
+
+}
+
+if (!('Symbol' in this && 'iterator' in this.Symbol && !!Array.prototype.entries)) {
+
+// Array.prototype.entries
+/* global CreateMethodProperty, ToObject */
+// 22.1.3.4. Array.prototype.entries ( )
+CreateMethodProperty(Array.prototype, 'entries', function entries() {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Return CreateArrayIterator(O, "key+value").
+       // TODO: Add CreateArrayIterator
+       return new ArrayIterator(O, 'key+value');
+});
+
+}
+
+if (!('fill' in Array.prototype)) {
+
+// Array.prototype.fill
+/* global CreateMethodProperty, Get, ToInteger, ToLength, ToObject, ToString */
+// 22.1.3.6. Array.prototype.fill ( value [ , start [ , end ] ] )
+CreateMethodProperty(Array.prototype, 'fill', function fill(value /* [ , start [ , end ] ] */) {
+       var start = arguments[1];
+       var end = arguments[2];
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. Let relativeStart be ? ToInteger(start).
+       var relativeStart = ToInteger(start);
+       // 4. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len)
+       var k = relativeStart < 0 ? Math.max((len + relativeStart), 0) : Math.min(relativeStart, len);
+       // 5. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
+       var relativeEnd = end === undefined ? len : ToInteger(end);
+       // 6. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
+       var final = relativeEnd < 0 ? Math.max((len + relativeEnd), 0) : Math.min(relativeEnd, len);
+       // 7. Repeat, while k < final
+       while (k < final) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Perform ? Set(O, Pk, value, true).
+               O[Pk] = value;
+               // c. Increase k by 1.
+               k = k + 1;
+       }
+       // 8. Return O.
+       return O;
+});
+
+}
+
+if (!('find' in Array.prototype)) {
+
+// Array.prototype.find
+/* global Call, CreateMethodProperty, Get, IsCallable, ToBoolean, ToLength, ToObject, ToString */
+// 22.1.3.8 Array.prototype.find ( predicate [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'find', function find( predicate /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(predicate) is false, throw a TypeError exception.
+       if (IsCallable(predicate) === false) {
+               throw new TypeError(predicate + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kValue be ? Get(O, Pk).
+               var kValue = Get(O, Pk);
+               // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
+               var testResult = ToBoolean(Call(predicate, T, [kValue, k, O ]));
+               // d. If testResult is true, return kValue.
+               if (testResult) {
+                       return kValue;
+               }
+               // e. Increase k by 1.
+               var k = k + 1;
+       }
+       // 7. Return undefined.
+       return undefined;
+});
+
+}
+
+if (!('findIndex' in Array.prototype)) {
+
+// Array.prototype.findIndex
+/* global Call, CreateMethodProperty, Get, IsCallable, ToBoolean, ToLength, ToObject, ToString */
+// 22.1.3.9. Array.prototype.findIndex ( predicate [ , thisArg ] )
+CreateMethodProperty(Array.prototype, 'findIndex', function findIndex(predicate /* [ , thisArg ] */) {
+       // 1. Let O be ? ToObject(this value).
+       var O = ToObject(this);
+       // 2. Let len be ? ToLength(? Get(O, "length")).
+       var len = ToLength(Get(O, "length"));
+       // 3. If IsCallable(predicate) is false, throw a TypeError exception.
+       if (IsCallable(predicate) === false) {
+               throw new TypeError(predicate + ' is not a function');
+       }
+       // 4. If thisArg is present, let T be thisArg; else let T be undefined.
+       var T = arguments.length > 1 ? arguments[1] : undefined;
+       // 5. Let k be 0.
+       var k = 0;
+       // 6. Repeat, while k < len
+       while (k < len) {
+               // a. Let Pk be ! ToString(k).
+               var Pk = ToString(k);
+               // b. Let kValue be ? Get(O, Pk).
+               var kValue = Get(O, Pk);
+               // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
+               var testResult = ToBoolean(Call(predicate, T, [kValue, k, O]));
+               // d. If testResult is true, return k.
+               if (testResult) {
+                       return k;
+               }
+               // e. Increase k by 1.