text: // Copyright (c) 2015 Kris Maglione <maglione.k@gmail.com>
  //
  // This work is licensed for reuse under an MIT license. Details are
  // given in the LICENSE.txt file included with this file.
  "use strict";
  
  // Implementations for some ES6 and ES7 features that aren't in Firefox
  // mainline yet.
  
  {
      // This is similar to the same-named function in self-hosted JS, but
      // somewhat less efficient.
      //
      // It helps dodge some of the pitfalls of using the `call` method of the
      // function you're intending to call, which might have been replaced,
      // and can fail for other reasons (on CPOWs, most notably).
      let callFunction = Function.call.bind(Function.call);
  
      let identity = x => x;
  
      if (!Object.entries)
          Object.entries = function (obj) {
              let result = [];
  
              for (let key of Object.keys(obj)) {
                  // The check is necessary, since keys may be removed during
                  // iteration.
                  if (key in obj)
                      result.push([key, obj[key]]);
              }
  
              return result;
          };
  
      if (!Object.values)
          Object.values = function (obj) {
              let result = [];
  
              for (let key of Object.keys(obj)) {
                  // The check is necessary, since keys may be removed during
                  // iteration.
                  if (key in obj)
                      result.push(obj[key]);
              }
  
              return result;
          };
  
      if (!Array.prototype.flatMap)
          Array.prototype.flatMap = function (fn = identity, self = null) {
              let result = [];
  
              for (let [i, value] of Array.prototype.entries.call(this)) {
                  let res = callFunction(fn, self, value, i);
  
                  if (isObject(res) && Symbol.iterator in res)
                      result.push(...res);
                  else if (res !== undefined)
                      result.push(res);
              }
  
              return result;
          };
  
      // < FF43
      if (!Array.prototype.includes)
          Array.prototype.includes = function (...args) {
  	    return this.indexOf(...args) != -1;
          };
  
      if (!Array.prototype.values)
          Array.prototype.values = function* () {
              for (let [i, value] of this.entries())
                  yield value;
          };
  
      // < FF40
      if (!String.prototype.includes)
          String.prototype.includes = String.prototype.contains;
  
  }
  