[JS/TS] Modernize TypeScript / JavaScript flatbuffers support (#6095)
authorBjörn Harrtell <bjornharrtell@users.noreply.github.com>
Thu, 17 Sep 2020 19:21:14 +0000 (21:21 +0200)
committerGitHub <noreply@github.com>
Thu, 17 Sep 2020 19:21:14 +0000 (12:21 -0700)
21 files changed:
.eslintrc.js [new file with mode: 0644]
.gitignore
appveyor.yml
js/README.md [new file with mode: 0644]
js/flatbuffers.js [deleted file]
mjs/README.md [new file with mode: 0644]
package.json
tests/TypeScriptTest.sh
tests/docker/languages/Dockerfile.testing.node.10_13_0
tests/docker/languages/Dockerfile.testing.node.11_2_0
ts/builder.ts [new file with mode: 0644]
ts/byte-buffer.ts [new file with mode: 0644]
ts/constants.ts [new file with mode: 0644]
ts/encoding.ts [new file with mode: 0644]
ts/flatbuffers.ts [new file with mode: 0644]
ts/long.ts [new file with mode: 0644]
ts/types.ts [new file with mode: 0644]
ts/utils.ts [new file with mode: 0644]
tsconfig.json [new file with mode: 0644]
tsconfig.mjs.json [new file with mode: 0644]
yarn.lock [new file with mode: 0644]

diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644 (file)
index 0000000..321169b
--- /dev/null
@@ -0,0 +1,13 @@
+/* eslint-env node */
+
+module.exports = {
+    root: true,
+    parser: '@typescript-eslint/parser',
+    plugins: [
+        '@typescript-eslint',
+    ],
+    extends: [
+        'eslint:recommended',
+        'plugin:@typescript-eslint/recommended',
+    ]
+};
\ No newline at end of file
index ab99dfa58e427cb90e21c88b70d1a1acb7542ad4..03fd44c7188d4c3f8a95a578065224dc77244415 100644 (file)
@@ -130,3 +130,8 @@ package-lock.json
 /*.ilk
 /*.pdb
 .clwb
+js/*.js
+js/*.d.ts
+mjs/*.js
+mjs/*.d.ts
+yarn-error.log
\ No newline at end of file
index 6655f3cdde0e3f40cca841e0a063d7ec6b2edcb2..9806fe4bd6a39c0af961ef67f2f08d0a0ab440d2 100644 (file)
@@ -86,6 +86,8 @@ test_script:
   - rem "---------------- JS -----------------"
   - "node --version"
   - "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
+  - "npm install"
+  - "npm run pretest"
   - "node JavaScriptTest ./monster_test_generated"
   - rem "-------------- Python ---------------"
   - where python
diff --git a/js/README.md b/js/README.md
new file mode 100644 (file)
index 0000000..cbcebe0
--- /dev/null
@@ -0,0 +1 @@
+This folder is intentionally empty and will contain transpiled js modules in Common JS format after compiling with tsc.
\ No newline at end of file
diff --git a/js/flatbuffers.js b/js/flatbuffers.js
deleted file mode 100644 (file)
index b1687b7..0000000
+++ /dev/null
@@ -1,1398 +0,0 @@
-/// @file
-/// @addtogroup flatbuffers_javascript_api
-/// @{
-/// @cond FLATBUFFERS_INTERNAL
-
-/**
- * @fileoverview
- *
- * Need to suppress 'global this' error so the Node.js export line doesn't cause
- * closure compile to error out.
- * @suppress {globalThis}
- */
-
-/**
- * @const
- * @namespace
- */
-var flatbuffers = {};
-
-/**
- * @typedef {number}
- */
-flatbuffers.Offset;
-
-/**
- * @typedef {{
- *   bb: flatbuffers.ByteBuffer,
- *   bb_pos: number
- * }}
- */
-flatbuffers.Table;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZEOF_SHORT = 2;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZEOF_INT = 4;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZE_PREFIX_LENGTH = 4;
-
-/**
- * @param {number} low
- * @param {number} high
- * @returns {flatbuffers.Long}
- */
-flatbuffers.createLong = function(low, high) {
-  return flatbuffers.Long.create(low, high);
-};
-
-/**
- * @enum {number}
- */
-flatbuffers.Encoding = {
-  UTF8_BYTES: 1,
-  UTF16_STRING: 2
-};
-
-/**
- * @type {Int32Array}
- * @const
- */
-flatbuffers.int32 = new Int32Array(2);
-
-/**
- * @type {Float32Array}
- * @const
- */
-flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
-
-/**
- * @type {Float64Array}
- * @const
- */
-flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
-
-/**
- * @type {boolean}
- * @const
- */
-flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @constructor
- * @param {number} low
- * @param {number} high
- */
-flatbuffers.Long = function(low, high) {
-  /**
-   * @type {number}
-   * @const
-   */
-  this.low = low | 0;
-
-  /**
-   * @type {number}
-   * @const
-   */
-  this.high = high | 0;
-};
-
-/**
- * @param {number} low
- * @param {number} high
- * @returns {!flatbuffers.Long}
- */
-flatbuffers.Long.create = function(low, high) {
-  // Special-case zero to avoid GC overhead for default values
-  return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
-};
-
-/**
- * @returns {number}
- */
-flatbuffers.Long.prototype.toFloat64 = function() {
-  return (this.low >>> 0) + this.high * 0x100000000;
-};
-
-/**
- * @param {flatbuffers.Long} other
- * @returns {boolean}
- */
-flatbuffers.Long.prototype.equals = function(other) {
-  return this.low == other.low && this.high == other.high;
-};
-
-/**
- * @type {!flatbuffers.Long}
- * @const
- */
-flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
-
-/// @endcond
-////////////////////////////////////////////////////////////////////////////////
-/**
- * Create a FlatBufferBuilder.
- *
- * @constructor
- * @param {number=} opt_initial_size
- */
-flatbuffers.Builder = function(opt_initial_size) {
-  if (!opt_initial_size) {
-    var initial_size = 1024;
-  } else {
-    var initial_size = opt_initial_size;
-  }
-
-  /**
-   * @type {flatbuffers.ByteBuffer}
-   * @private
-   */
-  this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
-
-  /**
-   * Remaining space in the ByteBuffer.
-   *
-   * @type {number}
-   * @private
-   */
-  this.space = initial_size;
-
-  /**
-   * Minimum alignment encountered so far.
-   *
-   * @type {number}
-   * @private
-   */
-  this.minalign = 1;
-
-  /**
-   * The vtable for the current table.
-   *
-   * @type {Array.<number>}
-   * @private
-   */
-  this.vtable = null;
-
-  /**
-   * The amount of fields we're actually using.
-   *
-   * @type {number}
-   * @private
-   */
-  this.vtable_in_use = 0;
-
-  /**
-   * Whether we are currently serializing a table.
-   *
-   * @type {boolean}
-   * @private
-   */
-  this.isNested = false;
-
-  /**
-   * Starting offset of the current struct/table.
-   *
-   * @type {number}
-   * @private
-   */
-  this.object_start = 0;
-
-  /**
-   * List of offsets of all vtables.
-   *
-   * @type {Array.<number>}
-   * @private
-   */
-  this.vtables = [];
-
-  /**
-   * For the current vector being built.
-   *
-   * @type {number}
-   * @private
-   */
-  this.vector_num_elems = 0;
-
-  /**
-   * False omits default values from the serialized data
-   *
-   * @type {boolean}
-   * @private
-   */
-  this.force_defaults = false;
-};
-
-flatbuffers.Builder.prototype.clear = function() {
-  this.bb.clear();
-  this.space = this.bb.capacity();
-  this.minalign = 1;
-  this.vtable = null;
-  this.vtable_in_use = 0;
-  this.isNested = false;
-  this.object_start = 0;
-  this.vtables = [];
-  this.vector_num_elems = 0;
-  this.force_defaults = false;
-  this.string_maps = null;
-};
-
-/**
- * In order to save space, fields that are set to their default value
- * don't get serialized into the buffer. Forcing defaults provides a
- * way to manually disable this optimization.
- *
- * @param {boolean} forceDefaults true always serializes default values
- */
-flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
-  this.force_defaults = forceDefaults;
-};
-
-/**
- * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
- * called finish(). The actual data starts at the ByteBuffer's current position,
- * not necessarily at 0.
- *
- * @returns {flatbuffers.ByteBuffer}
- */
-flatbuffers.Builder.prototype.dataBuffer = function() {
-  return this.bb;
-};
-
-/**
- * Get the bytes representing the FlatBuffer. Only call this after you've
- * called finish().
- *
- * @returns {!Uint8Array}
- */
-flatbuffers.Builder.prototype.asUint8Array = function() {
-  return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Prepare to write an element of `size` after `additional_bytes` have been
- * written, e.g. if you write a string, you need to align such the int length
- * field is aligned to 4 bytes, and the string data follows it directly. If all
- * you need to do is alignment, `additional_bytes` will be 0.
- *
- * @param {number} size This is the of the new element to write
- * @param {number} additional_bytes The padding size
- */
-flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
-  // Track the biggest thing we've ever aligned to.
-  if (size > this.minalign) {
-    this.minalign = size;
-  }
-
-  // Find the amount of alignment needed such that `size` is properly
-  // aligned after `additional_bytes`
-  var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
-
-  // Reallocate the buffer if needed.
-  while (this.space < align_size + size + additional_bytes) {
-    var old_buf_size = this.bb.capacity();
-    this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
-    this.space += this.bb.capacity() - old_buf_size;
-  }
-
-  this.pad(align_size);
-};
-
-/**
- * @param {number} byte_size
- */
-flatbuffers.Builder.prototype.pad = function(byte_size) {
-  for (var i = 0; i < byte_size; i++) {
-    this.bb.writeInt8(--this.space, 0);
-  }
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt8 = function(value) {
-  this.bb.writeInt8(this.space -= 1, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt16 = function(value) {
-  this.bb.writeInt16(this.space -= 2, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt32 = function(value) {
-  this.bb.writeInt32(this.space -= 4, value);
-};
-
-/**
- * @param {flatbuffers.Long} value
- */
-flatbuffers.Builder.prototype.writeInt64 = function(value) {
-  this.bb.writeInt64(this.space -= 8, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeFloat32 = function(value) {
-  this.bb.writeFloat32(this.space -= 4, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeFloat64 = function(value) {
-  this.bb.writeFloat64(this.space -= 8, value);
-};
-/// @endcond
-
-/**
- * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int8` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt8 = function(value) {
-  this.prep(1, 0);
-  this.writeInt8(value);
-};
-
-/**
- * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int16` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt16 = function(value) {
-  this.prep(2, 0);
-  this.writeInt16(value);
-};
-
-/**
- * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int32` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt32 = function(value) {
-  this.prep(4, 0);
-  this.writeInt32(value);
-};
-
-/**
- * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {flatbuffers.Long} value The `int64` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt64 = function(value) {
-  this.prep(8, 0);
-  this.writeInt64(value);
-};
-
-/**
- * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `float32` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addFloat32 = function(value) {
-  this.prep(4, 0);
-  this.writeFloat32(value);
-};
-
-/**
- * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `float64` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addFloat64 = function(value) {
-  this.prep(8, 0);
-  this.writeFloat64(value);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt8(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt16(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt32(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {flatbuffers.Long} value
- * @param {flatbuffers.Long} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || !value.equals(defaultValue)) {
-    this.addInt64(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addFloat32(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addFloat64(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {flatbuffers.Offset} value
- * @param {flatbuffers.Offset} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addOffset(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * Structs are stored inline, so nothing additional is being added. `d` is always 0.
- *
- * @param {number} voffset
- * @param {flatbuffers.Offset} value
- * @param {flatbuffers.Offset} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
-  if (value != defaultValue) {
-    this.nested(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * Structures are always stored inline, they need to be created right
- * where they're used.  You'll get this assertion failure if you
- * created it elsewhere.
- *
- * @param {flatbuffers.Offset} obj The offset of the created object
- */
-flatbuffers.Builder.prototype.nested = function(obj) {
-  if (obj != this.offset()) {
-    throw new Error('FlatBuffers: struct must be serialized inline.');
-  }
-};
-
-/**
- * Should not be creating any other object, string or vector
- * while an object is being constructed
- */
-flatbuffers.Builder.prototype.notNested = function() {
-  if (this.isNested) {
-    throw new Error('FlatBuffers: object serialization must not be nested.');
-  }
-};
-
-/**
- * Set the current vtable at `voffset` to the current location in the buffer.
- *
- * @param {number} voffset
- */
-flatbuffers.Builder.prototype.slot = function(voffset) {
-  this.vtable[voffset] = this.offset();
-};
-
-/**
- * @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
- */
-flatbuffers.Builder.prototype.offset = function() {
-  return this.bb.capacity() - this.space;
-};
-
-/**
- * Doubles the size of the backing ByteBuffer and copies the old data towards
- * the end of the new buffer (since we build the buffer backwards).
- *
- * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
- * @returns {!flatbuffers.ByteBuffer} A new byte buffer with the old data copied
- * to it. The data is located at the end of the buffer.
- *
- * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
- * it a uint8Array we need to suppress the type check:
- * @suppress {checkTypes}
- */
-flatbuffers.Builder.growByteBuffer = function(bb) {
-  var old_buf_size = bb.capacity();
-
-  // Ensure we don't grow beyond what fits in an int.
-  if (old_buf_size & 0xC0000000) {
-    throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
-  }
-
-  var new_buf_size = old_buf_size << 1;
-  var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
-  nbb.setPosition(new_buf_size - old_buf_size);
-  nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
-  return nbb;
-};
-/// @endcond
-
-/**
- * Adds on offset, relative to where it will be written.
- *
- * @param {flatbuffers.Offset} offset The offset to add.
- */
-flatbuffers.Builder.prototype.addOffset = function(offset) {
-  this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
-  this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Start encoding a new object in the buffer.  Users will not usually need to
- * call this directly. The FlatBuffers compiler will generate helper methods
- * that call this method internally.
- *
- * @param {number} numfields
- */
-flatbuffers.Builder.prototype.startObject = function(numfields) {
-  this.notNested();
-  if (this.vtable == null) {
-    this.vtable = [];
-  }
-  this.vtable_in_use = numfields;
-  for (var i = 0; i < numfields; i++) {
-    this.vtable[i] = 0; // This will push additional elements as needed
-  }
-  this.isNested = true;
-  this.object_start = this.offset();
-};
-
-/**
- * Finish off writing the object that is under construction.
- *
- * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
- */
-flatbuffers.Builder.prototype.endObject = function() {
-  if (this.vtable == null || !this.isNested) {
-    throw new Error('FlatBuffers: endObject called without startObject');
-  }
-
-  this.addInt32(0);
-  var vtableloc = this.offset();
-
-  // Trim trailing zeroes.
-  var i = this.vtable_in_use - 1;
-  for (; i >= 0 && this.vtable[i] == 0; i--) {}
-  var trimmed_size = i + 1;
-
-  // Write out the current vtable.
-  for (; i >= 0; i--) {
-    // Offset relative to the start of the table.
-    this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
-  }
-
-  var standard_fields = 2; // The fields below:
-  this.addInt16(vtableloc - this.object_start);
-  var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
-  this.addInt16(len);
-
-  // Search for an existing vtable that matches the current one.
-  var existing_vtable = 0;
-  var vt1 = this.space;
-outer_loop:
-  for (i = 0; i < this.vtables.length; i++) {
-    var vt2 = this.bb.capacity() - this.vtables[i];
-    if (len == this.bb.readInt16(vt2)) {
-      for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
-        if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
-          continue outer_loop;
-        }
-      }
-      existing_vtable = this.vtables[i];
-      break;
-    }
-  }
-
-  if (existing_vtable) {
-    // Found a match:
-    // Remove the current vtable.
-    this.space = this.bb.capacity() - vtableloc;
-
-    // Point table to existing vtable.
-    this.bb.writeInt32(this.space, existing_vtable - vtableloc);
-  } else {
-    // No match:
-    // Add the location of the current vtable to the list of vtables.
-    this.vtables.push(this.offset());
-
-    // Point table to current vtable.
-    this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
-  }
-
-  this.isNested = false;
-  return vtableloc;
-};
-/// @endcond
-
-/**
- * Finalize a buffer, poiting to the given `root_table`.
- *
- * @param {flatbuffers.Offset} root_table
- * @param {string=} opt_file_identifier
- * @param {boolean=} opt_size_prefix
- */
-flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
-  var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
-  if (opt_file_identifier) {
-    var file_identifier = opt_file_identifier;
-    this.prep(this.minalign, flatbuffers.SIZEOF_INT +
-      flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
-    if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
-      throw new Error('FlatBuffers: file identifier must be length ' +
-        flatbuffers.FILE_IDENTIFIER_LENGTH);
-    }
-    for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
-      this.writeInt8(file_identifier.charCodeAt(i));
-    }
-  }
-  this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
-  this.addOffset(root_table);
-  if (size_prefix) {
-    this.addInt32(this.bb.capacity() - this.space);
-  }
-  this.bb.setPosition(this.space);
-};
-
-/**
- * Finalize a size prefixed buffer, pointing to the given `root_table`.
- *
- * @param {flatbuffers.Offset} root_table
- * @param {string=} opt_file_identifier
- */
-flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
-  this.finish(root_table, opt_file_identifier, true);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * This checks a required field has been set in a given table that has
- * just been constructed.
- *
- * @param {flatbuffers.Offset} table
- * @param {number} field
- */
-flatbuffers.Builder.prototype.requiredField = function(table, field) {
-  var table_start = this.bb.capacity() - table;
-  var vtable_start = table_start - this.bb.readInt32(table_start);
-  var ok = this.bb.readInt16(vtable_start + field) != 0;
-
-  // If this fails, the caller will show what field needs to be set.
-  if (!ok) {
-    throw new Error('FlatBuffers: field ' + field + ' must be set');
-  }
-};
-
-/**
- * Start a new array/vector of objects.  Users usually will not call
- * this directly. The FlatBuffers compiler will create a start/end
- * method for vector types in generated code.
- *
- * @param {number} elem_size The size of each element in the array
- * @param {number} num_elems The number of elements in the array
- * @param {number} alignment The alignment of the array
- */
-flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
-  this.notNested();
-  this.vector_num_elems = num_elems;
-  this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
-  this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
-};
-
-/**
- * Finish off the creation of an array and all its elements. The array must be
- * created with `startVector`.
- *
- * @returns {flatbuffers.Offset} The offset at which the newly created array
- * starts.
- */
-flatbuffers.Builder.prototype.endVector = function() {
-  this.writeInt32(this.vector_num_elems);
-  return this.offset();
-};
-/// @endcond
-
-/**
- * Encode the string `s` in the buffer using UTF-8. If the string passed has 
- * already been seen, we return the offset of the already written string
- *
- * @param {string|Uint8Array} s The string to encode
- * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
- */
-flatbuffers.Builder.prototype.createSharedString = function(s) {
-  if (!s) { return 0 }
-
-  if (!this.string_maps) {
-    this.string_maps = new Map();
-  }
-
-  if (this.string_maps.has(s)) {
-    return this.string_maps.get(s)
-  }
-  let offset = this.createString(s)
-  this.string_maps.set(s, offset)
-  return offset
-}
-
-/**
- * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
- * instead of a string, it is assumed to contain valid UTF-8 encoded data.
- *
- * @param {string|Uint8Array} s The string to encode
- * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
- */
-flatbuffers.Builder.prototype.createString = function(s) {
-  if (!s) { return 0 }
-  if (s instanceof Uint8Array) {
-    var utf8 = s;
-  } else {
-    var utf8 = [];
-    var i = 0;
-
-    while (i < s.length) {
-      var codePoint;
-
-      // Decode UTF-16
-      var a = s.charCodeAt(i++);
-      if (a < 0xD800 || a >= 0xDC00) {
-        codePoint = a;
-      } else {
-        var b = s.charCodeAt(i++);
-        codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
-      }
-
-      // Encode UTF-8
-      if (codePoint < 0x80) {
-        utf8.push(codePoint);
-      } else {
-        if (codePoint < 0x800) {
-          utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
-        } else {
-          if (codePoint < 0x10000) {
-            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
-          } else {
-            utf8.push(
-              ((codePoint >> 18) & 0x07) | 0xF0,
-              ((codePoint >> 12) & 0x3F) | 0x80);
-          }
-          utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
-        }
-        utf8.push((codePoint & 0x3F) | 0x80);
-      }
-    }
-  }
-
-  this.addInt8(0);
-  this.startVector(1, utf8.length, 1);
-  this.bb.setPosition(this.space -= utf8.length);
-  for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
-    bytes[offset++] = utf8[i];
-  }
-  return this.endVector();
-};
-
-/**
- * A helper function to avoid generated code depending on this file directly.
- *
- * @param {number} low
- * @param {number} high
- * @returns {!flatbuffers.Long}
- */
-flatbuffers.Builder.prototype.createLong = function(low, high) {
-  return flatbuffers.Long.create(low, high);
-};
-
-/**
- * A helper function to pack an object
- * 
- * @returns offset of obj
- */
-flatbuffers.Builder.prototype.createObjectOffset = function(obj) {
-  if(obj === null) {
-    return 0
-  }
-
-  if(typeof obj === 'string') {
-    return this.createString(obj);
-  } else {
-    return obj.pack(this);
-  }
-}
-
-/**
- * A helper function to pack a list of object
- * 
- * @returns list of offsets of each non null object
- */
-flatbuffers.Builder.prototype.createObjectOffsetList = function(list) {
-  let ret = [];
-
-  for(let i = 0; i < list.length; ++i) {
-    let val = list[i];
-
-    if(val !== null) {
-      ret.push(this.createObjectOffset(val));
-    } else {
-      throw new Error(
-        'FlatBuffers: Argument for createObjectOffsetList cannot contain null.'); 
-    }
-  }
-  
-  return ret;
-};
-
-flatbuffers.Builder.prototype.createStructOffsetList = function(list, startFunc) {
-  startFunc(this, list.length);
-  this.createObjectOffsetList(list);
-  return this.endVector();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
- *
- * @constructor
- * @param {Uint8Array} bytes
- */
-flatbuffers.ByteBuffer = function(bytes) {
-  /**
-   * @type {Uint8Array}
-   * @private
-   */
-  this.bytes_ = bytes;
-
-  /**
-   * @type {number}
-   * @private
-   */
-  this.position_ = 0;
-};
-
-/**
- * Create and allocate a new ByteBuffer with a given size.
- *
- * @param {number} byte_size
- * @returns {!flatbuffers.ByteBuffer}
- */
-flatbuffers.ByteBuffer.allocate = function(byte_size) {
-  return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
-};
-
-flatbuffers.ByteBuffer.prototype.clear = function() {
-  this.position_ = 0;
-};
-
-/**
- * Get the underlying `Uint8Array`.
- *
- * @returns {Uint8Array}
- */
-flatbuffers.ByteBuffer.prototype.bytes = function() {
-  return this.bytes_;
-};
-
-/**
- * Get the buffer's position.
- *
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.position = function() {
-  return this.position_;
-};
-
-/**
- * Set the buffer's position.
- *
- * @param {number} position
- */
-flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
-  this.position_ = position;
-};
-
-/**
- * Get the buffer's capacity.
- *
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.capacity = function() {
-  return this.bytes_.length;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
-  return this.readUint8(offset) << 24 >> 24;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
-  return this.bytes_[offset];
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
-  return this.readUint16(offset) << 16 >> 16;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
-  return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
-  return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
-  return this.readInt32(offset) >>> 0;
-};
-
-/**
- * @param {number} offset
- * @returns {!flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
-  return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
-};
-
-/**
- * @param {number} offset
- * @returns {!flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
-  return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
-  flatbuffers.int32[0] = this.readInt32(offset);
-  return flatbuffers.float32[0];
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
-  flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
-  flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
-  return flatbuffers.float64[0];
-};
-
-/**
- * @param {number} offset
- * @param {number|boolean} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
-  this.bytes_[offset] = /** @type {number} */(value);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
-  this.bytes_[offset] = value;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
-  this.bytes_[offset] = value;
-  this.bytes_[offset + 1] = value >> 8;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
-    this.bytes_[offset] = value;
-    this.bytes_[offset + 1] = value >> 8;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
-  this.bytes_[offset] = value;
-  this.bytes_[offset + 1] = value >> 8;
-  this.bytes_[offset + 2] = value >> 16;
-  this.bytes_[offset + 3] = value >> 24;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
-    this.bytes_[offset] = value;
-    this.bytes_[offset + 1] = value >> 8;
-    this.bytes_[offset + 2] = value >> 16;
-    this.bytes_[offset + 3] = value >> 24;
-};
-
-/**
- * @param {number} offset
- * @param {flatbuffers.Long} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
-  this.writeInt32(offset, value.low);
-  this.writeInt32(offset + 4, value.high);
-};
-
-/**
- * @param {number} offset
- * @param {flatbuffers.Long} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
-    this.writeUint32(offset, value.low);
-    this.writeUint32(offset + 4, value.high);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
-  flatbuffers.float32[0] = value;
-  this.writeInt32(offset, flatbuffers.int32[0]);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
-  flatbuffers.float64[0] = value;
-  this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
-  this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
-};
-
-/**
- * Return the file identifier.   Behavior is undefined for FlatBuffers whose
- * schema does not include a file_identifier (likely points at padding or the
- * start of a the root vtable).
- * @returns {string}
- */
-flatbuffers.ByteBuffer.prototype.getBufferIdentifier = function() {
-  if (this.bytes_.length < this.position_ + flatbuffers.SIZEOF_INT +
-      flatbuffers.FILE_IDENTIFIER_LENGTH) {
-    throw new Error(
-        'FlatBuffers: ByteBuffer is too short to contain an identifier.');
-  }
-  var result = "";
-  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
-    result += String.fromCharCode(
-        this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i));
-  }
-  return result;
-};
-
-/**
- * Look up a field in the vtable, return an offset into the object, or 0 if the
- * field is not present.
- *
- * @param {number} bb_pos
- * @param {number} vtable_offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
-  var vtable = bb_pos - this.readInt32(bb_pos);
-  return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
-};
-
-/**
- * Initialize any Table-derived type to point to the union at the given offset.
- *
- * @param {flatbuffers.Table} t
- * @param {number} offset
- * @returns {flatbuffers.Table}
- */
-flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
-  t.bb_pos = offset + this.readInt32(offset);
-  t.bb = this;
-  return t;
-};
-
-/**
- * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
- * This allocates a new string and converts to wide chars upon each access.
- *
- * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
- * the "optionalEncoding" argument. This is useful for avoiding conversion to
- * and from UTF-16 when the data will just be packaged back up in another
- * FlatBuffer later on.
- *
- * @param {number} offset
- * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
- * @returns {string|!Uint8Array}
- */
-flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
-  offset += this.readInt32(offset);
-
-  var length = this.readInt32(offset);
-  var result = '';
-  var i = 0;
-
-  offset += flatbuffers.SIZEOF_INT;
-
-  if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
-    return this.bytes_.subarray(offset, offset + length);
-  }
-
-  while (i < length) {
-    var codePoint;
-
-    // Decode UTF-8
-    var a = this.readUint8(offset + i++);
-    if (a < 0xC0) {
-      codePoint = a;
-    } else {
-      var b = this.readUint8(offset + i++);
-      if (a < 0xE0) {
-        codePoint =
-          ((a & 0x1F) << 6) |
-          (b & 0x3F);
-      } else {
-        var c = this.readUint8(offset + i++);
-        if (a < 0xF0) {
-          codePoint =
-            ((a & 0x0F) << 12) |
-            ((b & 0x3F) << 6) |
-            (c & 0x3F);
-        } else {
-          var d = this.readUint8(offset + i++);
-          codePoint =
-            ((a & 0x07) << 18) |
-            ((b & 0x3F) << 12) |
-            ((c & 0x3F) << 6) |
-            (d & 0x3F);
-        }
-      }
-    }
-
-    // Encode UTF-16
-    if (codePoint < 0x10000) {
-      result += String.fromCharCode(codePoint);
-    } else {
-      codePoint -= 0x10000;
-      result += String.fromCharCode(
-        (codePoint >> 10) + 0xD800,
-        (codePoint & ((1 << 10) - 1)) + 0xDC00);
-    }
-  }
-
-  return result;
-};
-
-/**
- * Handle unions that can contain string as its member, if a Table-derived type then initialize it, 
- * if a string then return a new one
- * 
- * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this 
- * makes the behaviour of __union_with_string different compared to __union
- *
- * @param {flatbuffers.Table|string} o
- * @param {number} offset
- * @returns {flatbuffers.Table|string}
- */
-flatbuffers.ByteBuffer.prototype.__union_with_string = function(o, offset) {
-  if(typeof o === 'string') {
-    return this.__string(offset);
-  } 
-  return this.__union(o, offset);
-};
-
-/**
- * Retrieve the relative offset stored at "offset"
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
-  return offset + this.readInt32(offset);
-};
-
-/**
- * Get the start of data of a vector whose offset is stored at "offset" in this object.
- *
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
-  return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
-};
-
-/**
- * Get the length of a vector whose offset is stored at "offset" in this object.
- *
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
-  return this.readInt32(offset + this.readInt32(offset));
-};
-
-/**
- * @param {string} ident
- * @returns {boolean}
- */
-flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
-  if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
-    throw new Error('FlatBuffers: file identifier must be length ' +
-                    flatbuffers.FILE_IDENTIFIER_LENGTH);
-  }
-  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
-    if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
-      return false;
-    }
-  }
-  return true;
-};
-
-/**
- * A helper function to avoid generated code depending on this file directly.
- *
- * @param {number} low
- * @param {number} high
- * @returns {!flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
-  return flatbuffers.Long.create(low, high);
-};
-
-/**
- * A helper function for generating list for obj api
- * @param listAccessor function that accepts an index and return data at that index
- * @param {number} listLength
- * @returns {any[]}
- */
-flatbuffers.ByteBuffer.prototype.createScalarList = function(listAccessor, listLength) {
-  let ret = [];
-  for(let i = 0; i < listLength; ++i) {
-    if(listAccessor(i) !== null) {
-      ret.push(listAccessor(i));
-    }
-  }
-
-  return ret;
-};
-
-/**
- * This function is here only to get around typescript type system
- */
-flatbuffers.ByteBuffer.prototype.createStringList = function(listAccessor, listLength) {
-  return this.createScalarList(listAccessor, listLength);
-};
-
-/**
- * A helper function for generating list for obj api
- * @param listAccessor function that accepts an index and return data at that index
- * @param listLength {number} listLength
- * @param res any[] result list
- */
-flatbuffers.ByteBuffer.prototype.createObjList = function(listAccessor, listLength) {
-  let ret = [];
-  for(let i = 0; i < listLength; ++i) {
-    let val = listAccessor(i);
-    if(val !== null) {
-      ret.push(val.unpack());
-    }
-  }
-  
-  return ret;
-};
-
-// Exports for Node.js and RequireJS
-this.flatbuffers = flatbuffers;
-
-/// @endcond
-/// @}
diff --git a/mjs/README.md b/mjs/README.md
new file mode 100644 (file)
index 0000000..e3ca9db
--- /dev/null
@@ -0,0 +1 @@
+This folder is intentionally empty and will contain transpiled js modules in ES modules format after compiling with tsc.
\ No newline at end of file
index d01680a0f702d72c559ab5e6735e8cfb2523c9fd..4b9f71f3042efec75c304f756e698d413ae52cf4 100644 (file)
@@ -3,19 +3,24 @@
   "version": "1.12.0",
   "description": "Memory Efficient Serialization Library",
   "files": [
-    "js/flatbuffers.js",
-    "js/flatbuffers.mjs"
+    "js/*.js",
+    "js/*.d.ts",
+    "mjs/*.js",
+    "mjs/*.d.ts",
+    "ts/*.ts"
   ],
   "main": "js/flatbuffers",
