Merge branch 'master' into wip

Change-Id: I5985bd1e7320a6f2a28c4f43b409fb50b00ff733
diff --git a/.gitignore b/.gitignore
index 01589f0..deff5f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+node_modules/
+out/
+/language-fidl-*.vsix
 *.pyc
 __pycache__
 
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..8384213
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,13 @@
+// A launch configuration that launches the extension inside a new window
+{
+    "version": "0.1.0",
+    "configurations": [
+        {
+            "name": "Launch Extension",
+            "type": "extensionHost",
+            "request": "launch",
+            "runtimeExecutable": "${execPath}",
+            "args": ["--extensionDevelopmentPath=${workspaceRoot}" ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/.vscodeignore b/.vscodeignore
new file mode 100644
index 0000000..f16fa55
--- /dev/null
+++ b/.vscodeignore
@@ -0,0 +1 @@
+.vscode/**
diff --git a/vscode-language-fidl/AUTHORS b/vscode-language-fidl/AUTHORS
new file mode 100644
index 0000000..c2a4eac
--- /dev/null
+++ b/vscode-language-fidl/AUTHORS
@@ -0,0 +1,8 @@
+# This is the list of Fuchsia Authors.
+
+# Names should be added to this file as one of
+#     Organization's name
+#     Individual's name <submission email address>
+#     Individual's name <submission email address> <email2> <emailN>
+
+Google Inc.
diff --git a/vscode-language-fidl/CHANGELOG.md b/vscode-language-fidl/CHANGELOG.md
new file mode 100644
index 0000000..3a0506a
--- /dev/null
+++ b/vscode-language-fidl/CHANGELOG.md
@@ -0,0 +1,16 @@
+# v0.0.1
+
+- Initial release with basic syntax highlighting support for FIDL.
+
+# v0.0.3
+
+- Offer a "FIDL: Go To Source" command to jump from generated bindings to FIDL source when working in the Fuchsia tree.
+
+# v0.1.0
+
+- FIDL2 syntax highlighting.
+
+# v0.2.0
+
+- FIDL formatting support
+- Syntax highlighting improvements
diff --git a/vscode-language-fidl/CONTRIBUTING.md b/vscode-language-fidl/CONTRIBUTING.md
new file mode 100644
index 0000000..81e2938
--- /dev/null
+++ b/vscode-language-fidl/CONTRIBUTING.md
@@ -0,0 +1,9 @@
+This repository accepts contributions using Gerrit.
+
+Instructions for using Gerrit:
+
+ * https://gerrit-review.googlesource.com/Documentation/
+
+Before we can land your change, you need to sign the Google CLA:
+
+ * https://cla.developers.google.com/
diff --git a/vscode-language-fidl/LICENSE b/vscode-language-fidl/LICENSE
new file mode 100644
index 0000000..cdfb473
--- /dev/null
+++ b/vscode-language-fidl/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vscode-language-fidl/PATENTS b/vscode-language-fidl/PATENTS
new file mode 100644
index 0000000..2746e78
--- /dev/null
+++ b/vscode-language-fidl/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Fuchsia project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell,
+import, transfer, and otherwise run, modify and propagate the contents
+of this implementation of Fuchsia, where such license applies only to
+those patent claims, both currently owned by Google and acquired in
+the future, licensable by Google that are necessarily infringed by
+this implementation. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute
+or order or agree to the institution of patent litigation or any other
+patent enforcement activity against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that this
+implementation of Fuchsia constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of
+Fuchsia shall terminate as of the date such litigation is filed.
diff --git a/vscode-language-fidl/README.md b/vscode-language-fidl/README.md
new file mode 100644
index 0000000..aa72e09
--- /dev/null
+++ b/vscode-language-fidl/README.md
@@ -0,0 +1,12 @@
+# FIDL Language Support for Visual Studio Code
+
+This extension adds syntax highlighting and formatting for [FIDL][fidl] files.
+
+The syntax highlighting is generated by a script called `generate-syntax.ts`. That can be run by:
+
+```
+npm install
+npm run-script build-syntax
+```
+
+[fidl]: https://fuchsia.dev/fuchsia-src/development/languages/fidl
diff --git a/vscode-language-fidl/images/fuchsia_logo_128x128.png b/vscode-language-fidl/images/fuchsia_logo_128x128.png
new file mode 100644
index 0000000..a5e83d3
--- /dev/null
+++ b/vscode-language-fidl/images/fuchsia_logo_128x128.png
Binary files differ
diff --git a/vscode-language-fidl/language-configuration.json b/vscode-language-fidl/language-configuration.json
new file mode 100644
index 0000000..9afbacf
--- /dev/null
+++ b/vscode-language-fidl/language-configuration.json
@@ -0,0 +1,26 @@
+{
+    "comments": {
+        "lineComment": "//",
+        "blockComment": [ "/*", "*/" ]
+    },
+    // symbols used as brackets
+    "brackets": [
+        ["{", "}"],
+        ["[", "]"],
+        ["(", ")"]
+    ],
+    // symbols that are auto closed when typing
+    "autoClosingPairs": [
+        ["{", "}"],
+        ["[", "]"],
+        ["(", ")"],
+        ["\"", "\""]
+    ],
+    // symbols that that can be used to surround a selection
+    "surroundingPairs": [
+        ["{", "}"],
+        ["[", "]"],
+        ["(", ")"],
+        ["\"", "\""]
+    ]
+}
\ No newline at end of file
diff --git a/vscode-language-fidl/package-lock.json b/vscode-language-fidl/package-lock.json
new file mode 100644
index 0000000..5ff8db8
--- /dev/null
+++ b/vscode-language-fidl/package-lock.json
@@ -0,0 +1,1244 @@
+{
+	"name": "language-fidl",
+	"version": "0.2.0",
+	"lockfileVersion": 1,
+	"requires": true,
+	"dependencies": {
+		"@types/mocha": {
+			"version": "5.2.6",
+			"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz",
+			"integrity": "sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==",
+			"dev": true
+		},
+		"@types/node": {
+			"version": "11.13.4",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.4.tgz",
+			"integrity": "sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ==",
+			"dev": true
+		},
+		"@types/oniguruma": {
+			"version": "7.0.1",
+			"resolved": "https://registry.npmjs.org/@types/oniguruma/-/oniguruma-7.0.1.tgz",
+			"integrity": "sha512-1MxY/ooNO67EQv7Jlv9v/lG1Cll26Uqo4mY00dNPE6TZ62sTJ39WTlEOWbLwn7elRpmqT6hX3fUaBhFeFcQeuA==",
+			"dev": true
+		},
+		"@types/tmp": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.1.0.tgz",
+			"integrity": "sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA==",
+			"dev": true
+		},
+		"@types/vscode": {
+			"version": "1.41.0",
+			"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.41.0.tgz",
+			"integrity": "sha512-7SfeY5u9jgiELwxyLB3z7l6l/GbN9CqpCQGkcRlB7tKRFBxzbz2PoBfGrLxI1vRfUCIq5+hg5vtDHExwq5j3+A==",
+			"dev": true
+		},
+		"ansi-colors": {
+			"version": "3.2.3",
+			"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+			"integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+			"dev": true
+		},
+		"ansi-regex": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+			"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+			"dev": true
+		},
+		"ansi-styles": {
+			"version": "3.2.1",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+			"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+			"dev": true,
+			"requires": {
+				"color-convert": "^1.9.0"
+			}
+		},
+		"arg": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz",
+			"integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==",
+			"dev": true
+		},
+		"argparse": {
+			"version": "1.0.10",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+			"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+			"dev": true,
+			"requires": {
+				"sprintf-js": "~1.0.2"
+			}
+		},
+		"babel-code-frame": {
+			"version": "6.26.0",
+			"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+			"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+			"dev": true,
+			"requires": {
+				"chalk": "^1.1.3",
+				"esutils": "^2.0.2",
+				"js-tokens": "^3.0.2"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "2.2.1",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+					"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+					"dev": true
+				},
+				"chalk": {
+					"version": "1.1.3",
+					"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+					"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+					"dev": true,
+					"requires": {
+						"ansi-styles": "^2.2.1",
+						"escape-string-regexp": "^1.0.2",
+						"has-ansi": "^2.0.0",
+						"strip-ansi": "^3.0.0",
+						"supports-color": "^2.0.0"
+					}
+				},
+				"supports-color": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+					"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+					"dev": true
+				}
+			}
+		},
+		"balanced-match": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+			"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+			"dev": true
+		},
+		"brace-expansion": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
+			"requires": {
+				"balanced-match": "^1.0.0",
+				"concat-map": "0.0.1"
+			}
+		},
+		"browser-stdout": {
+			"version": "1.3.1",
+			"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+			"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+			"dev": true
+		},
+		"buffer-from": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+			"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+			"dev": true
+		},
+		"builtin-modules": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+			"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+			"dev": true
+		},
+		"camelcase": {
+			"version": "5.3.1",
+			"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+			"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+			"dev": true
+		},
+		"chalk": {
+			"version": "2.4.1",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+			"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+			"dev": true,
+			"requires": {
+				"ansi-styles": "^3.2.1",
+				"escape-string-regexp": "^1.0.5",
+				"supports-color": "^5.3.0"
+			}
+		},
+		"cliui": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+			"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+			"dev": true,
+			"requires": {
+				"string-width": "^2.1.1",
+				"strip-ansi": "^4.0.0",
+				"wrap-ansi": "^2.0.0"
+			},
+			"dependencies": {
+				"ansi-regex": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+					"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+					"dev": true
+				},
+				"strip-ansi": {
+					"version": "4.0.0",
+					"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+					"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+					"dev": true,
+					"requires": {
+						"ansi-regex": "^3.0.0"
+					}
+				}
+			}
+		},
+		"code-point-at": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+			"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+			"dev": true
+		},
+		"color-convert": {
+			"version": "1.9.3",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+			"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+			"dev": true,
+			"requires": {
+				"color-name": "1.1.3"
+			}
+		},
+		"color-name": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+			"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+			"dev": true
+		},
+		"commander": {
+			"version": "2.15.1",
+			"resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+			"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+			"dev": true
+		},
+		"concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
+		},
+		"cross-spawn": {
+			"version": "6.0.5",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+			"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+			"dev": true,
+			"requires": {
+				"nice-try": "^1.0.4",
+				"path-key": "^2.0.1",
+				"semver": "^5.5.0",
+				"shebang-command": "^1.2.0",
+				"which": "^1.2.9"
+			}
+		},
+		"decamelize": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+			"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+			"dev": true
+		},
+		"define-properties": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+			"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+			"dev": true,
+			"requires": {
+				"object-keys": "^1.0.12"
+			}
+		},
+		"diff": {
+			"version": "3.5.0",
+			"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+			"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+			"dev": true
+		},
+		"emoji-regex": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+			"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+			"dev": true
+		},
+		"end-of-stream": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+			"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+			"dev": true,
+			"requires": {
+				"once": "^1.4.0"
+			}
+		},
+		"es-abstract": {
+			"version": "1.13.0",
+			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
+			"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
+			"dev": true,
+			"requires": {
+				"es-to-primitive": "^1.2.0",
+				"function-bind": "^1.1.1",
+				"has": "^1.0.3",
+				"is-callable": "^1.1.4",
+				"is-regex": "^1.0.4",
+				"object-keys": "^1.0.12"
+			}
+		},
+		"es-to-primitive": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+			"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+			"dev": true,
+			"requires": {
+				"is-callable": "^1.1.4",
+				"is-date-object": "^1.0.1",
+				"is-symbol": "^1.0.2"
+			}
+		},
+		"escape-string-regexp": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+			"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+			"dev": true
+		},
+		"esprima": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+			"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+			"dev": true
+		},
+		"esutils": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+			"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+			"dev": true
+		},
+		"execa": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+			"dev": true,
+			"requires": {
+				"cross-spawn": "^6.0.0",
+				"get-stream": "^4.0.0",
+				"is-stream": "^1.1.0",
+				"npm-run-path": "^2.0.0",
+				"p-finally": "^1.0.0",
+				"signal-exit": "^3.0.0",
+				"strip-eof": "^1.0.0"
+			}
+		},
+		"find-up": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+			"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+			"dev": true,
+			"requires": {
+				"locate-path": "^3.0.0"
+			}
+		},
+		"flat": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
+			"integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
+			"dev": true,
+			"requires": {
+				"is-buffer": "~2.0.3"
+			}
+		},
+		"fs.realpath": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
+		},
+		"function-bind": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+			"dev": true
+		},
+		"get-caller-file": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+			"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+			"dev": true
+		},
+		"get-stream": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+			"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+			"dev": true,
+			"requires": {
+				"pump": "^3.0.0"
+			}
+		},
+		"glob": {
+			"version": "7.1.2",
+			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+			"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+			"dev": true,
+			"requires": {
+				"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"
+			}
+		},
+		"growl": {
+			"version": "1.10.5",
+			"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+			"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+			"dev": true
+		},
+		"has": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+			"dev": true,
+			"requires": {
+				"function-bind": "^1.1.1"
+			}
+		},
+		"has-ansi": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+			"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+			"dev": true,
+			"requires": {
+				"ansi-regex": "^2.0.0"
+			}
+		},
+		"has-flag": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+			"dev": true
+		},
+		"has-symbols": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+			"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+			"dev": true
+		},
+		"inflight": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
+			"requires": {
+				"once": "^1.3.0",
+				"wrappy": "1"
+			}
+		},
+		"inherits": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+			"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+			"dev": true
+		},
+		"invert-kv": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+			"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+			"dev": true
+		},
+		"is-buffer": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
+			"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
+			"dev": true
+		},
+		"is-callable": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+			"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
+			"dev": true
+		},
+		"is-date-object": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+			"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+			"dev": true
+		},
+		"is-fullwidth-code-point": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+			"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+			"dev": true
+		},
+		"is-regex": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+			"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+			"dev": true,
+			"requires": {
+				"has": "^1.0.1"
+			}
+		},
+		"is-stream": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+			"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+			"dev": true
+		},
+		"is-symbol": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+			"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+			"dev": true,
+			"requires": {
+				"has-symbols": "^1.0.0"
+			}
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"js-tokens": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+			"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+			"dev": true
+		},
+		"js-yaml": {
+			"version": "3.13.1",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+			"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+			"dev": true,
+			"requires": {
+				"argparse": "^1.0.7",
+				"esprima": "^4.0.0"
+			}
+		},
+		"lcid": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+			"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+			"dev": true,
+			"requires": {
+				"invert-kv": "^2.0.0"
+			}
+		},
+		"locate-path": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+			"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+			"dev": true,
+			"requires": {
+				"p-locate": "^3.0.0",
+				"path-exists": "^3.0.0"
+			}
+		},
+		"lodash": {
+			"version": "4.17.15",
+			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+			"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+			"dev": true
+		},
+		"log-symbols": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+			"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+			"dev": true,
+			"requires": {
+				"chalk": "^2.0.1"
+			}
+		},
+		"make-error": {
+			"version": "1.3.5",
+			"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
+			"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
+			"dev": true
+		},
+		"map-age-cleaner": {
+			"version": "0.1.3",
+			"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+			"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+			"dev": true,
+			"requires": {
+				"p-defer": "^1.0.0"
+			}
+		},
+		"mem": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+			"integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+			"dev": true,
+			"requires": {
+				"map-age-cleaner": "^0.1.1",
+				"mimic-fn": "^2.0.0",
+				"p-is-promise": "^2.0.0"
+			}
+		},
+		"mimic-fn": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+			"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+			"dev": true
+		},
+		"minimatch": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+			"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+			"dev": true,
+			"requires": {
+				"brace-expansion": "^1.1.7"
+			}
+		},
+		"minimist": {
+			"version": "0.0.8",
+			"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+			"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+			"dev": true
+		},
+		"mkdirp": {
+			"version": "0.5.1",
+			"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+			"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+			"dev": true,
+			"requires": {
+				"minimist": "0.0.8"
+			}
+		},
+		"mocha": {
+			"version": "6.1.2",
+			"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.2.tgz",
+			"integrity": "sha512-BgD2/RozoSC3uQK5R0isDcxjqaWw2n5HWdk8njYUyZf2NC79ErO5FtYVX52+rfqGoEgMfJf4fuG0IWh2TMzFoA==",
+			"dev": true,
+			"requires": {
+				"ansi-colors": "3.2.3",
+				"browser-stdout": "1.3.1",
+				"debug": "3.2.6",
+				"diff": "3.5.0",
+				"escape-string-regexp": "1.0.5",
+				"find-up": "3.0.0",
+				"glob": "7.1.3",
+				"growl": "1.10.5",
+				"he": "1.2.0",
+				"js-yaml": "3.13.0",
+				"log-symbols": "2.2.0",
+				"minimatch": "3.0.4",
+				"mkdirp": "0.5.1",
+				"ms": "2.1.1",
+				"node-environment-flags": "1.0.4",
+				"object.assign": "4.1.0",
+				"strip-json-comments": "2.0.1",
+				"supports-color": "6.0.0",
+				"which": "1.3.1",
+				"wide-align": "1.1.3",
+				"yargs": "13.2.2",
+				"yargs-parser": "13.0.0",
+				"yargs-unparser": "1.5.0"
+			},
+			"dependencies": {
+				"debug": {
+					"version": "3.2.6",
+					"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+					"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+					"dev": true,
+					"requires": {
+						"ms": "^2.1.1"
+					}
+				},
+				"glob": {
+					"version": "7.1.3",
+					"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+					"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+					"dev": true,
+					"requires": {
+						"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"
+					}
+				},
+				"he": {
+					"version": "1.2.0",
+					"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+					"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+					"dev": true
+				},
+				"js-yaml": {
+					"version": "3.13.0",
+					"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz",
+					"integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==",
+					"dev": true,
+					"requires": {
+						"argparse": "^1.0.7",
+						"esprima": "^4.0.0"
+					}
+				},
+				"ms": {
+					"version": "2.1.1",
+					"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+					"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+					"dev": true
+				},
+				"supports-color": {
+					"version": "6.0.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+					"integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+					"dev": true,
+					"requires": {
+						"has-flag": "^3.0.0"
+					}
+				}
+			}
+		},
+		"nan": {
+			"version": "2.13.2",
+			"resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
+			"integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
+			"dev": true
+		},
+		"nice-try": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+			"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+			"dev": true
+		},
+		"node-environment-flags": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz",
+			"integrity": "sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q==",
+			"dev": true,
+			"requires": {
+				"object.getownpropertydescriptors": "^2.0.3"
+			}
+		},
+		"npm-run-path": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+			"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+			"dev": true,
+			"requires": {
+				"path-key": "^2.0.0"
+			}
+		},
+		"number-is-nan": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+			"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+			"dev": true
+		},
+		"object-keys": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+			"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+			"dev": true
+		},
+		"object.assign": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+			"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+			"dev": true,
+			"requires": {
+				"define-properties": "^1.1.2",
+				"function-bind": "^1.1.1",
+				"has-symbols": "^1.0.0",
+				"object-keys": "^1.0.11"
+			}
+		},
+		"object.getownpropertydescriptors": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+			"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+			"dev": true,
+			"requires": {
+				"define-properties": "^1.1.2",
+				"es-abstract": "^1.5.1"
+			}
+		},
+		"once": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
+			"requires": {
+				"wrappy": "1"
+			}
+		},
+		"oniguruma": {
+			"version": "7.0.2",
+			"resolved": "https://registry.npmjs.org/oniguruma/-/oniguruma-7.0.2.tgz",
+			"integrity": "sha512-zCsdNxTrrB4yVPMxhcIODGv1p4NVBu9WvsWnIGhMpu5djO4MQWXrC7YKjtza+OyoRqqgy27CqYWa1h5e2DDbig==",
+			"dev": true,
+			"requires": {
+				"nan": "^2.10.0"
+			}
+		},
+		"os-locale": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+			"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+			"dev": true,
+			"requires": {
+				"execa": "^1.0.0",
+				"lcid": "^2.0.0",
+				"mem": "^4.0.0"
+			}
+		},
+		"p-defer": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+			"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+			"dev": true
+		},
+		"p-finally": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+			"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+			"dev": true
+		},
+		"p-is-promise": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+			"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+			"dev": true
+		},
+		"p-limit": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+			"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+			"dev": true,
+			"requires": {
+				"p-try": "^2.0.0"
+			}
+		},
+		"p-locate": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+			"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+			"dev": true,
+			"requires": {
+				"p-limit": "^2.0.0"
+			}
+		},
+		"p-try": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+			"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+			"dev": true
+		},
+		"path-exists": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+			"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+			"dev": true
+		},
+		"path-is-absolute": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true
+		},
+		"path-key": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+			"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+			"dev": true
+		},
+		"path-parse": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+			"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+			"dev": true
+		},
+		"prettier": {
+			"version": "1.16.4",
+			"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz",
+			"integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==",
+			"dev": true
+		},
+		"pump": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+			"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+			"dev": true,
+			"requires": {
+				"end-of-stream": "^1.1.0",
+				"once": "^1.3.1"
+			}
+		},
+		"require-directory": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+			"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+			"dev": true
+		},
+		"require-main-filename": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+			"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+			"dev": true
+		},
+		"resolve": {
+			"version": "1.10.0",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+			"integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
+			"dev": true,
+			"requires": {
+				"path-parse": "^1.0.6"
+			}
+		},
+		"semver": {
+			"version": "5.7.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+			"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+			"dev": true
+		},
+		"set-blocking": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+			"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+			"dev": true
+		},
+		"shebang-command": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+			"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+			"dev": true,
+			"requires": {
+				"shebang-regex": "^1.0.0"
+			}
+		},
+		"shebang-regex": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+			"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+			"dev": true
+		},
+		"signal-exit": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+			"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+			"dev": true
+		},
+		"source-map": {
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+			"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+			"dev": true
+		},
+		"source-map-support": {
+			"version": "0.5.9",
+			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz",
+			"integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
+			"dev": true,
+			"requires": {
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			}
+		},
+		"sprintf-js": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+			"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+			"dev": true
+		},
+		"string-width": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+			"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+			"dev": true,
+			"requires": {
+				"is-fullwidth-code-point": "^2.0.0",
+				"strip-ansi": "^4.0.0"
+			},
+			"dependencies": {
+				"ansi-regex": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+					"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+					"dev": true
+				},
+				"strip-ansi": {
+					"version": "4.0.0",
+					"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+					"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+					"dev": true,
+					"requires": {
+						"ansi-regex": "^3.0.0"
+					}
+				}
+			}
+		},
+		"strip-ansi": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+			"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+			"dev": true,
+			"requires": {
+				"ansi-regex": "^2.0.0"
+			}
+		},
+		"strip-eof": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+			"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+			"dev": true
+		},
+		"strip-json-comments": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+			"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+			"dev": true
+		},
+		"supports-color": {
+			"version": "5.4.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+			"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+			"dev": true,
+			"requires": {
+				"has-flag": "^3.0.0"
+			}
+		},
+		"ts-node": {
+			"version": "8.0.3",
+			"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz",
+			"integrity": "sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA==",
+			"dev": true,
+			"requires": {
+				"arg": "^4.1.0",
+				"diff": "^3.1.0",
+				"make-error": "^1.1.1",
+				"source-map-support": "^0.5.6",
+				"yn": "^3.0.0"
+			}
+		},
+		"tslib": {
+			"version": "1.9.3",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+			"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+			"dev": true
+		},
+		"tslint": {
+			"version": "5.15.0",
+			"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.15.0.tgz",
+			"integrity": "sha512-6bIEujKR21/3nyeoX2uBnE8s+tMXCQXhqMmaIPJpHmXJoBJPTLcI7/VHRtUwMhnLVdwLqqY3zmd8Dxqa5CVdJA==",
+			"dev": true,
+			"requires": {
+				"babel-code-frame": "^6.22.0",
+				"builtin-modules": "^1.1.1",
+				"chalk": "^2.3.0",
+				"commander": "^2.12.1",
+				"diff": "^3.2.0",
+				"glob": "^7.1.1",
+				"js-yaml": "^3.13.0",
+				"minimatch": "^3.0.4",
+				"mkdirp": "^0.5.1",
+				"resolve": "^1.3.2",
+				"semver": "^5.3.0",
+				"tslib": "^1.8.0",
+				"tsutils": "^2.29.0"
+			}
+		},
+		"tsutils": {
+			"version": "2.29.0",
+			"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+			"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+			"dev": true,
+			"requires": {
+				"tslib": "^1.8.1"
+			}
+		},
+		"typescript": {
+			"version": "3.4.3",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz",
+			"integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==",
+			"dev": true
+		},
+		"which": {
+			"version": "1.3.1",
+			"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+			"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+			"dev": true,
+			"requires": {
+				"isexe": "^2.0.0"
+			}
+		},
+		"which-module": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+			"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+			"dev": true
+		},
+		"wide-align": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+			"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+			"dev": true,
+			"requires": {
+				"string-width": "^1.0.2 || 2"
+			}
+		},
+		"wrap-ansi": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+			"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+			"dev": true,
+			"requires": {
+				"string-width": "^1.0.1",
+				"strip-ansi": "^3.0.1"
+			},
+			"dependencies": {
+				"is-fullwidth-code-point": {
+					"version": "1.0.0",
+					"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+					"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+					"dev": true,
+					"requires": {
+						"number-is-nan": "^1.0.0"
+					}
+				},
+				"string-width": {
+					"version": "1.0.2",
+					"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+					"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+					"dev": true,
+					"requires": {
+						"code-point-at": "^1.0.0",
+						"is-fullwidth-code-point": "^1.0.0",
+						"strip-ansi": "^3.0.0"
+					}
+				}
+			}
+		},
+		"wrappy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
+		},
+		"y18n": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+			"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+			"dev": true
+		},
+		"yargs": {
+			"version": "13.2.2",
+			"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
+			"integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
+			"dev": true,
+			"requires": {
+				"cliui": "^4.0.0",
+				"find-up": "^3.0.0",
+				"get-caller-file": "^2.0.1",
+				"os-locale": "^3.1.0",
+				"require-directory": "^2.1.1",
+				"require-main-filename": "^2.0.0",
+				"set-blocking": "^2.0.0",
+				"string-width": "^3.0.0",
+				"which-module": "^2.0.0",
+				"y18n": "^4.0.0",
+				"yargs-parser": "^13.0.0"
+			},
+			"dependencies": {
+				"ansi-regex": {
+					"version": "4.1.0",
+					"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+					"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+					"dev": true
+				},
+				"string-width": {
+					"version": "3.1.0",
+					"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+					"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+					"dev": true,
+					"requires": {
+						"emoji-regex": "^7.0.1",
+						"is-fullwidth-code-point": "^2.0.0",
+						"strip-ansi": "^5.1.0"
+					}
+				},
+				"strip-ansi": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+					"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+					"dev": true,
+					"requires": {
+						"ansi-regex": "^4.1.0"
+					}
+				}
+			}
+		},
+		"yargs-parser": {
+			"version": "13.0.0",
+			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
+			"integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
+			"dev": true,
+			"requires": {
+				"camelcase": "^5.0.0",
+				"decamelize": "^1.2.0"
+			}
+		},
+		"yargs-unparser": {
+			"version": "1.5.0",
+			"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz",
+			"integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==",
+			"dev": true,
+			"requires": {
+				"flat": "^4.1.0",
+				"lodash": "^4.17.11",
+				"yargs": "^12.0.5"
+			},
+			"dependencies": {
+				"get-caller-file": {
+					"version": "1.0.3",
+					"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+					"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+					"dev": true
+				},
+				"require-main-filename": {
+					"version": "1.0.1",
+					"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+					"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+					"dev": true
+				},
+				"yargs": {
+					"version": "12.0.5",
+					"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+					"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+					"dev": true,
+					"requires": {
+						"cliui": "^4.0.0",
+						"decamelize": "^1.2.0",
+						"find-up": "^3.0.0",
+						"get-caller-file": "^1.0.1",
+						"os-locale": "^3.0.0",
+						"require-directory": "^2.1.1",
+						"require-main-filename": "^1.0.1",
+						"set-blocking": "^2.0.0",
+						"string-width": "^2.0.0",
+						"which-module": "^2.0.0",
+						"y18n": "^3.2.1 || ^4.0.0",
+						"yargs-parser": "^11.1.1"
+					}
+				},
+				"yargs-parser": {
+					"version": "11.1.1",
+					"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
+					"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
+					"dev": true,
+					"requires": {
+						"camelcase": "^5.0.0",
+						"decamelize": "^1.2.0"
+					}
+				}
+			}
+		},
+		"yn": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz",
+			"integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==",
+			"dev": true
+		}
+	}
+}
diff --git a/vscode-language-fidl/package.json b/vscode-language-fidl/package.json
new file mode 100644
index 0000000..6b6a8c3
--- /dev/null
+++ b/vscode-language-fidl/package.json
@@ -0,0 +1,89 @@
+{
+	"name": "language-fidl",
+	"displayName": "FIDL Language Support",
+	"description": "Support for FIDL files",
+	"license": "SEE LICENSE IN LICENSE",
+	"version": "0.2.0",
+	"publisher": "fuchsia-authors",
+	"engines": {
+		"vscode": "^1.41.0"
+	},
+	"categories": [
+		"Programming Languages"
+	],
+	"main": "./out/extension.js",
+	"contributes": {
+		"languages": [
+			{
+				"id": "fidl",
+				"aliases": [
+					"FIDL",
+					"fidl"
+				],
+				"extensions": [
+					".fidl"
+				],
+				"configuration": "./language-configuration.json"
+			}
+		],
+		"grammars": [
+			{
+				"language": "fidl",
+				"scopeName": "source.fidl",
+				"path": "./syntaxes/fidl.tmLanguage.json"
+			}
+		],
+		"configuration": [
+			{
+				"title": "FIDL",
+				"properties": {
+					"fidl.format.enable": {
+						"type": "boolean",
+						"default": true,
+						"description": "Enable/disable FIDL formatter."
+					},
+					"fidl.formatTool": {
+						"type": "string",
+						"description": "Specifies the absolute path to the fidl-format tool."
+					}
+				}
+			}
+		]
+	},
+	"homepage": "https://fuchsia.googlesource.com/vscode-language-fidl",
+	"repository": {
+		"type": "git",
+		"url": "https://fuchsia.googlesource.com/vscode-language-fidl"
+	},
+	"icon": "images/fuchsia_logo_128x128.png",
+	"activationEvents": [
+		"onLanguage:fidl"
+	],
+	"scripts": {
+		"vscode:prepublish": "npm run compile",
+		"compile": "tsc -p ./",
+		"watch": "tsc -watch -p ./",
+		"test": "mocha --require ts-node/register ./test/*.test.ts",
+		"build-syntax": "ts-node ./tools/generate-syntax.ts > ./syntaxes/fidl.tmLanguage.json",
+		"presubmit": "prettier --write tools/generate-syntax.ts"
+	},
+	"devDependencies": {
+		"@types/mocha": "^5.2.6",
+		"@types/node": "^11.13.4",
+		"@types/oniguruma": "^7.0.1",
+		"@types/tmp": "^0.1.0",
+		"@types/vscode": "^1.41.0",
+		"mocha": "^6.1.2",
+		"oniguruma": "^7.0.2",
+		"prettier": "*",
+		"ts-node": "^8.0.3",
+		"tslint": "*",
+		"typescript": "^3.4.3"
+	},
+	"__metadata": {
+		"id": "0eda5a5d-beca-458d-9855-7994a1f8d22c",
+		"publisherDisplayName": "The Fuchsia Authors",
+		"publisherId": "6b4341fb-1e2c-4a5e-9c1f-1d34016009f5"
+	},
+	"dependencies": {}
+}
diff --git a/vscode-language-fidl/src/extension.ts b/vscode-language-fidl/src/extension.ts
new file mode 100644
index 0000000..e3cc0a0
--- /dev/null
+++ b/vscode-language-fidl/src/extension.ts
@@ -0,0 +1,12 @@
+'use strict';
+
+import * as vscode from 'vscode';
+import FidlFormattingEditProvider from './formatter';
+
+export function activate(_context: vscode.ExtensionContext) {
+    if (vscode.workspace.getConfiguration('fidl.format').get('enable')) {
+        vscode.languages.registerDocumentFormattingEditProvider(
+            { language: 'fidl' },
+            new FidlFormattingEditProvider());
+    }
+}
\ No newline at end of file
diff --git a/vscode-language-fidl/src/formatter.ts b/vscode-language-fidl/src/formatter.ts
new file mode 100644
index 0000000..1f4e421
--- /dev/null
+++ b/vscode-language-fidl/src/formatter.ts
@@ -0,0 +1,124 @@
+'use strict';
+
+import * as vscode from 'vscode';
+import { spawnSync } from 'child_process';
+import {
+    guessFidlFormatToolPath,
+    getFidlFormatToolPathFromPreferences,
+    FormatToolError,
+    FormatToolErrorCause
+} from './tool_finder';
+
+const notDefined = "FIDL format tool not specified. Please set the path to fidl-format in Settings.";
+const notExecutable = "FIDL format tool doesn't exist or can't be run. Please verify the path to fidl-format in Settings.";
+const formatterError = "Error formatting FIDL";
+
+const editSettingLabel = "Edit setting";
+
+async function showError(e: FormatToolError) {
+    let message;
+    let showEdit = false;
+    switch (e.cause) {
+        case FormatToolErrorCause.ToolNotSpecified:
+            message = notDefined;
+            showEdit = true;
+            break;
+        case FormatToolErrorCause.ToolNotExecutable:
+            message = notExecutable;
+            showEdit = true;
+            break;
+        case FormatToolErrorCause.FormatterError:
+            message = `${formatterError}: ${e.formatterMessage}`
+            break;
+        default:
+            // This shouldn't happen. Since we don't know what kind of error we
+            // have, we rethrow so this error appears in the console during
+            // development.
+            throw e;
+    }
+    let items: string[] = [];
+    if (showEdit) {
+        items.push(editSettingLabel);
+    }
+    let item = await vscode.window.showErrorMessage(message, ...items);
+    switch (item) {
+        case undefined:
+        case null:
+            // The user did not choose to edit setting.
+            return;
+        case editSettingLabel:
+            vscode.commands.executeCommand('workbench.action.openSettings', 'fidl.formatTool');
+    }
+}
+
+/**
+ * A formatting edit provider that runs fidl-format over the code in the
+ * current FIDL file.
+ *
+ * Objects of this class will check for the presence of the fidl-format path in
+ * settings when instantiated and on every formatting request. If the path is
+ * left empty (the default) and the path to fidl-format isn't specified,
+ * objects of this class will show a notification to the user each time they
+ * try to format a FIDL file.
+ */
+export default class FidlFormattingEditProvider implements vscode.DocumentFormattingEditProvider {
+    /**
+     * The cached path to the autodetected fidl-format tool. This is set once
+     * for the session if the user hasn't explicitly set a path in preferences.
+     */
+    cachedGuessedFidlFormatToolPath: string | null = null;
+    constructor() {
+        if (getFidlFormatToolPathFromPreferences()) {
+            // The fidl-format tool path is specified in preferences, so no
+            // caching is needed.
+            return;
+        }
+
+        guessFidlFormatToolPath().then(
+            (p) => this.cachedGuessedFidlFormatToolPath = p,
+            (e: FormatToolError) => showError(e));
+
+    }
+
+    async provideDocumentFormattingEdits(document: vscode.TextDocument): Promise<vscode.TextEdit[]> {
+        const fromPrefs = getFidlFormatToolPathFromPreferences();
+        let formatTool: string;
+
+        if (fromPrefs) {
+            // If the user has set a fidl-format path, that takes precedence.
+            formatTool = fromPrefs;
+            // Remove any cached (i.e. autodetected) tool.
+            this.cachedGuessedFidlFormatToolPath = null;
+        } else if (this.cachedGuessedFidlFormatToolPath) {
+            // If there is a cached fidl-format path, use that for this
+            // session.
+            formatTool = this.cachedGuessedFidlFormatToolPath;
+        } else {
+            // Find the fidl-format tool.
+            try {
+                formatTool = await guessFidlFormatToolPath();
+            } catch (e) {
+                showError(e);
+                return [];
+            }
+        }
+
+        // FIDL files are assumed to always be UTF-8.
+        const format = spawnSync(formatTool, [], { encoding: 'utf8', input: document.getText() });
+        if (format.status) {
+            // fidl-format exited with an error.
+            const e = new FormatToolError(FormatToolErrorCause.FormatterError);
+            e.formatterMessage = format.stderr;
+            showError(e);
+            // Return no edits. i.e. no changes to document.
+            return [];
+        }
+
+        const fileStart = new vscode.Position(0, 0);
+        const fileEnd = document.lineAt(document.lineCount - 1).range.end;
+
+        // Casting: because spawnSync was called with an encoding,
+        // format.stdout is already a string.
+        return [new vscode.TextEdit(new vscode.Range(fileStart, fileEnd), format.stdout as string)];
+    }
+}
diff --git a/vscode-language-fidl/src/tool_finder.ts b/vscode-language-fidl/src/tool_finder.ts
new file mode 100644
index 0000000..bb1ec03
--- /dev/null
+++ b/vscode-language-fidl/src/tool_finder.ts
@@ -0,0 +1,210 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as fs from 'fs';
+
+export enum FormatToolErrorCause {
+    ToolNotSpecified, ToolNotExecutable, FormatterError
+}
+
+export class FormatToolError extends Error {
+    cause: FormatToolErrorCause;
+    formatterMessage: string | undefined;
+
+    constructor(cause: FormatToolErrorCause) {
+        super();
+        this.cause = cause;
+    }
+}
+
+/**
+ * Finds the Zircon build output directory given a Fuchsia repository root.
+ *
+ * This function derives the correct filesystem path, but it doesn't check to
+ * ensure that the path exists. Callers are responsible for ensuring that the
+ * resulting path exists and has the expected contents.
+ *
+ * @param fuchsiaRoot the filesystem path to the root of the Fuchsia
+ * repository.
+ * @returns the filesystem path to the root of the Zircon build output
+ * directory.
+ */
+function deriveZirconOutPath(fuchsiaRoot: string): string | null {
+    const buildOutputPointer = path.join(fuchsiaRoot, '.fx-build-dir');
+    try {
+        const outputRoot = fs.readFileSync(buildOutputPointer, { encoding: 'utf8' }).trim();
+        return path.join(fuchsiaRoot, outputRoot + '.zircon');
+    } catch (err) {
+        // TODO: proper error handling
+        return null;
+    }
+}
+
+/**
+ * Finds the fidl-format tool given a Zircon output repository root.
+ *
+ * This function derives the correct filesystem path, but it doesn't check to
+ * ensure that the path exists. Callers are responsible for ensuring that the
+ * resulting path exists and has the expected contents.
+ *
+ * @param zirconRoot the filesystem path to the root of the Fuchsia
+ * repository.
+ * @returns the filesystem path to the fidl-format tool.
+ */
+function deriveFidlFormatPath(zirconRoot: string): string | null {
+    return path.join(zirconRoot, 'tools', 'fidl-format');
+}
+
+/**
+ * Attempts to find the fidl-format tool in the current directory, returning
+ * the path to the tool if it's present and executable by the current user.
+ *
+ * @param folderPath The path to the folder to search in.
+ * @returns The path to the fidl-format tool in folderPath or null if the tool can't be found or isn't executable.
+ */
+function findFidlFormatInFolder(folderPath: string): string | null {
+    const zirconRoot = deriveZirconOutPath(folderPath);
+    if (!zirconRoot) {
+        return null;
+    }
+
+    const toolPath = deriveFidlFormatPath(zirconRoot);
+    if (!toolPath) {
+        return null;
+    }
+
+    try {
+        fs.accessSync(toolPath, fs.constants.X_OK);
+    } catch (err) {
+        return null;
+    }
+
+    return toolPath;
+}
+
+/**
+ * Attempts to find the fidl-format tool by asking VS Code to find the root of
+ * the Fuchsia repository.
+ *
+ * @returns the absolute path to fidl-format or null if it couldn't be found.
+ */
+async function guessFidlFormatPathFromWorkspace(): Promise<string | null> {
+    const uris = await vscode.workspace.findFiles('.fx-build-dir', null, 1);
+    if (uris.length < 1) {
+        return null;
+    }
+
+    for (const uri of uris) {
+        if (uri.scheme !== 'file') {
+            // If the repository isn't local, fidl-format won't be runnable
+            // even if present.
+            continue;
+        }
+
+        const basePath = path.dirname(uri.fsPath);
+        const toolPath = findFidlFormatInFolder(basePath);
+        if (toolPath === null) {
+            continue;
+        }
+
+        return toolPath;
+    }
+
+    return null;
+}
+
+/**
+ * Attempts to find the fidl-format tool by traversing the directory tree up
+ * from the root of each workspace folder toward the root of the filesystem.
+ *
+ * @returns the absolute path to fidl-format or null if it couldn't be found.
+ */
+function guessFidlFormatPathFromAncestors(): string | null {
+    const folders = vscode.workspace.workspaceFolders;
+    if (!folders) {
+        return null;
+    }
+
+    for (const folder of folders) {
+        if (folder.uri.scheme !== 'file') {
+            // If the repository isn't local, fidl-format won't be runnable
+            // even if present.
+            continue;
+        }
+
+        let folderPath;
+
+        // Traverse through parent repositories until the direct child of the
+        // root directory.
+        for (folderPath = folder.uri.fsPath;
+            path.dirname(folderPath) !== folderPath;
+            folderPath = path.dirname(folderPath)) {
+
+            const toolPath = findFidlFormatInFolder(folderPath);
+            if (toolPath) {
+                return toolPath;
+            }
+        }
+
+        // Also check the root directory.
+        const toolPath = findFidlFormatInFolder(folderPath);
+        if (toolPath) {
+            return toolPath;
+        }
+    }
+
+    return null;
+}
+
+/**
+ * Gets the fidl-format tool path as configured in VS Code preferences.
+ *
+ * @returns the path to fidl-format as configured by the user, or `null` if the
+ * tool isn't set.
+ */
+export function getFidlFormatToolPathFromPreferences(): string | null {
+    let formatTool: string | undefined | null
+        = vscode.workspace.getConfiguration('fidl').get('formatTool');
+
+    if (formatTool) {
+        try {
+            fs.accessSync(formatTool, fs.constants.X_OK);
+        } catch (err) {
+            throw new FormatToolError(FormatToolErrorCause.ToolNotExecutable);
+        }
+        return formatTool;
+    } else {
+        return null;
+    }
+}
+
+/**
+ * Checks whether the path to fidl-format has been filled out. If the default
+ * value of an empty string is found, an error is shown as a notification.
+ */
+export async function guessFidlFormatToolPath(): Promise<string> {
+    let formatTool: string | undefined | null
+        = getFidlFormatToolPathFromPreferences();
+
+    // Guessing by ancestor is faster than searching a large workspace for the
+    // Fuchsia root, so we try this approach first.
+    if (!formatTool) {
+        formatTool = guessFidlFormatPathFromAncestors();
+    }
+
+    if (!formatTool) {
+        formatTool = await guessFidlFormatPathFromWorkspace();
+    }
+
+    if (!formatTool) {
+        throw new FormatToolError(FormatToolErrorCause.ToolNotSpecified);
+    }
+
+    try {
+        // Throws if tool is not present or not executable.
+        fs.accessSync(formatTool, fs.constants.X_OK);
+    } catch (err) {
+        throw new FormatToolError(FormatToolErrorCause.ToolNotExecutable);
+    }
+
+    return formatTool;
+}
diff --git a/vscode-language-fidl/syntaxes/fidl.tmLanguage.json b/vscode-language-fidl/syntaxes/fidl.tmLanguage.json
new file mode 100644
index 0000000..3810fd1
--- /dev/null
+++ b/vscode-language-fidl/syntaxes/fidl.tmLanguage.json
@@ -0,0 +1,959 @@
+{
+    "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+    "name": "FIDL",
+    "scopeName": "source.fidl",
+    "patterns": [
+        {
+            "include": "#comments"
+        },
+        {
+            "name": "meta.library.fidl",
+            "match": "\\b(library)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(;)",
+            "captures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "punctuation.terminator"
+                }
+            }
+        },
+        {
+            "name": "meta.library.fidl",
+            "match": "\\b(using)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(;)",
+            "captures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "punctuation.terminator"
+                }
+            }
+        },
+        {
+            "name": "meta.library.fidl",
+            "match": "\\b(using)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*\\b(as)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(;)",
+            "captures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "keyword.control"
+                },
+                "4": {
+                    "name": "entity.name.type"
+                },
+                "5": {
+                    "name": "punctuation.terminator"
+                }
+            }
+        },
+        {
+            "name": "meta.library.fidl",
+            "match": "\\b(using)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(=)\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))\\s*(;)",
+            "captures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "punctuation.separator"
+                },
+                "4": {
+                    "name": "entity.name.type"
+                },
+                "5": {
+                    "name": "storage.type.basic"
+                },
+                "6": {
+                    "name": "storage.type.basic"
+                },
+                "7": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "8": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "9": {
+                    "name": "punctuation.nullable"
+                },
+                "10": {
+                    "name": "storage.type.basic"
+                },
+                "11": {
+                    "name": "storage.type.basic"
+                },
+                "12": {
+                    "name": "storage.type.basic"
+                },
+                "13": {
+                    "name": "storage.type.basic"
+                },
+                "14": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "15": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "16": {
+                    "name": "punctuation.separator"
+                },
+                "17": {
+                    "name": "constant.numeric"
+                },
+                "18": {
+                    "name": "punctuation.nullable"
+                },
+                "19": {
+                    "name": "punctuation.terminator"
+                }
+            }
+        },
+        {
+            "name": "meta.const.fidl",
+            "match": "\\b(const)\\b\\s*(?:@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*|(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b))\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(=)\\s*(?:(?:(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|(\\b(?:true|false)\\b)|(\"(?:[^\\\"]|\\.)*\"))|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)|(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))\\s*(;)",
+            "captures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "storage.type.basic"
+                },
+                "3": {
+                    "name": "variable.constant"
+                },
+                "4": {
+                    "name": "punctuation.separator"
+                },
+                "5": {
+                    "name": "constant.numeric"
+                },
+                "6": {
+                    "name": "constant.language"
+                },
+                "7": {
+                    "name": "string.quoted.double"
+                },
+                "8": {
+                    "name": "constant.numeric"
+                },
+                "9": {
+                    "name": "punctuation.terminator"
+                }
+            }
+        },
+        {
+            "name": "meta.protocol-block.fidl",
+            "begin": "\\b(protocol)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "name": "meta.attrbutes.fidl",
+                    "begin": "\\[",
+                    "beginCaptures": {},
+                    "end": "\\]",
+                    "endCaptures": {},
+                    "patterns": [
+                        {
+                            "match": "(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(?:=\\s*(\"(?:[^\\\"]|\\.)*\"))?",
+                            "captures": {
+                                "1": {
+                                    "name": "support.variable"
+                                },
+                                "2": {
+                                    "name": "string.quoted.double"
+                                }
+                            }
+                        }
+                    ]
+                },
+                {
+                    "match": "\\b(compose)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)",
+                    "captures": {
+                        "1": {
+                            "name": "keyword.control"
+                        },
+                        "2": {
+                            "name": "entity.name.type"
+                        }
+                    }
+                },
+                {
+                    "include": "#method"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        },
+        {
+            "name": "meta.enum-block.fidl",
+            "begin": "\\b(enum)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(?:(:)\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?)))?\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "punctuation.separator"
+                },
+                "4": {
+                    "name": "entity.name.type"
+                },
+                "5": {
+                    "name": "storage.type.basic"
+                },
+                "6": {
+                    "name": "storage.type.basic"
+                },
+                "7": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "8": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "9": {
+                    "name": "punctuation.nullable"
+                },
+                "10": {
+                    "name": "storage.type.basic"
+                },
+                "11": {
+                    "name": "storage.type.basic"
+                },
+                "12": {
+                    "name": "storage.type.basic"
+                },
+                "13": {
+                    "name": "storage.type.basic"
+                },
+                "14": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "15": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "16": {
+                    "name": "punctuation.separator"
+                },
+                "17": {
+                    "name": "constant.numeric"
+                },
+                "18": {
+                    "name": "punctuation.nullable"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "include": "#enum-member"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        },
+        {
+            "name": "meta.bits-block.fidl",
+            "begin": "\\b(bits)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(?:(:)\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?)))?\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                },
+                "3": {
+                    "name": "punctuation.separator"
+                },
+                "4": {
+                    "name": "entity.name.type"
+                },
+                "5": {
+                    "name": "storage.type.basic"
+                },
+                "6": {
+                    "name": "storage.type.basic"
+                },
+                "7": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "8": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "9": {
+                    "name": "punctuation.nullable"
+                },
+                "10": {
+                    "name": "storage.type.basic"
+                },
+                "11": {
+                    "name": "storage.type.basic"
+                },
+                "12": {
+                    "name": "storage.type.basic"
+                },
+                "13": {
+                    "name": "storage.type.basic"
+                },
+                "14": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "15": {
+                    "name": "punctuation.bracket.angle"
+                },
+                "16": {
+                    "name": "punctuation.separator"
+                },
+                "17": {
+                    "name": "constant.numeric"
+                },
+                "18": {
+                    "name": "punctuation.nullable"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "include": "#enum-member"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        },
+        {
+            "name": "meta.struct-block.fidl",
+            "begin": "\\b(struct)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "include": "#struct-member"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        },
+        {
+            "name": "meta.table-block.fidl",
+            "begin": "\\b(table)\\b\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "entity.name.type"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "include": "#table-member"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        },
+        {
+            "name": "meta.union-block.fidl",
+            "begin": "(?:\\b(union)\\b|\\b(xunion)\\b)\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*{",
+            "beginCaptures": {
+                "1": {
+                    "name": "keyword.control"
+                },
+                "2": {
+                    "name": "keyword.control"
+                },
+                "3": {
+                    "name": "entity.name.type"
+                }
+            },
+            "end": "}",
+            "endCaptures": {},
+            "patterns": [
+                {
+                    "include": "#union-member"
+                },
+                {
+                    "include": "#comments"
+                }
+            ]
+        }
+    ],
+    "repository": {
+        "comments": {
+            "patterns": [
+                {
+                    "name": "invalid.illegal.stray-comment-end.fidl",
+                    "match": "\\*/.*\\n",
+                    "captures": {}
+                },
+                {
+                    "name": "comment.line.documentation.fidl",
+                    "match": "///.*\\n",
+                    "captures": {}
+                },
+                {
+                    "name": "comment.line.double-slash.fidl",
+                    "match": "//.*\\n",
+                    "captures": {}
+                }
+            ]
+        },
+        "method": {
+            "patterns": [
+                {
+                    "name": "meta.method.fidl",
+                    "begin": "(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)",
+                    "beginCaptures": {
+                        "1": {
+                            "name": "entity.name.function"
+                        }
+                    },
+                    "end": "(?:\\b(error)\\b\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?)))?\\s*(;)",
+                    "endCaptures": {
+                        "1": {
+                            "name": "keyword.control"
+                        },
+                        "2": {
+                            "name": "entity.name.type"
+                        },
+                        "3": {
+                            "name": "storage.type.basic"
+                        },
+                        "4": {
+                            "name": "storage.type.basic"
+                        },
+                        "5": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "6": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "7": {
+                            "name": "punctuation.nullable"
+                        },
+                        "8": {
+                            "name": "storage.type.basic"
+                        },
+                        "9": {
+                            "name": "storage.type.basic"
+                        },
+                        "10": {
+                            "name": "storage.type.basic"
+                        },
+                        "11": {
+                            "name": "storage.type.basic"
+                        },
+                        "12": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "13": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "14": {
+                            "name": "punctuation.separator"
+                        },
+                        "15": {
+                            "name": "constant.numeric"
+                        },
+                        "16": {
+                            "name": "punctuation.nullable"
+                        },
+                        "17": {
+                            "name": "punctuation.terminator"
+                        }
+                    },
+                    "patterns": [
+                        {
+                            "include": "#method-arguments"
+                        },
+                        {
+                            "match": "(->)",
+                            "captures": {
+                                "1": {
+                                    "name": "punctuation.separator"
+                                }
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "meta.method.event.fidl",
+                    "begin": "(->)\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*[(]",
+                    "beginCaptures": {
+                        "1": {
+                            "name": "punctuation.separator"
+                        },
+                        "2": {
+                            "name": "entity.name.function"
+                        }
+                    },
+                    "end": "[)]\\s*(;)",
+                    "endCaptures": {
+                        "1": {
+                            "name": "punctuation.terminator"
+                        }
+                    },
+                    "patterns": [
+                        {
+                            "include": "#method-argument"
+                        }
+                    ]
+                }
+            ]
+        },
+        "method-arguments": {
+            "patterns": [
+                {
+                    "name": "meta.method.arguments.fidl",
+                    "begin": "\\(",
+                    "beginCaptures": {},
+                    "end": "\\)",
+                    "endCaptures": {},
+                    "patterns": [
+                        {
+                            "include": "#method-argument"
+                        }
+                    ]
+                }
+            ]
+        },
+        "method-argument": {
+            "patterns": [
+                {
+                    "name": "meta.method.argument.fidl",
+                    "begin": "(?=[a-zA-Z_@])",
+                    "beginCaptures": {},
+                    "end": "(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(?:(?:,)|(?=\\)))",
+                    "endCaptures": {
+                        "1": {
+                            "name": "variable.name"
+                        }
+                    },
+                    "patterns": [
+                        {
+                            "match": "(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))",
+                            "captures": {
+                                "1": {
+                                    "name": "entity.name.type"
+                                },
+                                "2": {
+                                    "name": "storage.type.basic"
+                                },
+                                "3": {
+                                    "name": "storage.type.basic"
+                                },
+                                "4": {
+                                    "name": "punctuation.bracket.angle"
+                                },
+                                "5": {
+                                    "name": "punctuation.bracket.angle"
+                                },
+                                "6": {
+                                    "name": "punctuation.nullable"
+                                },
+                                "7": {
+                                    "name": "storage.type.basic"
+                                },
+                                "8": {
+                                    "name": "storage.type.basic"
+                                },
+                                "9": {
+                                    "name": "storage.type.basic"
+                                },
+                                "10": {
+                                    "name": "storage.type.basic"
+                                },
+                                "11": {
+                                    "name": "punctuation.bracket.angle"
+                                },
+                                "12": {
+                                    "name": "punctuation.bracket.angle"
+                                },
+                                "13": {
+                                    "name": "punctuation.separator"
+                                },
+                                "14": {
+                                    "name": "constant.numeric"
+                                },
+                                "15": {
+                                    "name": "punctuation.nullable"
+                                }
+                            }
+                        },
+                        {
+                            "match": "(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)",
+                            "captures": {
+                                "1": {
+                                    "name": "variable.parameter"
+                                }
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        "enum-member": {
+            "patterns": [
+                {
+                    "name": "meta.enum.member.fidl",
+                    "match": "(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(=)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "variable"
+                        },
+                        "2": {
+                            "name": "punctuation.separator"
+                        },
+                        "3": {
+                            "name": "constant.numeric"
+                        },
+                        "4": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                }
+            ]
+        },
+        "struct-member": {
+            "patterns": [
+                {
+                    "name": "meta.struct.member.fidl",
+                    "match": "(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "entity.name.type"
+                        },
+                        "2": {
+                            "name": "storage.type.basic"
+                        },
+                        "3": {
+                            "name": "storage.type.basic"
+                        },
+                        "4": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "5": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "6": {
+                            "name": "punctuation.nullable"
+                        },
+                        "7": {
+                            "name": "storage.type.basic"
+                        },
+                        "8": {
+                            "name": "storage.type.basic"
+                        },
+                        "9": {
+                            "name": "storage.type.basic"
+                        },
+                        "10": {
+                            "name": "storage.type.basic"
+                        },
+                        "11": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "12": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "13": {
+                            "name": "punctuation.separator"
+                        },
+                        "14": {
+                            "name": "constant.numeric"
+                        },
+                        "15": {
+                            "name": "punctuation.nullable"
+                        },
+                        "16": {
+                            "name": "variable"
+                        },
+                        "17": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                },
+                {
+                    "name": "meta.struct.member.fidl",
+                    "match": "(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(=)\\s*(?:(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|(\\b(?:true|false)\\b)|(\"(?:[^\\\"]|\\.)*\"))|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "entity.name.type"
+                        },
+                        "2": {
+                            "name": "storage.type.basic"
+                        },
+                        "3": {
+                            "name": "storage.type.basic"
+                        },
+                        "4": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "5": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "6": {
+                            "name": "punctuation.nullable"
+                        },
+                        "7": {
+                            "name": "storage.type.basic"
+                        },
+                        "8": {
+                            "name": "storage.type.basic"
+                        },
+                        "9": {
+                            "name": "storage.type.basic"
+                        },
+                        "10": {
+                            "name": "storage.type.basic"
+                        },
+                        "11": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "12": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "13": {
+                            "name": "punctuation.separator"
+                        },
+                        "14": {
+                            "name": "constant.numeric"
+                        },
+                        "15": {
+                            "name": "punctuation.nullable"
+                        },
+                        "16": {
+                            "name": "variable"
+                        },
+                        "17": {
+                            "name": "punctuation.separator"
+                        },
+                        "18": {
+                            "name": "constant.numeric"
+                        },
+                        "19": {
+                            "name": "constant.language"
+                        },
+                        "20": {
+                            "name": "string.quoted.double"
+                        },
+                        "21": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                }
+            ]
+        },
+        "table-member": {
+            "patterns": [
+                {
+                    "name": "meta.table.member.fidl",
+                    "match": "(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)\\s*(:)\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "constant.numeric"
+                        },
+                        "2": {
+                            "name": "punctuation.separator"
+                        },
+                        "3": {
+                            "name": "entity.name.type"
+                        },
+                        "4": {
+                            "name": "storage.type.basic"
+                        },
+                        "5": {
+                            "name": "storage.type.basic"
+                        },
+                        "6": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "7": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "8": {
+                            "name": "punctuation.nullable"
+                        },
+                        "9": {
+                            "name": "storage.type.basic"
+                        },
+                        "10": {
+                            "name": "storage.type.basic"
+                        },
+                        "11": {
+                            "name": "storage.type.basic"
+                        },
+                        "12": {
+                            "name": "storage.type.basic"
+                        },
+                        "13": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "14": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "15": {
+                            "name": "punctuation.separator"
+                        },
+                        "16": {
+                            "name": "constant.numeric"
+                        },
+                        "17": {
+                            "name": "punctuation.nullable"
+                        },
+                        "18": {
+                            "name": "variable"
+                        },
+                        "19": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                },
+                {
+                    "name": "meta.table.reserved.fidl",
+                    "match": "(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)\\s*(:)\\s*\\b(reserved)\\b\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "constant.numeric"
+                        },
+                        "2": {
+                            "name": "punctuation.separator"
+                        },
+                        "3": {
+                            "name": "keyword.control"
+                        },
+                        "4": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                }
+            ]
+        },
+        "union-member": {
+            "patterns": [
+                {
+                    "name": "meta.union.member.fidl",
+                    "match": "(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)\\s*(:)\\s*(?<type-constructor>(?:(\\b(?:bool|float32|float64|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b)|(\\bhandle\\b\\s*(?:(<)\\s*\\b(?:bti|channel|debuglog|event|eventpair|fifo|guest|interrupt|job|port|process|profile|resource|socket|thread|timer|vmar|vmo)\\b\\s*(>))?\\s*([?]))|(?:\\b(vector)\\b|\\b(array)\\b|\\b(request)\\b|(\\bstring\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*(?:(<)\\s*\\g<type-constructor>\\s*(>))?\\s*(?:(:)\\s*(?:(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)|@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*(?:([?]))?))\\s*(@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "constant.numeric"
+                        },
+                        "2": {
+                            "name": "punctuation.separator"
+                        },
+                        "3": {
+                            "name": "entity.name.type"
+                        },
+                        "4": {
+                            "name": "storage.type.basic"
+                        },
+                        "5": {
+                            "name": "storage.type.basic"
+                        },
+                        "6": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "7": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "8": {
+                            "name": "punctuation.nullable"
+                        },
+                        "9": {
+                            "name": "storage.type.basic"
+                        },
+                        "10": {
+                            "name": "storage.type.basic"
+                        },
+                        "11": {
+                            "name": "storage.type.basic"
+                        },
+                        "12": {
+                            "name": "storage.type.basic"
+                        },
+                        "13": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "14": {
+                            "name": "punctuation.bracket.angle"
+                        },
+                        "15": {
+                            "name": "punctuation.separator"
+                        },
+                        "16": {
+                            "name": "constant.numeric"
+                        },
+                        "17": {
+                            "name": "punctuation.nullable"
+                        },
+                        "18": {
+                            "name": "variable"
+                        },
+                        "19": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                },
+                {
+                    "name": "meta.union.member.reserved.fidl",
+                    "match": "(-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b)\\s*(:)\\s*\\b(reserved)\\b\\s*(;)",
+                    "captures": {
+                        "1": {
+                            "name": "constant.numeric"
+                        },
+                        "2": {
+                            "name": "punctuation.separator"
+                        },
+                        "3": {
+                            "name": "keyword.control"
+                        },
+                        "4": {
+                            "name": "punctuation.terminator"
+                        }
+                    }
+                }
+            ]
+        },
+        "attributes": {
+            "patterns": []
+        }
+    }
+}
diff --git a/vscode-language-fidl/tools/generate-syntax.ts b/vscode-language-fidl/tools/generate-syntax.ts
new file mode 100644
index 0000000..5677ef8
--- /dev/null
+++ b/vscode-language-fidl/tools/generate-syntax.ts
@@ -0,0 +1,559 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This generates a language definition file because writing it by hand is too hard.
+
+import { OnigRegExp } from "oniguruma";
+
+// Format of language definition JSON
+const tmSchema =
+  "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json";
+type TmCaptures = { [k: string]: { name: string } };
+type TmIncludePattern = { include: string };
+type TmMatchPattern = {
+  name?: string;
+  match: string;
+  captures?: TmCaptures;
+};
+type TmBlockPattern = {
+  name?: string;
+  begin: string;
+  beginCaptures?: TmCaptures;
+  end: string;
+  endCaptures?: TmCaptures;
+  patterns: TmPattern[];
+};
+type TmPattern = TmIncludePattern | TmMatchPattern | TmBlockPattern;
+type TmLanguage = {
+  $schema: string;
+  name: string;
+  scopeName: string;
+  patterns: TmPattern[];
+  repository: {
+    [key: string]: { patterns: TmPattern[] };
+  };
+};
+
+class NamedPattern {
+  readonly re: string;
+  readonly names: string[];
+  constructor(re: string, names?: string[]) {
+    this.re = re;
+    this.names = names || [];
+    // Hack to only validate if there are no unresolved recursive groups
+    const recursive_re = /\\g<(.*?)>/g;
+    let match;
+    while ((match = recursive_re.exec(re)) !== null) {
+      if (!re.includes(`(?<${match[1]}>`)) {
+        // Group definition not found, can't validate yet.
+        return;
+      }
+    }
+    this.validate();
+  }
+
+  validate() {
+    const num_groups = new OnigRegExp(this.re + "|").searchSync("")!.length - 1;
+    if (num_groups !== this.names.length) {
+      throw new Error(
+        `Found ${num_groups} but expected ${this.names.length} groups in ${
+          this.re
+        }`
+      );
+    }
+  }
+
+  toString() {
+    return this.re;
+  }
+
+  assert(s: string) {
+    const re = new OnigRegExp(this.re);
+    const m = re.searchSync(s);
+    if (!m) {
+      throw Error(
+        `${JSON.stringify(s)} did not match pattern ${JSON.stringify(this.re)}`
+      );
+    }
+    const c = m[0];
+    if (c.index !== 0 || c.start !== 0 || c.length !== s.length) {
+      throw Error(
+        `${JSON.stringify(s)} did not fully match pattern ${JSON.stringify(
+          this.re
+        )}, only matched ${JSON.stringify(m[0])}`
+      );
+    }
+  }
+}
+
+function _captures(pattern: Pattern): TmCaptures {
+  const captures: { [k: string]: { name: string } } = {};
+  const names = _names(pattern);
+  for (let i = 0; i < names.length; i++) {
+    captures[`${i + 1}`] = { name: names[i] };
+  }
+  return captures;
+}
+
+function include(name: string): TmIncludePattern {
+  return { include: `#${name}` };
+}
+
+function match(name: string, pat: Pattern): TmMatchPattern {
+  return {
+    name: `${name}.fidl`,
+    match: pat.toString(),
+    captures: _captures(pat)
+  };
+}
+
+function anonMatch(pattern: Pattern | TmPattern): TmPattern {
+  if (pattern instanceof String) {
+    return {
+      match: pattern.toString()
+    };
+  }
+  if (pattern instanceof NamedPattern) {
+    return {
+      match: pattern.toString(),
+      captures: _captures(pattern)
+    };
+  }
+  return pattern;
+}
+
+function block(args: {
+  name: string;
+  begin: Pattern;
+  end: Pattern;
+  patterns: Array<Pattern | TmPattern>;
+}): TmBlockPattern {
+  const tmPatterns: TmPattern[] = args.patterns.map(anonMatch);
+  return {
+    name: `${args.name}.fidl`,
+    begin: args.begin.toString(),
+    beginCaptures: _captures(args.begin),
+    end: args.end.toString(),
+    endCaptures: _captures(args.end),
+    patterns: tmPatterns
+  };
+}
+
+type Pattern = NamedPattern | String;
+
+/** Return names of the groups in the pattern. */
+function _names(pat: Pattern | Pattern[]): string[] {
+  if (pat instanceof Array) {
+    return pat.map(_names).reduce((prev, names) => [...(prev || []), ...names]);
+  }
+  if (pat instanceof NamedPattern) {
+    return pat.names;
+  } else {
+    return [];
+  }
+}
+
+function _join(
+  pats: Pattern[],
+  prefix: string,
+  separator: string,
+  suffix: string
+): NamedPattern {
+  const re = pats.map(p => p.toString()).join(separator);
+  return new NamedPattern(prefix + re + suffix, _names(pats));
+}
+
+/**
+ * Create a new pattern consisting of adjacent input patterns optionally separated by whitespace.
+ * @param pats Patterns
+ */
+function seq(...pats: Pattern[]): NamedPattern {
+  return _join(pats, "", "\\s*", "");
+}
+
+function one_of(...pats: Pattern[]): NamedPattern {
+  return _join(pats, "(?:", "|", ")");
+}
+
+function one_of_words(...words: string[]) {
+  return word(one_of(...words));
+}
+
+function optional(pat: Pattern): NamedPattern {
+  return new NamedPattern(`(?:${pat})?`, _names(pat));
+}
+
+function word(word: Pattern): NamedPattern {
+  return new NamedPattern(`\\b${word}\\b`, _names(word));
+}
+
+function named(pat: Pattern, name: string) {
+  return new NamedPattern(`(${pat})`, [name, ..._names(pat)]);
+}
+
+function recursive_group(
+  context_name: string,
+  group_name: string,
+  body: Pattern
+): NamedPattern {
+  return new NamedPattern(`(?<${group_name}>${body})`, [
+    context_name,
+    ..._names(body)
+  ]);
+}
+
+function recursive_group_reference(group_name: string): Pattern {
+  return String.raw`\g<${group_name}>`;
+}
+
+const NUMERIC_LITERAL = named(
+  "-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b",
+  "constant.numeric"
+);
+const BOOLEAN_LITERAL = named(
+  one_of_words("true", "false"),
+  "constant.language"
+);
+const STRING_LITERAL = named('"(?:[^\\"]|\\.)*"', "string.quoted.double");
+const LITERAL = one_of(NUMERIC_LITERAL, BOOLEAN_LITERAL, STRING_LITERAL);
+
+const IDENTIFIER = "@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b";
+const COMPOUND_IDENTIFIER = new NamedPattern(
+  `${IDENTIFIER}(?:\\.${IDENTIFIER})*`
+);
+
+const CONSTANT = one_of(LITERAL, COMPOUND_IDENTIFIER);
+const NUMERIC_CONSTANT = one_of(NUMERIC_LITERAL, COMPOUND_IDENTIFIER);
+
+const NULLABLE = named("[?]", "punctuation.nullable");
+
+function nullable(pat: Pattern): Pattern {
+  return seq(pat, NULLABLE);
+}
+
+function angle_brackets(contents: Pattern) {
+  const scope = "punctuation.bracket.angle";
+  return seq(named("<", scope), contents, named(">", scope));
+}
+
+function keyword(keyword: string, name: string = "keyword.control") {
+  return word(named(keyword, name));
+}
+
+function type_keyword(type_name: string) {
+  return keyword(type_name, "storage.type.basic");
+}
+
+function separator(sep: string) {
+  return named(sep, "punctuation.separator");
+}
+
+const primitive_types = [
+  "bool",
+  "float32",
+  "float64",
+  "int8",
+  "int16",
+  "int32",
+  "int64",
+  "uint8",
+  "uint16",
+  "uint32",
+  "uint64"
+];
+const handle_types = [
+  "bti",
+  "channel",
+  "debuglog",
+  "event",
+  "eventpair",
+  "fifo",
+  "guest",
+  "interrupt",
+  "job",
+  "port",
+  "process",
+  "profile",
+  "resource",
+  "socket",
+  "thread",
+  "timer",
+  "vmar",
+  "vmo"
+];
+const PRIMITIVE_TYPE = named(
+  one_of_words(...primitive_types),
+  "storage.type.basic"
+);
+const HANDLE_TYPE = named(
+  nullable(
+    seq(word("handle"), optional(angle_brackets(one_of_words(...handle_types))))
+  ),
+  "storage.type.basic"
+);
+const EOL = new NamedPattern("(;)", ["punctuation.terminator"]);
+const LIBRARY_NAME = named(COMPOUND_IDENTIFIER, "entity.name.type");
+const LOCAL_TYPE = named(IDENTIFIER, "entity.name.type");
+const VARIABLE = named(IDENTIFIER, "variable");
+
+const LOOKAHEAD_IDENTIFIER = "(?=[a-zA-Z_@])";
+
+const ATTRIBUTE = seq(
+  named(IDENTIFIER, "support.variable"),
+  optional(seq("=", STRING_LITERAL))
+);
+
+const ATTRIBUTES = block({
+  name: "meta.attrbutes",
+  begin: String.raw`\[`,
+  end: String.raw`\]`,
+  patterns: [ATTRIBUTE]
+});
+
+const TYPE_CONSTRAINT = seq(
+  separator(":"),
+  one_of(NUMERIC_LITERAL, COMPOUND_IDENTIFIER)
+);
+
+const TYPE_CONSTRUCTOR = recursive_group(
+  "entity.name.type",
+  "type-constructor",
+  seq(
+    one_of(
+      PRIMITIVE_TYPE,
+      HANDLE_TYPE,
+      seq(
+        one_of(
+          type_keyword("vector"),
+          type_keyword("array"),
+          type_keyword("request"),
+          named(word("string"), "storage.type.basic"),
+          COMPOUND_IDENTIFIER
+        ),
+        optional(angle_brackets(recursive_group_reference("type-constructor"))),
+        optional(TYPE_CONSTRAINT),
+        optional(NULLABLE)
+      )
+    )
+  )
+);
+
+// Checks
+
+COMPOUND_IDENTIFIER.assert("foo");
+COMPOUND_IDENTIFIER.assert("foo_bar");
+COMPOUND_IDENTIFIER.assert("foo.bar.baz");
+
+TYPE_CONSTRUCTOR.assert("string");
+TYPE_CONSTRUCTOR.assert("string?");
+TYPE_CONSTRUCTOR.assert("string:2");
+TYPE_CONSTRUCTOR.assert("string:MAX_LEN");
+TYPE_CONSTRUCTOR.assert("string:2?");
+TYPE_CONSTRUCTOR.assert("string:MAX_LEN?");
+
+NUMERIC_LITERAL.assert("-42");
+NUMERIC_LITERAL.assert("0x12345deadbeef");
+NUMERIC_LITERAL.assert("0b101110");
+
+TYPE_CONSTRUCTOR.assert("handle");
+TYPE_CONSTRUCTOR.assert("handle?");
+TYPE_CONSTRUCTOR.assert("handle<socket>");
+TYPE_CONSTRUCTOR.assert("handle<debuglog>?");
+
+TYPE_CONSTRUCTOR.assert("foo.bar.myvectoralias<uint8>:8");
+
+// TODO: support attributes
+const tmLanguage: TmLanguage = {
+  $schema: tmSchema,
+  name: "FIDL",
+  scopeName: "source.fidl",
+  patterns: [
+    include("comments"),
+
+    // Library declaration
+    match("meta.library", seq(keyword("library"), LIBRARY_NAME, EOL)),
+
+    // Variations of using
+    match("meta.library", seq(keyword("using"), LIBRARY_NAME, EOL)),
+    match(
+      "meta.library",
+      seq(keyword("using"), LIBRARY_NAME, keyword("as"), LOCAL_TYPE, EOL)
+    ),
+    match(
+      "meta.library",
+      seq(keyword("using"), LOCAL_TYPE, separator("="), TYPE_CONSTRUCTOR, EOL)
+    ),
+
+    // Const declaration
+    match(
+      "meta.const",
+      seq(
+        keyword("const"),
+        one_of(COMPOUND_IDENTIFIER, PRIMITIVE_TYPE),
+        named(IDENTIFIER, "variable.constant"),
+        separator("="),
+        one_of(CONSTANT, NUMERIC_CONSTANT),
+        EOL
+      )
+    ),
+
+    // Protocols
+    block({
+      name: "meta.protocol-block",
+      begin: seq(keyword("protocol"), LOCAL_TYPE, "{"),
+      end: "}",
+      patterns: [
+        ATTRIBUTES,
+        seq(keyword("compose"), named(COMPOUND_IDENTIFIER, "entity.name.type")),
+        include("method"),
+        include("comments")
+      ]
+    }),
+
+    // Enums
+    block({
+      name: "meta.enum-block",
+      begin: seq(
+        keyword("enum"),
+        LOCAL_TYPE,
+        optional(seq(separator(":"), TYPE_CONSTRUCTOR)),
+        "{"
+      ),
+      end: "}",
+      patterns: [include("enum-member"), include("comments")]
+    }),
+
+    // Bits
+    block({
+      name: "meta.bits-block",
+      begin: seq(
+        keyword("bits"),
+        LOCAL_TYPE,
+        optional(seq(separator(":"), TYPE_CONSTRUCTOR)),
+        "{"
+      ),
+      end: "}",
+      patterns: [include("enum-member"), include("comments")]
+    }),
+
+    // Struct
+    block({
+      name: "meta.struct-block",
+      begin: seq(keyword("struct"), LOCAL_TYPE, "{"),
+      end: "}",
+      patterns: [include("struct-member"), include("comments")]
+    }),
+
+    // Table
+    block({
+      name: "meta.table-block",
+      begin: seq(keyword("table"), LOCAL_TYPE, "{"),
+      end: "}",
+      patterns: [include("table-member"), include("comments")]
+    }),
+
+    // Union and XUnion
+    block({
+      name: "meta.union-block",
+      begin: seq(one_of(keyword("union"), keyword("xunion")), LOCAL_TYPE, "{"),
+      end: "}",
+      patterns: [include("union-member"), include("comments")]
+    })
+  ],
+  repository: {
+    comments: {
+      patterns: [
+        match("invalid.illegal.stray-comment-end", "\\*/.*\\n"),
+        match("comment.line.documentation", "///.*\\n"),
+        match("comment.line.double-slash", "//.*\\n")
+      ]
+    },
+    method: {
+      patterns: [
+        block({
+          name: "meta.method",
+          begin: seq(named(IDENTIFIER, "entity.name.function")),
+          end: seq(optional(seq(keyword("error"), TYPE_CONSTRUCTOR)), EOL),
+          patterns: [include("method-arguments"), separator("->")]
+        }),
+        block({
+          name: "meta.method.event",
+          begin: seq(
+            separator("->"),
+            named(IDENTIFIER, "entity.name.function"),
+            "[(]"
+          ),
+          end: seq("[)]", EOL),
+          patterns: [include("method-argument")]
+        })
+      ]
+    },
+    "method-arguments": {
+      patterns: [
+        block({
+          name: "meta.method.arguments",
+          begin: "\\(",
+          end: "\\)",
+          patterns: [include("method-argument")]
+        })
+      ]
+    },
+    "method-argument": {
+      patterns: [
+        block({
+          name: "meta.method.argument",
+          begin: LOOKAHEAD_IDENTIFIER,
+          end: seq(named(IDENTIFIER, "variable.name"), "(?:(?:,)|(?=\\)))"),
+          patterns: [TYPE_CONSTRUCTOR, named(IDENTIFIER, "variable.parameter")]
+        })
+      ]
+    },
+    "enum-member": {
+      patterns: [
+        match(
+          "meta.enum.member",
+          seq(VARIABLE, separator("="), NUMERIC_CONSTANT, EOL)
+        )
+      ]
+    },
+    "struct-member": {
+      patterns: [
+        match("meta.struct.member", seq(TYPE_CONSTRUCTOR, VARIABLE, EOL)),
+        match(
+          "meta.struct.member",
+          seq(TYPE_CONSTRUCTOR, VARIABLE, separator("="), CONSTANT, EOL)
+        )
+      ]
+    },
+    "table-member": {
+      patterns: [
+        match(
+          "meta.table.member",
+          seq(NUMERIC_LITERAL, separator(":"), TYPE_CONSTRUCTOR, VARIABLE, EOL)
+        ),
+        match(
+          "meta.table.reserved",
+          seq(NUMERIC_LITERAL, separator(":"), keyword("reserved"), EOL)
+        )
+      ]
+    },
+    "union-member": {
+      patterns: [
+        match(
+          "meta.union.member",
+          seq(NUMERIC_LITERAL, separator(":"), TYPE_CONSTRUCTOR, VARIABLE, EOL)
+        ),
+        match(
+          "meta.union.member.reserved",
+          seq(NUMERIC_LITERAL, separator(":"), keyword("reserved"), EOL)
+        )
+      ]
+    },
+    attributes: {
+      patterns: []
+    }
+  }
+};
+
+console.log(JSON.stringify(tmLanguage, null, "    "));
diff --git a/vscode-language-fidl/tsconfig.json b/vscode-language-fidl/tsconfig.json
new file mode 100644
index 0000000..e7d2872
--- /dev/null
+++ b/vscode-language-fidl/tsconfig.json
@@ -0,0 +1,25 @@
+{
+    "compilerOptions": {
+        "module": "commonjs",
+        "target": "es6",
+        "outDir": "out",
+        "lib": [
+            "es6"
+        ],
+        "sourceMap": true,
+        "rootDir": "src",
+        /* Strict Type-Checking Option */
+        "strict": true,   /* enable all strict type-checking options */
+        /* Additional Checks */
+        "noUnusedLocals": true /* Report errors on unused locals. */
+        // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+        // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+        // "noUnusedParameters": true,  /* Report errors on unused parameters. */
+    },
+    "exclude": [
+        "node_modules",
+        ".vscode-test",
+        "tools",
+        "test"
+    ]
+}
diff --git a/vscode-language-fidl/tslint.json b/vscode-language-fidl/tslint.json
new file mode 100644
index 0000000..c791efd
--- /dev/null
+++ b/vscode-language-fidl/tslint.json
@@ -0,0 +1,15 @@
+{
+    "rules": {
+        "no-string-throw": true,
+        "no-unused-expression": true,
+        "no-duplicate-variable": true,
+        "curly": true,
+        "class-name": true,
+        "semicolon": [
+            true,
+            "always"
+        ],
+        "triple-equals": true
+    },
+    "defaultSeverity": "warning"
+}
\ No newline at end of file