[
  {
    "path": "README.md",
    "content": "# Float Toy\n\nVisit [http://evanw.github.io/float-toy/](http://evanw.github.io/float-toy/) to play around.\nUse this to build intuition for the IEEE floating-point format.\n"
  },
  {
    "path": "float16.js",
    "content": "/**\n * @petamoriken/float16 aa4af43 | MIT License - https://git.io/float16\n *\n * @license\n * lodash-es v4.17.15 | MIT License - https://lodash.com/custom-builds\n */\n\nvar float16 = (function (exports) {\n    'use strict';\n\n    // algorithm: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf\n    const buffer = new ArrayBuffer(4);\n    const floatView = new Float32Array(buffer);\n    const uint32View = new Uint32Array(buffer);\n    const baseTable = new Uint32Array(512);\n    const shiftTable = new Uint32Array(512);\n\n    for (let i = 0; i < 256; ++i) {\n      const e = i - 127; // very small number (0, -0)\n\n      if (e < -27) {\n        baseTable[i | 0x000] = 0x0000;\n        baseTable[i | 0x100] = 0x8000;\n        shiftTable[i | 0x000] = 24;\n        shiftTable[i | 0x100] = 24; // small number (denorm)\n      } else if (e < -14) {\n        baseTable[i | 0x000] = 0x0400 >> -e - 14;\n        baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;\n        shiftTable[i | 0x000] = -e - 1;\n        shiftTable[i | 0x100] = -e - 1; // normal number\n      } else if (e <= 15) {\n        baseTable[i | 0x000] = e + 15 << 10;\n        baseTable[i | 0x100] = e + 15 << 10 | 0x8000;\n        shiftTable[i | 0x000] = 13;\n        shiftTable[i | 0x100] = 13; // large number (Infinity, -Infinity)\n      } else if (e < 128) {\n        baseTable[i | 0x000] = 0x7c00;\n        baseTable[i | 0x100] = 0xfc00;\n        shiftTable[i | 0x000] = 24;\n        shiftTable[i | 0x100] = 24; // stay (NaN, Infinity, -Infinity)\n      } else {\n        baseTable[i | 0x000] = 0x7c00;\n        baseTable[i | 0x100] = 0xfc00;\n        shiftTable[i | 0x000] = 13;\n        shiftTable[i | 0x100] = 13;\n      }\n    }\n    /**\n     * round a number to a half float number bits.\n     * @param {number} num\n     */\n\n\n    function roundToFloat16Bits(num) {\n      floatView[0] = num;\n      const f = uint32View[0];\n      const e = f >> 23 & 0x1ff;\n      return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);\n    }\n    const mantissaTable = new Uint32Array(2048);\n    const exponentTable = new Uint32Array(64);\n    const offsetTable = new Uint32Array(64);\n    mantissaTable[0] = 0;\n\n    for (let i = 1; i < 1024; ++i) {\n      let m = i << 13; // zero pad mantissa bits\n\n      let e = 0; // zero exponent\n      // normalized\n\n      while ((m & 0x00800000) === 0) {\n        e -= 0x00800000; // decrement exponent\n\n        m <<= 1;\n      }\n\n      m &= ~0x00800000; // clear leading 1 bit\n\n      e += 0x38800000; // adjust bias\n\n      mantissaTable[i] = m | e;\n    }\n\n    for (let i = 1024; i < 2048; ++i) {\n      mantissaTable[i] = 0x38000000 + (i - 1024 << 13);\n    }\n\n    exponentTable[0] = 0;\n\n    for (let i = 1; i < 31; ++i) {\n      exponentTable[i] = i << 23;\n    }\n\n    exponentTable[31] = 0x47800000;\n    exponentTable[32] = 0x80000000;\n\n    for (let i = 33; i < 63; ++i) {\n      exponentTable[i] = 0x80000000 + (i - 32 << 23);\n    }\n\n    exponentTable[63] = 0xc7800000;\n    offsetTable[0] = 0;\n\n    for (let i = 1; i < 64; ++i) {\n      if (i === 32) {\n        offsetTable[i] = 0;\n      } else {\n        offsetTable[i] = 1024;\n      }\n    }\n    /**\n     * convert a half float number bits to a number.\n     * @param {number} float16bits - half float number bits\n     */\n\n\n    function convertToNumber(float16bits) {\n      const m = float16bits >> 10;\n      uint32View[0] = mantissaTable[offsetTable[m] + (float16bits & 0x3ff)] + exponentTable[m];\n      return floatView[0];\n    }\n\n    /**\n     * returns the nearest half precision float representation of a number.\n     * @param {number} num\n     */\n\n    function hfround(num) {\n      num = Number(num); // for optimization\n\n      if (!Number.isFinite(num) || num === 0) {\n        return num;\n      }\n\n      const x16 = roundToFloat16Bits(num);\n      return convertToNumber(x16);\n    }\n\n    function ToInteger(num) {\n      if (typeof num !== \"number\") num = Number(num);\n      if (Number.isNaN(num)) num = 0;\n      return Math.trunc(num);\n    }\n    function defaultCompareFunction(x, y) {\n      const [isNaN_x, isNaN_y] = [Number.isNaN(x), Number.isNaN(y)];\n      if (isNaN_x && isNaN_y) return 0;\n      if (isNaN_x) return 1;\n      if (isNaN_y) return -1;\n      if (x < y) return -1;\n      if (x > y) return 1;\n\n      if (x === 0 && y === 0) {\n        const [isPlusZero_x, isPlusZero_y] = [Object.is(x, 0), Object.is(y, 0)];\n        if (!isPlusZero_x && isPlusZero_y) return -1;\n        if (isPlusZero_x && !isPlusZero_y) return 1;\n      }\n\n      return 0;\n    }\n\n    /** Detect free variable `global` from Node.js. */\n    var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n    /** Detect free variable `self`. */\n\n    var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n    /** Used as a reference to the global object. */\n\n    var root = freeGlobal || freeSelf || Function('return this')();\n\n    /** Built-in value references. */\n\n    var Symbol$1 = root.Symbol;\n\n    /** Used for built-in method references. */\n\n    var objectProto = Object.prototype;\n    /** Used to check objects for own properties. */\n\n    var hasOwnProperty = objectProto.hasOwnProperty;\n    /**\n     * Used to resolve the\n     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n\n    var nativeObjectToString = objectProto.toString;\n    /** Built-in value references. */\n\n    var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;\n    /**\n     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the raw `toStringTag`.\n     */\n\n    function getRawTag(value) {\n      var isOwn = hasOwnProperty.call(value, symToStringTag),\n          tag = value[symToStringTag];\n\n      try {\n        value[symToStringTag] = undefined;\n        var unmasked = true;\n      } catch (e) {}\n\n      var result = nativeObjectToString.call(value);\n\n      if (unmasked) {\n        if (isOwn) {\n          value[symToStringTag] = tag;\n        } else {\n          delete value[symToStringTag];\n        }\n      }\n\n      return result;\n    }\n\n    /** Used for built-in method references. */\n    var objectProto$1 = Object.prototype;\n    /**\n     * Used to resolve the\n     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n\n    var nativeObjectToString$1 = objectProto$1.toString;\n    /**\n     * Converts `value` to a string using `Object.prototype.toString`.\n     *\n     * @private\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     */\n\n    function objectToString(value) {\n      return nativeObjectToString$1.call(value);\n    }\n\n    /** `Object#toString` result references. */\n\n    var nullTag = '[object Null]',\n        undefinedTag = '[object Undefined]';\n    /** Built-in value references. */\n\n    var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;\n    /**\n     * The base implementation of `getTag` without fallbacks for buggy environments.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n\n    function baseGetTag(value) {\n      if (value == null) {\n        return value === undefined ? undefinedTag : nullTag;\n      }\n\n      return symToStringTag$1 && symToStringTag$1 in Object(value) ? getRawTag(value) : objectToString(value);\n    }\n\n    /**\n     * Checks if `value` is object-like. A value is object-like if it's not `null`\n     * and has a `typeof` result of \"object\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n     * @example\n     *\n     * _.isObjectLike({});\n     * // => true\n     *\n     * _.isObjectLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isObjectLike(_.noop);\n     * // => false\n     *\n     * _.isObjectLike(null);\n     * // => false\n     */\n    function isObjectLike(value) {\n      return value != null && typeof value == 'object';\n    }\n\n    var arrayBufferTag = '[object ArrayBuffer]';\n    /**\n     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     */\n\n    function baseIsArrayBuffer(value) {\n      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n    }\n\n    /**\n     * The base implementation of `_.unary` without support for storing metadata.\n     *\n     * @private\n     * @param {Function} func The function to cap arguments for.\n     * @returns {Function} Returns the new capped function.\n     */\n    function baseUnary(func) {\n      return function (value) {\n        return func(value);\n      };\n    }\n\n    /** Detect free variable `exports`. */\n\n    var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n    /** Detect free variable `module`. */\n\n    var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n    /** Detect the popular CommonJS extension `module.exports`. */\n\n    var moduleExports = freeModule && freeModule.exports === freeExports;\n    /** Detect free variable `process` from Node.js. */\n\n    var freeProcess = moduleExports && freeGlobal.process;\n    /** Used to access faster Node.js helpers. */\n\n    var nodeUtil = function () {\n      try {\n        // Use `util.types` for Node.js 10+.\n        var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n        if (types) {\n          return types;\n        } // Legacy `process.binding('util')` for Node.js < 10.\n\n\n        return freeProcess && freeProcess.binding && freeProcess.binding('util');\n      } catch (e) {}\n    }();\n\n    /* Node.js helper references. */\n\n    var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer;\n    /**\n     * Checks if `value` is classified as an `ArrayBuffer` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     * @example\n     *\n     * _.isArrayBuffer(new ArrayBuffer(2));\n     * // => true\n     *\n     * _.isArrayBuffer(new Array(2));\n     * // => false\n     */\n\n    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n    function isDataView(view) {\n      return view instanceof DataView;\n    }\n    function isStringNumberKey(key) {\n      return typeof key === \"string\" && key === ToInteger(key) + \"\";\n    }\n\n    function createPrivateStorage() {\n      const wm = new WeakMap();\n      return self => {\n        let obj = wm.get(self);\n\n        if (obj) {\n          return obj;\n        } else {\n          obj = Object.create(null);\n          wm.set(self, obj);\n          return obj;\n        }\n      };\n    }\n\n    /**\n     * Checks if `value` is the\n     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n     * @example\n     *\n     * _.isObject({});\n     * // => true\n     *\n     * _.isObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isObject(_.noop);\n     * // => true\n     *\n     * _.isObject(null);\n     * // => false\n     */\n    function isObject(value) {\n      var type = typeof value;\n      return value != null && (type == 'object' || type == 'function');\n    }\n\n    /** `Object#toString` result references. */\n\n    var asyncTag = '[object AsyncFunction]',\n        funcTag = '[object Function]',\n        genTag = '[object GeneratorFunction]',\n        proxyTag = '[object Proxy]';\n    /**\n     * Checks if `value` is classified as a `Function` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n     * @example\n     *\n     * _.isFunction(_);\n     * // => true\n     *\n     * _.isFunction(/abc/);\n     * // => false\n     */\n\n    function isFunction(value) {\n      if (!isObject(value)) {\n        return false;\n      } // The use of `Object#toString` avoids issues with the `typeof` operator\n      // in Safari 9 which returns 'object' for typed arrays and other constructors.\n\n\n      var tag = baseGetTag(value);\n      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n    }\n\n    /** Used to detect overreaching core-js shims. */\n\n    var coreJsData = root['__core-js_shared__'];\n\n    /** Used to detect methods masquerading as native. */\n\n    var maskSrcKey = function () {\n      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n      return uid ? 'Symbol(src)_1.' + uid : '';\n    }();\n    /**\n     * Checks if `func` has its source masked.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n     */\n\n\n    function isMasked(func) {\n      return !!maskSrcKey && maskSrcKey in func;\n    }\n\n    /** Used for built-in method references. */\n    var funcProto = Function.prototype;\n    /** Used to resolve the decompiled source of functions. */\n\n    var funcToString = funcProto.toString;\n    /**\n     * Converts `func` to its source code.\n     *\n     * @private\n     * @param {Function} func The function to convert.\n     * @returns {string} Returns the source code.\n     */\n\n    function toSource(func) {\n      if (func != null) {\n        try {\n          return funcToString.call(func);\n        } catch (e) {}\n\n        try {\n          return func + '';\n        } catch (e) {}\n      }\n\n      return '';\n    }\n\n    /**\n     * Used to match `RegExp`\n     * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n     */\n\n    var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n    /** Used to detect host constructors (Safari). */\n\n    var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n    /** Used for built-in method references. */\n\n    var funcProto$1 = Function.prototype,\n        objectProto$2 = Object.prototype;\n    /** Used to resolve the decompiled source of functions. */\n\n    var funcToString$1 = funcProto$1.toString;\n    /** Used to check objects for own properties. */\n\n    var hasOwnProperty$1 = objectProto$2.hasOwnProperty;\n    /** Used to detect if a method is native. */\n\n    var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\\\$&').replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$');\n    /**\n     * The base implementation of `_.isNative` without bad shim checks.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     */\n\n    function baseIsNative(value) {\n      if (!isObject(value) || isMasked(value)) {\n        return false;\n      }\n\n      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n      return pattern.test(toSource(value));\n    }\n\n    /**\n     * Gets the value at `key` of `object`.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {string} key The key of the property to get.\n     * @returns {*} Returns the property value.\n     */\n    function getValue(object, key) {\n      return object == null ? undefined : object[key];\n    }\n\n    /**\n     * Gets the native function at `key` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the method to get.\n     * @returns {*} Returns the function if it's native, else `undefined`.\n     */\n\n    function getNative(object, key) {\n      var value = getValue(object, key);\n      return baseIsNative(value) ? value : undefined;\n    }\n\n    /* Built-in method references that are verified to be native. */\n\n    var nativeCreate = getNative(Object, 'create');\n\n    /**\n     * Removes all key-value entries from the hash.\n     *\n     * @private\n     * @name clear\n     * @memberOf Hash\n     */\n\n    function hashClear() {\n      this.__data__ = nativeCreate ? nativeCreate(null) : {};\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the hash.\n     *\n     * @private\n     * @name delete\n     * @memberOf Hash\n     * @param {Object} hash The hash to modify.\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function hashDelete(key) {\n      var result = this.has(key) && delete this.__data__[key];\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /** Used to stand-in for `undefined` hash values. */\n\n    var HASH_UNDEFINED = '__lodash_hash_undefined__';\n    /** Used for built-in method references. */\n\n    var objectProto$3 = Object.prototype;\n    /** Used to check objects for own properties. */\n\n    var hasOwnProperty$2 = objectProto$3.hasOwnProperty;\n    /**\n     * Gets the hash value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Hash\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n\n    function hashGet(key) {\n      var data = this.__data__;\n\n      if (nativeCreate) {\n        var result = data[key];\n        return result === HASH_UNDEFINED ? undefined : result;\n      }\n\n      return hasOwnProperty$2.call(data, key) ? data[key] : undefined;\n    }\n\n    /** Used for built-in method references. */\n\n    var objectProto$4 = Object.prototype;\n    /** Used to check objects for own properties. */\n\n    var hasOwnProperty$3 = objectProto$4.hasOwnProperty;\n    /**\n     * Checks if a hash value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Hash\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n\n    function hashHas(key) {\n      var data = this.__data__;\n      return nativeCreate ? data[key] !== undefined : hasOwnProperty$3.call(data, key);\n    }\n\n    /** Used to stand-in for `undefined` hash values. */\n\n    var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';\n    /**\n     * Sets the hash `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Hash\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the hash instance.\n     */\n\n    function hashSet(key, value) {\n      var data = this.__data__;\n      this.size += this.has(key) ? 0 : 1;\n      data[key] = nativeCreate && value === undefined ? HASH_UNDEFINED$1 : value;\n      return this;\n    }\n\n    /**\n     * Creates a hash object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n\n    function Hash(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n      this.clear();\n\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    } // Add methods to `Hash`.\n\n\n    Hash.prototype.clear = hashClear;\n    Hash.prototype['delete'] = hashDelete;\n    Hash.prototype.get = hashGet;\n    Hash.prototype.has = hashHas;\n    Hash.prototype.set = hashSet;\n\n    /**\n     * Removes all key-value entries from the list cache.\n     *\n     * @private\n     * @name clear\n     * @memberOf ListCache\n     */\n    function listCacheClear() {\n      this.__data__ = [];\n      this.size = 0;\n    }\n\n    /**\n     * Performs a\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * comparison between two values to determine if they are equivalent.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.eq(object, object);\n     * // => true\n     *\n     * _.eq(object, other);\n     * // => false\n     *\n     * _.eq('a', 'a');\n     * // => true\n     *\n     * _.eq('a', Object('a'));\n     * // => false\n     *\n     * _.eq(NaN, NaN);\n     * // => true\n     */\n    function eq(value, other) {\n      return value === other || value !== value && other !== other;\n    }\n\n    /**\n     * Gets the index at which the `key` is found in `array` of key-value pairs.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {*} key The key to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     */\n\n    function assocIndexOf(array, key) {\n      var length = array.length;\n\n      while (length--) {\n        if (eq(array[length][0], key)) {\n          return length;\n        }\n      }\n\n      return -1;\n    }\n\n    /** Used for built-in method references. */\n\n    var arrayProto = Array.prototype;\n    /** Built-in value references. */\n\n    var splice = arrayProto.splice;\n    /**\n     * Removes `key` and its value from the list cache.\n     *\n     * @private\n     * @name delete\n     * @memberOf ListCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n\n    function listCacheDelete(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        return false;\n      }\n\n      var lastIndex = data.length - 1;\n\n      if (index == lastIndex) {\n        data.pop();\n      } else {\n        splice.call(data, index, 1);\n      }\n\n      --this.size;\n      return true;\n    }\n\n    /**\n     * Gets the list cache value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf ListCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n\n    function listCacheGet(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n      return index < 0 ? undefined : data[index][1];\n    }\n\n    /**\n     * Checks if a list cache value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf ListCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n\n    function listCacheHas(key) {\n      return assocIndexOf(this.__data__, key) > -1;\n    }\n\n    /**\n     * Sets the list cache `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf ListCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the list cache instance.\n     */\n\n    function listCacheSet(key, value) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        ++this.size;\n        data.push([key, value]);\n      } else {\n        data[index][1] = value;\n      }\n\n      return this;\n    }\n\n    /**\n     * Creates an list cache object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n\n    function ListCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n      this.clear();\n\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    } // Add methods to `ListCache`.\n\n\n    ListCache.prototype.clear = listCacheClear;\n    ListCache.prototype['delete'] = listCacheDelete;\n    ListCache.prototype.get = listCacheGet;\n    ListCache.prototype.has = listCacheHas;\n    ListCache.prototype.set = listCacheSet;\n\n    /* Built-in method references that are verified to be native. */\n\n    var Map = getNative(root, 'Map');\n\n    /**\n     * Removes all key-value entries from the map.\n     *\n     * @private\n     * @name clear\n     * @memberOf MapCache\n     */\n\n    function mapCacheClear() {\n      this.size = 0;\n      this.__data__ = {\n        'hash': new Hash(),\n        'map': new (Map || ListCache)(),\n        'string': new Hash()\n      };\n    }\n\n    /**\n     * Checks if `value` is suitable for use as unique object key.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n     */\n    function isKeyable(value) {\n      var type = typeof value;\n      return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null;\n    }\n\n    /**\n     * Gets the data for `map`.\n     *\n     * @private\n     * @param {Object} map The map to query.\n     * @param {string} key The reference key.\n     * @returns {*} Returns the map data.\n     */\n\n    function getMapData(map, key) {\n      var data = map.__data__;\n      return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map;\n    }\n\n    /**\n     * Removes `key` and its value from the map.\n     *\n     * @private\n     * @name delete\n     * @memberOf MapCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n\n    function mapCacheDelete(key) {\n      var result = getMapData(this, key)['delete'](key);\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the map value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf MapCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n\n    function mapCacheGet(key) {\n      return getMapData(this, key).get(key);\n    }\n\n    /**\n     * Checks if a map value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf MapCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n\n    function mapCacheHas(key) {\n      return getMapData(this, key).has(key);\n    }\n\n    /**\n     * Sets the map `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf MapCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the map cache instance.\n     */\n\n    function mapCacheSet(key, value) {\n      var data = getMapData(this, key),\n          size = data.size;\n      data.set(key, value);\n      this.size += data.size == size ? 0 : 1;\n      return this;\n    }\n\n    /**\n     * Creates a map cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n\n    function MapCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n      this.clear();\n\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    } // Add methods to `MapCache`.\n\n\n    MapCache.prototype.clear = mapCacheClear;\n    MapCache.prototype['delete'] = mapCacheDelete;\n    MapCache.prototype.get = mapCacheGet;\n    MapCache.prototype.has = mapCacheHas;\n    MapCache.prototype.set = mapCacheSet;\n\n    /** Error message constants. */\n\n    var FUNC_ERROR_TEXT = 'Expected a function';\n    /**\n     * Creates a function that memoizes the result of `func`. If `resolver` is\n     * provided, it determines the cache key for storing the result based on the\n     * arguments provided to the memoized function. By default, the first argument\n     * provided to the memoized function is used as the map cache key. The `func`\n     * is invoked with the `this` binding of the memoized function.\n     *\n     * **Note:** The cache is exposed as the `cache` property on the memoized\n     * function. Its creation may be customized by replacing the `_.memoize.Cache`\n     * constructor with one whose instances implement the\n     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n     * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to have its output memoized.\n     * @param {Function} [resolver] The function to resolve the cache key.\n     * @returns {Function} Returns the new memoized function.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     * var other = { 'c': 3, 'd': 4 };\n     *\n     * var values = _.memoize(_.values);\n     * values(object);\n     * // => [1, 2]\n     *\n     * values(other);\n     * // => [3, 4]\n     *\n     * object.a = 2;\n     * values(object);\n     * // => [1, 2]\n     *\n     * // Modify the result cache.\n     * values.cache.set(object, ['a', 'b']);\n     * values(object);\n     * // => ['a', 'b']\n     *\n     * // Replace `_.memoize.Cache`.\n     * _.memoize.Cache = WeakMap;\n     */\n\n    function memoize(func, resolver) {\n      if (typeof func != 'function' || resolver != null && typeof resolver != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n\n      var memoized = function memoized() {\n        var args = arguments,\n            key = resolver ? resolver.apply(this, args) : args[0],\n            cache = memoized.cache;\n\n        if (cache.has(key)) {\n          return cache.get(key);\n        }\n\n        var result = func.apply(this, args);\n        memoized.cache = cache.set(key, result) || cache;\n        return result;\n      };\n\n      memoized.cache = new (memoize.Cache || MapCache)();\n      return memoized;\n    } // Expose `MapCache`.\n\n\n    memoize.Cache = MapCache;\n\n    // JavaScriptCore bug: https://bugs.webkit.org/show_bug.cgi?id=171606\n    const isTypedArrayIndexedPropertyWritable = Object.getOwnPropertyDescriptor(new Uint8Array(1), 0).writable;\n\n    const _ = createPrivateStorage();\n\n    function isFloat16Array(target) {\n      return target instanceof Float16Array;\n    }\n\n    function assertFloat16Array(target) {\n      if (!isFloat16Array(target)) {\n        throw new TypeError(\"This is not a Float16Array\");\n      }\n    }\n\n    function isDefaultFloat16ArrayMethods(target) {\n      return typeof target === \"function\" && defaultFloat16ArrayMethods.has(target);\n    }\n\n    function copyToArray(float16bits) {\n      const length = float16bits.length;\n      const array = new Array(length);\n\n      for (let i = 0; i < length; ++i) {\n        array[i] = convertToNumber(float16bits[i]);\n      }\n\n      return array;\n    } // proxy handler\n\n\n    const applyHandler = {\n      apply(func, thisArg, args) {\n        // peel off proxy\n        if (isFloat16Array(thisArg) && isDefaultFloat16ArrayMethods(func)) return Reflect.apply(func, _(thisArg).target, args);\n        return Reflect.apply(func, thisArg, args);\n      }\n\n    };\n    const handler = {\n      get(target, key) {\n        let wrapper = null;\n\n        if (!isTypedArrayIndexedPropertyWritable) {\n          wrapper = target;\n          target = _(wrapper).target;\n        }\n\n        if (isStringNumberKey(key)) {\n          return Reflect.has(target, key) ? convertToNumber(Reflect.get(target, key)) : undefined;\n        } else {\n          const ret = wrapper !== null && Reflect.has(wrapper, key) ? Reflect.get(wrapper, key) : Reflect.get(target, key);\n          if (typeof ret !== \"function\") return ret; // TypedArray methods can't be called by Proxy Object\n\n          let proxy = _(ret).proxy;\n\n          if (proxy === undefined) {\n            proxy = _(ret).proxy = new Proxy(ret, applyHandler);\n          }\n\n          return proxy;\n        }\n      },\n\n      set(target, key, value) {\n        let wrapper = null;\n\n        if (!isTypedArrayIndexedPropertyWritable) {\n          wrapper = target;\n          target = _(wrapper).target;\n        }\n\n        if (isStringNumberKey(key)) {\n          return Reflect.set(target, key, roundToFloat16Bits(value));\n        } else {\n          // frozen object can't change prototype property\n          if (wrapper !== null && (!Reflect.has(target, key) || Object.isFrozen(wrapper))) {\n            return Reflect.set(wrapper, key, value);\n          } else {\n            return Reflect.set(target, key, value);\n          }\n        }\n      }\n\n    };\n\n    if (!isTypedArrayIndexedPropertyWritable) {\n      handler.getPrototypeOf = wrapper => Reflect.getPrototypeOf(_(wrapper).target);\n\n      handler.setPrototypeOf = (wrapper, prototype) => Reflect.setPrototypeOf(_(wrapper).target, prototype);\n\n      handler.defineProperty = (wrapper, key, descriptor) => {\n        const target = _(wrapper).target;\n\n        return !Reflect.has(target, key) || Object.isFrozen(wrapper) ? Reflect.defineProperty(wrapper, key, descriptor) : Reflect.defineProperty(target, key, descriptor);\n      };\n\n      handler.deleteProperty = (wrapper, key) => {\n        const target = _(wrapper).target;\n\n        return Reflect.has(wrapper, key) ? Reflect.deleteProperty(wrapper, key) : Reflect.deleteProperty(target, key);\n      };\n\n      handler.has = (wrapper, key) => Reflect.has(wrapper, key) || Reflect.has(_(wrapper).target, key);\n\n      handler.isExtensible = wrapper => Reflect.isExtensible(wrapper);\n\n      handler.preventExtensions = wrapper => Reflect.preventExtensions(wrapper);\n\n      handler.getOwnPropertyDescriptor = (wrapper, key) => Reflect.getOwnPropertyDescriptor(wrapper, key);\n\n      handler.ownKeys = wrapper => Reflect.ownKeys(wrapper);\n    }\n\n    class Float16Array extends Uint16Array {\n      constructor(input, byteOffset, length) {\n        // input Float16Array\n        if (isFloat16Array(input)) {\n          super(_(input).target); // 22.2.1.3, 22.2.1.4 TypedArray, Array, ArrayLike, Iterable\n        } else if (input !== null && typeof input === \"object\" && !isArrayBuffer(input)) {\n          // if input is not ArrayLike and Iterable, get Array\n          const arrayLike = !Reflect.has(input, \"length\") && input[Symbol.iterator] !== undefined ? [...input] : input;\n          const length = arrayLike.length;\n          super(length);\n\n          for (let i = 0; i < length; ++i) {\n            // super (Uint16Array)\n            this[i] = roundToFloat16Bits(arrayLike[i]);\n          } // 22.2.1.2, 22.2.1.5 primitive, ArrayBuffer\n\n        } else {\n          switch (arguments.length) {\n            case 0:\n              super();\n              break;\n\n            case 1:\n              super(input);\n              break;\n\n            case 2:\n              super(input, byteOffset);\n              break;\n\n            case 3:\n              super(input, byteOffset, length);\n              break;\n\n            default:\n              super(...arguments);\n          }\n        }\n\n        let proxy;\n\n        if (isTypedArrayIndexedPropertyWritable) {\n          proxy = new Proxy(this, handler);\n        } else {\n          const wrapper = Object.create(null);\n          _(wrapper).target = this;\n          proxy = new Proxy(wrapper, handler);\n        } // proxy private storage\n\n\n        _(proxy).target = this; // this private storage\n\n        _(this).proxy = proxy;\n        return proxy;\n      } // static methods\n\n\n      static from(src) {\n        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) return new Float16Array(Uint16Array.from(src, roundToFloat16Bits).buffer);\n        const mapFunc = arguments.length <= 1 ? undefined : arguments[1];\n        const thisArg = arguments.length <= 2 ? undefined : arguments[2];\n        return new Float16Array(Uint16Array.from(src, function (val) {\n          for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n            args[_key - 1] = arguments[_key];\n          }\n\n          return roundToFloat16Bits(mapFunc.call(this, val, ...args));\n        }, thisArg).buffer);\n      }\n\n      static of() {\n        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n          args[_key2] = arguments[_key2];\n        }\n\n        return new Float16Array(args);\n      } // iterate methods\n\n\n      *[Symbol.iterator]() {\n        for (const val of super[Symbol.iterator]()) {\n          yield convertToNumber(val);\n        }\n      }\n\n      keys() {\n        return super.keys();\n      }\n\n      *values() {\n        for (const val of super.values()) {\n          yield convertToNumber(val);\n        }\n      }\n\n      *entries() {\n        for (const [i, val] of super.entries()) {\n          yield [i, convertToNumber(val)];\n        }\n      } // functional methods\n\n\n      map(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n        const array = [];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          const val = convertToNumber(this[i]);\n          array.push(callback.call(thisArg, val, i, _(this).proxy));\n        }\n\n        return new Float16Array(array);\n      }\n\n      filter(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n        const array = [];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          const val = convertToNumber(this[i]);\n\n          if (callback.call(thisArg, val, i, _(this).proxy)) {\n            array.push(val);\n          }\n        }\n\n        return new Float16Array(array);\n      }\n\n      reduce(callback) {\n        assertFloat16Array(this);\n        let val, start;\n\n        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) {\n          val = convertToNumber(this[0]);\n          start = 1;\n        } else {\n          val = arguments.length <= 1 ? undefined : arguments[1];\n          start = 0;\n        }\n\n        for (let i = start, l = this.length; i < l; ++i) {\n          val = callback(val, convertToNumber(this[i]), i, _(this).proxy);\n        }\n\n        return val;\n      }\n\n      reduceRight(callback) {\n        assertFloat16Array(this);\n        let val, start;\n        const length = this.length;\n\n        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) {\n          val = convertToNumber(this[length - 1]);\n          start = length - 1;\n        } else {\n          val = arguments.length <= 1 ? undefined : arguments[1];\n          start = length;\n        }\n\n        for (let i = start; i--;) {\n          val = callback(val, convertToNumber(this[i]), i, _(this).proxy);\n        }\n\n        return val;\n      }\n\n      forEach(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy);\n        }\n      }\n\n      find(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          const value = convertToNumber(this[i]);\n          if (callback.call(thisArg, value, i, _(this).proxy)) return value;\n        }\n      }\n\n      findIndex(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          const value = convertToNumber(this[i]);\n          if (callback.call(thisArg, value, i, _(this).proxy)) return i;\n        }\n\n        return -1;\n      }\n\n      every(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          if (!callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy)) return false;\n        }\n\n        return true;\n      }\n\n      some(callback) {\n        assertFloat16Array(this);\n        const thisArg = arguments.length <= 1 ? undefined : arguments[1];\n\n        for (let i = 0, l = this.length; i < l; ++i) {\n          if (callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy)) return true;\n        }\n\n        return false;\n      } // change element methods\n\n\n      set(input) {\n        assertFloat16Array(this);\n        const offset = arguments.length <= 1 ? undefined : arguments[1];\n        let float16bits; // input Float16Array\n\n        if (isFloat16Array(input)) {\n          float16bits = _(input).target; // input others\n        } else {\n          const arrayLike = !Reflect.has(input, \"length\") && input[Symbol.iterator] !== undefined ? [...input] : input;\n          const length = arrayLike.length;\n          float16bits = new Uint16Array(length);\n\n          for (let i = 0, l = arrayLike.length; i < l; ++i) {\n            float16bits[i] = roundToFloat16Bits(arrayLike[i]);\n          }\n        }\n\n        super.set(float16bits, offset);\n      }\n\n      reverse() {\n        assertFloat16Array(this);\n        super.reverse();\n        return _(this).proxy;\n      }\n\n      fill(value) {\n        assertFloat16Array(this);\n\n        for (var _len3 = arguments.length, opts = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n          opts[_key3 - 1] = arguments[_key3];\n        }\n\n        super.fill(roundToFloat16Bits(value), ...opts);\n        return _(this).proxy;\n      }\n\n      copyWithin(target, start) {\n        assertFloat16Array(this);\n\n        for (var _len4 = arguments.length, opts = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {\n          opts[_key4 - 2] = arguments[_key4];\n        }\n\n        super.copyWithin(target, start, ...opts);\n        return _(this).proxy;\n      }\n\n      sort() {\n        assertFloat16Array(this);\n        let compareFunction = arguments.length <= 0 ? undefined : arguments[0];\n\n        if (compareFunction === undefined) {\n          compareFunction = defaultCompareFunction;\n        }\n\n        const _convertToNumber = memoize(convertToNumber);\n\n        super.sort((x, y) => compareFunction(_convertToNumber(x), _convertToNumber(y)));\n        return _(this).proxy;\n      } // copy element methods\n\n\n      slice() {\n        assertFloat16Array(this);\n        let float16bits; // V8, SpiderMonkey, JavaScriptCore, Chakra throw TypeError\n\n        try {\n          float16bits = super.slice(...arguments);\n        } catch (e) {\n          if (e instanceof TypeError) {\n            const uint16 = new Uint16Array(this.buffer, this.byteOffset, this.length);\n            float16bits = uint16.slice(...arguments);\n          } else {\n            throw e;\n          }\n        }\n\n        return new Float16Array(float16bits.buffer);\n      }\n\n      subarray() {\n        assertFloat16Array(this);\n        let float16bits; // V8, SpiderMonkey, JavaScriptCore, Chakra throw TypeError\n\n        try {\n          float16bits = super.subarray(...arguments);\n        } catch (e) {\n          if (e instanceof TypeError) {\n            const uint16 = new Uint16Array(this.buffer, this.byteOffset, this.length);\n            float16bits = uint16.subarray(...arguments);\n          } else {\n            throw e;\n          }\n        }\n\n        return new Float16Array(float16bits.buffer, float16bits.byteOffset, float16bits.length);\n      } // contains methods\n\n\n      indexOf(element) {\n        assertFloat16Array(this);\n        const length = this.length;\n        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);\n\n        if (from < 0) {\n          from += length;\n          if (from < 0) from = 0;\n        }\n\n        for (let i = from, l = length; i < l; ++i) {\n          if (convertToNumber(this[i]) === element) return i;\n        }\n\n        return -1;\n      }\n\n      lastIndexOf(element) {\n        assertFloat16Array(this);\n        const length = this.length;\n        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);\n        from = from === 0 ? length : from + 1;\n\n        if (from >= 0) {\n          from = from < length ? from : length;\n        } else {\n          from += length;\n        }\n\n        for (let i = from; i--;) {\n          if (convertToNumber(this[i]) === element) return i;\n        }\n\n        return -1;\n      }\n\n      includes(element) {\n        assertFloat16Array(this);\n        const length = this.length;\n        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);\n\n        if (from < 0) {\n          from += length;\n          if (from < 0) from = 0;\n        }\n\n        const isNaN = Number.isNaN(element);\n\n        for (let i = from, l = length; i < l; ++i) {\n          const value = convertToNumber(this[i]);\n          if (isNaN && Number.isNaN(value)) return true;\n          if (value === element) return true;\n        }\n\n        return false;\n      } // string methods\n\n\n      join() {\n        assertFloat16Array(this);\n        const array = copyToArray(this);\n        return array.join(...arguments);\n      }\n\n      toLocaleString() {\n        assertFloat16Array(this);\n        const array = copyToArray(this);\n        return array.toLocaleString(...arguments);\n      }\n\n      get [Symbol.toStringTag]() {\n        if (isFloat16Array(this)) return \"Float16Array\";\n      }\n\n    }\n    const Float16Array$prototype = Float16Array.prototype;\n    const defaultFloat16ArrayMethods = new WeakSet();\n\n    for (const key of Reflect.ownKeys(Float16Array$prototype)) {\n      const val = Float16Array$prototype[key];\n      if (typeof val === \"function\") defaultFloat16ArrayMethods.add(val);\n    }\n\n    /**\n     * returns an unsigned 16-bit float at the specified byte offset from the start of the DataView.\n     * @param {DataView} dataView\n     * @param {nunmber} byteOffset\n     * @param {*} opts\n     */\n\n    function getFloat16(dataView, byteOffset) {\n      if (!isDataView(dataView)) throw new TypeError(\"First argument to getFloat16 function must be a DataView\");\n\n      for (var _len = arguments.length, opts = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n        opts[_key - 2] = arguments[_key];\n      }\n\n      return convertToNumber(dataView.getUint16(byteOffset, ...opts));\n    }\n    /**\n     * stores an unsigned 16-bit float value at the specified byte offset from the start of the DataView.\n     * @param {DataView} dataView\n     * @param {number} byteOffset\n     * @param {number} value\n     * @param {*} opts\n     */\n\n    function setFloat16(dataView, byteOffset, value) {\n      if (!isDataView(dataView)) throw new TypeError(\"First argument to setFloat16 function must be a DataView\");\n\n      for (var _len2 = arguments.length, opts = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {\n        opts[_key2 - 3] = arguments[_key2];\n      }\n\n      dataView.setUint16(byteOffset, roundToFloat16Bits(value), ...opts);\n    }\n\n    exports.Float16Array = Float16Array;\n    exports.getFloat16 = getFloat16;\n    exports.hfround = hfround;\n    exports.setFloat16 = setFloat16;\n\n    return exports;\n\n}({}));\n"
  },
  {
    "path": "index.html",
    "content": "<meta charset=\"utf8\">\n<title>Float Toy</title>\n<style>\n  body {\n    margin: 50px;\n    font: 14px/20px sans-serif;\n    cursor: default;\n  }\n\n  a {\n    color: inherit;\n  }\n\n  p {\n    margin: 30px 0;\n  }\n\n  h2 {\n    margin: 60px 0 30px 0;\n  }\n\n  table {\n    border-collapse: collapse;\n    font-size: 20px;\n    line-height: 14px;\n    width: 100%;\n  }\n\n  td {\n    font: inherit;\n    padding: 0;\n    text-align: center;\n  }\n\n  td.sign { background: #BBF; }\n  td.exponent { background: #BFB; }\n  td.fraction { background: #FBB; }\n\n  td.sign.hover { background: #99D; }\n  td.exponent.hover { background: #9D9; }\n  td.fraction.hover { background: #D99; }\n\n  .input td {\n    border: 1px solid #000;\n    padding: 5px 2px;\n    font-size: 14px;\n  }\n\n  .zerox-col {\n    vertical-align: bottom;\n  }\n\n  .zerox {\n    height: 26px;\n    line-height: 26px;\n  }\n\n  .output-col {\n    width: 100%;\n    vertical-align: bottom;\n  }\n\n  .hex-col {\n    width: 100%;\n  }\n\n  .output {\n    font: inherit;\n    padding: 5px;\n    margin: -5px;\n    border: 0;\n    outline: none;\n    width: 100%;\n    min-width: 200px;\n    background: none;\n    height: 26px;\n    line-height: 26px;\n    box-sizing: content-box;\n  }\n\n  .output:hover, .output:focus {\n    background: rgba(0, 0, 0, 0.066);\n  }\n\n  .help {\n    height: 50px;\n    font-size: 20px;\n    line-height: 60px;\n    padding-left: 3px;\n    white-space: nowrap;\n  }\n\n  .help sup {\n    vertical-align: top;\n    font-size: 12px;\n    line-height: 50px;\n  }\n\n  .help span {\n    padding: 3px;\n    margin: -3px;\n  }\n\n  td.nibble {\n    font-size: 10px;\n    line-height: 6px;\n    border: none;\n  }\n\n  td.dark.nibble {\n    background: #DDD;\n  }\n\n  span.sign { background: #DDF; }\n  span.exponent { background: #DFD; }\n  span.fraction { background: #FDD; }\n\n</style>\n<body>\n  <h1>Float Toy</h1>\n  <p>\n    Click on a cell below to toggle bit values, or edit the hex or decimal values directly.\n    Use this to build intuition for the IEEE floating-point format.\n    See Wikipedia for details on the <a href=\"https://en.wikipedia.org/wiki/Half-precision_floating-point_format\">half-precision</a>, <a href=\"https://en.wikipedia.org/wiki/Single-precision_floating-point_format\">single-precision</a> and <a href=\"https://en.wikipedia.org/wiki/Double-precision_floating-point_format\">double-precision</a> floating-point formats.\n  </p>\n\n  <h2>16-bit (half)</h2>\n  <table>\n    <tr>\n      <td><span id=\"input16\" class=\"input\"></span></td>\n      <td class=\"zerox-col\"><span class=\"zerox\">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>\n      <td class=\"output-col\"><input id=\"hex16\" class=\"output\"></td>\n    </tr>\n  </table>\n  <table>\n    <tr>\n      <td><span id=\"help16\" class=\"help\"></span></td>\n      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>\n      <td class=\"hex-col\"><input id=\"output16\" class=\"output\"></td>\n    </tr>\n  </table>\n\n  <h2>32-bit (float)</h2>\n  <table>\n    <tr>\n      <td><span id=\"input32\" class=\"input\"></span></td>\n      <td class=\"zerox-col\"><span class=\"zerox\">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>\n      <td class=\"output-col\"><input id=\"hex32\" class=\"output\"></td>\n    </tr>\n  </table>\n  <table>\n    <tr>\n      <td><span id=\"help32\" class=\"help\"></span></td>\n      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>\n      <td class=\"hex-col\"><input id=\"output32\" class=\"output\"></td>\n    </tr>\n  </table>\n\n  <h2>64-bit (double)</h2>\n  <table>\n    <tr>\n      <td><span id=\"input64\" class=\"input\"></span></td>\n      <td class=\"zerox-col\"><span class=\"zerox\">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>\n      <td class=\"output-col\"><input id=\"hex64\" class=\"output\"></td>\n    </tr>\n  </table>\n  <table>\n    <tr>\n      <td><span id=\"help64\" class=\"help\"></span></td>\n      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>\n      <td class=\"hex-col\"><input id=\"output64\" class=\"output\"></td>\n    </tr>\n  </table>\n</body>\n<script src=\"./float16.js\"></script>\n<script>\nconst {Float16Array} = float16;\n\n(function () {\n\n  function load(array, exponentBits, input, output, help, hex) {\n    var bytes = new Uint8Array(array.buffer);\n    var hexLength = bytes.length;\n\n    function reduceNumber(x) {\n      var copy = bytes.length === 2 ? new Float16Array(1) : bytes.length === 4 ? new Float32Array(1) : new Float64Array(1);\n      copy[0] = +x;\n      var value = copy[0];\n      x = value === 0 && 1 / value === -Infinity ? '-0' : value + '';\n\n      if (x === 'NaN' || x === 'Infinity' || x === '-Infinity') {\n        return x;\n      }\n\n      var parts = /^([+-]?\\d+)((?:\\.\\d+)?)((?:[eE][+-]?\\d+)?)$/.exec(x);\n      var whole = parts[1];\n      var fraction = parts[2];\n      var exponent = parts[3];\n\n      // Remove digits one-by-one until the number changes\n      while (fraction.length > 0) {\n        // Try truncating\n        var truncatedFraction = fraction.slice(0, -1);\n        var text = whole + (truncatedFraction !== '.' ? truncatedFraction : '') + exponent;\n        copy[0] = +text;\n        var truncatedValue = copy[0];\n        if (truncatedValue === value) {\n          fraction = truncatedFraction;\n          x = text;\n          continue;\n        }\n\n        // Try rounding\n        var roundedFraction = truncatedFraction;\n        var i = roundedFraction.length - 1;\n        var zero = '0'.charCodeAt(0);\n        while (i > 0) {\n          var c = roundedFraction.charCodeAt(i) - zero;\n          roundedFraction = roundedFraction.slice(0, i) + String.fromCharCode((c + 1) % 10 + zero) + roundedFraction.slice(i + 1);\n          if (c < 9) break; // Do we need to carry?\n          i--;\n        }\n        var text = whole + (roundedFraction !== '.' ? roundedFraction : '') + exponent;\n        copy[0] = +text;\n        var roundedValue = copy[0];\n        if (roundedValue === value) {\n          fraction = roundedFraction;\n          x = text;\n          continue;\n        }\n\n        // Both numbers changed, keep the old value\n        break;\n      }\n\n      return x;\n    }\n\n    // Populate HTML\n    var html = '<table>';\n    // The bit numbers\n    html += '<tr>';\n    for (var i = 0; i < bytes.length; i++) {\n      for (var j = 0; j < 8; j++) {\n        var index = (bytes.length - i) * 8 - j;\n        if (j > 3) {\n          html += '<td class=\"nibble\">' + index + '</td>'\n        } else {\n          html += '<td class=\"dark nibble\">' + index + '</td>'\n        }\n      }\n    }\n    html += '</tr>';\n    // The bits\n    html += '<tr>';\n    for (var i = 0; i < bytes.length; i++) {\n      for (var j = 0; j < 8; j++) {\n        var index = i * 8 + j;\n        var className =\n          index === 0 ? 'sign' :\n            index < 1 + exponentBits ? 'exponent' :\n              'fraction';\n        html += '<td data-index=\"' + index + '\" class=\"' + className + '\">0</td>';\n      }\n    }\n    html += '</tr></table>';\n    input.innerHTML = html;\n\n    // Grab elements\n    var elements = [];\n    for (var i = 0; i < bytes.length * 8; i++) {\n      (function (i) {\n        var element = input.querySelector('[data-index=\"' + i + '\"]');\n        element.onmouseover = function () { this.classList.add('hover'); };\n        element.onmouseout = function () { this.classList.remove('hover'); };\n        elements.push(element);\n      })(i);\n    }\n\n    // Event handlers\n    function extractNumber() {\n      return +(output.value.replace(/\\b(?:infinity|inf)\\b/gi, 'Infinity'));\n    }\n    output.onkeydown = function (e) {\n      if (e.which === 13) {\n        e.preventDefault();\n        output.blur();\n      }\n\n      else if (e.which === 38) {\n        e.preventDefault();\n        output.value = reduceNumber(extractNumber() + 1);\n        output.select();\n        output.oninput();\n      }\n\n      else if (e.which === 40) {\n        e.preventDefault();\n        output.value = reduceNumber(extractNumber() - 1);\n        output.select();\n        output.oninput();\n      }\n    };\n    output.onfocus = function () {\n      output.select();\n    };\n    output.oninput = function () {\n      array[0] = extractNumber();\n      render();\n    };\n    output.onblur = function () {\n      render();\n    };\n\n    hex.onkeydown = function (e) {\n      if (e.which === 13) {\n        e.preventDefault();\n        hex.blur();\n      }\n    };\n    hex.onfocus = function () {\n      hex.select();\n    };\n    hex.oninput = function () {\n      var hexAlphabet = '0123456789abcdefABCDEF';\n      var validHexCharas = hex.value.split('').every(function (c) {\n        return hexAlphabet.split('').lastIndexOf(c) !== -1;\n      });\n      if (hex.value.length > (hexLength * 2) || validHexCharas === false) {\n        hex.value = hex.value.slice(0, -1);\n        return;\n      }\n\n      var tmpBytes = toByteArray(hex.value);\n      bytes.fill(0);\n      bytes.set(tmpBytes.reverse(), hexLength - tmpBytes.length);\n      render();\n    };\n    hex.onblur = function () {\n      render();\n    };\n\n    input.onmousedown = function (e) {\n      if ('index' in e.target.dataset) {\n        var index = e.target.dataset.index | 0;\n        var byteIndex = bytes.length - (index >> 3) - 1;\n        var byteMask = 1 << (7 - (index & 7));\n        var mouseDownValue = bytes[byteIndex] & byteMask ? 0 : 1;\n        bytes[byteIndex] ^= byteMask;\n        render();\n\n        document.onmousemove = function (e2) {\n          if ('index' in e2.target.dataset) {\n            var index = e2.target.dataset.index | 0;\n            var byteIndex = bytes.length - (index >> 3) - 1;\n            var byteMask = 1 << (7 - (index & 7));\n            bytes[byteIndex] = (bytes[byteIndex] & ~byteMask) | (byteMask * mouseDownValue);\n            render();\n          }\n        };\n\n        document.onmouseup = function () {\n          document.onmousemove = null;\n          document.onmouseup = null;\n        };\n      }\n    };\n\n    // Update loop\n    function render() {\n      for (var i = 0; i < bytes.length * 8; i++) {\n        elements[i].textContent = ((bytes[bytes.length - (i >> 3) - 1] >> (7 - (i & 7))) & 1);\n      }\n\n      // Figure out exponent\n      var exponent = 0;\n      for (var i = 0; i < exponentBits; i++) {\n        var index = 1 + i;\n        var bit = (bytes[bytes.length - (index >> 3) - 1] >> (7 - (index & 7))) & 1;\n        exponent += bit << (exponentBits - i - 1);\n      }\n      var exponentBias = (1 << (exponentBits - 1)) - 1;\n      exponent -= exponentBias;\n\n      // Figure out fraction\n      var copyBytes = new Uint8Array(bytes);\n      var copy = bytes.length === 2 ? new Float16Array(copyBytes.buffer) : bytes.length === 4 ? new Float32Array(copyBytes.buffer) : new Float64Array(copyBytes.buffer);\n      for (var i = 0; i < exponentBits; i++) {\n        var index = 1 + i;\n        var byteIndex = bytes.length - (index >> 3) - 1;\n        var byteMask = 1 << (7 - (index & 7));\n        copyBytes[byteIndex] = (copyBytes[byteIndex] & ~byteMask) | (i === 0 ? 0 : byteMask);\n      }\n      var signIndex = bytes.length - 1;\n      var signMask = 0x80;\n      var sign = copyBytes[signIndex] & signMask;\n      copyBytes[signIndex] &= ~signMask;\n      var fraction = copy[0];\n\n      // Handle denormal numbers\n      if (exponent === -exponentBias) {\n        exponent++;\n        fraction--;\n      }\n\n      // Update views according to which input was edited\n      if (document.activeElement === hex) {\n        var value = array[0];\n        output.value = reduceNumber(value === 0 && 1 / value === -Infinity ? '-0' : value);\n      } else if (document.activeElement === output) {\n        var tmpBytes = bytes.slice().reverse();\n        hex.value = toHexString(tmpBytes);\n      } else { // This branch is for when the individual bits get toggled\n        var value = array[0];\n        output.value = reduceNumber(value === 0 && 1 / value === -Infinity ? '-0' : value);\n        var tmpBytes = bytes.slice().reverse();\n        hex.value = toHexString(tmpBytes);\n      }\n\n      help.innerHTML =\n        '<span class=\"sign\">' + (sign ? -1 : 1) + '</span>' +\n        '&nbsp;&nbsp;&times;&nbsp;&nbsp;' +\n        '<span class=\"exponent\">2<sup>' + exponent + '</sup></span>' +\n        '&nbsp;&nbsp;&times;&nbsp;&nbsp;' +\n        '<span class=\"fraction\">' + reduceNumber(fraction) + '</span>';\n    }\n\n    function toHexString(byteArray) {\n      return Array.from(byteArray, function (byte) {\n        return ('0' + byte.toString(16).toUpperCase()).slice(-2);\n      }).join('')\n    }\n\n    function toByteArray(hexString) {\n      var result = [];\n      if (hexString.length % 2 == 1) {\n        hexString = hexString + '0';\n      }\n      for (var i = 0; i < hexString.length; i += 2) {\n        result.push(parseInt(hexString.substr(i, 2), 16));\n      }\n      return result;\n    }\n\n    render();\n  }\n\n  load(new Float16Array([Math.PI]), 5, document.getElementById('input16'), document.getElementById('output16'), document.getElementById('help16'), document.getElementById('hex16'));\n  load(new Float32Array([Math.PI]), 8, document.getElementById('input32'), document.getElementById('output32'), document.getElementById('help32'), document.getElementById('hex32'));\n  load(new Float64Array([Math.PI]), 11, document.getElementById('input64'), document.getElementById('output64'), document.getElementById('help64'), document.getElementById('hex64'));\n\n})();\n\n</script>\n"
  }
]