-  "module": "js/flatbuffers.mjs",
+  "module": "mjs/index.mjs",
   "directories": {
     "doc": "docs",
     "test": "tests"
   },
   "scripts": {
-    "test": "tests/JavaScriptTest.sh",
+    "test": "cd tests && ./JavaScriptTest.sh",
+    "compile-ts": "tsc && tsc -p tsconfig.mjs.json",
+    "pretest": "npm run compile-ts",
     "append-esm-export": "sed \"s/this.flatbuffers = flatbuffers;/export { flatbuffers };/\" js/flatbuffers.js > js/flatbuffers.mjs",
-    "prepublishOnly": "npm run append-esm-export"
+    "prepublishOnly": "npm run compile-ts && npm run append-esm-export"
   },
   "repository": {
     "type": "git",
     "url": "https://github.com/google/flatbuffers/issues"
   },
   "homepage": "https://google.github.io/flatbuffers/",
-  "dependencies": {}
+  "dependencies": {},
+  "devDependencies": {
+    "@typescript-eslint/eslint-plugin": "^4.1.0",
+    "@typescript-eslint/parser": "^4.1.0",
+    "eslint": "^7.8.1",
+    "typescript": "^4.0.2"
+  }
 }
index 84d2475efa96f3b93cdbd58dbd33e62f8d949bc7..f1143545939926c65c64b5b368ed670ebb189069 100755 (executable)
@@ -17,6 +17,7 @@
 pushd "$(dirname $0)" >/dev/null
 
 npm install @types/flatbuffers
