function copyFromBufferString(n, list) {
    var p = list.head;
    var c = 1;
    var ret = p.data;
    n -= ret.length;
    while (p = p.next) {
      var str = p.data;
      var nb = n > str.length ? str.length : n;
      if (nb === str.length) ret += str;else ret += str.slice(0, n);
      n -= nb;
      if (n === 0) {
        if (nb === str.length) {
          ++c;
          if (p.next) list.head = p.next;else list.head = list.tail = null;
        } else {
          list.head = p;
          p.data = str.slice(nb);
        }
        break;
      }
      ++c;
    }
    list.length -= c;
    return ret;
  }

// Copies a specified amount of characters from the list of buffered data


doPong(data, mask, readOnly, cb) {
    this.sendFrame(
      Sender.frame(data, {
        fin: true,
        rsv1: false,
        opcode: 0x0a,
        mask,
        readOnly
      }),
      cb
    );
  }

/**
   * Frames and sends a pong message.
   *
   * @param {Buffer} data The message to send
   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
   * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
   * @param {Function} [cb] Callback
   * @private
   */


function socketOnError() {
  this.destroy();
}

/**
 * Handle premature socket errors.
 *
 * @private
 */


function Progress(runner, options) {
  Base.call(this, runner, options);

  var self = this;
  var width = (Base.window.width * 0.5) | 0;
  var total = runner.total;
  var complete = 0;
  var lastN = -1;

  // default chars
  options = options || {};
  var reporterOptions = options.reporterOptions || {};

  options.open = reporterOptions.open || '[';
  options.complete = reporterOptions.complete || '▬';
  options.incomplete = reporterOptions.incomplete || Base.symbols.dot;
  options.close = reporterOptions.close || ']';
  options.verbose = reporterOptions.verbose || false;

  // tests started
  runner.on(EVENT_RUN_BEGIN, function() {
    process.stdout.write('\n');
    cursor.hide();
  });

  // tests complete
  runner.on(EVENT_TEST_END, function() {
    complete++;

    var percent = complete / total;
    var n = (width * percent) | 0;
    var i = width - n;

    if (n === lastN && !options.verbose) {
      // Don't re-render the line if it hasn't changed
      return;
    }
    lastN = n;

    cursor.CR();
    process.stdout.write('\u001b[J');
    process.stdout.write(color('progress', '  ' + options.open));
    process.stdout.write(Array(n).join(options.complete));
    process.stdout.write(Array(i).join(options.incomplete));
    process.stdout.write(color('progress', options.close));
    if (options.verbose) {
      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
    }
  });

  // tests are complete, output some stats
  // and the failures if any
  runner.once(EVENT_RUN_END, function() {
    cursor.show();
    process.stdout.write('\n');
    self.epilogue();
  });
}

/**
 * Constructs a new `Progress` reporter instance.
 *
 * @public
 * @class
 * @memberof Mocha.reporters
 * @extends Mocha.reporters.Base
 * @param {Runner} runner - Instance triggers reporter actions.
 * @param {Object} [options] - runner options
 */


function getAllKeys(object) {
      return baseGetAllKeys(object, keys, getSymbols);
    }

/**
     * Creates an array of own enumerable property names and symbols of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names and symbols.
     */


function memoizeCapped(func) {
      var result = memoize(func, function(key) {
        if (cache.size === MAX_MEMOIZE_SIZE) {
          cache.clear();
        }
        return key;
      });

      var cache = result.cache;
      return result;
    }

/**
     * A specialized version of `_.memoize` which clears the memoized function's
     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
     *
     * @private
     * @param {Function} func The function to have its output memoized.
     * @returns {Function} Returns the new memoized function.
     */


function baseLt(value, other) {
  return value < other;
}

/**
 * The base implementation of `_.lt` which doesn't coerce arguments.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if `value` is less than `other`,
 *  else `false`.
 */


async function httpFetch (fetchParams) {
  // 1. Let request be fetchParams’s request.
  const request = fetchParams.request

  // 2. Let response be null.
  let response = null

  // 3. Let actualResponse be null.
  let actualResponse = null

  // 4. Let timingInfo be fetchParams’s timing info.
  const timingInfo = fetchParams.timingInfo

  // 5. If request’s service-workers mode is "all", then:
  if (request.serviceWorkers === 'all') {
    // TODO
  }

  // 6. If response is null, then:
  if (response === null) {
    // 1. If makeCORSPreflight is true and one of these conditions is true:
    // TODO

    // 2. If request’s redirect mode is "follow", then set request’s
    // service-workers mode to "none".
    if (request.redirect === 'follow') {
      request.serviceWorkers = 'none'
    }

    // 3. Set response and actualResponse to the result of running
    // HTTP-network-or-cache fetch given fetchParams.
    actualResponse = response = await httpNetworkOrCacheFetch(fetchParams)

    // 4. If request’s response tainting is "cors" and a CORS check
    // for request and response returns failure, then return a network error.
    if (
      request.responseTainting === 'cors' &&
      corsCheck(request, response) === 'failure'
    ) {
      return makeNetworkError('cors failure')
    }

    // 5. If the TAO check for request and response returns failure, then set
    // request’s timing allow failed flag.
    if (TAOCheck(request, response) === 'failure') {
      request.timingAllowFailed = true
    }
  }

  // 7. If either request’s response tainting or response’s type
  // is "opaque", and the cross-origin resource policy check with
  // request’s origin, request’s client, request’s destination,
  // and actualResponse returns blocked, then return a network error.
  if (
    (request.responseTainting === 'opaque' || response.type === 'opaque') &&
    crossOriginResourcePolicyCheck(
      request.origin,
      request.client,
      request.destination,
      actualResponse
    ) === 'blocked'
  ) {
    return makeNetworkError('blocked')
  }

  // 8. If actualResponse’s status is a redirect status, then:
  if (redirectStatus.includes(actualResponse.status)) {
    // 1. If actualResponse’s status is not 303, request’s body is not null,
    // and the connection uses HTTP/2, then user agents may, and are even
    // encouraged to, transmit an RST_STREAM frame.
    // See, https://github.com/whatwg/fetch/issues/1288
    if (request.redirect !== 'manual') {
      fetchParams.controller.connection.destroy()
    }

    // 2. Switch on request’s redirect mode:
    if (request.redirect === 'error') {
      // Set response to a network error.
      response = makeNetworkError('unexpected redirect')
    } else if (request.redirect === 'manual') {
      // Set response to an opaque-redirect filtered response whose internal
      // response is actualResponse.
      // NOTE(spec): On the web this would return an `opaqueredirect` response,
      // but that doesn't make sense server side.
      // See https://github.com/nodejs/undici/issues/1193.
      response = actualResponse
    } else if (request.redirect === 'follow') {
      // Set response to the result of running HTTP-redirect fetch given
      // fetchParams and response.
      response = await httpRedirectFetch(fetchParams, response)
    } else {
      assert(false)
    }
  }

  // 9. Set response’s timing info to timingInfo.
  response.timingInfo = timingInfo

  // 10. Return response.
  return response
}


async mine(iterations = 0) {
        const solution = await this.iterate(iterations);
        if (solution) {
            if (this.block) {
                const data = this.block.toJSON();
                data.header.mixHash = solution.mixHash;
                data.header.nonce = solution.nonce;
                return ethereumjs_block_1.Block.fromBlockData(data, { common: this.block._common });
            }
            else {
                const data = this.blockHeader.toJSON();
                data.mixHash = solution.mixHash;
                data.nonce = solution.nonce;
                return ethereumjs_block_1.BlockHeader.fromHeaderData(data, { common: this.blockHeader._common });
            }
        }
    }

/**
     * Iterate `iterations` time over nonces, returns a `BlockHeader` or `Block` if a solution is found, `undefined` otherwise
     * @param iterations - Number of iterations to iterate over. If `-1` is passed, the loop runs until a solution is found
     * @returns - `undefined` if no solution was found within the iterations, or a `BlockHeader` or `Block`
     *           with valid PoW based upon what was passed in the constructor
     */


function trap(err) {
    // TODO: facilitate extra data along with errors
    throw new exceptions_1.EvmError(err);
}

/**
 * Wraps error message as EvmError
 */


async getProof(address, storageSlots = []) {
        const account = await this.getAccount(address);
        const accountProof = (await this._trie.createProof(address.buf)).map((p) => (0, ethereumjs_util_1.bufferToHex)(p));
        const storageProof = [];
        const storageTrie = await this._getStorageTrie(address);
        for (const storageKey of storageSlots) {
            const proof = (await storageTrie.createProof(storageKey)).map((p) => (0, ethereumjs_util_1.bufferToHex)(p));
            let value = (0, ethereumjs_util_1.bufferToHex)(await this.getContractStorage(address, storageKey));
            if (value === '0x') {
                value = '0x0';
            }
            const proofItem = {
                key: (0, ethereumjs_util_1.bufferToHex)(storageKey),
                value,
                proof,
            };
            storageProof.push(proofItem);
        }
        const returnValue = {
            address: address.toString(),
            balance: (0, ethereumjs_util_1.bigIntToHex)(account.balance),
            codeHash: (0, ethereumjs_util_1.bufferToHex)(account.codeHash),
            nonce: (0, ethereumjs_util_1.bigIntToHex)(account.nonce),
            storageHash: (0, ethereumjs_util_1.bufferToHex)(account.storageRoot),
            accountProof,
            storageProof,
        };
        return returnValue;
    }

/**
     * Get an EIP-1186 proof
     * @param address address to get proof of
     * @param storageSlots storage slots to get proof of
     */


function generatorEqual(leftHandOperand, rightHandOperand, options) {
  return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);
}

/*!
 * Simple equality for generator objects such as those returned by generator functions.
 *
 * @param {Iterable} leftHandOperand
 * @param {Iterable} rightHandOperand
 * @param {Object} [options] (Optional)
 * @return {Boolean} result
 */


function errorDiff(actual, expected) {
  return diff
    .diffWordsWithSpace(actual, expected)
    .map(function(str) {
      if (str.added) {
        return colorLines('diff added', str.value);
      }
      if (str.removed) {
        return colorLines('diff removed', str.value);
      }
      return str.value;
    })
    .join('');
}

/**
 * Returns character diff for `err`.
 *
 * @private
 * @param {String} actual
 * @param {String} expected
 * @return {string} the diff
 */


function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }


function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {

		Geometry.call( this );

		this.type = 'TorusGeometry';

		this.parameters = {
			radius: radius,
			tube: tube,
			radialSegments: radialSegments,
			tubularSegments: tubularSegments,
			arc: arc
		};

		this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
		this.mergeVertices();

	}

/**
	 * @author oosmoxiecode
	 * @author mrdoob / http://mrdoob.com/
	 * @author Mugen87 / https://github.com/Mugen87
	 */


addSublanguage(emitter, name) {
    /** @type DataNode */
    const node = emitter.root;
    node.kind = name;
    node.sublanguage = true;
    this.add(node);
  }

/**
   * @param {Emitter & {root: DataNode}} emitter
   * @param {string} name
   */


function dateTimeDeserializer(key, value) {
                    if (typeof value === 'string') {
                        const a = new Date(value);
                        if (!isNaN(a.valueOf())) {
                            return a;
                        }
                    }
                    return value;
                }


get signal() {
        return getSignal(this);
    }

/**
     * Returns the `AbortSignal` object associated with this object.
     */


get desiredSize() {
            if (!IsReadableStreamDefaultController(this)) {
                throw defaultControllerBrandCheckException$1('desiredSize');
            }
            return ReadableStreamDefaultControllerGetDesiredSize(this);
        }

/**
         * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
         * over-full. An underlying source ought to use this information to determine when and how to apply backpressure.
         */


function Ellipse$1(rx,ry,ax){if(!(this instanceof Ellipse$1)){return new Ellipse$1(rx,ry,ax);}this.rx=rx;this.ry=ry;this.ax=ax;}// Apply a linear transform m to the ellipse


async savePreferences(e) {
      const {
        lang,
        bgcolor,
        bgurl,
        gridsnappingon,
        gridsnappingstep,
        gridcolor,
        showrulers,
        baseunit
      } = e.detail;
      // Set background
      this.editor.setBackground(bgcolor, bgurl);

      // set language
      if (lang && lang !== this.editor.configObj.pref('lang')) {
        this.editor.configObj.pref('lang', lang);
        seAlert('Changing the language needs reload');
      }

      // set grid setting
      this.editor.configObj.curConfig.gridSnapping = gridsnappingon;
      this.editor.configObj.curConfig.snappingStep = gridsnappingstep;
      this.editor.configObj.curConfig.gridColor = gridcolor;
      this.editor.configObj.curConfig.showRulers = showrulers;
      if (this.editor.configObj.curConfig.showRulers) {
        this.editor.rulers.updateRulers();
      }
      this.editor.configObj.curConfig.baseUnit = baseunit;
      this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
      this.editor.updateCanvas();
      this.hidePreferences();
    }

/**
     * Save user preferences based on current values in the UI.
     * @param {Event} e
     * @function module:SVGthis.savePreferences
     * @returns {Promise<void>}
     */


function keyDown(e) {
      if (e.target.value === '' && e.target !== hex && (bindedHex && e.target !== bindedHex || !bindedHex)) return undefined;
      if (!validateKey(e)) return e;
      switch (e.target) {
        case red:
          switch (e.keyCode) {
            case 38:
              red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255);
              color.val('r', red.value, e.target);
              return false;
            case 40:
              red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255);
              color.val('r', red.value, e.target);
              return false;
          }
          break;
        case green:
          switch (e.keyCode) {
            case 38:
              green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255);
              color.val('g', green.value, e.target);
              return false;
            case 40:
              green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255);
              color.val('g', green.value, e.target);
              return false;
          }
          break;
        case blue:
          switch (e.keyCode) {
            case 38:
              blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255);
              color.val('b', blue.value, e.target);
              return false;
            case 40:
              blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255);
              color.val('b', blue.value, e.target);
              return false;
          }
          break;
        case alpha:
          switch (e.keyCode) {
            case 38:
              alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100);
              color.val('a', toFixedNumeric$1(alpha.value * 255 / 100, alphaPrecision), e.target);
              return false;
            case 40:
              alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100);
              color.val('a', toFixedNumeric$1(alpha.value * 255 / 100, alphaPrecision), e.target);
              return false;
          }
          break;
        case hue:
          switch (e.keyCode) {
            case 38:
              hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360);
              color.val('h', hue.value, e.target);
              return false;
            case 40:
              hue.value = setValueInRange.call(that, (hue.value << 0) - 1, 0, 360);
              color.val('h', hue.value, e.target);
              return false;
          }
          break;
        case saturation:
          switch (e.keyCode) {
            case 38:
              saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100);
              color.val('s', saturation.value, e.target);
              return false;
            case 40:
              saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100);
              color.val('s', saturation.value, e.target);
              return false;
          }
          break;
        case value:
          switch (e.keyCode) {
            case 38:
              value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100);
              color.val('v', value.value, e.target);
              return false;
            case 40:
              value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100);
              color.val('v', value.value, e.target);
              return false;
          }
          break;
      }
      return undefined;
    }

// input box key down - use arrows to alter color


function uncurryThis( fn ) {
            return function() {
                return call.apply( fn, arguments );
            };
        }


function getStreamingResponseStatusCodes(operationSpec) {
    const result = new Set();
    for (const statusCode in operationSpec.responses) {
        const operationResponse = operationSpec.responses[statusCode];
        if (operationResponse.bodyMapper &&
            operationResponse.bodyMapper.type.name === serializer_js_1.MapperTypeNames.Stream) {
            result.add(Number(statusCode));
        }
    }
    return result;
}

/**
 * Gets the list of status codes for streaming responses.
 * @internal
 */


function array_default(a4, b) {
  return (isNumberArray(b) ? numberArray_default : genericArray)(a4, b);
}


function conicProjection(projectAt) {
  var phi02 = 0, phi12 = pi4 / 3, m3 = projectionMutator(projectAt), p = m3(phi02, phi12);
  p.parallels = function(_) {
    return arguments.length ? m3(phi02 = _[0] * radians2, phi12 = _[1] * radians2) : [phi02 * degrees3, phi12 * degrees3];
  };
  return p;
}