+npm run pretest
 
 export FB_TS_TEST="TRUE"
 
index b821105d1a0c0cfd92c37fd1cf3b339f9864b092..8e48c23cae27d318173bf2170efe2db439b68ffa 100644 (file)
@@ -5,4 +5,6 @@ RUN cp flatc_debian_stretch flatc
 WORKDIR /code/tests
 RUN node --version
 RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN npm install
+RUN npm run pretest
 RUN node JavaScriptTest ./monster_test_generated
index f6b48e6e696ece282d194d1fb23d5562b5c9d0af..090bb457e45699f76e049670539c801582376c07 100644 (file)
@@ -5,4 +5,6 @@ RUN cp flatc_debian_stretch flatc
 WORKDIR /code/tests
 RUN node --version
 RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN npm install
+RUN npm run pretest
 RUN node JavaScriptTest ./monster_test_generated
diff --git a/ts/builder.ts b/ts/builder.ts
new file mode 100644 (file)
index 0000000..6be72fb
--- /dev/null
@@ -0,0 +1,628 @@
+import { ByteBuffer } from "./byte-buffer"
+import { SIZEOF_SHORT, SIZE_PREFIX_LENGTH, SIZEOF_INT, FILE_IDENTIFIER_LENGTH } from "./constants"
+import { Offset, IGeneratedObject } from "./types"
+import { Long } from "./long"
+
+export class Builder {
+    private bb: ByteBuffer
+    /** Remaining space in the ByteBuffer. */
+    private space: number
+    /** Minimum alignment encountered so far. */
+    private minalign = 1
+    /** The vtable for the current table. */
+    private vtable: number[] | null = null
+    /** The amount of fields we're actually using. */
+    private vtable_in_use = 0
+    /** Whether we are currently serializing a table. */
+    private isNested = false;
+    /** Starting offset of the current struct/table. */
+    private object_start = 0
+    /** List of offsets of all vtables. */
+    private vtables: number[] = []
+    /** For the current vector being built. */
+    private vector_num_elems = 0 
+    /** False omits default values from the serialized data */
+    private force_defaults = false;
+    
+    private string_maps: Map<string | Uint8Array, number> | null = null;
+  
+    /**
+     * Create a FlatBufferBuilder.
+     */
+    constructor(opt_initial_size?: number) {
+      let initial_size: number;
+  
+      if (!opt_initial_size) {
+        initial_size = 1024;
+      } else {
+        initial_size = opt_initial_size;
+      }
+  
+      /**
+       * @type {ByteBuffer}
+       * @private
+       */
+      this.bb = ByteBuffer.allocate(initial_size);
+      this.space = initial_size;
+    }
+  
+  
+    clear(): void {
+      this.bb.clear();
+      this.space = this.bb.capacity();
+      this.minalign = 1;
+      this.vtable = null;
+      this.vtable_in_use = 0;
+      this.isNested = false;
+      this.object_start = 0;
+      this.vtables = [];
+      this.vector_num_elems = 0;
+      this.force_defaults = false;
+      this.string_maps = null;
+    }
+  
+    /**
+     * In order to save space, fields that are set to their default value
+     * don't get serialized into the buffer. Forcing defaults provides a
+     * way to manually disable this optimization.
+     *
+     * @param forceDefaults true always serializes default values
+     */
+    forceDefaults(forceDefaults: boolean): void {
+      this.force_defaults = forceDefaults;
+    }
+  
+    /**
+     * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+     * called finish(). The actual data starts at the ByteBuffer's current position,
+     * not necessarily at 0.
+     */
+    dataBuffer(): ByteBuffer {
+      return this.bb;
+    }
+  
+    /**
+     * Get the bytes representing the FlatBuffer. Only call this after you've
+     * called finish().
+     */
+    asUint8Array(): Uint8Array {
+      return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
+    }
+  
+    /**
+     * Prepare to write an element of `size` after `additional_bytes` have been
+     * written, e.g. if you write a string, you need to align such the int length
+     * field is aligned to 4 bytes, and the string data follows it directly. If all
+     * you need to do is alignment, `additional_bytes` will be 0.
+     *
+     * @param size This is the of the new element to write
+     * @param additional_bytes The padding size
+     */
+    prep(size: number, additional_bytes: number): void {
+      // Track the biggest thing we've ever aligned to.
+      if (size > this.minalign) {
+        this.minalign = size;
+      }
+  
+      // Find the amount of alignment needed such that `size` is properly
+      // aligned after `additional_bytes`
+      const align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
+  
+      // Reallocate the buffer if needed.
+      while (this.space < align_size + size + additional_bytes) {
+        const old_buf_size = this.bb.capacity();
+        this.bb = Builder.growByteBuffer(this.bb);
+        this.space += this.bb.capacity() - old_buf_size;
+      }
+  
+      this.pad(align_size);
+    }
+  
+    pad(byte_size: number): void {
+      for (let i = 0; i < byte_size; i++) {
+        this.bb.writeInt8(--this.space, 0);
+      }
+    }
+  
+    writeInt8(value: number): void {
+      this.bb.writeInt8(this.space -= 1, value);
+    }
+  
+    writeInt16(value: number): void {
+      this.bb.writeInt16(this.space -= 2, value);
+    }
+  
+    writeInt32(value: number): void {
+      this.bb.writeInt32(this.space -= 4, value);
+    }
+  
+    writeInt64(value: Long): void {
+      this.bb.writeInt64(this.space -= 8, value);
+    }
+  
+    writeFloat32(value: number): void {
+      this.bb.writeFloat32(this.space -= 4, value);
+    }
+  
+    writeFloat64(value: number): void {
+      this.bb.writeFloat64(this.space -= 8, value);
+    }
+  
+    /**
+     * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int8` to add the the buffer.
+     */
+    addInt8(value: number): void {
+      this.prep(1, 0);
+      this.writeInt8(value);
+    }
+  
+    /**
+     * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int16` to add the the buffer.
+     */
+    addInt16(value: number): void {
+      this.prep(2, 0);
+      this.writeInt16(value);
+    }
+  
+    /**
+     * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int32` to add the the buffer.
+     */
+    addInt32(value: number): void {
+      this.prep(4, 0);
+      this.writeInt32(value);
+    }
+  
+    /**
+     * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int64` to add the the buffer.
+     */
+    addInt64(value: Long): void {
+      this.prep(8, 0);
+      this.writeInt64(value);
+    }
+  
+    /**
+     * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float32` to add the the buffer.
+     */
+    addFloat32(value: number): void {
+      this.prep(4, 0);
+      this.writeFloat32(value);
+    }
+  
+    /**
+     * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float64` to add the the buffer.
+     */
+    addFloat64(value: number): void {
+      this.prep(8, 0);
+      this.writeFloat64(value);
+    }
+  
+    addFieldInt8(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt8(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt16(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt16(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt32(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt32(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt64(voffset: number, value: Long, defaultValue: Long): void {
+      if (this.force_defaults || !value.equals(defaultValue)) {
+        this.addInt64(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldFloat32(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addFloat32(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldFloat64(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addFloat64(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldOffset(voffset: number, value: Offset, defaultValue: Offset): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addOffset(value);
+        this.slot(voffset);
+      }
+    }
+  
+    /**
+     * Structs are stored inline, so nothing additional is being added. `d` is always 0.
+     */
+    addFieldStruct(voffset: number, value: Offset, defaultValue: Offset): void {
+      if (value != defaultValue) {
+        this.nested(value);
+        this.slot(voffset);
+      }
+    }
+  
+    /**
+     * Structures are always stored inline, they need to be created right
+     * where they're used.  You'll get this assertion failure if you
+     * created it elsewhere.
+     */
+    nested(obj: Offset): void {
+      if (obj != this.offset()) {
+        throw new Error('FlatBuffers: struct must be serialized inline.');
+      }
+    }
+  
+    /**
+     * Should not be creating any other object, string or vector
+     * while an object is being constructed
+     */
+    notNested(): void {
+      if (this.isNested) {
+        throw new Error('FlatBuffers: object serialization must not be nested.');
+      }
+    }
+  
+    /**
+     * Set the current vtable at `voffset` to the current location in the buffer.
+     */
+    slot(voffset: number): void {
+      if (this.vtable !== null)
+        this.vtable[voffset] = this.offset();
+    }
+  
+    /**
+     * @returns Offset relative to the end of the buffer.
+     */
+    offset(): Offset {
+      return this.bb.capacity() - this.space;
+    }
+  
+    /**
+     * Doubles the size of the backing ByteBuffer and copies the old data towards
+     * the end of the new buffer (since we build the buffer backwards).
+     *
+     * @param bb The current buffer with the existing data
+     * @returns A new byte buffer with the old data copied
+     * to it. The data is located at the end of the buffer.
+     *
+     * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
+     * it a uint8Array we need to suppress the type check:
+     * @suppress {checkTypes}
+     */
+    static growByteBuffer(bb: ByteBuffer): ByteBuffer {
+      const old_buf_size = bb.capacity();
+  
+      // Ensure we don't grow beyond what fits in an int.
+      if (old_buf_size & 0xC0000000) {
+        throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
+      }
+  
+      const new_buf_size = old_buf_size << 1;
+      const nbb = ByteBuffer.allocate(new_buf_size);
+      nbb.setPosition(new_buf_size - old_buf_size);
+      nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
+      return nbb;
+    }
+  
+    /**
+     * Adds on offset, relative to where it will be written.
+     *
+     * @param offset The offset to add.
+     */
+    addOffset(offset: Offset): void {
+      this.prep(SIZEOF_INT, 0); // Ensure alignment is already done.
+      this.writeInt32(this.offset() - offset + SIZEOF_INT);
+    }
+  
+    /**
+     * Start encoding a new object in the buffer.  Users will not usually need to
+     * call this directly. The FlatBuffers compiler will generate helper methods
+     * that call this method internally.
+     */
+    startObject(numfields: number): void {
+      this.notNested();
+      if (this.vtable == null) {
+        this.vtable = [];
+      }
+      this.vtable_in_use = numfields;
+      for (let i = 0; i < numfields; i++) {
+        this.vtable[i] = 0; // This will push additional elements as needed
+      }
+      this.isNested = true;
+      this.object_start = this.offset();
+    }
+  
+    /**
+     * Finish off writing the object that is under construction.
+     *
+     * @returns The offset to the object inside `dataBuffer`
+     */
+    endObject(): Offset {
+      if (this.vtable == null || !this.isNested) {
+        throw new Error('FlatBuffers: endObject called without startObject');
+      }
+  
+      this.addInt32(0);
+      const vtableloc = this.offset();
+  
+      // Trim trailing zeroes.
+      let i = this.vtable_in_use - 1;
+      // eslint-disable-next-line no-empty
+      for (; i >= 0 && this.vtable[i] == 0; i--) {}
+      const trimmed_size = i + 1;
+  
+      // Write out the current vtable.
+      for (; i >= 0; i--) {
+        // Offset relative to the start of the table.
+        this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
+      }
+  
+      const standard_fields = 2; // The fields below:
+      this.addInt16(vtableloc - this.object_start);
+      const len = (trimmed_size + standard_fields) * SIZEOF_SHORT;
+      this.addInt16(len);
+  
+      // Search for an existing vtable that matches the current one.
+      let existing_vtable = 0;
+      const vt1 = this.space;
+    outer_loop:
+      for (i = 0; i < this.vtables.length; i++) {
+        const vt2 = this.bb.capacity() - this.vtables[i];
+        if (len == this.bb.readInt16(vt2)) {
+          for (let j = SIZEOF_SHORT; j < len; j += SIZEOF_SHORT) {
+            if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
+              continue outer_loop;
+            }
+          }
+          existing_vtable = this.vtables[i];
+          break;
+        }
+      }
+  
+      if (existing_vtable) {
+        // Found a match:
+        // Remove the current vtable.
+        this.space = this.bb.capacity() - vtableloc;
+  
+        // Point table to existing vtable.
+        this.bb.writeInt32(this.space, existing_vtable - vtableloc);
+      } else {
+        // No match:
+        // Add the location of the current vtable to the list of vtables.
+        this.vtables.push(this.offset());
+  
+        // Point table to current vtable.
+        this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
+      }
+  
+      this.isNested = false;
+      return vtableloc as Offset;
+    }
+  
+    /**
+     * Finalize a buffer, poiting to the given `root_table`.
+     */
+    finish(root_table: Offset, opt_file_identifier?: string, opt_size_prefix?: boolean): void {
+      const size_prefix = opt_size_prefix ? SIZE_PREFIX_LENGTH : 0;
+      if (opt_file_identifier) {
+        const file_identifier = opt_file_identifier;
+        this.prep(this.minalign, SIZEOF_INT +
+          FILE_IDENTIFIER_LENGTH + size_prefix);
+        if (file_identifier.length != FILE_IDENTIFIER_LENGTH) {
+          throw new Error('FlatBuffers: file identifier must be length ' +
+            FILE_IDENTIFIER_LENGTH);
+        }
+        for (let i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+          this.writeInt8(file_identifier.charCodeAt(i));
+        }
+      }
+      this.prep(this.minalign, SIZEOF_INT + size_prefix);
+      this.addOffset(root_table);
+      if (size_prefix) {
+        this.addInt32(this.bb.capacity() - this.space);
+      }
+      this.bb.setPosition(this.space);
+    }
+  
+    /**
+     * Finalize a size prefixed buffer, pointing to the given `root_table`.
+     */
+    finishSizePrefixed(this: Builder, root_table: Offset, opt_file_identifier?: string): void {
+      this.finish(root_table, opt_file_identifier, true);
+    }
+  
+    /**
+     * This checks a required field has been set in a given table that has
+     * just been constructed.
+     */
+    requiredField(table: Offset, field: number): void {
+      const table_start = this.bb.capacity() - table;
+      const vtable_start = table_start - this.bb.readInt32(table_start);
+      const ok = this.bb.readInt16(vtable_start + field) != 0;
+  
+      // If this fails, the caller will show what field needs to be set.
+      if (!ok) {
+        throw new Error('FlatBuffers: field ' + field + ' must be set');
+      }
+    }
+  
+    /**
+     * Start a new array/vector of objects.  Users usually will not call
+     * this directly. The FlatBuffers compiler will create a start/end
+     * method for vector types in generated code.
+     *
+     * @param elem_size The size of each element in the array
+     * @param num_elems The number of elements in the array
+     * @param alignment The alignment of the array
+     */
+    startVector(elem_size: number, num_elems: number, alignment: number): void {
+      this.notNested();
+      this.vector_num_elems = num_elems;
+      this.prep(SIZEOF_INT, elem_size * num_elems);
+      this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+    }
+  
+    /**
+     * Finish off the creation of an array and all its elements. The array must be
+     * created with `startVector`.
+     *
+     * @returns The offset at which the newly created array
+     * starts.
+     */
+    endVector(): Offset {
+      this.writeInt32(this.vector_num_elems);
+      return this.offset();
+    }
+  
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If the string passed has 
+     * already been seen, we return the offset of the already written string
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    createSharedString(s: string | Uint8Array): Offset {
+      if (!s) { return 0 }
+  
+      if (!this.string_maps) {
+        this.string_maps = new Map();
+      }
+  
+      if (this.string_maps.has(s)) {
+        return this.string_maps.get(s) as Offset
+      }
+      const offset = this.createString(s)
+      this.string_maps.set(s, offset)
+      return offset
+    }
+  
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
+     * instead of a string, it is assumed to contain valid UTF-8 encoded data.
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    createString(s: string | Uint8Array): Offset {
+      if (!s) { return 0 }
+      let utf8: string | Uint8Array | number[];
+      if (s instanceof Uint8Array) {
+        utf8 = s;
+      } else {
+        utf8 = [];
+        let i = 0;
+  
+        while (i < s.length) {
+          let codePoint;
+  
+          // Decode UTF-16
+          const a = s.charCodeAt(i++);
+          if (a < 0xD800 || a >= 0xDC00) {
+            codePoint = a;
+          } else {
+            const b = s.charCodeAt(i++);
+            codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
+          }
+  
+          // Encode UTF-8
+          if (codePoint < 0x80) {
+            utf8.push(codePoint);
+          } else {
+            if (codePoint < 0x800) {
+              utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
+            } else {
+              if (codePoint < 0x10000) {
+                utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
+              } else {
+                utf8.push(
+                  ((codePoint >> 18) & 0x07) | 0xF0,
+                  ((codePoint >> 12) & 0x3F) | 0x80);
+              }
+              utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
+            }
+            utf8.push((codePoint & 0x3F) | 0x80);
+          }
+        }
+      }
+  
+      this.addInt8(0);
+      this.startVector(1, utf8.length, 1);
+      this.bb.setPosition(this.space -= utf8.length);
+      for (let i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
+        bytes[offset++] = utf8[i];
+      }
+      return this.endVector();
+    }
+  
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    createLong(low: number, high: number): Long {
+      return Long.create(low, high);
+    }
+  
+    /**
+     * A helper function to pack an object
+     * 
+     * @returns offset of obj
+     */
+    createObjectOffset(obj: string | IGeneratedObject): Offset {
+      if(obj === null) {
+        return 0
+      }
+  
+      if(typeof obj === 'string') {
+        return this.createString(obj);
+      } else {
+        return obj.pack(this);
+      }
+    }
+  
+    /**
+     * A helper function to pack a list of object
+     * 
+     * @returns list of offsets of each non null object
+     */
+    createObjectOffsetList(list: string[]): Offset[] {
+      const ret = [];
+  
+      for(let i = 0; i < list.length; ++i) {
+        const val = list[i];
+  
+        if(val !== null) {
+          ret.push(this.createObjectOffset(val));
+        } else {
+          throw new Error(
+            'FlatBuffers: Argument for createObjectOffsetList cannot contain null.'); 
+        }
+      }
+      
+      return ret;
+    }
+  
+    createStructOffsetList(list: string[], startFunc: (builder: Builder, length: number) => void): Offset {
+      startFunc(this, list.length);
+      this.createObjectOffsetList(list);
+      return this.endVector();
+    }
+  }
\ No newline at end of file
diff --git a/ts/byte-buffer.ts b/ts/byte-buffer.ts
new file mode 100644 (file)
index 0000000..b936c7b
--- /dev/null
@@ -0,0 +1,351 @@
+import { FILE_IDENTIFIER_LENGTH, SIZEOF_INT } from "./constants";
+import { Long } from "./long";
+import { int32, isLittleEndian, float32, float64 } from "./utils";
+import { Offset, Table, IGeneratedObject } from "./types";
+import { Encoding } from "./encoding";
+
+export class ByteBuffer {
+    private position_ = 0;
+  
+    /**
+     * Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
+     */
+    constructor(private bytes_: Uint8Array) { }
+  
+    /**
+     * Create and allocate a new ByteBuffer with a given size.
+     */
+    static allocate(byte_size: number): ByteBuffer {
+      return new ByteBuffer(new Uint8Array(byte_size));
+    }
+  
+    clear(): void {
+      this.position_ = 0;
+    }
+  
+    /**
+     * Get the underlying `Uint8Array`.
+     */
+    bytes(): Uint8Array {
+      return this.bytes_;
+    }
+  
+    /**
+     * Get the buffer's position.
+     */
+    position(): number {
+      return this.position_;
+    }
+  
+    /**
+     * Set the buffer's position.
+     */
+    setPosition(position: number): void {
+      this.position_ = position;
+    }
+  
+    /**
+     * Get the buffer's capacity.
+     */
+    capacity(): number {
+      return this.bytes_.length;
+    }
+  
+    readInt8(offset: number): number {
+      return this.readUint8(offset) << 24 >> 24;
+    }
+  
+    readUint8(offset: number): number {
+      return this.bytes_[offset];
+    }
+  
+    readInt16(offset: number): number {
+      return this.readUint16(offset) << 16 >> 16;
+    }
+  
+    readUint16(offset: number): number {
+      return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
+    }
+  
+    readInt32(offset: number): number {
+      return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
+    }
+  
+    readUint32(offset: number): number {
+      return this.readInt32(offset) >>> 0;
+    }
+  
+    readInt64(offset: number): Long {
+      return new Long(this.readInt32(offset), this.readInt32(offset + 4));
+    }
+  
+    readUint64(offset: number): Long {
+      return new Long(this.readUint32(offset), this.readUint32(offset + 4));
+    }
+  
+    readFloat32(offset: number): number {
+      int32[0] = this.readInt32(offset);
+      return float32[0];
+    }
+  
+    readFloat64(offset: number): number {
+      int32[isLittleEndian ? 0 : 1] = this.readInt32(offset);
+      int32[isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
+      return float64[0];
+    }
+  
+    writeInt8(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+    }
+  
+    writeUint8(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+    }
+  
+    writeInt16(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+      this.bytes_[offset + 1] = value >> 8;
+    }
+  
+    writeUint16(offset: number, value: number): void {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+    }
+  
+    writeInt32(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+      this.bytes_[offset + 1] = value >> 8;
+      this.bytes_[offset + 2] = value >> 16;
+      this.bytes_[offset + 3] = value >> 24;
+    }
+  
+    writeUint32(offset: number, value: number): void {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+        this.bytes_[offset + 2] = value >> 16;
+        this.bytes_[offset + 3] = value >> 24;
+    }
+  
+    writeInt64(offset: number, value: Long): void {
+      this.writeInt32(offset, value.low);
+      this.writeInt32(offset + 4, value.high);
+    }
+  
+    writeUint64(offset: number, value: Long): void {
+        this.writeUint32(offset, value.low);
+        this.writeUint32(offset + 4, value.high);
+    }
+  
+    writeFloat32(offset: number, value: number): void {
+      float32[0] = value;
+      this.writeInt32(offset, int32[0]);
+    }
+  
+    writeFloat64(offset: number, value: number): void {
+      float64[0] = value;
+      this.writeInt32(offset, int32[isLittleEndian ? 0 : 1]);
+      this.writeInt32(offset + 4, int32[isLittleEndian ? 1 : 0]);
+    }
+  
+    /**
+     * Return the file identifier.   Behavior is undefined for FlatBuffers whose
+     * schema does not include a file_identifier (likely points at padding or the
+     * start of a the root vtable).
+     */
+    getBufferIdentifier(): string {
+      if (this.bytes_.length < this.position_ + SIZEOF_INT +
+          FILE_IDENTIFIER_LENGTH) {
+        throw new Error(
+            'FlatBuffers: ByteBuffer is too short to contain an identifier.');
+      }
+      let result = "";
+      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+        result += String.fromCharCode(
+            this.readInt8(this.position_ + SIZEOF_INT + i));
+      }
+      return result;
+    }
+  
+    /**
+     * Look up a field in the vtable, return an offset into the object, or 0 if the
+     * field is not present.
+     */
+    __offset(bb_pos: number, vtable_offset: number): Offset {
+      const vtable = bb_pos - this.readInt32(bb_pos);
+      return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
+    }
+  
+    /**
+     * Initialize any Table-derived type to point to the union at the given offset.
+     */
+    __union(t: Table, offset: number): Table {
+      t.bb_pos = offset + this.readInt32(offset);
+      t.bb = this;
+      return t;
+    }
+  
+    /**
+     * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
+     * This allocates a new string and converts to wide chars upon each access.
+     *
+     * To avoid the conversion to UTF-16, pass Encoding.UTF8_BYTES as
+     * the "optionalEncoding" argument. This is useful for avoiding conversion to
+     * and from UTF-16 when the data will just be packaged back up in another
+     * FlatBuffer later on.
+     *
+     * @param offset
+     * @param opt_encoding Defaults to UTF16_STRING
+     */
+    __string(offset: number, opt_encoding?: Encoding): string | Uint8Array {
+      offset += this.readInt32(offset);
+  
+      const length = this.readInt32(offset);
+      let result = '';
+      let i = 0;
+  
+      offset += SIZEOF_INT;
+  
+      if (opt_encoding === Encoding.UTF8_BYTES) {
+        return this.bytes_.subarray(offset, offset + length);
+      }
+  
+      while (i < length) {
+        let codePoint;
+  
+        // Decode UTF-8
+        const a = this.readUint8(offset + i++);
+        if (a < 0xC0) {
+          codePoint = a;
+        } else {
+          const b = this.readUint8(offset + i++);
+          if (a < 0xE0) {
+            codePoint =
+              ((a & 0x1F) << 6) |
+              (b & 0x3F);
+          } else {
+            const c = this.readUint8(offset + i++);
+            if (a < 0xF0) {
+              codePoint =
+                ((a & 0x0F) << 12) |
+                ((b & 0x3F) << 6) |
+                (c & 0x3F);
+            } else {
+              const d = this.readUint8(offset + i++);
+              codePoint =
+                ((a & 0x07) << 18) |
+                ((b & 0x3F) << 12) |
+                ((c & 0x3F) << 6) |
+                (d & 0x3F);
+            }
+          }
+        }
+  
+        // Encode UTF-16
+        if (codePoint < 0x10000) {
+          result += String.fromCharCode(codePoint);
+        } else {
+          codePoint -= 0x10000;
+          result += String.fromCharCode(
+            (codePoint >> 10) + 0xD800,
+            (codePoint & ((1 << 10) - 1)) + 0xDC00);
+        }
+      }
+  
+      return result;
+    }
+  
+    /**
+     * Handle unions that can contain string as its member, if a Table-derived type then initialize it, 
+     * if a string then return a new one
+     * 
+     * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this 
+     * makes the behaviour of __union_with_string different compared to __union
+     */
+    __union_with_string(o: Table | string, offset: number) : Table | string {
+      if(typeof o === 'string') {
+        return this.__string(offset) as string;
+      } 
+      return this.__union(o, offset);
+    }
+  
+    /**
+     * Retrieve the relative offset stored at "offset"
+     */
+    __indirect(offset: Offset): Offset {
+      return offset + this.readInt32(offset);
+    }
+  
+    /**
+     * Get the start of data of a vector whose offset is stored at "offset" in this object.
+     */
+    __vector(offset: Offset): Offset {
+      return offset + this.readInt32(offset) + SIZEOF_INT; // data starts after the length
+    }
+  
+    /**
+     * Get the length of a vector whose offset is stored at "offset" in this object.
+     */
+    __vector_len(offset: Offset): Offset {
+      return this.readInt32(offset + this.readInt32(offset));
+    }
+  
+    __has_identifier(ident: string): boolean {
+      if (ident.length != FILE_IDENTIFIER_LENGTH) {
+        throw new Error('FlatBuffers: file identifier must be length ' +
+                        FILE_IDENTIFIER_LENGTH);
+      }
+      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+        if (ident.charCodeAt(i) != this.readInt8(this.position() + SIZEOF_INT + i)) {
+          return false;
+        }
+      }
+      return true;
+    }
+  
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    createLong(low: number, high: number): Long {
+      return Long.create(low, high);
+    }
+  
+    /**
+     * A helper function for generating list for obj api
+     */
+    createScalarList(listAccessor: (i: number) => unknown, listLength: number) : unknown[] {
+      const ret: unknown[] = [];
+      for(let i = 0; i < listLength; ++i) {
+        if(listAccessor(i) !== null) {
+          ret.push(listAccessor(i));
+        }
+      }
+  
+      return ret;
+    }
+  
+    /**
+     * This function is here only to get around typescript type system
+     */
+    createStringList(listAccessor: (i: number) => unknown, listLength: number): unknown[] {
+      return this.createScalarList(listAccessor, listLength);
+    }
+  
+    /**
+     * A helper function for generating list for obj api
+     * @param listAccessor function that accepts an index and return data at that index
+     * @param listLength listLength
+     * @param res result list
+     */
+    createObjList(listAccessor: (i: number) => IGeneratedObject, listLength: number): IGeneratedObject[] {
+      const ret: IGeneratedObject[] = [];
+      for(let i = 0; i < listLength; ++i) {
+        const val = listAccessor(i);
+        if(val !== null) {
+          ret.push(val.unpack());
+        }
+      }
+      
+      return ret;
+    }
+  
+  }
\ No newline at end of file
diff --git a/ts/constants.ts b/ts/constants.ts
new file mode 100644 (file)
index 0000000..04510fb
--- /dev/null
@@ -0,0 +1,4 @@
+export const SIZEOF_SHORT = 2;
+export const SIZEOF_INT = 4;
+export const FILE_IDENTIFIER_LENGTH = 4;
+export const SIZE_PREFIX_LENGTH = 4;
\ No newline at end of file
diff --git a/ts/encoding.ts b/ts/encoding.ts
new file mode 100644 (file)
index 0000000..856792c
--- /dev/null
@@ -0,0 +1,4 @@
+export enum Encoding {
+    UTF8_BYTES = 1,
+    UTF16_STRING = 2
+}
\ No newline at end of file
diff --git a/ts/flatbuffers.ts b/ts/flatbuffers.ts
new file mode 100644 (file)
index 0000000..2c2a295
--- /dev/null
@@ -0,0 +1,33 @@
+/* eslint-disable @typescript-eslint/no-namespace */
+import * as constants from './constants'
+import * as types from './types'
+import * as utils from './utils'
+
+import { Long as LongClass } from './long'
+import { Encoding as EncodingEnum } from './encoding'
+import { Builder as BuilderClass } from './builder'
+import { ByteBuffer as ByteBufferClass } from './byte-buffer'
+
+export namespace flatbuffers {
+
+    export type Offset = types.Offset;
+
+    export type Table = types.Table;
+
+    export const SIZEOF_SHORT = constants.SIZEOF_SHORT;
+    export const SIZEOF_INT = constants.SIZEOF_INT;
+    export const FILE_IDENTIFIER_LENGTH = constants.FILE_IDENTIFIER_LENGTH;
+    export const SIZE_PREFIX_LENGTH = constants.SIZE_PREFIX_LENGTH;
+
+    export const Encoding = EncodingEnum;
+
+    export const int32 = utils.int32;
+    export const float32 = utils.float32;
+    export const float64 = utils.float64;
+    export const isLittleEndian = utils.isLittleEndian;
+
+    export const Long = LongClass;
+    export const Builder = BuilderClass;
+    export const ByteBuffer = ByteBufferClass;
+}
+
diff --git a/ts/long.ts b/ts/long.ts
new file mode 100644 (file)
index 0000000..50a3ea8
--- /dev/null
@@ -0,0 +1,23 @@
+export function createLong(low: number, high: number): Long {
+    return Long.create(low, high);
+}
+  
+export class Long {
+    static readonly ZERO = new Long(0, 0)
+    low: number
+    high: number
+    constructor(low: number, high: number) {
+        this.low = low | 0;
+        this.high = high | 0;
+    }
+    static create(low: number, high: number): Long {
+        // Special-case zero to avoid GC overhead for default values
+        return low == 0 && high == 0 ? Long.ZERO : new Long(low, high);
+    }
+    toFloat64(): number {
+        return (this.low >>> 0) + this.high * 0x100000000;
+    }
+    equals(other: Long): boolean {
+        return this.low == other.low && this.high == other.high;
+    }
+}
\ No newline at end of file
diff --git a/ts/types.ts b/ts/types.ts
new file mode 100644 (file)
index 0000000..30e4050
--- /dev/null
@@ -0,0 +1,14 @@
+import { ByteBuffer } from './byte-buffer'
+import { Builder } from './builder'
+
+export type Offset = number;
+
+export type Table = {
+  bb: ByteBuffer
+  bb_pos: number
+};
+
+export interface IGeneratedObject {
+  pack(builder:Builder): Offset
+  unpack(): IGeneratedObject
+}
\ No newline at end of file
diff --git a/ts/utils.ts b/ts/utils.ts
new file mode 100644 (file)
index 0000000..a2902e3
--- /dev/null
@@ -0,0 +1,4 @@
+export const int32 = new Int32Array(2);
+export const float32 = new Float32Array(int32.buffer);
+export const float64 = new Float64Array(int32.buffer);
+export const isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644 (file)
index 0000000..0e4fdc4
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "commonjs",
+    "lib": ["es2015"],
+    "declaration": true,
+    "outDir": "./js",
+    "strict": true,
+    "esModuleInterop": true,
+    "skipLibCheck": true, 
+    "forceConsistentCasingInFileNames": true
+  },
+  "include": [
+    "ts/*.ts"
+  ]
+}
diff --git a/tsconfig.mjs.json b/tsconfig.mjs.json
new file mode 100644 (file)
index 0000000..a887a1c
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "compilerOptions": {
+    "target": "ES2017",
+    "module": "ES2015",
+    "lib": ["ES2017"],
+    "declaration": true,
+    "outDir": "./mjs",
+    "strict": true,
+    "esModuleInterop": true,
+    "skipLibCheck": true, 
+    "forceConsistentCasingInFileNames": true
+  },
+  "include": [
+    "ts/*.ts"
+  ]
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
new file mode 100644 (file)
index 0000000..0ec94dd
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,956 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@^7.0.0":
+  version "7.10.4"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
+  integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
+  dependencies:
+    "@babel/highlight" "^7.10.4"
+
+"@babel/helper-validator-identifier@^7.10.4":
+  version "7.10.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
+  integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
+
+"@babel/highlight@^7.10.4":
+  version "7.10.4"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
+  integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
+  dependencies:
+    "@babel/helper-validator-identifier" "^7.10.4"
+    chalk "^2.0.0"
+    js-tokens "^4.0.0"
+
+"@eslint/eslintrc@^0.1.3":
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085"
+  integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==
+  dependencies:
+    ajv "^6.12.4"
+    debug "^4.1.1"
+    espree "^7.3.0"
+    globals "^12.1.0"
+    ignore "^4.0.6"
+    import-fresh "^3.2.1"
+    js-yaml "^3.13.1"
+    lodash "^4.17.19"
+    minimatch "^3.0.4"
+    strip-json-comments "^3.1.1"
+
+"@nodelib/fs.scandir@2.1.3":
+  version "2.1.3"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
+  integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
+  dependencies:
+    "@nodelib/fs.stat" "2.0.3"
+    run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3"
+  integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
+
+"@nodelib/fs.walk@^1.2.3":
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976"
+  integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
+  dependencies:
+    "@nodelib/fs.scandir" "2.1.3"
+    fastq "^1.6.0"
+
+"@types/color-name@^1.1.1":
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
+  integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+
+"@types/json-schema@^7.0.3":
+  version "7.0.6"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
+  integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
+
+"@typescript-eslint/eslint-plugin@^4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.0.tgz#7d309f60815ff35e9627ad85e41928d7b7fd443f"
+  integrity sha512-U+nRJx8XDUqJxYF0FCXbpmD9nWt/xHDDG0zsw1vrVYAmEAuD/r49iowfurjSL2uTA2JsgtpsyG7mjO7PHf2dYw==
+  dependencies:
+    "@typescript-eslint/experimental-utils" "4.1.0"
+    "@typescript-eslint/scope-manager" "4.1.0"
+    debug "^4.1.1"
+    functional-red-black-tree "^1.0.1"
+    regexpp "^3.0.0"
+    semver "^7.3.2"
+    tsutils "^3.17.1"
+
+"@typescript-eslint/experimental-utils@4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.0.tgz#263d7225645c09a411c8735eeffd417f50f49026"
+  integrity sha512-paEYLA37iqRIDPeQwAmoYSiZ3PiHsaAc3igFeBTeqRHgPnHjHLJ9OGdmP6nwAkF65p2QzEsEBtpjNUBWByNWzA==
+  dependencies:
+    "@types/json-schema" "^7.0.3"
+    "@typescript-eslint/scope-manager" "4.1.0"
+    "@typescript-eslint/types" "4.1.0"
+    "@typescript-eslint/typescript-estree" "4.1.0"
+    eslint-scope "^5.0.0"
+    eslint-utils "^2.0.0"
+
+"@typescript-eslint/parser@^4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.1.0.tgz#9b0409411725f14cd7faa81a664e5051225961db"
+  integrity sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==
+  dependencies:
+    "@typescript-eslint/scope-manager" "4.1.0"
+    "@typescript-eslint/types" "4.1.0"
+    "@typescript-eslint/typescript-estree" "4.1.0"
+    debug "^4.1.1"
+
+"@typescript-eslint/scope-manager@4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz#9e389745ee9cfe12252ed1e9958808abd6b3a683"
+  integrity sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==
+  dependencies:
+    "@typescript-eslint/types" "4.1.0"
+    "@typescript-eslint/visitor-keys" "4.1.0"
+
+"@typescript-eslint/types@4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.0.tgz#edbd3fec346f34e13ce7aa176b03b497a32c496a"
+  integrity sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==
+
+"@typescript-eslint/typescript-estree@4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz#394046ead25164494218c0e3d6b960695ea967f6"
+  integrity sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==
+  dependencies:
+    "@typescript-eslint/types" "4.1.0"
+    "@typescript-eslint/visitor-keys" "4.1.0"
+    debug "^4.1.1"
+    globby "^11.0.1"
+    is-glob "^4.0.1"
+    lodash "^4.17.15"
+    semver "^7.3.2"
+    tsutils "^3.17.1"
+
+"@typescript-eslint/visitor-keys@4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz#b2d528c9484e7eda1aa4f86ccf0432fb16e4d545"
+  integrity sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==
+  dependencies:
+    "@typescript-eslint/types" "4.1.0"
+    eslint-visitor-keys "^2.0.0"
+
+acorn-jsx@^5.2.0:
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
+  integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
+
+acorn@^7.4.0:
+  version "7.4.0"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
+  integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
+
+ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4:
+  version "6.12.4"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
+  integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
+  dependencies:
+    fast-deep-equal "^3.1.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
+
+ansi-colors@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
+  integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
+
+ansi-regex@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
+  integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+
+ansi-regex@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
+  integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+  dependencies:
+    color-convert "^1.9.0"
+
+ansi-styles@^4.1.0:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
+  integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
+  dependencies:
+    "@types/color-name" "^1.1.1"
+    color-convert "^2.0.1"
+
+argparse@^1.0.7:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+  integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
+  dependencies:
+    sprintf-js "~1.0.2"
+
+array-union@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
+  integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
+astral-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
+  integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
+
+balanced-match@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+  integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
+
+brace-expansion@^1.1.7:
+  version "1.1.11"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+  dependencies:
+    balanced-match "^1.0.0"
+    concat-map "0.0.1"
+
+braces@^3.0.1:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+  integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+  dependencies:
+    fill-range "^7.0.1"
+
+callsites@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
+  integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+
+chalk@^2.0.0:
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+  dependencies:
+    ansi-styles "^3.2.1"
+    escape-string-regexp "^1.0.5"
+    supports-color "^5.3.0"
+
+chalk@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
+  integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
+  dependencies:
+    ansi-styles "^4.1.0"
+    supports-color "^7.1.0"
+
+color-convert@^1.9.0:
+  version "1.9.3"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+  dependencies:
+    color-name "1.1.3"
+
+color-convert@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+  dependencies:
+    color-name "~1.1.4"
+
+color-name@1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+  integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+
+color-name@~1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+
+cross-spawn@^7.0.2:
+  version "7.0.3"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
+  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+  dependencies:
+    path-key "^3.1.0"
+    shebang-command "^2.0.0"
+    which "^2.0.1"
+
+debug@^4.0.1, debug@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
+  integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
+  dependencies:
+    ms "^2.1.1"
+
+deep-is@^0.1.3:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+  integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
+
+dir-glob@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
+  integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+  dependencies:
+    path-type "^4.0.0"
+
+doctrine@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
+  integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
+  dependencies:
+    esutils "^2.0.2"
+
+emoji-regex@^7.0.1:
+  version "7.0.3"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
+  integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
+
+enquirer@^2.3.5:
+  version "2.3.6"
+  resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
+  integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
+  dependencies:
+    ansi-colors "^4.1.1"
+
+escape-string-regexp@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+
+eslint-scope@^5.0.0, eslint-scope@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
+  integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
+  dependencies:
+    esrecurse "^4.1.0"
+    estraverse "^4.1.1"
+
+eslint-utils@^2.0.0, eslint-utils@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
+  integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
+  dependencies:
+    eslint-visitor-keys "^1.1.0"
+
+eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
+  integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
+
+eslint-visitor-keys@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
+  integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
+
+eslint@^7.8.1:
+  version "7.8.1"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.8.1.tgz#e59de3573fb6a5be8ff526c791571646d124a8fa"
+  integrity sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@eslint/eslintrc" "^0.1.3"
+    ajv "^6.10.0"
+    chalk "^4.0.0"
+    cross-spawn "^7.0.2"
+    debug "^4.0.1"
+    doctrine "^3.0.0"
+    enquirer "^2.3.5"
+    eslint-scope "^5.1.0"
+    eslint-utils "^2.1.0"
+    eslint-visitor-keys "^1.3.0"
+    espree "^7.3.0"
+    esquery "^1.2.0"
+    esutils "^2.0.2"
+    file-entry-cache "^5.0.1"
+    functional-red-black-tree "^1.0.1"
+    glob-parent "^5.0.0"
+    globals "^12.1.0"
+    ignore "^4.0.6"
+    import-fresh "^3.0.0"
+    imurmurhash "^0.1.4"
+    is-glob "^4.0.0"
+    js-yaml "^3.13.1"
+    json-stable-stringify-without-jsonify "^1.0.1"
+    levn "^0.4.1"
+    lodash "^4.17.19"
+    minimatch "^3.0.4"
+    natural-compare "^1.4.0"
+    optionator "^0.9.1"
+    progress "^2.0.0"
+    regexpp "^3.1.0"
+    semver "^7.2.1"
+    strip-ansi "^6.0.0"
+    strip-json-comments "^3.1.0"
+    table "^5.2.3"
+    text-table "^0.2.0"
+    v8-compile-cache "^2.0.3"
+
+espree@^7.3.0:
+  version "7.3.0"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348"
+  integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==
+  dependencies:
+    acorn "^7.4.0"
+    acorn-jsx "^5.2.0"
+    eslint-visitor-keys "^1.3.0"
+
+esprima@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+
+esquery@^1.2.0:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57"
+  integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==
+  dependencies:
+    estraverse "^5.1.0"
+
+esrecurse@^4.1.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+  integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+  dependencies:
+    estraverse "^5.2.0"
+
+estraverse@^4.1.1:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
+  integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
+estraverse@^5.1.0, estraverse@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
+  integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
+
+esutils@^2.0.2:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
+  integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
+fast-deep-equal@^3.1.1:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-glob@^3.1.1:
+  version "3.2.4"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3"
+  integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==
+  dependencies:
+    "@nodelib/fs.stat" "^2.0.2"
+    "@nodelib/fs.walk" "^1.2.3"
+    glob-parent "^5.1.0"
+    merge2 "^1.3.0"
+    micromatch "^4.0.2"
+    picomatch "^2.2.1"
+
+fast-json-stable-stringify@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+  integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+fast-levenshtein@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+  integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+
+fastq@^1.6.0:
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
+  integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==
+  dependencies:
+    reusify "^1.0.4"
+
+file-entry-cache@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
+  integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
+  dependencies:
+    flat-cache "^2.0.1"
+
+fill-range@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+  integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+  dependencies:
+    to-regex-range "^5.0.1"
+
+flat-cache@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
+  integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
+  dependencies:
+    flatted "^2.0.0"
+    rimraf "2.6.3"
+    write "1.0.3"
+
+flatted@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
+  integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
+
+fs.realpath@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+
+functional-red-black-tree@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+  integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+
+glob-parent@^5.0.0, glob-parent@^5.1.0:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
+  integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
+  dependencies:
+    is-glob "^4.0.1"
+
+glob@^7.1.3:
+  version "7.1.6"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
+  integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+globals@^12.1.0:
+  version "12.4.0"
+  resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8"
+  integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==
+  dependencies:
+    type-fest "^0.8.1"
+
+globby@^11.0.1:
+  version "11.0.1"
+  resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357"
+  integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==
+  dependencies:
+    array-union "^2.1.0"
+    dir-glob "^3.0.1"
+    fast-glob "^3.1.1"
+    ignore "^5.1.4"
+    merge2 "^1.3.0"
+    slash "^3.0.0"
+
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+
+has-flag@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+  integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+ignore@^4.0.6:
+  version "4.0.6"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
+  integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
+
+ignore@^5.1.4:
+  version "5.1.8"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
+  integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+
+import-fresh@^3.0.0, import-fresh@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
+  integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==
+  dependencies:
+    parent-module "^1.0.0"
+    resolve-from "^4.0.0"
+
+imurmurhash@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+
+inflight@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+  dependencies:
+    once "^1.3.0"
+    wrappy "1"
+
+inherits@2:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+is-extglob@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+
+is-fullwidth-code-point@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+  integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+
+is-glob@^4.0.0, is-glob@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
+  integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
+  dependencies:
+    is-extglob "^2.1.1"
+
+is-number@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+  integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+
+js-tokens@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+  integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+js-yaml@^3.13.1:
+  version "3.14.0"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
+  integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
+  dependencies:
+    argparse "^1.0.7"
+    esprima "^4.0.0"
+
+json-schema-traverse@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+json-stable-stringify-without-jsonify@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+  integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+
+levn@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+  integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+  dependencies:
+    prelude-ls "^1.2.1"
+    type-check "~0.4.0"
+
+lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19:
+  version "4.17.20"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
+  integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
+
+merge2@^1.3.0:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
+  integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+micromatch@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
+  integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
+  dependencies:
+    braces "^3.0.1"
+    picomatch "^2.0.5"
+
+minimatch@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+  dependencies:
+    brace-expansion "^1.1.7"
+
+minimist@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
+mkdirp@^0.5.1:
+  version "0.5.5"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
+  integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
+  dependencies:
+    minimist "^1.2.5"
+
+ms@^2.1.1:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+natural-compare@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+  integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+
+once@^1.3.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+  dependencies:
+    wrappy "1"
+
+optionator@^0.9.1:
+  version "0.9.1"
+  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
+  integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
+  dependencies:
+    deep-is "^0.1.3"
+    fast-levenshtein "^2.0.6"
+    levn "^0.4.1"
+    prelude-ls "^1.2.1"
+    type-check "^0.4.0"
+    word-wrap "^1.2.3"
+
+parent-module@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
+  integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+  dependencies:
+    callsites "^3.0.0"
+
+path-is-absolute@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+
+path-key@^3.1.0:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+  integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-type@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
+  integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+picomatch@^2.0.5, picomatch@^2.2.1:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
+  integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+
+prelude-ls@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+  integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
+progress@^2.0.0:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
+  integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+
+punycode@^2.1.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
+regexpp@^3.0.0, regexpp@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
+  integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+
+resolve-from@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
+  integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+
+reusify@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
+  integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rimraf@2.6.3:
+  version "2.6.3"
+  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
+  integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
+  dependencies:
+    glob "^7.1.3"
+
+run-parallel@^1.1.9:
+  version "1.1.9"
+  resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
+  integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
+
+semver@^7.2.1, semver@^7.3.2:
+  version "7.3.2"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
+  integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
+
+shebang-command@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+  integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+  dependencies:
+    shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+  integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+slash@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
+  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
+slice-ansi@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
+  integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
+  dependencies:
+    ansi-styles "^3.2.0"
+    astral-regex "^1.0.0"
+    is-fullwidth-code-point "^2.0.0"
+
+sprintf-js@~1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+
+string-width@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
+  integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
+  dependencies:
+    emoji-regex "^7.0.1"
+    is-fullwidth-code-point "^2.0.0"
+    strip-ansi "^5.1.0"
+
+strip-ansi@^5.1.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
+  integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
+  dependencies:
+    ansi-regex "^4.1.0"
+
+strip-ansi@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
+  integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+  dependencies:
+    ansi-regex "^5.0.0"
+
+strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+  integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
+supports-color@^5.3.0:
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+  dependencies:
+    has-flag "^3.0.0"
+
+supports-color@^7.1.0:
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+  integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+  dependencies:
+    has-flag "^4.0.0"
+
+table@^5.2.3:
+  version "5.4.6"
+  resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
+  integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
+  dependencies:
+    ajv "^6.10.2"
+    lodash "^4.17.14"
+    slice-ansi "^2.1.0"
+    string-width "^3.0.0"
+
+text-table@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+  integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+
+to-regex-range@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+  integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+  dependencies:
+    is-number "^7.0.0"
+
+tslib@^1.8.1:
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
+  integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
+
+tsutils@^3.17.1:
+  version "3.17.1"
+  resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
+  integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
+  dependencies:
+    tslib "^1.8.1"
+
+type-check@^0.4.0, type-check@~0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+  integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+  dependencies:
+    prelude-ls "^1.2.1"
+
+type-fest@^0.8.1:
+  version "0.8.1"
+  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
+  integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
+
+typescript@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
+  integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==
+
+uri-js@^4.2.2:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602"
+  integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==
+  dependencies:
+    punycode "^2.1.0"
+
+v8-compile-cache@^2.0.3:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
+  integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
+
+which@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+  dependencies:
+    isexe "^2.0.0"
+
+word-wrap@^1.2.3:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
+  integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+  integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+
+write@1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
+  integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
+  dependencies:
+    mkdirp "^0.5.1"