function WebMidi() {

    // Singleton. Prevent instantiation through WebMidi.__proto__.constructor()
    if (WebMidi.prototype._singleton) {
      throw new Error("WebMidi is a singleton, it cannot be instantiated directly.");
    }
    WebMidi.prototype._singleton = this;

    // MIDI inputs and outputs
    this._inputs = [];
    this._outputs = [];

    // Object to hold all user-defined handlers for interface-wide events (connected, disconnected,
    // etc.)
    this._userHandlers = {};

    // Array of statechange events to process. These events must be parsed synchronously so they do
    // not override each other.
    this._stateChangeQueue = [];

    // Indicates whether we are currently processing a statechange event (in which case new events
    // are to be queued).
    this._processingStateChange = false;

    // Events triggered at the interface level (WebMidi)
    this._midiInterfaceEvents = ["connected", "disconnected"];

    // the current nrpns being constructed, by channel
    this._nrpnBuffer = [[],[],[],[], [],[],[],[], [],[],[],[], [],[],[],[]];

    // Enable/Disable NRPN event dispatch
    this._nrpnEventsEnabled = true;

    // NRPN message types
    this._nrpnTypes = ["entry", "increment", "decrement"];

    // Notes and semitones for note guessing
    this._notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
    this._semitones = {C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };

    // Define some "static" properties
    Object.defineProperties(this, {

      /**
       * [read-only] List of valid MIDI system messages and matching hexadecimal values.
       *
       * Note: values 249 and 253 are actually dispatched by the Web MIDI API but the MIDI 1.0 does
       * not say what they are used for. About those values, it only states: undefined (reserved)
       *
       * @property MIDI_SYSTEM_MESSAGES
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_SYSTEM_MESSAGES: {
        value: {

          // System common messages
          sysex: 0xF0,            // 240
          timecode: 0xF1,         // 241
          songposition: 0xF2,     // 242
          songselect: 0xF3,       // 243
          tuningrequest: 0xF6,    // 246
          sysexend: 0xF7,         // 247 (never actually received - simply ends a sysex)

          // System real-time messages
          clock: 0xF8,            // 248
          start: 0xFA,            // 250
          continue: 0xFB,         // 251
          stop: 0xFC,             // 252
          activesensing: 0xFE,    // 254
          reset: 0xFF,            // 255

          // Custom WebMidi.js messages
          midimessage: 0,
          unknownsystemmessage: -1
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * [read-only] An object containing properties for each MIDI channel messages and their
       * associated hexadecimal value.
       *
       * @property MIDI_CHANNEL_MESSAGES
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_CHANNEL_MESSAGES: {
        value: {
          noteoff: 0x8,           // 8
          noteon: 0x9,            // 9
          keyaftertouch: 0xA,     // 10
          controlchange: 0xB,     // 11
          channelmode: 0xB,       // 11
          nrpn: 0xB,              // 11
          programchange: 0xC,     // 12
          channelaftertouch: 0xD, // 13
          pitchbend: 0xE          // 14
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * [read-only] An object containing properties for each registered parameters and their
       * associated pair of hexadecimal values. MIDI registered parameters extend the original list
       * of control change messages (a.k.a. CC messages). Currently, there are only a limited number
       * of them.
       *
       * @property MIDI_REGISTERED_PARAMETER
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_REGISTERED_PARAMETER: {
        value: {
          pitchbendrange: [0x00, 0x00],
          channelfinetuning: [0x00, 0x01],
          channelcoarsetuning: [0x00, 0x02],
          tuningprogram: [0x00, 0x03],
          tuningbank: [0x00, 0x04],
          modulationrange: [0x00, 0x05],

          azimuthangle: [0x3D, 0x00],
          elevationangle: [0x3D, 0x01],
          gain: [0x3D, 0x02],
          distanceratio: [0x3D, 0x03],
          maximumdistance: [0x3D, 0x04],
          maximumdistancegain: [0x3D, 0x05],
          referencedistanceratio: [0x3D, 0x06],
          panspreadangle: [0x3D, 0x07],
          rollangle: [0x3D, 0x08]
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * [read-only] An object containing properties for each MIDI control change messages (a.k.a.
       * CC messages) and their associated hexadecimal value.
       *
       * @property MIDI_CONTROL_CHANGE_MESSAGES
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_CONTROL_CHANGE_MESSAGES: {
        value: {
          bankselectcoarse: 0,
          modulationwheelcoarse: 1,
          breathcontrollercoarse: 2,
          footcontrollercoarse: 4,
          portamentotimecoarse: 5,
          dataentrycoarse: 6,
          volumecoarse: 7,
          balancecoarse: 8,
          pancoarse: 10,
          expressioncoarse: 11,
          effectcontrol1coarse: 12,
          effectcontrol2coarse: 13,
          generalpurposeslider1: 16,
          generalpurposeslider2: 17,
          generalpurposeslider3: 18,
          generalpurposeslider4: 19,
          bankselectfine: 32,
          modulationwheelfine: 33,
          breathcontrollerfine: 34,
          footcontrollerfine: 36,
          portamentotimefine: 37,
          dataentryfine: 38,
          volumefine: 39,
          balancefine: 40,
          panfine: 42,
          expressionfine: 43,
          effectcontrol1fine: 44,
          effectcontrol2fine: 45,
          holdpedal: 64,
          portamento: 65,
          sustenutopedal: 66,
          softpedal: 67,
          legatopedal: 68,
          hold2pedal: 69,
          soundvariation: 70,
          resonance: 71,
          soundreleasetime: 72,
          soundattacktime: 73,
          brightness: 74,
          soundcontrol6: 75,
          soundcontrol7: 76,
          soundcontrol8: 77,
          soundcontrol9: 78,
          soundcontrol10: 79,
          generalpurposebutton1: 80,
          generalpurposebutton2: 81,
          generalpurposebutton3: 82,
          generalpurposebutton4: 83,
          reverblevel: 91,
          tremololevel: 92,
          choruslevel: 93,
          celestelevel: 94,
          phaserlevel: 95,
          databuttonincrement: 96,
          databuttondecrement: 97,
          nonregisteredparametercoarse: 98,
          nonregisteredparameterfine: 99,
          registeredparametercoarse: 100,
          registeredparameterfine: 101
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * [read-only] An object containing properties for MIDI control change messages
       * that make up NRPN messages
       *
       * @property MIDI_NRPN_MESSAGES
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_NRPN_MESSAGES: {
        value: {
          entrymsb: 6,
          entrylsb: 38,
          increment: 96,
          decrement: 97,
          paramlsb: 98,
          parammsb: 99,
          nullactiveparameter: 127
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * [read-only] List of MIDI channel mode messages as defined in the official MIDI
       * specification.
       *
       * @property MIDI_CHANNEL_MODE_MESSAGES
       * @type Object
       * @static
       *
       * @since 2.0.0
       */
      MIDI_CHANNEL_MODE_MESSAGES: {
        value: {
          allsoundoff: 120,
          resetallcontrollers: 121,
          localcontrol: 122,
          allnotesoff: 123,
          omnimodeoff: 124,
          omnimodeon: 125,
          monomodeon: 126,
          polymodeon: 127
        },
        writable: false,
        enumerable: true,
        configurable: false
      },

      /**
       * An integer to offset the octave both in inbound and outbound messages. By default, middle C
       * (MIDI note number 60) is placed on the 4th octave (C4).
       *
       * If, for example, `octaveOffset` is set to 2, MIDI note number 60 will be reported as C6. If
       * `octaveOffset` is set to -1, MIDI note number 60 will be reported as C3.
       *
       * @property octaveOffset
       * @type Number
       * @static
       *
       * @since 2.1
       */
      octaveOffset: {
        value: 0,
        writable: true,
        enumerable: true,
        configurable: false
      }

    });

    // Define getters/setters
    Object.defineProperties(this, {

      /**
       * [read-only] Indicates whether the environment supports the Web MIDI API or not.
       *
       * Note: in environments that do not offer built-in MIDI support, this will report true if the
       * `navigator.requestMIDIAccess` function is available. For example, if you have installed
       * WebMIDIAPIShim but no plugin, this property will be true even though actual support might
       * not be there.
       *
       * @property supported
       * @type Boolean
       * @static
       */
      supported: {
        enumerable: true,
        get: function() {
          return "requestMIDIAccess" in navigator;
        }
      },

      /**
       * [read-only] Indicates whether the interface to the host"s MIDI subsystem is currently
       * enabled.
       *
       * @property enabled
       * @type Boolean
       * @static
       */
      enabled: {
        enumerable: true,
        get: function() {
          return this.interface !== undefined;
        }.bind(this)
      },

      /**
       * [read-only] An array of all currently available MIDI input ports.
       *
       * @property inputs
       * @type {Array}
       * @static
       */
      inputs: {
        enumerable: true,
        get: function() {
          return this._inputs;
        }.bind(this)
      },

      /**
       * [read-only] An array of all currently available MIDI output ports.
       *
       * @property outputs
       * @type {Array}
       * @static
       */
      outputs: {
        enumerable: true,
        get: function() {
          return this._outputs;
        }.bind(this)
      },

      /**
       * [read-only] Indicates whether the interface to the host"s MIDI subsystem is currently
       * active.
       *
       * @property sysexEnabled
       * @type Boolean
       * @static
       */
      sysexEnabled: {
        enumerable: true,
        get: function() {
          return !!(this.interface && this.interface.sysexEnabled);
        }.bind(this)
      },

      /**
       * [read-only] Indicates whether WebMidi should dispatch Non-Registered
       * Parameter Number events (which are generally groups of CC messages)
       * If correct sequences of CC messages are received, NRPN events will
       * fire. The first out of order NRPN CC will fall through the collector
       * logic and all CC messages buffered will be discarded as incomplete.
       *
       * @private
       *
       * @property nrpnEventsEnabled
       * @type Boolean
       * @static
       */
      nrpnEventsEnabled: {
        enumerable: true,
        get: function() {
          return !!(this._nrpnEventsEnabled);
        }.bind(this),
        set: function(enabled) {
          this._nrpnEventsEnabled = enabled;
          return this._nrpnEventsEnabled;
        }
      },

      /**
       * [read-only] NRPN message types
       *
       * @property nrpnTypes
       * @type Array
       * @static
       */
      nrpnTypes: {
        enumerable: true,
        get: function() {
          return this._nrpnTypes;
        }.bind(this)
      },

      /**
       * [read-only] Current MIDI performance time in milliseconds. This can be used to queue events
       * in the future.
       *
       * @property time
       * @type DOMHighResTimeStamp
       * @static
       */
      time: {
        enumerable: true,
        get: function() {
          return performance.now();
        }
      }

    });

  }

/**
   * The `WebMidi` object makes it easier to work with the Web MIDI API. Basically, it simplifies
   * two things: sending outgoing MIDI messages and reacting to incoming MIDI messages.
   *
   * Sending MIDI messages is done via an `Output` object. All available outputs can be accessed in
   * the `WebMidi.outputs` array. There is one `Output` object for each output port available on
   * your system. Similarly, reacting to MIDI messages as they are coming in is simply a matter of
   * adding a listener to an `Input` object. Similarly, all inputs can be found in the
   * `WebMidi.inputs` array.
   *
   * Please note that a single hardware device might create more than one input and/or output ports.
   *
   * #### Sending messages
   *
   * To send MIDI messages, you simply need to call the desired method (`playNote()`,
   * `sendPitchBend()`, `stopNote()`, etc.) from an `Output` object and pass in the appropriate
   * parameters. All the native MIDI communication will be handled for you. The only additional
   * thing that needs to be done is to first enable `WebMidi`. Here is an example:
   *
   *      WebMidi.enable(function(err) {
   *        if (err) console.log("An error occurred", err);
   *        WebMidi.outputs[0].playNote("C3");
   *      });
   *
   * The code above, calls the `WebMidi.enable()` method. Upon success, this method executes the
   * callback function specified as a parameter. In this case, the callback calls the `playnote()`
   * function to play a 3rd octave C on the first available output port.
   *
   * #### Receiving messages
   *
   * Receiving messages is just as easy. You simply have to set a callback function to be triggered
   * when a specific MIDI message is received. For example, here"s how to listen for pitch bend
   * events on the first input port:
   *
   *      WebMidi.enable(function(err) {
   *        if (err) console.log("An error occurred", err);
   *
   *        WebMidi.inputs[0].addListener("pitchbend", "all", function(e) {
   *          console.log("Pitch value: " + e.value);
   *        });
   *
   *      });
   *
   * As you can see, this library is much easier to use than the native Web MIDI API. No need to
   * manually craft or decode binary MIDI messages anymore!
   *
   * @class WebMidi
   * @static
   *
   * @throws Error WebMidi is a singleton, it cannot be instantiated directly.
   *
   * @todo  Switch away from yuidoc (deprecated) to be able to serve doc over https
   * @todo  Yuidoc does not allow multiple exceptions (@throws) for a single method ?!
   *
   */


addCacheListener() {
        // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
        self.addEventListener('message', event => {
          // event.data is type 'any'
          // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
          if (event.data && event.data.type === 'CACHE_URLS') {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
            const {
              payload
            } = event.data;
            {
              logger.debug(`Caching URLs from the window`, payload.urlsToCache);
            }
            const requestPromises = Promise.all(payload.urlsToCache.map(entry => {
              if (typeof entry === 'string') {
                entry = [entry];
              }
              const request = new Request(...entry);
              return this.handleRequest({
                request,
                event
              });
              // TODO(philipwalton): TypeScript errors without this typecast for
              // some reason (probably a bug). The real type here should work but
              // doesn't: `Array<Promise<Response> | undefined>`.
            })); // TypeScript
            event.waitUntil(requestPromises);
            // If a MessageChannel was used, reply to the message on success.
            if (event.ports && event.ports[0]) {
              void requestPromises.then(() => event.ports[0].postMessage(true));
            }
          }
        });
      }

/**
       * Adds a message event listener for URLs to cache from the window.
       * This is useful to cache resources loaded on the page prior to when the
       * service worker started controlling it.
       *
       * The format of the message data sent from the window should be as follows.
       * Where the `urlsToCache` array may consist of URL strings or an array of
       * URL string + `requestInit` object (the same as you'd pass to `fetch()`).
       *
       * ```
       * {
       *   type: 'CACHE_URLS',
       *   payload: {
       *     urlsToCache: [
       *       './script1.js',
       *       './script2.js',
       *       ['./script3.js', {mode: 'no-cors'}],
       *     ],
       *   },
       * }
       * ```
       */


function waitUntil(event, asyncFn) {
      const returnPromise = asyncFn();
      event.waitUntil(returnPromise);
      return returnPromise;
    }

/*
      Copyright 2020 Google LLC
      Use of this source code is governed by an MIT-style
      license that can be found in the LICENSE file or at
      https://opensource.org/licenses/MIT.
    */


getCachedURLs() {
        return [...this._urlsToCacheKeys.keys()];
      }

/**
       * Returns a list of all the URLs that have been precached by the current
       * service worker.
       *
       * @return {Array<string>} The precached URLs.
       */


function isEmpty$1(value) {
    if (value == null) {
      return true;
    }
    if (isArrayLike(value) && (isArray$3(value) || typeof value == 'string' || typeof value.splice == 'function' || isBuffer(value) || isTypedArray(value) || isArguments$1(value))) {
      return !value.length;
    }
    var tag = getTag(value);
    if (tag == mapTag || tag == setTag) {
      return !value.size;
    }
    if (isPrototype(value)) {
      return !baseKeys(value).length;
    }
    for (var key in value) {
      if (hasOwnProperty.call(value, key)) {
        return false;
      }
    }
    return true;
  }

/**
   * Checks if `value` is an empty object, collection, map, or set.
   *
   * Objects are considered empty if they have no own enumerable string keyed
   * properties.
   *
   * Array-like values such as `arguments` objects, arrays, buffers, strings, or
   * jQuery-like collections are considered empty if they have a `length` of `0`.
   * Similarly, maps and sets are considered empty if they have a `size` of `0`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is empty, else `false`.
   * @example
   *
   * _.isEmpty(null);
   * // => true
   *
   * _.isEmpty(true);
   * // => true
   *
   * _.isEmpty(1);
   * // => true
   *
   * _.isEmpty([1, 2, 3]);
   * // => false
   *
   * _.isEmpty({ 'a': 1 });
   * // => false
   */


function initCloneArray$1(array) {
    var length = array.length,
      result = new array.constructor(length);

    // Add properties assigned by `RegExp#exec`.
    if (length && typeof array[0] == 'string' && hasOwnProperty$2.call(array, 'index')) {
      result.index = array.index;
      result.input = array.input;
    }
    return result;
  }

/**
   * Initializes an array clone.
   *
   * @private
   * @param {Array} array The array to clone.
   * @returns {Array} Returns the initialized clone.
   */


function stringToArray$2(string) {
    return hasUnicode$1(string) ? unicodeToArray(string) : asciiToArray(string);
  }

/**
   * Converts `string` to an array.
   *
   * @private
   * @param {string} string The string to convert.
   * @returns {Array} Returns the converted array.
   */


function memoize$1(func, resolver) {
    if (typeof func != 'function' || resolver != null && typeof resolver != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    var memoized = function () {
      var args = arguments,
        key = resolver ? resolver.apply(this, args) : args[0],
        cache = memoized.cache;
      if (cache.has(key)) {
        return cache.get(key);
      }
      var result = func.apply(this, args);
      memoized.cache = cache.set(key, result) || cache;
      return result;
    };
    memoized.cache = new (memoize$1.Cache || MapCache$1)();
    return memoized;
  }

/**
   * Creates a function that memoizes the result of `func`. If `resolver` is
   * provided, it determines the cache key for storing the result based on the
   * arguments provided to the memoized function. By default, the first argument
   * provided to the memoized function is used as the map cache key. The `func`
   * is invoked with the `this` binding of the memoized function.
   *
   * **Note:** The cache is exposed as the `cache` property on the memoized
   * function. Its creation may be customized by replacing the `_.memoize.Cache`
   * constructor with one whose instances implement the
   * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
   * method interface of `clear`, `delete`, `get`, `has`, and `set`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to have its output memoized.
   * @param {Function} [resolver] The function to resolve the cache key.
   * @returns {Function} Returns the new memoized function.
   * @example
   *
   * var object = { 'a': 1, 'b': 2 };
   * var other = { 'c': 3, 'd': 4 };
   *
   * var values = _.memoize(_.values);
   * values(object);
   * // => [1, 2]
   *
   * values(other);
   * // => [3, 4]
   *
   * object.a = 2;
   * values(object);
   * // => [1, 2]
   *
   * // Modify the result cache.
   * values.cache.set(object, ['a', 'b']);
   * values(object);
   * // => ['a', 'b']
   *
   * // Replace `_.memoize.Cache`.
   * _.memoize.Cache = WeakMap;
   */


function baseFindIndex$1(array, predicate, fromIndex, fromRight) {
  var length = array.length,
    index = fromIndex + (fromRight ? 1 : -1);
  while (fromRight ? index-- : ++index < length) {
    if (predicate(array[index], index, array)) {
      return index;
    }
  }
  return -1;
}

/**
 * The base implementation of `_.findIndex` and `_.findLastIndex` without
 * support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} predicate The function invoked per iteration.
 * @param {number} fromIndex The index to search from.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */


function listCacheHas$1(key) {
    return assocIndexOf$1(this.__data__, key) > -1;
  }

/**
   * Checks if a list cache value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf ListCache
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */


function isIndex$3(value, length) {
    var type = typeof value;
    length = length == null ? MAX_SAFE_INTEGER$1 : length;
    return !!length && (type == 'number' || type != 'symbol' && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length;
  }

/**
   * Checks if `value` is a valid array-like index.
   *
   * @private
   * @param {*} value The value to check.
   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
   */


function bnpFromString(s,b) {
      var k;
      if(b == 16) k = 4;
      else if(b == 8) k = 3;
      else if(b == 256) k = 8; // byte array
      else if(b == 2) k = 1;
      else if(b == 32) k = 5;
      else if(b == 4) k = 2;
      else { this.fromRadix(s,b); return; }
      this.t = 0;
      this.s = 0;
      var i = s.length, mi = false, sh = 0;
      while(--i >= 0) {
        var x = (k==8)?s[i]&0xff:intAt(s,i);
        if(x < 0) {
          if(s.charAt(i) == "-") mi = true;
          continue;
        }
        mi = false;
        if(sh == 0)
          this[this.t++] = x;
        else if(sh+k > this.DB) {
          this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
          this[this.t++] = (x>>(this.DB-sh));
        }
        else
          this[this.t-1] |= x<<sh;
        sh += k;
        if(sh >= this.DB) sh -= this.DB;
      }
      if(k == 8 && (s[0]&0x80) != 0) {
        this.s = -1;
        if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
      }
      this.clamp();
      if(mi) BigInteger.ZERO.subTo(this,this);
    }

// (protected) set from string and radix


function vendorPropName( name ) {

	// Shortcut for names that are not vendor prefixed
	if ( name in emptyStyle ) {
		return name;
	}

	// Check for vendor prefixed names
	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
		i = cssPrefixes.length;

	while ( i-- ) {
		name = cssPrefixes[ i ] + capName;
		if ( name in emptyStyle ) {
			return name;
		}
	}
}

// Return a css property mapped to a potentially vendor prefixed property


function makeChangeSingleDocInEditor(cm, change, spans) {
  var doc = cm.doc, display = cm.display, from = change.from, to = change.to

  var recomputeMaxLength = false, checkWidthStart = from.line
  if (!cm.options.lineWrapping) {
    checkWidthStart = lineNo(visualLine(getLine(doc, from.line)))
    doc.iter(checkWidthStart, to.line + 1, function (line) {
      if (line == display.maxLine) {
        recomputeMaxLength = true
        return true
      }
    })
  }

  if (doc.sel.contains(change.from, change.to) > -1)
    { signalCursorActivity(cm) }

  updateDoc(doc, change, spans, estimateHeight(cm))

  if (!cm.options.lineWrapping) {
    doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
      var len = lineLength(line)
      if (len > display.maxLineLength) {
        display.maxLine = line
        display.maxLineLength = len
        display.maxLineChanged = true
        recomputeMaxLength = false
      }
    })
    if (recomputeMaxLength) { cm.curOp.updateMaxLine = true }
  }

  // Adjust frontier, schedule worker
  doc.frontier = Math.min(doc.frontier, from.line)
  startWorker(cm, 400)

  var lendiff = change.text.length - (to.line - from.line) - 1
  // Remember that these lines changed, for updating the display
  if (change.full)
    { regChange(cm) }
  else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
    { regLineChange(cm, from.line, "text") }
  else
    { regChange(cm, from.line, to.line + 1, lendiff) }

  var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change")
  if (changeHandler || changesHandler) {
    var obj = {
      from: from, to: to,
      text: change.text,
      removed: change.removed,
      origin: change.origin
    }
    if (changeHandler) { signalLater(cm, "change", cm, obj) }
    if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) }
  }
  cm.display.selForContextMenu = null
}

// Handle the interaction of a change to a document with the editor


function attachLocalSpans(doc, change, from, to) {
  var existing = change["spans_" + doc.id], n = 0
  doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
    if (line.markedSpans)
      { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans }
    ++n
  })
}

// Used to store marked span information in the history.


function countColumn(string, end, tabSize, startIndex, startValue) {
  if (end == null) {
    end = string.search(/[^\s\u00a0]/)
    if (end == -1) { end = string.length }
  }
  for (var i = startIndex || 0, n = startValue || 0;;) {
    var nextTab = string.indexOf("\t", i)
    if (nextTab < 0 || nextTab >= end)
      { return n + (end - i) }
    n += nextTab - i
    n += tabSize - (n % tabSize)
    i = nextTab + 1
  }
}

// Counts the column offset in a string, taking tabs into account.


function handleCharBinding(cm, e, ch) {
  return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
}


function LinkedList() {
		/** @type {LinkedListNode<T>} */
		var head = { value: null, prev: null, next: null };
		/** @type {LinkedListNode<T>} */
		var tail = { value: null, prev: head, next: null };
		head.next = tail;

		/** @type {LinkedListNode<T>} */
		this.head = head;
		/** @type {LinkedListNode<T>} */
		this.tail = tail;
		this.length = 0;
	}

/**
	 * @typedef LinkedListNode
	 * @property {T} value
	 * @property {LinkedListNode<T> | null} prev The previous node.
	 * @property {LinkedListNode<T> | null} next The next node.
	 * @template T
	 * @private
	 */


constructor(headline, more) {
    super(stripAnsi(headline))
    this.headline = headline
    this.more = more
  }

/**
   * @param {string} headline
   * @param {{ error?: Error, detail?: string }} [more]
   */


function ensureCtor (comp, base) {
    if (
      comp.__esModule ||
      (hasSymbol && comp[Symbol.toStringTag] === 'Module')
    ) {
      comp = comp.default;
    }
    return isObject(comp)
      ? base.extend(comp)
      : comp
  }


function length(val) {
  return val.toString().length;
}

/**
 * Get the string length of `val`
 */


function baseIndexOfWith(array, value, fromIndex, comparator) {
  var index = fromIndex - 1,
      length = array.length;

  while (++index < length) {
    if (comparator(array[index], value)) {
      return index;
    }
  }
  return -1;
}

/**
 * This function is like `baseIndexOf` except that it accepts a comparator.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @param {Function} comparator The comparator invoked per element.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */


function isIndex(value, length) {
      var type = typeof value;
      length = length == null ? MAX_SAFE_INTEGER : length;

      return !!length &&
        (type == 'number' ||
          (type != 'symbol' && reIsUint.test(value))) &&
            (value > -1 && value % 1 == 0 && value < length);
    }

/**
     * Checks if `value` is a valid array-like index.
     *
     * @private
     * @param {*} value The value to check.
     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
     */


function baseCreate(prototype) {
    if (!isObject(prototype)) return {};
    if (nativeCreate) return nativeCreate(prototype);
    var Ctor = ctor();
    Ctor.prototype = prototype;
    var result = new Ctor;
    Ctor.prototype = null;
    return result;
  }

// An internal function for creating a new object that inherits from another.


function preventSelection(el) {
        el.style.userSelect = 'none';
        el.style.webkitUserSelect = 'none';
        el.addEventListener('selectstart', preventDefault);
    }


zintercard(...keys) {
        const intersection = this.ZINTER(...keys);
        return intersection.size;
    }

/**
     * Get the number of members in the intersection between the given sorted sets stored at the specified keys.
     *
     * @param {...string} keys - The keys where the sorted sets are stored.
     * @returns {number} - The number of members in the intersection.
     */


function toType(obj) {
    if (obj === null || typeof obj === 'undefined') {
      return "" + obj;
    }

    return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
  }

// Shoutout AngusCroll (https://goo.gl/pxwQGp)


function createFxNow() {
	window.setTimeout( function() {
		fxNow = undefined;
	} );
	return ( fxNow = jQuery.now() );
}

// Animations created synchronously will run synchronously


function cleanupStylesWhenDeleting() {
                var doc = editor.getDoc(),
                    dom = editor.dom,
                    selection = editor.selection;
                var MutationObserver = window.MutationObserver,
                    olderWebKit, dragStartRng;

                // Add mini polyfill for older WebKits
                // TODO: Remove this when old Safari versions gets updated
                if (!MutationObserver) {
                    olderWebKit = true;

                    MutationObserver = function() {
                        var records = [],
                            target;

                        function nodeInsert(e) {
                            var target = e.relatedNode || e.target;
                            records.push({ target: target, addedNodes: [target] });
                        }

                        function attrModified(e) {
                            var target = e.relatedNode || e.target;
                            records.push({ target: target, attributeName: e.attrName });
                        }

                        this.observe = function(node) {
                            target = node;
                            target.addEventListener('DOMSubtreeModified', nodeInsert, false);
                            target.addEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
                            target.addEventListener('DOMNodeInserted', nodeInsert, false);
                            target.addEventListener('DOMAttrModified', attrModified, false);
                        };

                        this.disconnect = function() {
                            target.removeEventListener('DOMSubtreeModified', nodeInsert, false);
                            target.removeEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
                            target.removeEventListener('DOMNodeInserted', nodeInsert, false);
                            target.removeEventListener('DOMAttrModified', attrModified, false);
                        };

                        this.takeRecords = function() {
                            return records;
                        };
                    };
                }

                function isTrailingBr(node) {
                    var blockElements = dom.schema.getBlockElements(),
                        rootNode = editor.getBody();

                    if (node.nodeName != 'BR') {
                        return false;
                    }

                    for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
                        if (node.nextSibling) {
                            return false;
                        }
                    }

                    return true;
                }

                function isSiblingsIgnoreWhiteSpace(node1, node2) {
                    var node;

                    for (node = node1.nextSibling; node && node != node2; node = node.nextSibling) {
                        if (node.nodeType == 3 && $.trim(node.data).length === 0) {
                            continue;
                        }

                        if (node !== node2) {
                            return false;
                        }
                    }

                    return node === node2;
                }

                function findCaretNode(node, forward, startNode) {
                    var walker, current, nonEmptyElements;

                    nonEmptyElements = dom.schema.getNonEmptyElements();

                    walker = new TreeWalker(startNode || node, node);

                    while ((current = walker[forward ? 'next' : 'prev']())) {
                        if (nonEmptyElements[current.nodeName] && !isTrailingBr(current)) {
                            return current;
                        }

                        if (current.nodeType == 3 && current.data.length > 0) {
                            return current;
                        }
                    }
                }

                function deleteRangeBetweenTextBlocks(rng) {
                    var startBlock, endBlock, caretNodeBefore, caretNodeAfter, textBlockElements;

                    if (rng.collapsed) {
                        return;
                    }

                    startBlock = dom.getParent(RangeUtils.getNode(rng.startContainer, rng.startOffset), dom.isBlock);
                    endBlock = dom.getParent(RangeUtils.getNode(rng.endContainer, rng.endOffset), dom.isBlock);
                    textBlockElements = editor.schema.getTextBlockElements();

                    if (startBlock == endBlock) {
                        return;
                    }

                    if (!textBlockElements[startBlock.nodeName] || !textBlockElements[endBlock.nodeName]) {
                        return;
                    }

                    if (dom.getContentEditable(startBlock) === "false" || dom.getContentEditable(endBlock) === "false") {
                        return;
                    }

                    rng.deleteContents();

                    caretNodeBefore = findCaretNode(startBlock, false);
                    caretNodeAfter = findCaretNode(endBlock, true);

                    if (!dom.isEmpty(endBlock)) {
                        $(startBlock).append(endBlock.childNodes);
                    }

                    $(endBlock).remove();

                    if (caretNodeBefore) {
                        if (caretNodeBefore.nodeType == 1) {
                            if (caretNodeBefore.nodeName == "BR") {
                                rng.setStartBefore(caretNodeBefore);
                                rng.setEndBefore(caretNodeBefore);
                            } else {
                                rng.setStartAfter(caretNodeBefore);
                                rng.setEndAfter(caretNodeBefore);
                            }
                        } else {
                            rng.setStart(caretNodeBefore, caretNodeBefore.data.length);
                            rng.setEnd(caretNodeBefore, caretNodeBefore.data.length);
                        }
                    } else if (caretNodeAfter) {
                        if (caretNodeAfter.nodeType == 1) {
                            rng.setStartBefore(caretNodeAfter);
                            rng.setEndBefore(caretNodeAfter);
                        } else {
                            rng.setStart(caretNodeAfter, 0);
                            rng.setEnd(caretNodeAfter, 0);
                        }
                    }

                    selection.setRng(rng);

                    return true;
                }

                function expandBetweenBlocks(rng, isForward) {
                    var caretNode, targetCaretNode, textBlock, targetTextBlock, container, offset;

                    if (!rng.collapsed) {
                        return rng;
                    }

                    container = rng.startContainer;
                    offset = rng.startOffset;

                    if (container.nodeType == 3) {
                        if (isForward) {
                            if (offset < container.data.length) {
                                return rng;
                            }
                        } else {
                            if (offset > 0) {
                                return rng;
                            }
                        }
                    }

                    caretNode = RangeUtils.getNode(rng.startContainer, rng.startOffset);
                    textBlock = dom.getParent(caretNode, dom.isBlock);
                    targetCaretNode = findCaretNode(editor.getBody(), isForward, caretNode);
                    targetTextBlock = dom.getParent(targetCaretNode, dom.isBlock);

                    if (!caretNode || !targetCaretNode) {
                        return rng;
                    }

                    if (targetTextBlock && textBlock != targetTextBlock) {
                        if (!isForward) {
                            if (!isSiblingsIgnoreWhiteSpace(targetTextBlock, textBlock)) {
                                return rng;
                            }

                            if (targetCaretNode.nodeType == 1) {
                                if (targetCaretNode.nodeName == "BR") {
                                    rng.setStartBefore(targetCaretNode);
                                } else {
                                    rng.setStartAfter(targetCaretNode);
                                }
                            } else {
                                rng.setStart(targetCaretNode, targetCaretNode.data.length);
                            }

                            if (caretNode.nodeType == 1) {
                                rng.setEnd(caretNode, 0);
                            } else {
                                rng.setEndBefore(caretNode);
                            }
                        } else {
                            if (!isSiblingsIgnoreWhiteSpace(textBlock, targetTextBlock)) {
                                return rng;
                            }

                            if (caretNode.nodeType == 1) {
                                if (caretNode.nodeName == "BR") {
                                    rng.setStartBefore(caretNode);
                                } else {
                                    rng.setStartAfter(caretNode);
                                }
                            } else {
                                rng.setStart(caretNode, caretNode.data.length);
                            }

                            if (targetCaretNode.nodeType == 1) {
                                rng.setEnd(targetCaretNode, 0);
                            } else {
                                rng.setEndBefore(targetCaretNode);
                            }
                        }
                    }

                    return rng;
                }

                function handleTextBlockMergeDelete(isForward) {
                    var rng = selection.getRng();

                    rng = expandBetweenBlocks(rng, isForward);

                    if (deleteRangeBetweenTextBlocks(rng)) {
                        return true;
                    }
                }

                /**
                 * This retains the formatting if the last character is to be deleted.
                 *
                 * Backspace on this:
a|
 would become
|
 in WebKit.
                 * With this patch:
|

                 */
                function handleLastBlockCharacterDelete(isForward, rng) {
                    var path, blockElm, newBlockElm, clonedBlockElm, sibling,
                        container, offset, br, currentFormatNodes;

                    function cloneTextBlockWithFormats(blockElm, node) {
                        currentFormatNodes = $(node).parents().filter(function(idx, node) {
                            return !!editor.schema.getTextInlineElements()[node.nodeName];
                        });

                        newBlockElm = blockElm.cloneNode(false);

                        currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) {
                            formatNode = formatNode.cloneNode(false);

                            if (newBlockElm.hasChildNodes()) {
                                formatNode.appendChild(newBlockElm.firstChild);
                                newBlockElm.appendChild(formatNode);
                            } else {
                                newBlockElm.appendChild(formatNode);
                            }

                            newBlockElm.appendChild(formatNode);

                            return formatNode;
                        });

                        if (currentFormatNodes.length) {
                            br = dom.create('br');
                            currentFormatNodes[0].appendChild(br);
                            dom.replace(newBlockElm, blockElm);

                            rng.setStartBefore(br);
                            rng.setEndBefore(br);
                            editor.selection.setRng(rng);

                            return br;
                        }

                        return null;
                    }

                    function isTextBlock(node) {
                        return node && editor.schema.getTextBlockElements()[node.tagName];
                    }

                    if (!rng.collapsed) {
                        return;
                    }

                    container = rng.startContainer;
                    offset = rng.startOffset;
                    blockElm = dom.getParent(container, dom.isBlock);
                    if (!isTextBlock(blockElm)) {
                        return;
                    }

                    if (container.nodeType == 1) {
                        container = container.childNodes[offset];
                        if (container && container.tagName != 'BR') {
                            return;
                        }

                        if (isForward) {
                            sibling = blockElm.nextSibling;
                        } else {
                            sibling = blockElm.previousSibling;
                        }

                        if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) {
                            if (cloneTextBlockWithFormats(blockElm, container)) {
                                dom.remove(sibling);
                                return true;
                            }
                        }
                    } else if (container.nodeType == 3) {
                        path = NodePath.create(blockElm, container);
                        clonedBlockElm = blockElm.cloneNode(true);
                        container = NodePath.resolve(clonedBlockElm, path);

                        if (isForward) {
                            if (offset >= container.data.length) {
                                return;
                            }

                            container.deleteData(offset, 1);
                        } else {
                            if (offset <= 0) {
                                return;
                            }

                            container.deleteData(offset - 1, 1);
                        }

                        if (dom.isEmpty(clonedBlockElm)) {
                            return cloneTextBlockWithFormats(blockElm, container);
                        }
                    }
                }

                function customDelete(isForward) {
                    var mutationObserver, rng, caretElement;

                    if (handleTextBlockMergeDelete(isForward)) {
                        return;
                    }

                    Tools.each(editor.getBody().getElementsByTagName('*'), function(elm) {
                        // Mark existing spans
                        if (elm.tagName == 'SPAN') {
                            elm.setAttribute('mce-data-marked', 1);
                        }

                        // Make sure all elements has a data-mce-style attribute
                        if (!elm.hasAttribute('data-mce-style') && elm.hasAttribute('style')) {
                            editor.dom.setAttrib(elm, 'style', editor.dom.getAttrib(elm, 'style'));
                        }
                    });

                    // Observe added nodes and style attribute changes
                    mutationObserver = new MutationObserver(function() {});
                    mutationObserver.observe(editor.getDoc(), {
                        childList: true,
                        attributes: true,
                        subtree: true,
                        attributeFilter: ['style']
                    });

                    editor.getDoc().execCommand(isForward ? 'ForwardDelete' : 'Delete', false, null);

                    rng = editor.selection.getRng();
                    caretElement = rng.startContainer.parentNode;

                    Tools.each(mutationObserver.takeRecords(), function(record) {
                        if (!dom.isChildOf(record.target, editor.getBody())) {
                            return;
                        }

                        // Restore style attribute to previous value
                        if (record.attributeName == "style") {
                            var oldValue = record.target.getAttribute('data-mce-style');

                            if (oldValue) {
                                record.target.setAttribute("style", oldValue);
                            } else {
                                record.target.removeAttribute("style");
                            }
                        }

                        // Remove all spans that aren't marked and retain selection
                        Tools.each(record.addedNodes, function(node) {
                            if (node.nodeName == "SPAN" && !node.getAttribute('mce-data-marked')) {
                                var offset, container;

                                if (node == caretElement) {
                                    offset = rng.startOffset;
                                    container = node.firstChild;
                                }

                                dom.remove(node, true);

                                if (container) {
                                    rng.setStart(container, offset);
                                    rng.setEnd(container, offset);
                                    editor.selection.setRng(rng);
                                }
                            }
                        });
                    });

                    mutationObserver.disconnect();

                    // Remove any left over marks
                    Tools.each(editor.dom.select('span[mce-data-marked]'), function(span) {
                        span.removeAttribute('mce-data-marked');
                    });
                }

                editor.on('keydown', function(e) {
                    var isForward = e.keyCode == DELETE,
                        isMetaOrCtrl = e.ctrlKey || e.metaKey;

                    if (!isDefaultPrevented(e) && (isForward || e.keyCode == BACKSPACE)) {
                        var rng = editor.selection.getRng(),
                            container = rng.startContainer,
                            offset = rng.startOffset;

                        // Shift+Delete is cut
                        if (isForward && e.shiftKey) {
                            return;
                        }

                        if (handleLastBlockCharacterDelete(isForward, rng)) {
                            e.preventDefault();
                            return;
                        }

                        // Ignore non meta delete in the where there is text before/after the caret
                        if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) {
                            if (isForward ? offset < container.data.length : offset > 0) {
                                return;
                            }
                        }

                        e.preventDefault();

                        if (isMetaOrCtrl) {
                            editor.selection.getSel().modify("extend", isForward ? "forward" : "backward", e.metaKey ? "lineboundary" : "word");
                        }

                        customDelete(isForward);
                    }
                });

                // Handle case where text is deleted by typing over
                editor.on('keypress', function(e) {
                    if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) {
                        var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText;

                        rng = editor.selection.getRng();
                        charText = String.fromCharCode(e.charCode);
                        e.preventDefault();

                        // Keep track of current format nodes
                        currentFormatNodes = $(rng.startContainer).parents().filter(function(idx, node) {
                            return !!editor.schema.getTextInlineElements()[node.nodeName];
                        });

                        customDelete(true);

                        // Check if the browser removed them
                        currentFormatNodes = currentFormatNodes.filter(function(idx, node) {
                            return !$.contains(editor.getBody(), node);
                        });

                        // Then re-add them
                        if (currentFormatNodes.length) {
                            fragmentNode = dom.createFragment();

                            currentFormatNodes.each(function(idx, formatNode) {
                                formatNode = formatNode.cloneNode(false);

                                if (fragmentNode.hasChildNodes()) {
                                    formatNode.appendChild(fragmentNode.firstChild);
                                    fragmentNode.appendChild(formatNode);
                                } else {
                                    caretNode = formatNode;
                                    fragmentNode.appendChild(formatNode);
                                }

                                fragmentNode.appendChild(formatNode);
                            });

                            caretNode.appendChild(editor.getDoc().createTextNode(charText));

                            // Prevent edge case where older WebKit would add an extra BR element
                            blockParent = dom.getParent(rng.startContainer, dom.isBlock);
                            if (dom.isEmpty(blockParent)) {
                                $(blockParent).empty().append(fragmentNode);
                            } else {
                                rng.insertNode(fragmentNode);
                            }

                            rng.setStart(caretNode.firstChild, 1);
                            rng.setEnd(caretNode.firstChild, 1);
                            editor.selection.setRng(rng);
                        } else {
                            editor.selection.setContent(charText);
                        }
                    }
                });

                editor.addCommand('Delete', function() {
                    customDelete();
                });

                editor.addCommand('ForwardDelete', function() {
                    customDelete(true);
                });

                // Older WebKits doesn't properly handle the clipboard so we can't add the rest
                if (olderWebKit) {
                    return;
                }

                editor.on('dragstart', function(e) {
                    dragStartRng = selection.getRng();
                    setMceInternalContent(e);
                });

                editor.on('drop', function(e) {
                    if (!isDefaultPrevented(e)) {
                        var internalContent = getMceInternalContent(e);

                        if (internalContent) {
                            e.preventDefault();

                            // Safari has a weird issue where drag/dropping images sometimes
                            // produces a green plus icon. When this happens the caretRangeFromPoint
                            // will return "null" even though the x, y coordinate is correct.
                            // But if we detach the insert from the drop event we will get a proper range
                            Delay.setEditorTimeout(editor, function() {
                                var pointRng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, doc);

                                if (dragStartRng) {
                                    selection.setRng(dragStartRng);
                                    dragStartRng = null;
                                }

                                customDelete();
                                selection.setRng(pointRng);
                                insertClipboardContents(internalContent.html);
                            });
                        }
                    }
                });

                editor.on('cut', function(e) {
                    if (!isDefaultPrevented(e) && e.clipboardData && !editor.selection.isCollapsed()) {
                        e.preventDefault();
                        e.clipboardData.clearData();
                        e.clipboardData.setData('text/html', editor.selection.getContent());
                        e.clipboardData.setData('text/plain', editor.selection.getContent({ format: 'text' }));

                        // Needed delay for https://code.google.com/p/chromium/issues/detail?id=363288#c3
                        // Nested delete/forwardDelete not allowed on execCommand("cut")
                        // This is ugly but not sure how to work around it otherwise
                        Delay.setEditorTimeout(editor, function() {
                            customDelete(true);
                        });
                    }
                });
            }

/**
             * Fixes a WebKit bug when deleting contents using backspace or delete key.
             * WebKit will produce a span element if you delete across two block elements.
             *
             * Example:
             *
a

|b

             *
             * Will produce this on backspace:
             *
a<span style="<all runtime styles>">b

             *
             * This fixes the backspace to produce:
             *
a|b

             *
             * See bug: https://bugs.webkit.org/show_bug.cgi?id=45784
             *
             * This fixes the following delete scenarios:
             *  1. Delete by pressing backspace key.
             *  2. Delete by pressing delete key.
             *  3. Delete by pressing backspace key with ctrl/cmd (Word delete).
             *  4. Delete by pressing delete key with ctrl/cmd (Word delete).
             *  5. Delete by drag/dropping contents inside the editor.
             *  6. Delete by using Cut Ctrl+X/Cmd+X.
             *  7. Delete by selecting contents and writing a character.
             *
             * This code is a ugly hack since writing full custom delete logic for just this bug
             * fix seemed like a huge task. I hope we can remove this before the year 2030.
             */


function isDefaultPrevented(e) {
			return e.isDefaultPrevented();
		}

/**
		 * Returns true/false if the event is prevented or not.
		 *
		 * @private
		 * @param {Event} e Event object.
		 * @return {Boolean} true/false if the event is prevented or not.
		 */


function setWrapToString(wrapper, reference, bitmask) {
      var source = (reference + '');
      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
    }

/**
     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
     * with wrapper details in a comment at the top of the source body.
     *
     * @private
     * @param {Function} wrapper The function to modify.
     * @param {Function} reference The reference function.
     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
     * @returns {Function} Returns `wrapper`.
     */


function forEachRight(collection, iteratee) {
      var func = isArray(collection) ? arrayEachRight : baseEachRight;
      return func(collection, getIteratee(iteratee, 3));
    }

/**
     * This method is like `_.forEach` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @since 2.0.0
     * @alias eachRight
     * @category Collection
     * @param {Array|Object} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @returns {Array|Object} Returns `collection`.
     * @see _.forEach
     * @example
     *
     * _.forEachRight([1, 2], function(value) {
     *   console.log(value);
     * });
     * // => Logs `2` then `1`.
     */


off() {
        activeEffectScope = this.parent;
    }

/**
     * This should only be called on non-detached scopes
     * @internal
     */


function checkKeyCodes(eventKeyCode, key, builtInKeyCode, eventKeyName, builtInKeyName) {
    const mappedKeyCode = config.keyCodes[key] || builtInKeyCode;
    if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
        return isKeyNotMatch(builtInKeyName, eventKeyName);
    }
    else if (mappedKeyCode) {
        return isKeyNotMatch(mappedKeyCode, eventKeyCode);
    }
    else if (eventKeyName) {
        return hyphenate(eventKeyName) !== key;
    }
    return eventKeyCode === undefined;
}

/**
 * Runtime helper for checking keyCodes from config.
 * exposed as Vue.prototype._k
 * passing in eventKeyName as last argument separately for backwards compat
 */


function queueActivatedComponent(vm) {
    // setting _inactive to false here so that a render function can
    // rely on checking whether it's in an inactive tree (e.g. router-view)
    vm._inactive = false;
    activatedChildren.push(vm);
}

/**
 * Queue a kept-alive component that was activated during patch.
 * The queue will be processed after the entire tree has been patched.
 */


function nextTick(cb, ctx) {
    let _resolve;
    callbacks.push(() => {
        if (cb) {
            try {
                cb.call(ctx);
            }
            catch (e) {
                handleError(e, ctx, 'nextTick');
            }
        }
        else if (_resolve) {
            _resolve(ctx);
        }
    });
    if (!pending) {
        pending = true;
        timerFunc();
    }
    // $flow-disable-line
    if (!cb && typeof Promise !== 'undefined') {
        return new Promise(resolve => {
            _resolve = resolve;
        });
    }
}


function hydrate(elm, vnode, insertedVnodeQueue, inVPre) {
        let i;
        const { tag, data, children } = vnode;
        inVPre = inVPre || (data && data.pre);
        vnode.elm = elm;
        if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
            vnode.isAsyncPlaceholder = true;
            return true;
        }
        // assert node match
        {
            if (!assertNodeMatch(elm, vnode, inVPre)) {
                return false;
            }
        }
        if (isDef(data)) {
            if (isDef((i = data.hook)) && isDef((i = i.init)))
                i(vnode, true /* hydrating */);
            if (isDef((i = vnode.componentInstance))) {
                // child component. it should have hydrated its own tree.
                initComponent(vnode, insertedVnodeQueue);
                return true;
            }
        }
        if (isDef(tag)) {
            if (isDef(children)) {
                // empty element, allow client to pick up and populate children
                if (!elm.hasChildNodes()) {
                    createChildren(vnode, children, insertedVnodeQueue);
                }
                else {
                    // v-html and domProps: innerHTML
                    if (isDef((i = data)) &&
                        isDef((i = i.domProps)) &&
                        isDef((i = i.innerHTML))) {
                        if (i !== elm.innerHTML) {
                            /* istanbul ignore if */
                            if (typeof console !== 'undefined' &&
                                !hydrationBailed) {
                                hydrationBailed = true;
                                console.warn('Parent: ', elm);
                                console.warn('server innerHTML: ', i);
                                console.warn('client innerHTML: ', elm.innerHTML);
                            }
                            return false;
                        }
                    }
                    else {
                        // iterate and compare children lists
                        let childrenMatch = true;
                        let childNode = elm.firstChild;
                        for (let i = 0; i < children.length; i++) {
                            if (!childNode ||
                                !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {
                                childrenMatch = false;
                                break;
                            }
                            childNode = childNode.nextSibling;
                        }
                        // if childNode is not null, it means the actual childNodes list is
                        // longer than the virtual children list.
                        if (!childrenMatch || childNode) {
                            /* istanbul ignore if */
                            if (typeof console !== 'undefined' &&
                                !hydrationBailed) {
                                hydrationBailed = true;
                                console.warn('Parent: ', elm);
                                console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
                            }
                            return false;
                        }
                    }
                }
            }
            if (isDef(data)) {
                let fullInvoke = false;
                for (const key in data) {
                    if (!isRenderedModule(key)) {
                        fullInvoke = true;
                        invokeCreateHooks(vnode, insertedVnodeQueue);
                        break;
                    }
                }
                if (!fullInvoke && data['class']) {
                    // ensure collecting deps for deep class bindings for future updates
                    traverse(data['class']);
                }
            }
        }
        else if (elm.data !== vnode.text) {
            elm.data = vnode.text;
        }
        return true;
    }

// Note: this is a browser-only function so we can assume elms are DOM nodes.


constructor(handedness, scene) {
        this.handedness = handedness;
        this.pinch = false;

        this.lastPosition = new THREE.Vector3();
        this.active = false;

        this.jointPhysicsBodies = {};
        this.pointer = new THREE.Object3D();

        this.identityPosition = new THREE.Vector3();

        this.tempJointPosition = new THREE.Vector3();
        this.tempJointOrientation = new THREE.Quaternion();

        this.controllerModelFactory = new XRControllerModelFactory();
        this.handModelFactory = new XRHandModelFactory();

        this.mesh;
        this.controller = mrjsUtils.xr.getController(HAND_MAPPING[handedness]);
        this.controller.add(this.pointer);
        this.pointer.position.setZ(-0.5);

        this.grip = mrjsUtils.xr.getControllerGrip(HAND_MAPPING[handedness]);
        this.grip.add(this.controllerModelFactory.createControllerModel(this.grip));

        this.hand = mrjsUtils.xr.getHand(HAND_MAPPING[handedness]);
        this.model = this.handModelFactory.createHandModel(this.hand, 'mesh');

        this.hand.add(this.model);

        this.hand.addEventListener('selectstart', this.onSelect);
        this.hand.addEventListener('selectend', this.onSelect);

        scene.add(this.controller);
        scene.add(this.grip);
        scene.add(this.hand);
        this.initPhysicsBodies();
    }

/**
     * @class
     * @description Constructor for the MRHand class object. Setups up all attributes for MRHand including physics, mouse/cursor information, hand tracking and state, and model
     * @param {object} handedness - enum for the `left`` or `right` hand.
     * @param {object} scene - the threejs scene object with information from the MRApp.
     */


func logStacks() {
	time.Sleep(time.Second) // Hack to wait for goroutines to end
	buf := make([]byte, 1<<20)
	n := runtime.Stack(buf, true)
	fmt.Fprintln(os.Stderr, string(buf[:n]))
}

// logStacks prints the stacks of live goroutines. This functionality
// is disabled by default but can be enabled to find background work that
// is not obeying cancellation.


func NewColorableStderr() io.Writer {
	return os.Stderr
}

// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.


func Pause() (err error) {
	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}

// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT


func pwrite(fd int, p []byte, offset int64) (n int, err error) {
	var _p0 *byte
	if len(p) > 0 {
		_p0 = &p[0]
	}
	var _p1 int
	_p1 = len(p)
	r0, er := C.pwrite64(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.longlong(offset))
	n = int(r0)
	if r0 == -1 && er != nil {
		err = er
	}
	return
}


func callfstatat(dirfd int, _p0 uintptr, stat uintptr, flags int) (r1 uintptr, e1 Errno) {
	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fstatat)), 4, uintptr(dirfd), _p0, stat, uintptr(flags), 0, 0)
	return
}


func calltruncate(_p0 uintptr, length int64) (r1 uintptr, e1 Errno) {
	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_truncate)), 2, _p0, uintptr(length), 0, 0, 0, 0)
	return
}


func callsetsid() (r1 uintptr, e1 Errno) {
	r1 = uintptr(C.setsid())
	e1 = syscall.GetErrno()
	return
}


func Ftruncate(fd int, length int64) (err error) {
	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}


func Flock(fd int, how int) (err error) {
	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}

//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT


func Mlock(b []byte) (err error) {
	var _p0 unsafe.Pointer
	if len(b) > 0 {
		_p0 = unsafe.Pointer(&b[0])
	} else {
		_p0 = unsafe.Pointer(&_zero)
	}
	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}


func (d *dbBaseOracle) ShowTablesQuery() string {
	return "SELECT TABLE_NAME FROM USER_TABLES"
}

// ShowTablesQuery show All the tables in database


func (t *idnaTrie) lookupUnsafe(s []byte) uint16 {
	c0 := s[0]
	if c0 < 0x80 { // is ASCII
		return idnaValues[c0]
	}
	i := idnaIndex[c0]
	if c0 < 0xE0 { // 2-byte UTF-8
		return t.lookupValue(uint32(i), s[1])
	}
	i = idnaIndex[uint32(i)<<6+uint32(s[1])]
	if c0 < 0xF0 { // 3-byte UTF-8
		return t.lookupValue(uint32(i), s[2])
	}
	i = idnaIndex[uint32(i)<<6+uint32(s[2])]
	if c0 < 0xF8 { // 4-byte UTF-8
		return t.lookupValue(uint32(i), s[3])
	}
	return 0
}

// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
// s must start with a full and valid UTF-8 encoded rune.


func callnrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) {
	r1 = uintptr(C.nrecvmsg(C.int(s), C.uintptr_t(msg), C.int(flags)))
	e1 = syscall.GetErrno()
	return
}


func Getegid() (egid int) {
	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
	egid = int(r0)
	return
}


func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
	var _p0 *byte
	_p0, err = BytePtrFromString(path)
	if err != nil {
		return
	}
	_, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}


func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
	var _p0 unsafe.Pointer
	if len(buf) > 0 {
		_p0 = unsafe.Pointer(&buf[0])
	} else {
		_p0 = unsafe.Pointer(&_zero)
	}
	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}


func SetLogger(l Logger) {
	internal.LoggerV2Impl = &internal.LoggerWrapper{Logger: l}
}

// SetLogger sets the logger that is used in grpc. Call only from
// init() functions.
//
// Deprecated: use SetLoggerV2.


func sizeStringPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
	v := **p.StringPtr()
	return f.tagsize + protowire.SizeBytes(len(v))
}

// sizeStringPtr returns the size of wire encoding a *string pointer as a String.
// It panics if the pointer is nil.


func newPluginManager(conf *katalystconfig.Configuration) (pluginmanager.PluginManager, error) {
	// make sure plugin registration directory already exist
	err := os.MkdirAll(conf.PluginRegistrationDir, os.FileMode(0o755))
	if err != nil {
		return nil, fmt.Errorf("initializes plugin registration dir failed: %s", err)
	}

	return &customizedPluginManager{
		enabled: *atomic.NewBool(false),
		PluginManager: pluginmanager.NewPluginManager(
			conf.PluginRegistrationDir, /* sockDir */
			&record.FakeRecorder{},
		),
	}, nil
}

// newPluginManager initializes the registration logic for extendable plugins.
// all plugin manager added to generic context must use the same socket and
// default checkpoint path, and if some plugin needs to use a different socket path,
// it should create the plugin manager itself.


func (p *StaticPolicy) ResourceName() string {
	return string(apiconsts.ResourceNetBandwidth)
}

// ResourceName returns resource names managed by this plugin


func (cl *CNRLifecycle) processNextWorkItem() bool {
	key, quit := cl.syncQueue.Get()
	if quit {
		return false
	}
	defer cl.syncQueue.Done(key)

	err := cl.sync(key.(string))
	if err == nil {
		cl.syncQueue.Forget(key)
		return true
	}

	utilruntime.HandleError(fmt.Errorf("sync %q failed with %v", key, err))
	cl.syncQueue.AddRateLimited(key)

	return true
}

// processNextWorkItem dequeues items, processes them, and marks them done.
// It enforces that the sync is never invoked concurrently with the same key.


func filterExpiredPodMetrics(metrics []apimetrics.PodMetrics) []apimetrics.PodMetrics {
	now := time.Now()
	return lo.Filter(metrics, func(item apimetrics.PodMetrics, _ int) bool {
		return now.Before(item.Timestamp.Time)
	})
}

// filterExpiredPodMetrics is used to filter out metrics before the current time from the metric slice.


func (i *Input) WithKeyMap(k *KeyMap) Field {
	i.keymap = k.Input
	i.textinput.KeyMap.AcceptSuggestion = i.keymap.AcceptSuggestion
	return i
}

// WithKeyMap sets the keymap on an input field.


func literal(s string) string {
	return regexp.QuoteMeta(s)
}

// literal compiles s into a literal regular expression, escaping any regexp
// reserved characters.


func (w *Watcher) AddWith(name string, opts ...addOpt) error {
	_ = getOptions(opts...)

	w.mu.Lock()
	w.userWatches[name] = struct{}{}
	w.mu.Unlock()
	_, err := w.addWatch(name, noteAllEvents)
	return err
}

// AddWith is like [Watcher.Add], but allows adding options. When using Add()
// the defaults described below are used.
//
// Possible options are:
//
//   - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
//     other platforms. The default is 64K (65536 bytes).


func (zero *evalZeroArity) OverloadID() string {
	return zero.overload
}

// OverloadID implements the InterpretableCall interface method.


func (m *MilestoneStats) GetTotalMilestones() int {
	if m == nil || m.TotalMilestones == nil {
		return 0
	}
	return *m.TotalMilestones
}

// GetTotalMilestones returns the TotalMilestones field if it's non-nil, zero value otherwise.


// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation
// of Decompress1X when tablelog > 8.
//
//go:noescape


func (o *Output) Hyperlink(link, name string) string {
	return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST
}

// Hyperlink creates a hyperlink using OSC8.


func BeTrueBecause(format string, args ...any) types.GomegaMatcher {
	return &matchers.BeTrueMatcher{Reason: fmt.Sprintf(format, args...)}
}

// BeTrueBecause succeeds if actual is true and displays the provided reason if it is false
// fmt.Sprintf is used to render the reason


func UseConcurrentReads(value bool) ClientOption {
	return func(c *Client) error {
		c.disableConcurrentReads = !value
		return nil
	}
}

// UseConcurrentReads allows the Client to perform concurrent Reads.
//
// Concurrent reads are generally safe to use and not using them will degrade
// performance, so this option is enabled by default.
//
// When enabled, WriteTo will use Stat/Fstat to get the file size and determines
// how many concurrent workers to use.
// Some "read once" servers will delete the file if they receive a stat call on an
// open file and then the download will fail.
// Disabling concurrent reads you will be able to download files from these servers.
// If concurrent reads are disabled, the UseFstat option is ignored.


func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc {
	result := &valueFunc{
		desc:       desc,
		valType:    valueType,
		function:   function,
		labelPairs: MakeLabelPairs(desc, nil),
	}
	result.init(result)
	return result
}

// newValueFunc returns a newly allocated valueFunc with the given Desc and
// ValueType. The value reported is determined by calling the given function
// from within the Write method. Take into account that metric collection may
// happen concurrently. If that results in concurrent calls to Write, like in
// the case where a valueFunc is directly registered with Prometheus, the
// provided function must be concurrency-safe.


func (linux *systemDRecord) servicePath() string {
	return "/etc/systemd/system/" + linux.name + ".service"
}

// Standard service path for systemD daemons


func WithInt64Callback(callback Int64Callback) Int64ObservableOption {
	return int64CallbackOpt{callback}
}

// WithInt64Callback adds callback to be called for an instrument.


func FaaSName(val string) attribute.KeyValue {
	return FaaSNameKey.String(val)
}

// FaaSName returns an attribute KeyValue conforming to the "faas.name"
// semantic conventions. It represents the name of the single function that
// this runtime instance executes.


func EnduserRole(val string) attribute.KeyValue {
	return EnduserRoleKey.String(val)
}

// EnduserRole returns an attribute KeyValue conforming to the
// "enduser.role" semantic conventions. It represents the actual/assumed role
// the client is making the request under extracted from token or application
// security context.


func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
	var tmp [16]byte
	Sum(&tmp, m, key)
	return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
}

// Verify returns true if mac is a valid authenticator for m with the given key.


func Setdomainname(p []byte) (err error) {
	var _p0 *byte
	if len(p) > 0 {
		_p0 = &p[0]
	}
	_, e1 := callsetdomainname(uintptr(unsafe.Pointer(_p0)), len(p))
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}

// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT


func Dup2(from int, to int) (err error) {
	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
	if e1 != 0 {
		err = errnoErr(e1)
	}
	return
}

//go:cgo_import_dynamic libc_dup dup "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT


func Creat(path string, mode uint32) (fd int, err error) {
	var _p0 *byte
	_p0, err = BytePtrFromString(path)
	if err != nil {
		return
	}
	runtime.EnterSyscall()
	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CREAT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
	runtime.ExitSyscall()
	fd = int(r0)
	if int64(r0) == -1 {
		err = errnoErr2(e1, e2)
	}
	return
}