diff --git a/Makefile b/Makefile
index 44c40a2..bf2a1e2 100644
--- a/Makefile
+++ b/Makefile
@@ -8,9 +8,7 @@
 grpc_proto_gen:
 	(cd src/killSwitch && \
 		protoc -I=. --js_out=import_style=commonjs_strict:. api_proto/*.proto && \
-		protoc -I. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. api_proto/*.proto && \
-		(cd api_proto && \
-			sed -i -E "s/require\('google-protobuf\//require('..\/..\/third_party\/google-protobuf-commonjs_strict\//" *_pb.js ))
+		protoc -I. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. api_proto/*.proto)
 
 node_deps:
 	npm ci --no-save
diff --git a/package-lock.json b/package-lock.json
index 4be81e0..41f390a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,14 +12,13 @@
         "@material/menu": "^10.0.0",
         "@material/tooltip": "^12.0.0",
         "async-mutex": "^0.3.2",
-        "google-protobuf": "^3.18.0-rc.2",
+        "google-protobuf": "^3.19.3",
         "grpc-web": "^1.2.1",
         "idb": "^6.1.2",
         "poll-until-promise": "^3.6.1",
         "semver": "^7.3.5",
         "sw-xhr": "^0.0.3",
         "vue": "^3.2.26",
-        "vue-loader": "^17.0.0",
         "vue-material-adapter": "^3.2.3"
       },
       "devDependencies": {
@@ -31,6 +30,7 @@
         "sass": "^1.38.1",
         "sass-loader": "^12.1.0",
         "style-loader": "^3.2.1",
+        "vue-loader": "^17.0.0",
         "vue-style-loader": "^4.1.3",
         "webpack": "^5.44.0",
         "webpack-cli": "^4.7.2",
@@ -2690,6 +2690,7 @@
       "version": "7.2.14",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.14.tgz",
       "integrity": "sha512-pESyhSbUOskqrGcaN+bCXIQDyT5zTaRWfj5ZjjSlMatgGjIn3QQPfocAu4WSabUR7CGyLZ2CQaZyISOEX7/saw==",
+      "dev": true,
       "dependencies": {
         "@types/estree": "*",
         "@types/json-schema": "*"
@@ -2699,6 +2700,7 @@
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz",
       "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==",
+      "dev": true,
       "dependencies": {
         "@types/eslint": "*",
         "@types/estree": "*"
@@ -2707,17 +2709,20 @@
     "node_modules/@types/estree": {
       "version": "0.0.50",
       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
-      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
+      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
+      "dev": true
     },
     "node_modules/@types/json-schema": {
       "version": "7.0.8",
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
-      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg=="
+      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==",
+      "dev": true
     },
     "node_modules/@types/node": {
       "version": "16.3.1",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
-      "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
+      "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==",
+      "dev": true
     },
     "node_modules/@vue/compiler-core": {
       "version": "3.2.28",
@@ -2825,6 +2830,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
       "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/helper-numbers": "1.11.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
@@ -2833,22 +2839,26 @@
     "node_modules/@webassemblyjs/floating-point-hex-parser": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
-      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ=="
+      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+      "dev": true
     },
     "node_modules/@webassemblyjs/helper-api-error": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
-      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg=="
+      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+      "dev": true
     },
     "node_modules/@webassemblyjs/helper-buffer": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
-      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA=="
+      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+      "dev": true
     },
     "node_modules/@webassemblyjs/helper-numbers": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
       "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/floating-point-hex-parser": "1.11.1",
         "@webassemblyjs/helper-api-error": "1.11.1",
@@ -2858,12 +2868,14 @@
     "node_modules/@webassemblyjs/helper-wasm-bytecode": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
-      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q=="
+      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+      "dev": true
     },
     "node_modules/@webassemblyjs/helper-wasm-section": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
       "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -2875,6 +2887,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
       "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+      "dev": true,
       "dependencies": {
         "@xtuc/ieee754": "^1.2.0"
       }
@@ -2883,6 +2896,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
       "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+      "dev": true,
       "dependencies": {
         "@xtuc/long": "4.2.2"
       }
@@ -2890,12 +2904,14 @@
     "node_modules/@webassemblyjs/utf8": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
-      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ=="
+      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+      "dev": true
     },
     "node_modules/@webassemblyjs/wasm-edit": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
       "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -2911,6 +2927,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
       "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
@@ -2923,6 +2940,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
       "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -2934,6 +2952,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
       "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-api-error": "1.11.1",
@@ -2947,6 +2966,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
       "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+      "dev": true,
       "dependencies": {
         "@webassemblyjs/ast": "1.11.1",
         "@xtuc/long": "4.2.2"
@@ -2991,17 +3011,20 @@
     "node_modules/@xtuc/ieee754": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
-      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
     },
     "node_modules/@xtuc/long": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
-      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
     },
     "node_modules/acorn": {
       "version": "8.4.1",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
       "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
+      "dev": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -3013,6 +3036,7 @@
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
       "dependencies": {
         "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
@@ -3028,6 +3052,7 @@
       "version": "3.5.2",
       "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "dev": true,
       "peerDependencies": {
         "ajv": "^6.9.1"
       }
@@ -3036,6 +3061,7 @@
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
       "dependencies": {
         "color-convert": "^2.0.1"
       },
@@ -3080,6 +3106,7 @@
       "version": "5.2.2",
       "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
       "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true,
       "engines": {
         "node": "*"
       }
@@ -3109,6 +3136,7 @@
       "version": "4.16.6",
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
       "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+      "dev": true,
       "dependencies": {
         "caniuse-lite": "^1.0.30001219",
         "colorette": "^1.2.2",
@@ -3130,12 +3158,14 @@
     "node_modules/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=="
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
     },
     "node_modules/caniuse-lite": {
       "version": "1.0.30001243",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
       "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
+      "dev": true,
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/browserslist"
@@ -3145,6 +3175,7 @@
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
       "dependencies": {
         "ansi-styles": "^4.1.0",
         "supports-color": "^7.1.0"
@@ -3160,6 +3191,7 @@
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
       "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
       "dependencies": {
         "has-flag": "^4.0.0"
       },
@@ -3204,6 +3236,7 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
       "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+      "dev": true,
       "engines": {
         "node": ">=6.0"
       }
@@ -3226,6 +3259,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
       "dependencies": {
         "color-name": "~1.1.4"
       },
@@ -3236,7 +3270,8 @@
     "node_modules/color-name": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
     },
     "node_modules/colorette": {
       "version": "1.2.2",
@@ -3246,7 +3281,8 @@
     "node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true
     },
     "node_modules/copy-webpack-plugin": {
       "version": "9.0.1",
@@ -3345,12 +3381,14 @@
     "node_modules/electron-to-chromium": {
       "version": "1.3.772",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
-      "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA=="
+      "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
+      "dev": true
     },
     "node_modules/emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
       "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true,
       "engines": {
         "node": ">= 4"
       }
@@ -3359,6 +3397,7 @@
       "version": "5.8.2",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
       "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
+      "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.4",
         "tapable": "^2.2.0"
@@ -3382,12 +3421,14 @@
     "node_modules/es-module-lexer": {
       "version": "0.7.1",
       "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
-      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw=="
+      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
+      "dev": true
     },
     "node_modules/escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true,
       "engines": {
         "node": ">=6"
       }
@@ -3396,6 +3437,7 @@
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
       "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
       "dependencies": {
         "esrecurse": "^4.3.0",
         "estraverse": "^4.1.1"
@@ -3408,6 +3450,7 @@
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
       "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
       "dependencies": {
         "estraverse": "^5.2.0"
       },
@@ -3419,6 +3462,7 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
       "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+      "dev": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -3427,6 +3471,7 @@
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
       "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -3440,6 +3485,7 @@
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
       "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "dev": true,
       "engines": {
         "node": ">=0.8.x"
       }
@@ -3470,7 +3516,8 @@
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
     },
     "node_modules/fast-glob": {
       "version": "3.2.7",
@@ -3503,7 +3550,8 @@
     "node_modules/fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
     },
     "node_modules/fastest-levenshtein": {
       "version": "1.0.12",
@@ -3592,7 +3640,8 @@
     "node_modules/glob-to-regexp": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
-      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "dev": true
     },
     "node_modules/globby": {
       "version": "11.0.4",
@@ -3615,14 +3664,15 @@
       }
     },
     "node_modules/google-protobuf": {
-      "version": "3.18.0-rc.2",
-      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.18.0-rc.2.tgz",
-      "integrity": "sha512-mKZG5WYrwR/y1mA8xB+qI1O/6Pmvu4V6zldf+dpHdx6zoyVWT5lJTyXU8rAlpL7jtbe47e6M9L4PyWnKsYMOXQ=="
+      "version": "3.19.3",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.3.tgz",
+      "integrity": "sha512-3GRDj8o9XjcALYjgxNKeD7Wm6w/V8r1Jo4sLYMic9+VaIMLBx8TQeHP9yaoRoDymNONhnkmmveDPyjw/Fpw8+A=="
     },
     "node_modules/graceful-fs": {
       "version": "4.2.6",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
-      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "dev": true
     },
     "node_modules/grpc-web": {
       "version": "1.2.1",
@@ -3645,6 +3695,7 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
       "engines": {
         "node": ">=8"
       }
@@ -3652,7 +3703,8 @@
     "node_modules/hash-sum": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
-      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
+      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+      "dev": true
     },
     "node_modules/human-signals": {
       "version": "2.1.0",
@@ -3814,6 +3866,7 @@
       "version": "27.0.6",
       "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
       "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
+      "dev": true,
       "dependencies": {
         "@types/node": "*",
         "merge-stream": "^2.0.0",
@@ -3826,17 +3879,20 @@
     "node_modules/json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
-      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
     },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
     },
     "node_modules/json5": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
       "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "dev": true,
       "dependencies": {
         "minimist": "^1.2.5"
       },
@@ -3869,6 +3925,7 @@
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
       "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+      "dev": true,
       "engines": {
         "node": ">=6.11.5"
       }
@@ -3877,6 +3934,7 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
       "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+      "dev": true,
       "dependencies": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",
@@ -4072,7 +4130,8 @@
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
     },
     "node_modules/merge2": {
       "version": "1.4.1",
@@ -4100,6 +4159,7 @@
       "version": "1.48.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
       "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -4108,6 +4168,7 @@
       "version": "2.1.31",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
       "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+      "dev": true,
       "dependencies": {
         "mime-db": "1.48.0"
       },
@@ -4127,7 +4188,8 @@
     "node_modules/minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
     },
     "node_modules/nanoid": {
       "version": "3.1.25",
@@ -4143,12 +4205,14 @@
     "node_modules/neo-async": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
     },
     "node_modules/node-releases": {
       "version": "1.1.73",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
-      "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
+      "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
+      "dev": true
     },
     "node_modules/normalize-path": {
       "version": "3.0.0",
@@ -4190,6 +4254,7 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
       "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
       "dependencies": {
         "yocto-queue": "^0.1.0"
       },
@@ -4416,6 +4481,7 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true,
       "engines": {
         "node": ">=6"
       }
@@ -4444,6 +4510,7 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
       "dependencies": {
         "safe-buffer": "^5.1.0"
       }
@@ -4543,6 +4610,7 @@
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -4611,6 +4679,7 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
       "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
+      "dev": true,
       "dependencies": {
         "@types/json-schema": "^7.0.7",
         "ajv": "^6.12.5",
@@ -4642,6 +4711,7 @@
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
       "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+      "dev": true,
       "dependencies": {
         "randombytes": "^2.1.0"
       }
@@ -4697,7 +4767,8 @@
     "node_modules/source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
-      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
     },
     "node_modules/source-map": {
       "version": "0.6.1",
@@ -4719,6 +4790,7 @@
       "version": "0.5.19",
       "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
       "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
       "dependencies": {
         "buffer-from": "^1.0.0",
         "source-map": "^0.6.0"
@@ -4758,6 +4830,7 @@
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
       "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
       "dependencies": {
         "has-flag": "^4.0.0"
       },
@@ -4777,6 +4850,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
       "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
+      "dev": true,
       "engines": {
         "node": ">=6"
       }
@@ -4785,6 +4859,7 @@
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
       "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
+      "dev": true,
       "dependencies": {
         "commander": "^2.20.0",
         "source-map": "~0.7.2",
@@ -4801,6 +4876,7 @@
       "version": "5.1.4",
       "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz",
       "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==",
+      "dev": true,
       "dependencies": {
         "jest-worker": "^27.0.2",
         "p-limit": "^3.1.0",
@@ -4824,6 +4900,7 @@
       "version": "0.7.3",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
       "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+      "dev": true,
       "engines": {
         "node": ">= 8"
       }
@@ -4849,6 +4926,7 @@
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dev": true,
       "dependencies": {
         "punycode": "^2.1.0"
       }
@@ -4890,6 +4968,7 @@
       "version": "17.0.0",
       "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.0.tgz",
       "integrity": "sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg==",
+      "dev": true,
       "dependencies": {
         "chalk": "^4.1.0",
         "hash-sum": "^2.0.0",
@@ -4960,6 +5039,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz",
       "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==",
+      "dev": true,
       "dependencies": {
         "glob-to-regexp": "^0.4.1",
         "graceful-fs": "^4.1.2"
@@ -4972,6 +5052,7 @@
       "version": "5.44.0",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
       "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
+      "dev": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.0",
         "@types/estree": "^0.0.50",
@@ -5101,6 +5182,7 @@
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz",
       "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==",
+      "dev": true,
       "dependencies": {
         "source-list-map": "^2.0.1",
         "source-map": "^0.6.1"
@@ -5139,6 +5221,7 @@
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
       "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true,
       "engines": {
         "node": ">=10"
       },
@@ -7854,6 +7937,7 @@
       "version": "7.2.14",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.14.tgz",
       "integrity": "sha512-pESyhSbUOskqrGcaN+bCXIQDyT5zTaRWfj5ZjjSlMatgGjIn3QQPfocAu4WSabUR7CGyLZ2CQaZyISOEX7/saw==",
+      "dev": true,
       "requires": {
         "@types/estree": "*",
         "@types/json-schema": "*"
@@ -7863,6 +7947,7 @@
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz",
       "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==",
+      "dev": true,
       "requires": {
         "@types/eslint": "*",
         "@types/estree": "*"
@@ -7871,17 +7956,20 @@
     "@types/estree": {
       "version": "0.0.50",
       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
-      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
+      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
+      "dev": true
     },
     "@types/json-schema": {
       "version": "7.0.8",
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
-      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg=="
+      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==",
+      "dev": true
     },
     "@types/node": {
       "version": "16.3.1",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
-      "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
+      "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==",
+      "dev": true
     },
     "@vue/compiler-core": {
       "version": "3.2.28",
@@ -7986,6 +8074,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
       "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/helper-numbers": "1.11.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
@@ -7994,22 +8083,26 @@
     "@webassemblyjs/floating-point-hex-parser": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
-      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ=="
+      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+      "dev": true
     },
     "@webassemblyjs/helper-api-error": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
-      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg=="
+      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+      "dev": true
     },
     "@webassemblyjs/helper-buffer": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
-      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA=="
+      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+      "dev": true
     },
     "@webassemblyjs/helper-numbers": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
       "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/floating-point-hex-parser": "1.11.1",
         "@webassemblyjs/helper-api-error": "1.11.1",
@@ -8019,12 +8112,14 @@
     "@webassemblyjs/helper-wasm-bytecode": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
-      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q=="
+      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+      "dev": true
     },
     "@webassemblyjs/helper-wasm-section": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
       "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -8036,6 +8131,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
       "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+      "dev": true,
       "requires": {
         "@xtuc/ieee754": "^1.2.0"
       }
@@ -8044,6 +8140,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
       "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+      "dev": true,
       "requires": {
         "@xtuc/long": "4.2.2"
       }
@@ -8051,12 +8148,14 @@
     "@webassemblyjs/utf8": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
-      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ=="
+      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+      "dev": true
     },
     "@webassemblyjs/wasm-edit": {
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
       "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -8072,6 +8171,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
       "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
@@ -8084,6 +8184,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
       "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-buffer": "1.11.1",
@@ -8095,6 +8196,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
       "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@webassemblyjs/helper-api-error": "1.11.1",
@@ -8108,6 +8210,7 @@
       "version": "1.11.1",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
       "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+      "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.11.1",
         "@xtuc/long": "4.2.2"
@@ -8139,22 +8242,26 @@
     "@xtuc/ieee754": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
-      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
     },
     "@xtuc/long": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
-      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
     },
     "acorn": {
       "version": "8.4.1",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
-      "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA=="
+      "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
+      "dev": true
     },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
       "requires": {
         "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
@@ -8166,12 +8273,14 @@
       "version": "3.5.2",
       "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "dev": true,
       "requires": {}
     },
     "ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
       "requires": {
         "color-convert": "^2.0.1"
       }
@@ -8203,7 +8312,8 @@
     "big.js": {
       "version": "5.2.2",
       "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
-      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
     },
     "binary-extensions": {
       "version": "2.2.0",
@@ -8224,6 +8334,7 @@
       "version": "4.16.6",
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
       "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+      "dev": true,
       "requires": {
         "caniuse-lite": "^1.0.30001219",
         "colorette": "^1.2.2",
@@ -8235,17 +8346,20 @@
     "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=="
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
     },
     "caniuse-lite": {
       "version": "1.0.30001243",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
-      "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA=="
+      "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
+      "dev": true
     },
     "chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
       "requires": {
         "ansi-styles": "^4.1.0",
         "supports-color": "^7.1.0"
@@ -8255,6 +8369,7 @@
           "version": "7.2.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
           "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
           "requires": {
             "has-flag": "^4.0.0"
           }
@@ -8291,7 +8406,8 @@
     "chrome-trace-event": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
-      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg=="
+      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+      "dev": true
     },
     "clone-deep": {
       "version": "4.0.1",
@@ -8308,6 +8424,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
       "requires": {
         "color-name": "~1.1.4"
       }
@@ -8315,7 +8432,8 @@
     "color-name": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
     },
     "colorette": {
       "version": "1.2.2",
@@ -8325,7 +8443,8 @@
     "commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true
     },
     "copy-webpack-plugin": {
       "version": "9.0.1",
@@ -8392,17 +8511,20 @@
     "electron-to-chromium": {
       "version": "1.3.772",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
-      "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA=="
+      "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
+      "dev": true
     },
     "emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
-      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true
     },
     "enhanced-resolve": {
       "version": "5.8.2",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
       "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
+      "dev": true,
       "requires": {
         "graceful-fs": "^4.2.4",
         "tapable": "^2.2.0"
@@ -8417,17 +8539,20 @@
     "es-module-lexer": {
       "version": "0.7.1",
       "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
-      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw=="
+      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
+      "dev": true
     },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true
     },
     "eslint-scope": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
       "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
       "requires": {
         "esrecurse": "^4.3.0",
         "estraverse": "^4.1.1"
@@ -8437,6 +8562,7 @@
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
       "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
       "requires": {
         "estraverse": "^5.2.0"
       },
@@ -8444,14 +8570,16 @@
         "estraverse": {
           "version": "5.2.0",
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+          "dev": true
         }
       }
     },
     "estraverse": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
     },
     "estree-walker": {
       "version": "2.0.2",
@@ -8461,7 +8589,8 @@
     "events": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
-      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "dev": true
     },
     "execa": {
       "version": "5.1.1",
@@ -8483,7 +8612,8 @@
     "fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
     },
     "fast-glob": {
       "version": "3.2.7",
@@ -8512,7 +8642,8 @@
     "fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
     },
     "fastest-levenshtein": {
       "version": "1.0.12",
@@ -8579,7 +8710,8 @@
     "glob-to-regexp": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
-      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "dev": true
     },
     "globby": {
       "version": "11.0.4",
@@ -8596,14 +8728,15 @@
       }
     },
     "google-protobuf": {
-      "version": "3.18.0-rc.2",
-      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.18.0-rc.2.tgz",
-      "integrity": "sha512-mKZG5WYrwR/y1mA8xB+qI1O/6Pmvu4V6zldf+dpHdx6zoyVWT5lJTyXU8rAlpL7jtbe47e6M9L4PyWnKsYMOXQ=="
+      "version": "3.19.3",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.3.tgz",
+      "integrity": "sha512-3GRDj8o9XjcALYjgxNKeD7Wm6w/V8r1Jo4sLYMic9+VaIMLBx8TQeHP9yaoRoDymNONhnkmmveDPyjw/Fpw8+A=="
     },
     "graceful-fs": {
       "version": "4.2.6",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
-      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "dev": true
     },
     "grpc-web": {
       "version": "1.2.1",
@@ -8622,12 +8755,14 @@
     "has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true
     },
     "hash-sum": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
-      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
+      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+      "dev": true
     },
     "human-signals": {
       "version": "2.1.0",
@@ -8745,6 +8880,7 @@
       "version": "27.0.6",
       "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
       "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
+      "dev": true,
       "requires": {
         "@types/node": "*",
         "merge-stream": "^2.0.0",
@@ -8754,17 +8890,20 @@
     "json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
-      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
     },
     "json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
     },
     "json5": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
       "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "dev": true,
       "requires": {
         "minimist": "^1.2.5"
       }
@@ -8784,12 +8923,14 @@
     "loader-runner": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
-      "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw=="
+      "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+      "dev": true
     },
     "loader-utils": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
       "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+      "dev": true,
       "requires": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",
@@ -8978,7 +9119,8 @@
     "merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
     },
     "merge2": {
       "version": "1.4.1",
@@ -8999,12 +9141,14 @@
     "mime-db": {
       "version": "1.48.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
-      "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
+      "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
+      "dev": true
     },
     "mime-types": {
       "version": "2.1.31",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
       "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+      "dev": true,
       "requires": {
         "mime-db": "1.48.0"
       }
@@ -9018,7 +9162,8 @@
     "minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
     },
     "nanoid": {
       "version": "3.1.25",
@@ -9028,12 +9173,14 @@
     "neo-async": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
     },
     "node-releases": {
       "version": "1.1.73",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
-      "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
+      "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
+      "dev": true
     },
     "normalize-path": {
       "version": "3.0.0",
@@ -9063,6 +9210,7 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
       "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
       "requires": {
         "yocto-queue": "^0.1.0"
       }
@@ -9218,7 +9366,8 @@
     "punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true
     },
     "queue-microtask": {
       "version": "1.2.3",
@@ -9230,6 +9379,7 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
       "requires": {
         "safe-buffer": "^5.1.0"
       }
@@ -9295,7 +9445,8 @@
     "safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true
     },
     "sass": {
       "version": "1.38.1",
@@ -9320,6 +9471,7 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
       "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
+      "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.7",
         "ajv": "^6.12.5",
@@ -9338,6 +9490,7 @@
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
       "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+      "dev": true,
       "requires": {
         "randombytes": "^2.1.0"
       }
@@ -9381,7 +9534,8 @@
     "source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
-      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
     },
     "source-map": {
       "version": "0.6.1",
@@ -9397,6 +9551,7 @@
       "version": "0.5.19",
       "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
       "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
       "requires": {
         "buffer-from": "^1.0.0",
         "source-map": "^0.6.0"
@@ -9424,6 +9579,7 @@
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
       "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
       "requires": {
         "has-flag": "^4.0.0"
       }
@@ -9436,12 +9592,14 @@
     "tapable": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
-      "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw=="
+      "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
+      "dev": true
     },
     "terser": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
       "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
+      "dev": true,
       "requires": {
         "commander": "^2.20.0",
         "source-map": "~0.7.2",
@@ -9451,7 +9609,8 @@
         "source-map": {
           "version": "0.7.3",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
+          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "dev": true
         }
       }
     },
@@ -9459,6 +9618,7 @@
       "version": "5.1.4",
       "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz",
       "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==",
+      "dev": true,
       "requires": {
         "jest-worker": "^27.0.2",
         "p-limit": "^3.1.0",
@@ -9486,6 +9646,7 @@
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dev": true,
       "requires": {
         "punycode": "^2.1.0"
       }
@@ -9527,6 +9688,7 @@
       "version": "17.0.0",
       "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.0.tgz",
       "integrity": "sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg==",
+      "dev": true,
       "requires": {
         "chalk": "^4.1.0",
         "hash-sum": "^2.0.0",
@@ -9583,6 +9745,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz",
       "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==",
+      "dev": true,
       "requires": {
         "glob-to-regexp": "^0.4.1",
         "graceful-fs": "^4.1.2"
@@ -9592,6 +9755,7 @@
       "version": "5.44.0",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
       "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
+      "dev": true,
       "requires": {
         "@types/eslint-scope": "^3.7.0",
         "@types/estree": "^0.0.50",
@@ -9674,6 +9838,7 @@
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz",
       "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==",
+      "dev": true,
       "requires": {
         "source-list-map": "^2.0.1",
         "source-map": "^0.6.1"
@@ -9702,7 +9867,8 @@
     "yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index 3d4fa5f..3752313 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@material/menu": "^10.0.0",
     "@material/tooltip": "^12.0.0",
     "async-mutex": "^0.3.2",
-    "google-protobuf": "^3.18.0-rc.2",
+    "google-protobuf": "^3.19.3",
     "grpc-web": "^1.2.1",
     "idb": "^6.1.2",
     "poll-until-promise": "^3.6.1",
diff --git a/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js b/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js
index 0c5f28a..d422d74 100644
--- a/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js
+++ b/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js
@@ -24,7 +24,7 @@
 /**
  * @param {string} hostname
  * @param {?Object} credentials
- * @param {?Object} options
+ * @param {?grpc.web.ClientOptions} options
  * @constructor
  * @struct
  * @final
@@ -32,7 +32,7 @@
 proto.KillSwitchServiceClient =
     function(hostname, credentials, options) {
   if (!options) options = {};
-  options['format'] = 'text';
+  options.format = 'text';
 
   /**
    * @private @const {!grpc.web.GrpcWebClientBase} The client
@@ -50,7 +50,7 @@
 /**
  * @param {string} hostname
  * @param {?Object} credentials
- * @param {?Object} options
+ * @param {?grpc.web.ClientOptions} options
  * @constructor
  * @struct
  * @final
@@ -58,7 +58,7 @@
 proto.KillSwitchServicePromiseClient =
     function(hostname, credentials, options) {
   if (!options) options = {};
-  options['format'] = 'text';
+  options.format = 'text';
 
   /**
    * @private @const {!grpc.web.GrpcWebClientBase} The client
@@ -96,30 +96,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.GetKillSwitchStatusRequest,
- *   !proto.GetKillSwitchStatusResponse>}
- */
-const methodInfo_KillSwitchService_GetKillSwitchStatus = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.GetKillSwitchStatusResponse,
-  /**
-   * @param {!proto.GetKillSwitchStatusRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.GetKillSwitchStatusResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.GetKillSwitchStatusRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.GetKillSwitchStatusResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.GetKillSwitchStatusResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchStatusResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -138,7 +119,7 @@
 /**
  * @param {!proto.GetKillSwitchStatusRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.GetKillSwitchStatusResponse>}
  *     Promise that resolves to the response
@@ -176,30 +157,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.GetKillSwitchOverviewRequest,
- *   !proto.GetKillSwitchOverviewResponse>}
- */
-const methodInfo_KillSwitchService_GetKillSwitchOverview = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.GetKillSwitchOverviewResponse,
-  /**
-   * @param {!proto.GetKillSwitchOverviewRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.GetKillSwitchOverviewResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.GetKillSwitchOverviewRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.GetKillSwitchOverviewResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.GetKillSwitchOverviewResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchOverviewResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -218,7 +180,7 @@
 /**
  * @param {!proto.GetKillSwitchOverviewRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.GetKillSwitchOverviewResponse>}
  *     Promise that resolves to the response
@@ -256,30 +218,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.ListFeaturesRequest,
- *   !proto.ListFeaturesResponse>}
- */
-const methodInfo_KillSwitchService_ListFeatures = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.ListFeaturesResponse,
-  /**
-   * @param {!proto.ListFeaturesRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.ListFeaturesResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.ListFeaturesRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.ListFeaturesResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.ListFeaturesResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.ListFeaturesResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -298,7 +241,7 @@
 /**
  * @param {!proto.ListFeaturesRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.ListFeaturesResponse>}
  *     Promise that resolves to the response
@@ -336,30 +279,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.SyncFeaturesRequest,
- *   !proto.SyncFeaturesResponse>}
- */
-const methodInfo_KillSwitchService_SyncFeatures = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.SyncFeaturesResponse,
-  /**
-   * @param {!proto.SyncFeaturesRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.SyncFeaturesResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.SyncFeaturesRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.SyncFeaturesResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.SyncFeaturesResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.SyncFeaturesResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -378,7 +302,7 @@
 /**
  * @param {!proto.SyncFeaturesRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.SyncFeaturesResponse>}
  *     Promise that resolves to the response
@@ -416,30 +340,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.EnableKillSwitchRequest,
- *   !proto.EnableKillSwitchResponse>}
- */
-const methodInfo_KillSwitchService_EnableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.EnableKillSwitchResponse,
-  /**
-   * @param {!proto.EnableKillSwitchRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.EnableKillSwitchResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.EnableKillSwitchRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.EnableKillSwitchResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.EnableKillSwitchResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.EnableKillSwitchResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -458,7 +363,7 @@
 /**
  * @param {!proto.EnableKillSwitchRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.EnableKillSwitchResponse>}
  *     Promise that resolves to the response
@@ -496,30 +401,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.DisableKillSwitchRequest,
- *   !proto.DisableKillSwitchResponse>}
- */
-const methodInfo_KillSwitchService_DisableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.DisableKillSwitchResponse,
-  /**
-   * @param {!proto.DisableKillSwitchRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.DisableKillSwitchResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.DisableKillSwitchRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.DisableKillSwitchResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.DisableKillSwitchResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.DisableKillSwitchResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -538,7 +424,7 @@
 /**
  * @param {!proto.DisableKillSwitchRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.DisableKillSwitchResponse>}
  *     Promise that resolves to the response
@@ -576,30 +462,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.ListAuthorizedUsersRequest,
- *   !proto.ListAuthorizedUsersResponse>}
- */
-const methodInfo_KillSwitchService_ListAuthorizedUsers = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.ListAuthorizedUsersResponse,
-  /**
-   * @param {!proto.ListAuthorizedUsersRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.ListAuthorizedUsersResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.ListAuthorizedUsersRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.ListAuthorizedUsersResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.ListAuthorizedUsersResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.ListAuthorizedUsersResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -618,7 +485,7 @@
 /**
  * @param {!proto.ListAuthorizedUsersRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.ListAuthorizedUsersResponse>}
  *     Promise that resolves to the response
@@ -656,30 +523,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.AddAuthorizedUserRequest,
- *   !proto.AddAuthorizedUserResponse>}
- */
-const methodInfo_KillSwitchService_AddAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.AddAuthorizedUserResponse,
-  /**
-   * @param {!proto.AddAuthorizedUserRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.AddAuthorizedUserResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.AddAuthorizedUserRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.AddAuthorizedUserResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.AddAuthorizedUserResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.AddAuthorizedUserResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -698,7 +546,7 @@
 /**
  * @param {!proto.AddAuthorizedUserRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.AddAuthorizedUserResponse>}
  *     Promise that resolves to the response
@@ -736,30 +584,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.UpdateAuthorizedUserRequest,
- *   !proto.UpdateAuthorizedUserResponse>}
- */
-const methodInfo_KillSwitchService_UpdateAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.UpdateAuthorizedUserResponse,
-  /**
-   * @param {!proto.UpdateAuthorizedUserRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.UpdateAuthorizedUserResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.UpdateAuthorizedUserRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.UpdateAuthorizedUserResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.UpdateAuthorizedUserResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.UpdateAuthorizedUserResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -778,7 +607,7 @@
 /**
  * @param {!proto.UpdateAuthorizedUserRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.UpdateAuthorizedUserResponse>}
  *     Promise that resolves to the response
@@ -816,30 +645,11 @@
 
 
 /**
- * @const
- * @type {!grpc.web.AbstractClientBase.MethodInfo<
- *   !proto.DeleteAuthorizedUserRequest,
- *   !proto.DeleteAuthorizedUserResponse>}
- */
-const methodInfo_KillSwitchService_DeleteAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
-  proto.DeleteAuthorizedUserResponse,
-  /**
-   * @param {!proto.DeleteAuthorizedUserRequest} request
-   * @return {!Uint8Array}
-   */
-  function(request) {
-    return request.serializeBinary();
-  },
-  proto.DeleteAuthorizedUserResponse.deserializeBinary
-);
-
-
-/**
  * @param {!proto.DeleteAuthorizedUserRequest} request The
  *     request proto
  * @param {?Object<string, string>} metadata User defined
  *     call metadata
- * @param {function(?grpc.web.Error, ?proto.DeleteAuthorizedUserResponse)}
+ * @param {function(?grpc.web.RpcError, ?proto.DeleteAuthorizedUserResponse)}
  *     callback The callback function(error, response)
  * @return {!grpc.web.ClientReadableStream<!proto.DeleteAuthorizedUserResponse>|undefined}
  *     The XHR Node Readable Stream
@@ -858,7 +668,7 @@
 /**
  * @param {!proto.DeleteAuthorizedUserRequest} request The
  *     request proto
- * @param {?Object<string, string>} metadata User defined
+ * @param {?Object<string, string>=} metadata User defined
  *     call metadata
  * @return {!Promise<!proto.DeleteAuthorizedUserResponse>}
  *     Promise that resolves to the response
diff --git a/src/killSwitch/api_proto/kill_switch_objects_pb.js b/src/killSwitch/api_proto/kill_switch_objects_pb.js
index 4b3d6e6..427daa5 100644
--- a/src/killSwitch/api_proto/kill_switch_objects_pb.js
+++ b/src/killSwitch/api_proto/kill_switch_objects_pb.js
@@ -17,7 +17,7 @@
 
 var api_proto_common_pb = require('../api_proto/common_pb.js');
 goog.object.extend(proto, api_proto_common_pb);
-var google_protobuf_timestamp_pb = require('../../third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js');
+var google_protobuf_timestamp_pb = require('google-protobuf/google/protobuf/timestamp_pb.js');
 goog.object.extend(proto, google_protobuf_timestamp_pb);
 goog.exportSymbol('AuthorizedUserTransformation', null, proto);
 goog.exportSymbol('Feature', null, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js
deleted file mode 100644
index 62b1383..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js
+++ /dev/null
@@ -1,275 +0,0 @@
-// source: google/protobuf/any.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.Any', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Any = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Any, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Any.displayName = 'proto.google.protobuf.Any';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Any.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Any.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Any} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Any.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    typeUrl: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    value: msg.getValue_asB64()
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Any}
- */
-proto.google.protobuf.Any.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Any;
-  return proto.google.protobuf.Any.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Any} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Any}
- */
-proto.google.protobuf.Any.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTypeUrl(value);
-      break;
-    case 2:
-      var value = /** @type {!Uint8Array} */ (reader.readBytes());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Any.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Any.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Any} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Any.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getTypeUrl();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getValue_asU8();
-  if (f.length > 0) {
-    writer.writeBytes(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string type_url = 1;
- * @return {string}
- */
-proto.google.protobuf.Any.prototype.getTypeUrl = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Any} returns this
- */
-proto.google.protobuf.Any.prototype.setTypeUrl = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional bytes value = 2;
- * @return {!(string|Uint8Array)}
- */
-proto.google.protobuf.Any.prototype.getValue = function() {
-  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * optional bytes value = 2;
- * This is a type-conversion wrapper around `getValue()`
- * @return {string}
- */
-proto.google.protobuf.Any.prototype.getValue_asB64 = function() {
-  return /** @type {string} */ (jspb.Message.bytesAsB64(
-      this.getValue()));
-};
-
-
-/**
- * optional bytes value = 2;
- * Note that Uint8Array is not supported on all browsers.
- * @see http://caniuse.com/Uint8Array
- * This is a type-conversion wrapper around `getValue()`
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Any.prototype.getValue_asU8 = function() {
-  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
-      this.getValue()));
-};
-
-
-/**
- * @param {!(string|Uint8Array)} value
- * @return {!proto.google.protobuf.Any} returns this
- */
-proto.google.protobuf.Any.prototype.setValue = function(value) {
-  return jspb.Message.setProto3BytesField(this, 2, value);
-};
-
-
-goog.object.extend(exports, proto);
-/* This code will be inserted into generated code for
- * google/protobuf/any.proto. */
-
-/**
- * Returns the type name contained in this instance, if any.
- * @return {string|undefined}
- */
-proto.google.protobuf.Any.prototype.getTypeName = function() {
-  return this.getTypeUrl().split('/').pop();
-};
-
-
-/**
- * Packs the given message instance into this Any.
- * For binary format usage only.
- * @param {!Uint8Array} serialized The serialized data to pack.
- * @param {string} name The type name of this message object.
- * @param {string=} opt_typeUrlPrefix the type URL prefix.
- */
-proto.google.protobuf.Any.prototype.pack = function(serialized, name,
-                                                    opt_typeUrlPrefix) {
-  if (!opt_typeUrlPrefix) {
-    opt_typeUrlPrefix = 'type.googleapis.com/';
-  }
-
-  if (opt_typeUrlPrefix.substr(-1) != '/') {
-    this.setTypeUrl(opt_typeUrlPrefix + '/' + name);
-  } else {
-    this.setTypeUrl(opt_typeUrlPrefix + name);
-  }
-
-  this.setValue(serialized);
-};
-
-
-/**
- * @template T
- * Unpacks this Any into the given message object.
- * @param {function(Uint8Array):T} deserialize Function that will deserialize
- *     the binary data properly.
- * @param {string} name The expected type name of this message object.
- * @return {?T} If the name matched the expected name, returns the deserialized
- *     object, otherwise returns null.
- */
-proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {
-  if (this.getTypeName() == name) {
-    return deserialize(this.getValue_asU8());
-  } else {
-    return null;
-  }
-};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js
deleted file mode 100644
index 2ca9be2..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js
+++ /dev/null
@@ -1,995 +0,0 @@
-// source: google/protobuf/api.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-var google_protobuf_source_context_pb = require('google-protobuf/google/protobuf/source_context_pb.js');
-goog.object.extend(proto, google_protobuf_source_context_pb);
-var google_protobuf_type_pb = require('google-protobuf/google/protobuf/type_pb.js');
-goog.object.extend(proto, google_protobuf_type_pb);
-goog.exportSymbol('google.protobuf.Api', null, proto);
-goog.exportSymbol('google.protobuf.Method', null, proto);
-goog.exportSymbol('google.protobuf.Mixin', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Api = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Api.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.Api, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Api.displayName = 'proto.google.protobuf.Api';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Method = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Method.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.Method, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Method.displayName = 'proto.google.protobuf.Method';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Mixin = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Mixin, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Mixin.displayName = 'proto.google.protobuf.Mixin';
-}
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.Api.repeatedFields_ = [2,3,6];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Api.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Api.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Api} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Api.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    methodsList: jspb.Message.toObjectList(msg.getMethodsList(),
-    proto.google.protobuf.Method.toObject, includeInstance),
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    google_protobuf_type_pb.Option.toObject, includeInstance),
-    version: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
-    mixinsList: jspb.Message.toObjectList(msg.getMixinsList(),
-    proto.google.protobuf.Mixin.toObject, includeInstance),
-    syntax: jspb.Message.getFieldWithDefault(msg, 7, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Api}
- */
-proto.google.protobuf.Api.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Api;
-  return proto.google.protobuf.Api.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Api} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Api}
- */
-proto.google.protobuf.Api.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.Method;
-      reader.readMessage(value,proto.google.protobuf.Method.deserializeBinaryFromReader);
-      msg.addMethods(value);
-      break;
-    case 3:
-      var value = new google_protobuf_type_pb.Option;
-      reader.readMessage(value,google_protobuf_type_pb.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setVersion(value);
-      break;
-    case 5:
-      var value = new google_protobuf_source_context_pb.SourceContext;
-      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
-      msg.setSourceContext(value);
-      break;
-    case 6:
-      var value = new proto.google.protobuf.Mixin;
-      reader.readMessage(value,proto.google.protobuf.Mixin.deserializeBinaryFromReader);
-      msg.addMixins(value);
-      break;
-    case 7:
-      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
-      msg.setSyntax(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Api.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Api.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Api} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Api.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getMethodsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.Method.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      3,
-      f,
-      google_protobuf_type_pb.Option.serializeBinaryToWriter
-    );
-  }
-  f = message.getVersion();
-  if (f.length > 0) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = message.getSourceContext();
-  if (f != null) {
-    writer.writeMessage(
-      5,
-      f,
-      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
-    );
-  }
-  f = message.getMixinsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      6,
-      f,
-      proto.google.protobuf.Mixin.serializeBinaryToWriter
-    );
-  }
-  f = message.getSyntax();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      7,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Api.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * repeated Method methods = 2;
- * @return {!Array<!proto.google.protobuf.Method>}
- */
-proto.google.protobuf.Api.prototype.getMethodsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Method>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Method, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Method>} value
- * @return {!proto.google.protobuf.Api} returns this
-*/
-proto.google.protobuf.Api.prototype.setMethodsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Method=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Method}
- */
-proto.google.protobuf.Api.prototype.addMethods = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.Method, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.clearMethodsList = function() {
-  return this.setMethodsList([]);
-};
-
-
-/**
- * repeated Option options = 3;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.Api.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, google_protobuf_type_pb.Option, 3));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.Api} returns this
-*/
-proto.google.protobuf.Api.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 3, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Api.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-/**
- * optional string version = 4;
- * @return {string}
- */
-proto.google.protobuf.Api.prototype.getVersion = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.setVersion = function(value) {
-  return jspb.Message.setProto3StringField(this, 4, value);
-};
-
-
-/**
- * optional SourceContext source_context = 5;
- * @return {?proto.google.protobuf.SourceContext}
- */
-proto.google.protobuf.Api.prototype.getSourceContext = function() {
-  return /** @type{?proto.google.protobuf.SourceContext} */ (
-    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 5));
-};
-
-
-/**
- * @param {?proto.google.protobuf.SourceContext|undefined} value
- * @return {!proto.google.protobuf.Api} returns this
-*/
-proto.google.protobuf.Api.prototype.setSourceContext = function(value) {
-  return jspb.Message.setWrapperField(this, 5, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.clearSourceContext = function() {
-  return this.setSourceContext(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Api.prototype.hasSourceContext = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * repeated Mixin mixins = 6;
- * @return {!Array<!proto.google.protobuf.Mixin>}
- */
-proto.google.protobuf.Api.prototype.getMixinsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Mixin>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Mixin, 6));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Mixin>} value
- * @return {!proto.google.protobuf.Api} returns this
-*/
-proto.google.protobuf.Api.prototype.setMixinsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 6, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Mixin=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Mixin}
- */
-proto.google.protobuf.Api.prototype.addMixins = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.Mixin, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.clearMixinsList = function() {
-  return this.setMixinsList([]);
-};
-
-
-/**
- * optional Syntax syntax = 7;
- * @return {!proto.google.protobuf.Syntax}
- */
-proto.google.protobuf.Api.prototype.getSyntax = function() {
-  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Syntax} value
- * @return {!proto.google.protobuf.Api} returns this
- */
-proto.google.protobuf.Api.prototype.setSyntax = function(value) {
-  return jspb.Message.setProto3EnumField(this, 7, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.Method.repeatedFields_ = [6];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Method.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Method.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Method} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Method.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    requestTypeUrl: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    requestStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
-    responseTypeUrl: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    responseStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    google_protobuf_type_pb.Option.toObject, includeInstance),
-    syntax: jspb.Message.getFieldWithDefault(msg, 7, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Method}
- */
-proto.google.protobuf.Method.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Method;
-  return proto.google.protobuf.Method.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Method} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Method}
- */
-proto.google.protobuf.Method.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setRequestTypeUrl(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setRequestStreaming(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setResponseTypeUrl(value);
-      break;
-    case 5:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setResponseStreaming(value);
-      break;
-    case 6:
-      var value = new google_protobuf_type_pb.Option;
-      reader.readMessage(value,google_protobuf_type_pb.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    case 7:
-      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
-      msg.setSyntax(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Method.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Method.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Method} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Method.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getRequestTypeUrl();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = message.getRequestStreaming();
-  if (f) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-  f = message.getResponseTypeUrl();
-  if (f.length > 0) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = message.getResponseStreaming();
-  if (f) {
-    writer.writeBool(
-      5,
-      f
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      6,
-      f,
-      google_protobuf_type_pb.Option.serializeBinaryToWriter
-    );
-  }
-  f = message.getSyntax();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      7,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Method.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional string request_type_url = 2;
- * @return {string}
- */
-proto.google.protobuf.Method.prototype.getRequestTypeUrl = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setRequestTypeUrl = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
-};
-
-
-/**
- * optional bool request_streaming = 3;
- * @return {boolean}
- */
-proto.google.protobuf.Method.prototype.getRequestStreaming = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setRequestStreaming = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 3, value);
-};
-
-
-/**
- * optional string response_type_url = 4;
- * @return {string}
- */
-proto.google.protobuf.Method.prototype.getResponseTypeUrl = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setResponseTypeUrl = function(value) {
-  return jspb.Message.setProto3StringField(this, 4, value);
-};
-
-
-/**
- * optional bool response_streaming = 5;
- * @return {boolean}
- */
-proto.google.protobuf.Method.prototype.getResponseStreaming = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setResponseStreaming = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 5, value);
-};
-
-
-/**
- * repeated Option options = 6;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.Method.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, google_protobuf_type_pb.Option, 6));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.Method} returns this
-*/
-proto.google.protobuf.Method.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 6, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Method.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-/**
- * optional Syntax syntax = 7;
- * @return {!proto.google.protobuf.Syntax}
- */
-proto.google.protobuf.Method.prototype.getSyntax = function() {
-  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Syntax} value
- * @return {!proto.google.protobuf.Method} returns this
- */
-proto.google.protobuf.Method.prototype.setSyntax = function(value) {
-  return jspb.Message.setProto3EnumField(this, 7, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Mixin.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Mixin.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Mixin} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Mixin.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    root: jspb.Message.getFieldWithDefault(msg, 2, "")
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Mixin}
- */
-proto.google.protobuf.Mixin.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Mixin;
-  return proto.google.protobuf.Mixin.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Mixin} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Mixin}
- */
-proto.google.protobuf.Mixin.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setRoot(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Mixin.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Mixin.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Mixin} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Mixin.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getRoot();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Mixin.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Mixin} returns this
- */
-proto.google.protobuf.Mixin.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional string root = 2;
- * @return {string}
- */
-proto.google.protobuf.Mixin.prototype.getRoot = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Mixin} returns this
- */
-proto.google.protobuf.Mixin.prototype.setRoot = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js
deleted file mode 100644
index d080473..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js
+++ /dev/null
@@ -1,1268 +0,0 @@
-// source: google/protobuf/compiler/plugin.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-var google_protobuf_descriptor_pb = require('google-protobuf/google/protobuf/descriptor_pb.js');
-goog.object.extend(proto, google_protobuf_descriptor_pb);
-goog.exportSymbol('google.protobuf.compiler.CodeGeneratorRequest', null, proto);
-goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse', null, proto);
-goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse.Feature', null, proto);
-goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse.File', null, proto);
-goog.exportSymbol('google.protobuf.compiler.Version', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.compiler.Version = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.compiler.Version, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.compiler.Version.displayName = 'proto.google.protobuf.compiler.Version';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.compiler.CodeGeneratorRequest.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.compiler.CodeGeneratorRequest, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.compiler.CodeGeneratorRequest.displayName = 'proto.google.protobuf.compiler.CodeGeneratorRequest';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.compiler.CodeGeneratorResponse.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.compiler.CodeGeneratorResponse, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.compiler.CodeGeneratorResponse.displayName = 'proto.google.protobuf.compiler.CodeGeneratorResponse';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.compiler.CodeGeneratorResponse.File, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.compiler.CodeGeneratorResponse.File.displayName = 'proto.google.protobuf.compiler.CodeGeneratorResponse.File';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.compiler.Version.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.compiler.Version.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.compiler.Version} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.Version.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    major: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    minor: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    patch: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    suffix: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.compiler.Version}
- */
-proto.google.protobuf.compiler.Version.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.compiler.Version;
-  return proto.google.protobuf.compiler.Version.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.compiler.Version} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.compiler.Version}
- */
-proto.google.protobuf.compiler.Version.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setMajor(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setMinor(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setPatch(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setSuffix(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.compiler.Version.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.compiler.Version.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.compiler.Version} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.Version.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {number} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeInt32(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeInt32(
-      3,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int32 major = 1;
- * @return {number}
- */
-proto.google.protobuf.compiler.Version.prototype.getMajor = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.setMajor = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.clearMajor = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.Version.prototype.hasMajor = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 minor = 2;
- * @return {number}
- */
-proto.google.protobuf.compiler.Version.prototype.getMinor = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.setMinor = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.clearMinor = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.Version.prototype.hasMinor = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional int32 patch = 3;
- * @return {number}
- */
-proto.google.protobuf.compiler.Version.prototype.getPatch = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.setPatch = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.clearPatch = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.Version.prototype.hasPatch = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional string suffix = 4;
- * @return {string}
- */
-proto.google.protobuf.compiler.Version.prototype.getSuffix = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.setSuffix = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.Version} returns this
- */
-proto.google.protobuf.compiler.Version.prototype.clearSuffix = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.Version.prototype.hasSuffix = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.repeatedFields_ = [1,15];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.compiler.CodeGeneratorRequest.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    fileToGenerateList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
-    parameter: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    protoFileList: jspb.Message.toObjectList(msg.getProtoFileList(),
-    google_protobuf_descriptor_pb.FileDescriptorProto.toObject, includeInstance),
-    compilerVersion: (f = msg.getCompilerVersion()) && proto.google.protobuf.compiler.Version.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.compiler.CodeGeneratorRequest;
-  return proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addFileToGenerate(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setParameter(value);
-      break;
-    case 15:
-      var value = new google_protobuf_descriptor_pb.FileDescriptorProto;
-      reader.readMessage(value,google_protobuf_descriptor_pb.FileDescriptorProto.deserializeBinaryFromReader);
-      msg.addProtoFile(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.compiler.Version;
-      reader.readMessage(value,proto.google.protobuf.compiler.Version.deserializeBinaryFromReader);
-      msg.setCompilerVersion(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.compiler.CodeGeneratorRequest.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getFileToGenerateList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = message.getProtoFileList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      15,
-      f,
-      google_protobuf_descriptor_pb.FileDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getCompilerVersion();
-  if (f != null) {
-    writer.writeMessage(
-      3,
-      f,
-      proto.google.protobuf.compiler.Version.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * repeated string file_to_generate = 1;
- * @return {!Array<string>}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getFileToGenerateList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setFileToGenerateList = function(value) {
-  return jspb.Message.setField(this, 1, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.addFileToGenerate = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearFileToGenerateList = function() {
-  return this.setFileToGenerateList([]);
-};
-
-
-/**
- * optional string parameter = 2;
- * @return {string}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getParameter = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setParameter = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearParameter = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.hasParameter = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * repeated google.protobuf.FileDescriptorProto proto_file = 15;
- * @return {!Array<!proto.google.protobuf.FileDescriptorProto>}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getProtoFileList = function() {
-  return /** @type{!Array<!proto.google.protobuf.FileDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, google_protobuf_descriptor_pb.FileDescriptorProto, 15));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.FileDescriptorProto>} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
-*/
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setProtoFileList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 15, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.FileDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FileDescriptorProto}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.addProtoFile = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 15, opt_value, proto.google.protobuf.FileDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearProtoFileList = function() {
-  return this.setProtoFileList([]);
-};
-
-
-/**
- * optional Version compiler_version = 3;
- * @return {?proto.google.protobuf.compiler.Version}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getCompilerVersion = function() {
-  return /** @type{?proto.google.protobuf.compiler.Version} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.compiler.Version, 3));
-};
-
-
-/**
- * @param {?proto.google.protobuf.compiler.Version|undefined} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
-*/
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setCompilerVersion = function(value) {
-  return jspb.Message.setWrapperField(this, 3, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearCompilerVersion = function() {
-  return this.setCompilerVersion(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.hasCompilerVersion = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.repeatedFields_ = [15];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.compiler.CodeGeneratorResponse.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    error: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    supportedFeatures: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    fileList: jspb.Message.toObjectList(msg.getFileList(),
-    proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.compiler.CodeGeneratorResponse;
-  return proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setError(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.setSupportedFeatures(value);
-      break;
-    case 15:
-      var value = new proto.google.protobuf.compiler.CodeGeneratorResponse.File;
-      reader.readMessage(value,proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader);
-      msg.addFile(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.compiler.CodeGeneratorResponse.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeUint64(
-      2,
-      f
-    );
-  }
-  f = message.getFileList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      15,
-      f,
-      proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.Feature = {
-  FEATURE_NONE: 0,
-  FEATURE_PROTO3_OPTIONAL: 1
-};
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    insertionPoint: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    content: (f = jspb.Message.getField(msg, 15)) == null ? undefined : f,
-    generatedCodeInfo: (f = msg.getGeneratedCodeInfo()) && google_protobuf_descriptor_pb.GeneratedCodeInfo.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.compiler.CodeGeneratorResponse.File;
-  return proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setInsertionPoint(value);
-      break;
-    case 15:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setContent(value);
-      break;
-    case 16:
-      var value = new google_protobuf_descriptor_pb.GeneratedCodeInfo;
-      reader.readMessage(value,google_protobuf_descriptor_pb.GeneratedCodeInfo.deserializeBinaryFromReader);
-      msg.setGeneratedCodeInfo(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 15));
-  if (f != null) {
-    writer.writeString(
-      15,
-      f
-    );
-  }
-  f = message.getGeneratedCodeInfo();
-  if (f != null) {
-    writer.writeMessage(
-      16,
-      f,
-      google_protobuf_descriptor_pb.GeneratedCodeInfo.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string insertion_point = 2;
- * @return {string}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getInsertionPoint = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setInsertionPoint = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearInsertionPoint = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasInsertionPoint = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string content = 15;
- * @return {string}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getContent = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 15, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setContent = function(value) {
-  return jspb.Message.setField(this, 15, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearContent = function() {
-  return jspb.Message.setField(this, 15, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasContent = function() {
-  return jspb.Message.getField(this, 15) != null;
-};
-
-
-/**
- * optional google.protobuf.GeneratedCodeInfo generated_code_info = 16;
- * @return {?proto.google.protobuf.GeneratedCodeInfo}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getGeneratedCodeInfo = function() {
-  return /** @type{?proto.google.protobuf.GeneratedCodeInfo} */ (
-    jspb.Message.getWrapperField(this, google_protobuf_descriptor_pb.GeneratedCodeInfo, 16));
-};
-
-
-/**
- * @param {?proto.google.protobuf.GeneratedCodeInfo|undefined} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
-*/
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setGeneratedCodeInfo = function(value) {
-  return jspb.Message.setWrapperField(this, 16, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearGeneratedCodeInfo = function() {
-  return this.setGeneratedCodeInfo(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasGeneratedCodeInfo = function() {
-  return jspb.Message.getField(this, 16) != null;
-};
-
-
-/**
- * optional string error = 1;
- * @return {string}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getError = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setError = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearError = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.hasError = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional uint64 supported_features = 2;
- * @return {number}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getSupportedFeatures = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setSupportedFeatures = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearSupportedFeatures = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.hasSupportedFeatures = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * repeated File file = 15;
- * @return {!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getFileList = function() {
-  return /** @type{!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.compiler.CodeGeneratorResponse.File, 15));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>} value
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
-*/
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setFileList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 15, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.addFile = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 15, opt_value, proto.google.protobuf.compiler.CodeGeneratorResponse.File, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
- */
-proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearFileList = function() {
-  return this.setFileList([]);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js
deleted file mode 100644
index b0a9f1f..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js
+++ /dev/null
@@ -1,10070 +0,0 @@
-// source: google/protobuf/descriptor.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.DescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.DescriptorProto.ExtensionRange', null, proto);
-goog.exportSymbol('google.protobuf.DescriptorProto.ReservedRange', null, proto);
-goog.exportSymbol('google.protobuf.EnumDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.EnumDescriptorProto.EnumReservedRange', null, proto);
-goog.exportSymbol('google.protobuf.EnumOptions', null, proto);
-goog.exportSymbol('google.protobuf.EnumValueDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.EnumValueOptions', null, proto);
-goog.exportSymbol('google.protobuf.ExtensionRangeOptions', null, proto);
-goog.exportSymbol('google.protobuf.FieldDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.FieldDescriptorProto.Label', null, proto);
-goog.exportSymbol('google.protobuf.FieldDescriptorProto.Type', null, proto);
-goog.exportSymbol('google.protobuf.FieldOptions', null, proto);
-goog.exportSymbol('google.protobuf.FieldOptions.CType', null, proto);
-goog.exportSymbol('google.protobuf.FieldOptions.JSType', null, proto);
-goog.exportSymbol('google.protobuf.FileDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.FileDescriptorSet', null, proto);
-goog.exportSymbol('google.protobuf.FileOptions', null, proto);
-goog.exportSymbol('google.protobuf.FileOptions.OptimizeMode', null, proto);
-goog.exportSymbol('google.protobuf.GeneratedCodeInfo', null, proto);
-goog.exportSymbol('google.protobuf.GeneratedCodeInfo.Annotation', null, proto);
-goog.exportSymbol('google.protobuf.MessageOptions', null, proto);
-goog.exportSymbol('google.protobuf.MethodDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.MethodOptions', null, proto);
-goog.exportSymbol('google.protobuf.MethodOptions.IdempotencyLevel', null, proto);
-goog.exportSymbol('google.protobuf.OneofDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.OneofOptions', null, proto);
-goog.exportSymbol('google.protobuf.ServiceDescriptorProto', null, proto);
-goog.exportSymbol('google.protobuf.ServiceOptions', null, proto);
-goog.exportSymbol('google.protobuf.SourceCodeInfo', null, proto);
-goog.exportSymbol('google.protobuf.SourceCodeInfo.Location', null, proto);
-goog.exportSymbol('google.protobuf.UninterpretedOption', null, proto);
-goog.exportSymbol('google.protobuf.UninterpretedOption.NamePart', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FileDescriptorSet = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FileDescriptorSet.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.FileDescriptorSet, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FileDescriptorSet.displayName = 'proto.google.protobuf.FileDescriptorSet';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FileDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FileDescriptorProto.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.FileDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FileDescriptorProto.displayName = 'proto.google.protobuf.FileDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.DescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.DescriptorProto.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.DescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.DescriptorProto.displayName = 'proto.google.protobuf.DescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.DescriptorProto.ExtensionRange, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.DescriptorProto.ExtensionRange.displayName = 'proto.google.protobuf.DescriptorProto.ExtensionRange';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.DescriptorProto.ReservedRange = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.DescriptorProto.ReservedRange, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.DescriptorProto.ReservedRange.displayName = 'proto.google.protobuf.DescriptorProto.ReservedRange';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.ExtensionRangeOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.ExtensionRangeOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.ExtensionRangeOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.ExtensionRangeOptions.displayName = 'proto.google.protobuf.ExtensionRangeOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.ExtensionRangeOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.ExtensionRangeOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FieldDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.FieldDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FieldDescriptorProto.displayName = 'proto.google.protobuf.FieldDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.OneofDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.OneofDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.OneofDescriptorProto.displayName = 'proto.google.protobuf.OneofDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.EnumDescriptorProto.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.EnumDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumDescriptorProto.displayName = 'proto.google.protobuf.EnumDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.displayName = 'proto.google.protobuf.EnumDescriptorProto.EnumReservedRange';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumValueDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.EnumValueDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumValueDescriptorProto.displayName = 'proto.google.protobuf.EnumValueDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.ServiceDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.ServiceDescriptorProto.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.ServiceDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.ServiceDescriptorProto.displayName = 'proto.google.protobuf.ServiceDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.MethodDescriptorProto = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.MethodDescriptorProto, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.MethodDescriptorProto.displayName = 'proto.google.protobuf.MethodDescriptorProto';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FileOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.FileOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.FileOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FileOptions.displayName = 'proto.google.protobuf.FileOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.FileOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.FileOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.MessageOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.MessageOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.MessageOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.MessageOptions.displayName = 'proto.google.protobuf.MessageOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.MessageOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.MessageOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FieldOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.FieldOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.FieldOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FieldOptions.displayName = 'proto.google.protobuf.FieldOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.FieldOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.FieldOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.OneofOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.OneofOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.OneofOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.OneofOptions.displayName = 'proto.google.protobuf.OneofOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.OneofOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.OneofOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.EnumOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.EnumOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumOptions.displayName = 'proto.google.protobuf.EnumOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.EnumOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.EnumOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumValueOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.EnumValueOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.EnumValueOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumValueOptions.displayName = 'proto.google.protobuf.EnumValueOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.EnumValueOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.EnumValueOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.ServiceOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.ServiceOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.ServiceOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.ServiceOptions.displayName = 'proto.google.protobuf.ServiceOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.ServiceOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.ServiceOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.MethodOptions = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.MethodOptions.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.MethodOptions, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.MethodOptions.displayName = 'proto.google.protobuf.MethodOptions';
-}
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldInfo>}
- */
-proto.google.protobuf.MethodOptions.extensions = {};
-
-
-/**
- * The extensions registered with this message class. This is a map of
- * extension field number to fieldInfo object.
- *
- * For example:
- *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
- *
- * fieldName contains the JsCompiler renamed field name property so that it
- * works in OPTIMIZED mode.
- *
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
- */
-proto.google.protobuf.MethodOptions.extensionsBinary = {};
-
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.UninterpretedOption = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.UninterpretedOption.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.UninterpretedOption, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.UninterpretedOption.displayName = 'proto.google.protobuf.UninterpretedOption';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.UninterpretedOption.NamePart = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.UninterpretedOption.NamePart, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.UninterpretedOption.NamePart.displayName = 'proto.google.protobuf.UninterpretedOption.NamePart';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.SourceCodeInfo = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.SourceCodeInfo.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.SourceCodeInfo, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.SourceCodeInfo.displayName = 'proto.google.protobuf.SourceCodeInfo';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.SourceCodeInfo.Location = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.SourceCodeInfo.Location.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.SourceCodeInfo.Location, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.SourceCodeInfo.Location.displayName = 'proto.google.protobuf.SourceCodeInfo.Location';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.GeneratedCodeInfo = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.GeneratedCodeInfo.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.GeneratedCodeInfo, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.GeneratedCodeInfo.displayName = 'proto.google.protobuf.GeneratedCodeInfo';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.GeneratedCodeInfo.Annotation.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.GeneratedCodeInfo.Annotation, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.GeneratedCodeInfo.Annotation.displayName = 'proto.google.protobuf.GeneratedCodeInfo.Annotation';
-}
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.FileDescriptorSet.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FileDescriptorSet.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FileDescriptorSet.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FileDescriptorSet} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileDescriptorSet.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    fileList: jspb.Message.toObjectList(msg.getFileList(),
-    proto.google.protobuf.FileDescriptorProto.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FileDescriptorSet}
- */
-proto.google.protobuf.FileDescriptorSet.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FileDescriptorSet;
-  return proto.google.protobuf.FileDescriptorSet.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FileDescriptorSet} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FileDescriptorSet}
- */
-proto.google.protobuf.FileDescriptorSet.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new proto.google.protobuf.FileDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader);
-      msg.addFile(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FileDescriptorSet.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FileDescriptorSet.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FileDescriptorSet} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileDescriptorSet.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getFileList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      1,
-      f,
-      proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * repeated FileDescriptorProto file = 1;
- * @return {!Array<!proto.google.protobuf.FileDescriptorProto>}
- */
-proto.google.protobuf.FileDescriptorSet.prototype.getFileList = function() {
-  return /** @type{!Array<!proto.google.protobuf.FileDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FileDescriptorProto, 1));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.FileDescriptorProto>} value
- * @return {!proto.google.protobuf.FileDescriptorSet} returns this
-*/
-proto.google.protobuf.FileDescriptorSet.prototype.setFileList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 1, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.FileDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FileDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorSet.prototype.addFile = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.FileDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorSet} returns this
- */
-proto.google.protobuf.FileDescriptorSet.prototype.clearFileList = function() {
-  return this.setFileList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.FileDescriptorProto.repeatedFields_ = [3,10,11,4,5,6,7];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FileDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FileDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    pb_package: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    dependencyList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
-    publicDependencyList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f,
-    weakDependencyList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f,
-    messageTypeList: jspb.Message.toObjectList(msg.getMessageTypeList(),
-    proto.google.protobuf.DescriptorProto.toObject, includeInstance),
-    enumTypeList: jspb.Message.toObjectList(msg.getEnumTypeList(),
-    proto.google.protobuf.EnumDescriptorProto.toObject, includeInstance),
-    serviceList: jspb.Message.toObjectList(msg.getServiceList(),
-    proto.google.protobuf.ServiceDescriptorProto.toObject, includeInstance),
-    extensionList: jspb.Message.toObjectList(msg.getExtensionList(),
-    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
-    options: (f = msg.getOptions()) && proto.google.protobuf.FileOptions.toObject(includeInstance, f),
-    sourceCodeInfo: (f = msg.getSourceCodeInfo()) && proto.google.protobuf.SourceCodeInfo.toObject(includeInstance, f),
-    syntax: (f = jspb.Message.getField(msg, 12)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FileDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FileDescriptorProto;
-  return proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FileDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FileDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setPackage(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addDependency(value);
-      break;
-    case 10:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addPublicDependency(values[i]);
-      }
-      break;
-    case 11:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addWeakDependency(values[i]);
-      }
-      break;
-    case 4:
-      var value = new proto.google.protobuf.DescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader);
-      msg.addMessageType(value);
-      break;
-    case 5:
-      var value = new proto.google.protobuf.EnumDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader);
-      msg.addEnumType(value);
-      break;
-    case 6:
-      var value = new proto.google.protobuf.ServiceDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader);
-      msg.addService(value);
-      break;
-    case 7:
-      var value = new proto.google.protobuf.FieldDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
-      msg.addExtension$(value);
-      break;
-    case 8:
-      var value = new proto.google.protobuf.FileOptions;
-      reader.readMessage(value,proto.google.protobuf.FileOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    case 9:
-      var value = new proto.google.protobuf.SourceCodeInfo;
-      reader.readMessage(value,proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader);
-      msg.setSourceCodeInfo(value);
-      break;
-    case 12:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setSyntax(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FileDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = message.getDependencyList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      3,
-      f
-    );
-  }
-  f = message.getPublicDependencyList();
-  if (f.length > 0) {
-    writer.writeRepeatedInt32(
-      10,
-      f
-    );
-  }
-  f = message.getWeakDependencyList();
-  if (f.length > 0) {
-    writer.writeRepeatedInt32(
-      11,
-      f
-    );
-  }
-  f = message.getMessageTypeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      4,
-      f,
-      proto.google.protobuf.DescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getEnumTypeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      5,
-      f,
-      proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getServiceList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      6,
-      f,
-      proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getExtensionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      7,
-      f,
-      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      8,
-      f,
-      proto.google.protobuf.FileOptions.serializeBinaryToWriter
-    );
-  }
-  f = message.getSourceCodeInfo();
-  if (f != null) {
-    writer.writeMessage(
-      9,
-      f,
-      proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 12));
-  if (f != null) {
-    writer.writeString(
-      12,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string package = 2;
- * @return {string}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getPackage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setPackage = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearPackage = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.hasPackage = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * repeated string dependency = 3;
- * @return {!Array<string>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getDependencyList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setDependencyList = function(value) {
-  return jspb.Message.setField(this, 3, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addDependency = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearDependencyList = function() {
-  return this.setDependencyList([]);
-};
-
-
-/**
- * repeated int32 public_dependency = 10;
- * @return {!Array<number>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getPublicDependencyList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 10));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setPublicDependencyList = function(value) {
-  return jspb.Message.setField(this, 10, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addPublicDependency = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearPublicDependencyList = function() {
-  return this.setPublicDependencyList([]);
-};
-
-
-/**
- * repeated int32 weak_dependency = 11;
- * @return {!Array<number>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getWeakDependencyList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 11));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setWeakDependencyList = function(value) {
-  return jspb.Message.setField(this, 11, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addWeakDependency = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 11, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearWeakDependencyList = function() {
-  return this.setWeakDependencyList([]);
-};
-
-
-/**
- * repeated DescriptorProto message_type = 4;
- * @return {!Array<!proto.google.protobuf.DescriptorProto>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getMessageTypeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.DescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto, 4));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.DescriptorProto>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setMessageTypeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 4, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.DescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.DescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addMessageType = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.DescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearMessageTypeList = function() {
-  return this.setMessageTypeList([]);
-};
-
-
-/**
- * repeated EnumDescriptorProto enum_type = 5;
- * @return {!Array<!proto.google.protobuf.EnumDescriptorProto>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getEnumTypeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto, 5));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.EnumDescriptorProto>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setEnumTypeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 5, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.EnumDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addEnumType = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.google.protobuf.EnumDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearEnumTypeList = function() {
-  return this.setEnumTypeList([]);
-};
-
-
-/**
- * repeated ServiceDescriptorProto service = 6;
- * @return {!Array<!proto.google.protobuf.ServiceDescriptorProto>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getServiceList = function() {
-  return /** @type{!Array<!proto.google.protobuf.ServiceDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.ServiceDescriptorProto, 6));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.ServiceDescriptorProto>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setServiceList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 6, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.ServiceDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.ServiceDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addService = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.ServiceDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearServiceList = function() {
-  return this.setServiceList([]);
-};
-
-
-/**
- * repeated FieldDescriptorProto extension = 7;
- * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getExtensionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 7));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setExtensionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 7, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FieldDescriptorProto}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.addExtension$ = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearExtensionList = function() {
-  return this.setExtensionList([]);
-};
-
-
-/**
- * optional FileOptions options = 8;
- * @return {?proto.google.protobuf.FileOptions}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.FileOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.FileOptions, 8));
-};
-
-
-/**
- * @param {?proto.google.protobuf.FileOptions|undefined} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 8, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 8) != null;
-};
-
-
-/**
- * optional SourceCodeInfo source_code_info = 9;
- * @return {?proto.google.protobuf.SourceCodeInfo}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getSourceCodeInfo = function() {
-  return /** @type{?proto.google.protobuf.SourceCodeInfo} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.SourceCodeInfo, 9));
-};
-
-
-/**
- * @param {?proto.google.protobuf.SourceCodeInfo|undefined} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
-*/
-proto.google.protobuf.FileDescriptorProto.prototype.setSourceCodeInfo = function(value) {
-  return jspb.Message.setWrapperField(this, 9, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearSourceCodeInfo = function() {
-  return this.setSourceCodeInfo(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.hasSourceCodeInfo = function() {
-  return jspb.Message.getField(this, 9) != null;
-};
-
-
-/**
- * optional string syntax = 12;
- * @return {string}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.getSyntax = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.setSyntax = function(value) {
-  return jspb.Message.setField(this, 12, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileDescriptorProto} returns this
- */
-proto.google.protobuf.FileDescriptorProto.prototype.clearSyntax = function() {
-  return jspb.Message.setField(this, 12, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileDescriptorProto.prototype.hasSyntax = function() {
-  return jspb.Message.getField(this, 12) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.DescriptorProto.repeatedFields_ = [2,6,3,4,5,8,9,10];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.DescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.DescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.DescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    fieldList: jspb.Message.toObjectList(msg.getFieldList(),
-    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
-    extensionList: jspb.Message.toObjectList(msg.getExtensionList(),
-    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
-    nestedTypeList: jspb.Message.toObjectList(msg.getNestedTypeList(),
-    proto.google.protobuf.DescriptorProto.toObject, includeInstance),
-    enumTypeList: jspb.Message.toObjectList(msg.getEnumTypeList(),
-    proto.google.protobuf.EnumDescriptorProto.toObject, includeInstance),
-    extensionRangeList: jspb.Message.toObjectList(msg.getExtensionRangeList(),
-    proto.google.protobuf.DescriptorProto.ExtensionRange.toObject, includeInstance),
-    oneofDeclList: jspb.Message.toObjectList(msg.getOneofDeclList(),
-    proto.google.protobuf.OneofDescriptorProto.toObject, includeInstance),
-    options: (f = msg.getOptions()) && proto.google.protobuf.MessageOptions.toObject(includeInstance, f),
-    reservedRangeList: jspb.Message.toObjectList(msg.getReservedRangeList(),
-    proto.google.protobuf.DescriptorProto.ReservedRange.toObject, includeInstance),
-    reservedNameList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.DescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.DescriptorProto;
-  return proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.DescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.DescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.FieldDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
-      msg.addField(value);
-      break;
-    case 6:
-      var value = new proto.google.protobuf.FieldDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
-      msg.addExtension$(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.DescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader);
-      msg.addNestedType(value);
-      break;
-    case 4:
-      var value = new proto.google.protobuf.EnumDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader);
-      msg.addEnumType(value);
-      break;
-    case 5:
-      var value = new proto.google.protobuf.DescriptorProto.ExtensionRange;
-      reader.readMessage(value,proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader);
-      msg.addExtensionRange(value);
-      break;
-    case 8:
-      var value = new proto.google.protobuf.OneofDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader);
-      msg.addOneofDecl(value);
-      break;
-    case 7:
-      var value = new proto.google.protobuf.MessageOptions;
-      reader.readMessage(value,proto.google.protobuf.MessageOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    case 9:
-      var value = new proto.google.protobuf.DescriptorProto.ReservedRange;
-      reader.readMessage(value,proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader);
-      msg.addReservedRange(value);
-      break;
-    case 10:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addReservedName(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.DescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.DescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.DescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getFieldList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getExtensionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      6,
-      f,
-      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getNestedTypeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      3,
-      f,
-      proto.google.protobuf.DescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getEnumTypeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      4,
-      f,
-      proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getExtensionRangeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      5,
-      f,
-      proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter
-    );
-  }
-  f = message.getOneofDeclList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      8,
-      f,
-      proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      7,
-      f,
-      proto.google.protobuf.MessageOptions.serializeBinaryToWriter
-    );
-  }
-  f = message.getReservedRangeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      9,
-      f,
-      proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter
-    );
-  }
-  f = message.getReservedNameList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      10,
-      f
-    );
-  }
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.DescriptorProto.ExtensionRange.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    options: (f = msg.getOptions()) && proto.google.protobuf.ExtensionRangeOptions.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.DescriptorProto.ExtensionRange;
-  return proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setStart(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setEnd(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.ExtensionRangeOptions;
-      reader.readMessage(value,proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {number} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeInt32(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      3,
-      f,
-      proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional int32 start = 1;
- * @return {number}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getStart = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setStart = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearStart = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasStart = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 end = 2;
- * @return {number}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getEnd = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setEnd = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearEnd = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasEnd = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional ExtensionRangeOptions options = 3;
- * @return {?proto.google.protobuf.ExtensionRangeOptions}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.ExtensionRangeOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.ExtensionRangeOptions, 3));
-};
-
-
-/**
- * @param {?proto.google.protobuf.ExtensionRangeOptions|undefined} value
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
-*/
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 3, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.DescriptorProto.ReservedRange.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.DescriptorProto.ReservedRange;
-  return proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setStart(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setEnd(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {number} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeInt32(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int32 start = 1;
- * @return {number}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.getStart = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.setStart = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.clearStart = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.hasStart = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 end = 2;
- * @return {number}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.getEnd = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.setEnd = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.clearEnd = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.ReservedRange.prototype.hasEnd = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.DescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * repeated FieldDescriptorProto field = 2;
- * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getFieldList = function() {
-  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setFieldList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FieldDescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.prototype.addField = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearFieldList = function() {
-  return this.setFieldList([]);
-};
-
-
-/**
- * repeated FieldDescriptorProto extension = 6;
- * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getExtensionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 6));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setExtensionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 6, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FieldDescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.prototype.addExtension$ = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearExtensionList = function() {
-  return this.setExtensionList([]);
-};
-
-
-/**
- * repeated DescriptorProto nested_type = 3;
- * @return {!Array<!proto.google.protobuf.DescriptorProto>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getNestedTypeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.DescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto, 3));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.DescriptorProto>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setNestedTypeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 3, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.DescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.DescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.prototype.addNestedType = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.DescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearNestedTypeList = function() {
-  return this.setNestedTypeList([]);
-};
-
-
-/**
- * repeated EnumDescriptorProto enum_type = 4;
- * @return {!Array<!proto.google.protobuf.EnumDescriptorProto>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getEnumTypeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto, 4));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.EnumDescriptorProto>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setEnumTypeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 4, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.EnumDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumDescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.prototype.addEnumType = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.EnumDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearEnumTypeList = function() {
-  return this.setEnumTypeList([]);
-};
-
-
-/**
- * repeated ExtensionRange extension_range = 5;
- * @return {!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getExtensionRangeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto.ExtensionRange, 5));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setExtensionRangeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 5, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
- */
-proto.google.protobuf.DescriptorProto.prototype.addExtensionRange = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.google.protobuf.DescriptorProto.ExtensionRange, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearExtensionRangeList = function() {
-  return this.setExtensionRangeList([]);
-};
-
-
-/**
- * repeated OneofDescriptorProto oneof_decl = 8;
- * @return {!Array<!proto.google.protobuf.OneofDescriptorProto>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getOneofDeclList = function() {
-  return /** @type{!Array<!proto.google.protobuf.OneofDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.OneofDescriptorProto, 8));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.OneofDescriptorProto>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setOneofDeclList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 8, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.OneofDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.OneofDescriptorProto}
- */
-proto.google.protobuf.DescriptorProto.prototype.addOneofDecl = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.google.protobuf.OneofDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearOneofDeclList = function() {
-  return this.setOneofDeclList([]);
-};
-
-
-/**
- * optional MessageOptions options = 7;
- * @return {?proto.google.protobuf.MessageOptions}
- */
-proto.google.protobuf.DescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.MessageOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.MessageOptions, 7));
-};
-
-
-/**
- * @param {?proto.google.protobuf.MessageOptions|undefined} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 7, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.DescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-/**
- * repeated ReservedRange reserved_range = 9;
- * @return {!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getReservedRangeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto.ReservedRange, 9));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
-*/
-proto.google.protobuf.DescriptorProto.prototype.setReservedRangeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 9, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.DescriptorProto.ReservedRange=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
- */
-proto.google.protobuf.DescriptorProto.prototype.addReservedRange = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.google.protobuf.DescriptorProto.ReservedRange, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearReservedRangeList = function() {
-  return this.setReservedRangeList([]);
-};
-
-
-/**
- * repeated string reserved_name = 10;
- * @return {!Array<string>}
- */
-proto.google.protobuf.DescriptorProto.prototype.getReservedNameList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 10));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.setReservedNameList = function(value) {
-  return jspb.Message.setField(this, 10, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.addReservedName = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.DescriptorProto} returns this
- */
-proto.google.protobuf.DescriptorProto.prototype.clearReservedNameList = function() {
-  return this.setReservedNameList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.ExtensionRangeOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.ExtensionRangeOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.ExtensionRangeOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.ExtensionRangeOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ExtensionRangeOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.ExtensionRangeOptions.extensions, proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.ExtensionRangeOptions}
- */
-proto.google.protobuf.ExtensionRangeOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.ExtensionRangeOptions;
-  return proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.ExtensionRangeOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.ExtensionRangeOptions}
- */
-proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.ExtensionRangeOptions.extensionsBinary,
-        proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension,
-        proto.google.protobuf.ExtensionRangeOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.ExtensionRangeOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.ExtensionRangeOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.ExtensionRangeOptions.extensionsBinary, proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension);
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.ExtensionRangeOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.ExtensionRangeOptions} returns this
-*/
-proto.google.protobuf.ExtensionRangeOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.ExtensionRangeOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.ExtensionRangeOptions} returns this
- */
-proto.google.protobuf.ExtensionRangeOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FieldDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FieldDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    number: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    label: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
-    type: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
-    typeName: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
-    extendee: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    defaultValue: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f,
-    oneofIndex: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f,
-    jsonName: (f = jspb.Message.getField(msg, 10)) == null ? undefined : f,
-    options: (f = msg.getOptions()) && proto.google.protobuf.FieldOptions.toObject(includeInstance, f),
-    proto3Optional: (f = jspb.Message.getBooleanField(msg, 17)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FieldDescriptorProto}
- */
-proto.google.protobuf.FieldDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FieldDescriptorProto;
-  return proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FieldDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FieldDescriptorProto}
- */
-proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNumber(value);
-      break;
-    case 4:
-      var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (reader.readEnum());
-      msg.setLabel(value);
-      break;
-    case 5:
-      var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (reader.readEnum());
-      msg.setType(value);
-      break;
-    case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTypeName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setExtendee(value);
-      break;
-    case 7:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDefaultValue(value);
-      break;
-    case 9:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setOneofIndex(value);
-      break;
-    case 10:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setJsonName(value);
-      break;
-    case 8:
-      var value = new proto.google.protobuf.FieldOptions;
-      reader.readMessage(value,proto.google.protobuf.FieldOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    case 17:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setProto3Optional(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FieldDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeInt32(
-      3,
-      f
-    );
-  }
-  f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeEnum(
-      4,
-      f
-    );
-  }
-  f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeEnum(
-      5,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeString(
-      6,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 7));
-  if (f != null) {
-    writer.writeString(
-      7,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 9));
-  if (f != null) {
-    writer.writeInt32(
-      9,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 10));
-  if (f != null) {
-    writer.writeString(
-      10,
-      f
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      8,
-      f,
-      proto.google.protobuf.FieldOptions.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 17));
-  if (f != null) {
-    writer.writeBool(
-      17,
-      f
-    );
-  }
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.FieldDescriptorProto.Type = {
-  TYPE_DOUBLE: 1,
-  TYPE_FLOAT: 2,
-  TYPE_INT64: 3,
-  TYPE_UINT64: 4,
-  TYPE_INT32: 5,
-  TYPE_FIXED64: 6,
-  TYPE_FIXED32: 7,
-  TYPE_BOOL: 8,
-  TYPE_STRING: 9,
-  TYPE_GROUP: 10,
-  TYPE_MESSAGE: 11,
-  TYPE_BYTES: 12,
-  TYPE_UINT32: 13,
-  TYPE_ENUM: 14,
-  TYPE_SFIXED32: 15,
-  TYPE_SFIXED64: 16,
-  TYPE_SINT32: 17,
-  TYPE_SINT64: 18
-};
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.FieldDescriptorProto.Label = {
-  LABEL_OPTIONAL: 1,
-  LABEL_REQUIRED: 2,
-  LABEL_REPEATED: 3
-};
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 number = 3;
- * @return {number}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getNumber = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setNumber = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearNumber = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasNumber = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional Label label = 4;
- * @return {!proto.google.protobuf.FieldDescriptorProto.Label}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getLabel = function() {
-  return /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (jspb.Message.getFieldWithDefault(this, 4, 1));
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldDescriptorProto.Label} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setLabel = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearLabel = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasLabel = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional Type type = 5;
- * @return {!proto.google.protobuf.FieldDescriptorProto.Type}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getType = function() {
-  return /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getFieldWithDefault(this, 5, 1));
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldDescriptorProto.Type} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setType = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearType = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasType = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional string type_name = 6;
- * @return {string}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getTypeName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setTypeName = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearTypeName = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasTypeName = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-/**
- * optional string extendee = 2;
- * @return {string}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getExtendee = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setExtendee = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearExtendee = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasExtendee = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string default_value = 7;
- * @return {string}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getDefaultValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setDefaultValue = function(value) {
-  return jspb.Message.setField(this, 7, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearDefaultValue = function() {
-  return jspb.Message.setField(this, 7, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasDefaultValue = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-/**
- * optional int32 oneof_index = 9;
- * @return {number}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getOneofIndex = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setOneofIndex = function(value) {
-  return jspb.Message.setField(this, 9, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearOneofIndex = function() {
-  return jspb.Message.setField(this, 9, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasOneofIndex = function() {
-  return jspb.Message.getField(this, 9) != null;
-};
-
-
-/**
- * optional string json_name = 10;
- * @return {string}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getJsonName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setJsonName = function(value) {
-  return jspb.Message.setField(this, 10, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearJsonName = function() {
-  return jspb.Message.setField(this, 10, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasJsonName = function() {
-  return jspb.Message.getField(this, 10) != null;
-};
-
-
-/**
- * optional FieldOptions options = 8;
- * @return {?proto.google.protobuf.FieldOptions}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.FieldOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.FieldOptions, 8));
-};
-
-
-/**
- * @param {?proto.google.protobuf.FieldOptions|undefined} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
-*/
-proto.google.protobuf.FieldDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 8, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 8) != null;
-};
-
-
-/**
- * optional bool proto3_optional = 17;
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.getProto3Optional = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 17, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.setProto3Optional = function(value) {
-  return jspb.Message.setField(this, 17, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.clearProto3Optional = function() {
-  return jspb.Message.setField(this, 17, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldDescriptorProto.prototype.hasProto3Optional = function() {
-  return jspb.Message.getField(this, 17) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.OneofDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.OneofDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.OneofDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    options: (f = msg.getOptions()) && proto.google.protobuf.OneofOptions.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.OneofDescriptorProto}
- */
-proto.google.protobuf.OneofDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.OneofDescriptorProto;
-  return proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.OneofDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.OneofDescriptorProto}
- */
-proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.OneofOptions;
-      reader.readMessage(value,proto.google.protobuf.OneofOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.OneofDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      2,
-      f,
-      proto.google.protobuf.OneofOptions.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional OneofOptions options = 2;
- * @return {?proto.google.protobuf.OneofOptions}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.OneofOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.OneofOptions, 2));
-};
-
-
-/**
- * @param {?proto.google.protobuf.OneofOptions|undefined} value
- * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
-*/
-proto.google.protobuf.OneofDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 2, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.OneofDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.EnumDescriptorProto.repeatedFields_ = [2,4,5];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    valueList: jspb.Message.toObjectList(msg.getValueList(),
-    proto.google.protobuf.EnumValueDescriptorProto.toObject, includeInstance),
-    options: (f = msg.getOptions()) && proto.google.protobuf.EnumOptions.toObject(includeInstance, f),
-    reservedRangeList: jspb.Message.toObjectList(msg.getReservedRangeList(),
-    proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject, includeInstance),
-    reservedNameList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumDescriptorProto}
- */
-proto.google.protobuf.EnumDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumDescriptorProto;
-  return proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumDescriptorProto}
- */
-proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.EnumValueDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader);
-      msg.addValue(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.EnumOptions;
-      reader.readMessage(value,proto.google.protobuf.EnumOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    case 4:
-      var value = new proto.google.protobuf.EnumDescriptorProto.EnumReservedRange;
-      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader);
-      msg.addReservedRange(value);
-      break;
-    case 5:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addReservedName(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getValueList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      3,
-      f,
-      proto.google.protobuf.EnumOptions.serializeBinaryToWriter
-    );
-  }
-  f = message.getReservedRangeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      4,
-      f,
-      proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter
-    );
-  }
-  f = message.getReservedNameList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      5,
-      f
-    );
-  }
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumDescriptorProto.EnumReservedRange;
-  return proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setStart(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setEnd(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {number} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeInt32(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int32 start = 1;
- * @return {number}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.getStart = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.setStart = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.clearStart = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.hasStart = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 end = 2;
- * @return {number}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.getEnd = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.setEnd = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.clearEnd = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.hasEnd = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * repeated EnumValueDescriptorProto value = 2;
- * @return {!Array<!proto.google.protobuf.EnumValueDescriptorProto>}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.getValueList = function() {
-  return /** @type{!Array<!proto.google.protobuf.EnumValueDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumValueDescriptorProto, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.EnumValueDescriptorProto>} value
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
-*/
-proto.google.protobuf.EnumDescriptorProto.prototype.setValueList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.EnumValueDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumValueDescriptorProto}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.addValue = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.EnumValueDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.clearValueList = function() {
-  return this.setValueList([]);
-};
-
-
-/**
- * optional EnumOptions options = 3;
- * @return {?proto.google.protobuf.EnumOptions}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.EnumOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.EnumOptions, 3));
-};
-
-
-/**
- * @param {?proto.google.protobuf.EnumOptions|undefined} value
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
-*/
-proto.google.protobuf.EnumDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 3, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * repeated EnumReservedRange reserved_range = 4;
- * @return {!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.getReservedRangeList = function() {
-  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, 4));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>} value
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
-*/
-proto.google.protobuf.EnumDescriptorProto.prototype.setReservedRangeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 4, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.addReservedRange = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.clearReservedRangeList = function() {
-  return this.setReservedRangeList([]);
-};
-
-
-/**
- * repeated string reserved_name = 5;
- * @return {!Array<string>}
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.getReservedNameList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.setReservedNameList = function(value) {
-  return jspb.Message.setField(this, 5, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.addReservedName = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
- */
-proto.google.protobuf.EnumDescriptorProto.prototype.clearReservedNameList = function() {
-  return this.setReservedNameList([]);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumValueDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumValueDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValueDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    number: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    options: (f = msg.getOptions()) && proto.google.protobuf.EnumValueOptions.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumValueDescriptorProto}
- */
-proto.google.protobuf.EnumValueDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumValueDescriptorProto;
-  return proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumValueDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumValueDescriptorProto}
- */
-proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNumber(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.EnumValueOptions;
-      reader.readMessage(value,proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumValueDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      3,
-      f,
-      proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional int32 number = 2;
- * @return {number}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.getNumber = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.setNumber = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.clearNumber = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.hasNumber = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional EnumValueOptions options = 3;
- * @return {?proto.google.protobuf.EnumValueOptions}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.EnumValueOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.EnumValueOptions, 3));
-};
-
-
-/**
- * @param {?proto.google.protobuf.EnumValueOptions|undefined} value
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
-*/
-proto.google.protobuf.EnumValueDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 3, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumValueDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.ServiceDescriptorProto.repeatedFields_ = [2];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.ServiceDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.ServiceDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ServiceDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    methodList: jspb.Message.toObjectList(msg.getMethodList(),
-    proto.google.protobuf.MethodDescriptorProto.toObject, includeInstance),
-    options: (f = msg.getOptions()) && proto.google.protobuf.ServiceOptions.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.ServiceDescriptorProto}
- */
-proto.google.protobuf.ServiceDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.ServiceDescriptorProto;
-  return proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.ServiceDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.ServiceDescriptorProto}
- */
-proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.MethodDescriptorProto;
-      reader.readMessage(value,proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader);
-      msg.addMethod(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.ServiceOptions;
-      reader.readMessage(value,proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.ServiceDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getMethodList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      3,
-      f,
-      proto.google.protobuf.ServiceOptions.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * repeated MethodDescriptorProto method = 2;
- * @return {!Array<!proto.google.protobuf.MethodDescriptorProto>}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.getMethodList = function() {
-  return /** @type{!Array<!proto.google.protobuf.MethodDescriptorProto>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.MethodDescriptorProto, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.MethodDescriptorProto>} value
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
-*/
-proto.google.protobuf.ServiceDescriptorProto.prototype.setMethodList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.MethodDescriptorProto=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.MethodDescriptorProto}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.addMethod = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.MethodDescriptorProto, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.clearMethodList = function() {
-  return this.setMethodList([]);
-};
-
-
-/**
- * optional ServiceOptions options = 3;
- * @return {?proto.google.protobuf.ServiceOptions}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.ServiceOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.ServiceOptions, 3));
-};
-
-
-/**
- * @param {?proto.google.protobuf.ServiceOptions|undefined} value
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
-*/
-proto.google.protobuf.ServiceDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 3, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.ServiceDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.MethodDescriptorProto.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.MethodDescriptorProto} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MethodDescriptorProto.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    inputType: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    outputType: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    options: (f = msg.getOptions()) && proto.google.protobuf.MethodOptions.toObject(includeInstance, f),
-    clientStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
-    serverStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.MethodDescriptorProto}
- */
-proto.google.protobuf.MethodDescriptorProto.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.MethodDescriptorProto;
-  return proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.MethodDescriptorProto} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.MethodDescriptorProto}
- */
-proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setInputType(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setOutputType(value);
-      break;
-    case 4:
-      var value = new proto.google.protobuf.MethodOptions;
-      reader.readMessage(value,proto.google.protobuf.MethodOptions.deserializeBinaryFromReader);
-      msg.setOptions(value);
-      break;
-    case 5:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setClientStreaming(value);
-      break;
-    case 6:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setServerStreaming(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.MethodDescriptorProto} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = message.getOptions();
-  if (f != null) {
-    writer.writeMessage(
-      4,
-      f,
-      proto.google.protobuf.MethodOptions.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeBool(
-      5,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeBool(
-      6,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string input_type = 2;
- * @return {string}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getInputType = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.setInputType = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearInputType = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasInputType = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string output_type = 3;
- * @return {string}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getOutputType = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.setOutputType = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearOutputType = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasOutputType = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional MethodOptions options = 4;
- * @return {?proto.google.protobuf.MethodOptions}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getOptions = function() {
-  return /** @type{?proto.google.protobuf.MethodOptions} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.MethodOptions, 4));
-};
-
-
-/**
- * @param {?proto.google.protobuf.MethodOptions|undefined} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
-*/
-proto.google.protobuf.MethodDescriptorProto.prototype.setOptions = function(value) {
-  return jspb.Message.setWrapperField(this, 4, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearOptions = function() {
-  return this.setOptions(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasOptions = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional bool client_streaming = 5;
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getClientStreaming = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.setClientStreaming = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearClientStreaming = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasClientStreaming = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional bool server_streaming = 6;
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.getServerStreaming = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.setServerStreaming = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.clearServerStreaming = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodDescriptorProto.prototype.hasServerStreaming = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.FileOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FileOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FileOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FileOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    javaPackage: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    javaOuterClassname: (f = jspb.Message.getField(msg, 8)) == null ? undefined : f,
-    javaMultipleFiles: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
-    javaGenerateEqualsAndHash: (f = jspb.Message.getBooleanField(msg, 20)) == null ? undefined : f,
-    javaStringCheckUtf8: jspb.Message.getBooleanFieldWithDefault(msg, 27, false),
-    optimizeFor: jspb.Message.getFieldWithDefault(msg, 9, 1),
-    goPackage: (f = jspb.Message.getField(msg, 11)) == null ? undefined : f,
-    ccGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 16, false),
-    javaGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 17, false),
-    pyGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 18, false),
-    phpGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 42, false),
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 23, false),
-    ccEnableArenas: jspb.Message.getBooleanFieldWithDefault(msg, 31, true),
-    objcClassPrefix: (f = jspb.Message.getField(msg, 36)) == null ? undefined : f,
-    csharpNamespace: (f = jspb.Message.getField(msg, 37)) == null ? undefined : f,
-    swiftPrefix: (f = jspb.Message.getField(msg, 39)) == null ? undefined : f,
-    phpClassPrefix: (f = jspb.Message.getField(msg, 40)) == null ? undefined : f,
-    phpNamespace: (f = jspb.Message.getField(msg, 41)) == null ? undefined : f,
-    phpMetadataNamespace: (f = jspb.Message.getField(msg, 44)) == null ? undefined : f,
-    rubyPackage: (f = jspb.Message.getField(msg, 45)) == null ? undefined : f,
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.FileOptions.extensions, proto.google.protobuf.FileOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FileOptions}
- */
-proto.google.protobuf.FileOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FileOptions;
-  return proto.google.protobuf.FileOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FileOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FileOptions}
- */
-proto.google.protobuf.FileOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setJavaPackage(value);
-      break;
-    case 8:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setJavaOuterClassname(value);
-      break;
-    case 10:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setJavaMultipleFiles(value);
-      break;
-    case 20:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setJavaGenerateEqualsAndHash(value);
-      break;
-    case 27:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setJavaStringCheckUtf8(value);
-      break;
-    case 9:
-      var value = /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (reader.readEnum());
-      msg.setOptimizeFor(value);
-      break;
-    case 11:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setGoPackage(value);
-      break;
-    case 16:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setCcGenericServices(value);
-      break;
-    case 17:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setJavaGenericServices(value);
-      break;
-    case 18:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setPyGenericServices(value);
-      break;
-    case 42:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setPhpGenericServices(value);
-      break;
-    case 23:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 31:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setCcEnableArenas(value);
-      break;
-    case 36:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setObjcClassPrefix(value);
-      break;
-    case 37:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setCsharpNamespace(value);
-      break;
-    case 39:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setSwiftPrefix(value);
-      break;
-    case 40:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setPhpClassPrefix(value);
-      break;
-    case 41:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setPhpNamespace(value);
-      break;
-    case 44:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setPhpMetadataNamespace(value);
-      break;
-    case 45:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setRubyPackage(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.FileOptions.extensionsBinary,
-        proto.google.protobuf.FileOptions.prototype.getExtension,
-        proto.google.protobuf.FileOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FileOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FileOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FileOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FileOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 8));
-  if (f != null) {
-    writer.writeString(
-      8,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 10));
-  if (f != null) {
-    writer.writeBool(
-      10,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 20));
-  if (f != null) {
-    writer.writeBool(
-      20,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 27));
-  if (f != null) {
-    writer.writeBool(
-      27,
-      f
-    );
-  }
-  f = /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (jspb.Message.getField(message, 9));
-  if (f != null) {
-    writer.writeEnum(
-      9,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 11));
-  if (f != null) {
-    writer.writeString(
-      11,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 16));
-  if (f != null) {
-    writer.writeBool(
-      16,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 17));
-  if (f != null) {
-    writer.writeBool(
-      17,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 18));
-  if (f != null) {
-    writer.writeBool(
-      18,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 42));
-  if (f != null) {
-    writer.writeBool(
-      42,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 23));
-  if (f != null) {
-    writer.writeBool(
-      23,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 31));
-  if (f != null) {
-    writer.writeBool(
-      31,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 36));
-  if (f != null) {
-    writer.writeString(
-      36,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 37));
-  if (f != null) {
-    writer.writeString(
-      37,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 39));
-  if (f != null) {
-    writer.writeString(
-      39,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 40));
-  if (f != null) {
-    writer.writeString(
-      40,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 41));
-  if (f != null) {
-    writer.writeString(
-      41,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 44));
-  if (f != null) {
-    writer.writeString(
-      44,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 45));
-  if (f != null) {
-    writer.writeString(
-      45,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.FileOptions.extensionsBinary, proto.google.protobuf.FileOptions.prototype.getExtension);
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.FileOptions.OptimizeMode = {
-  SPEED: 1,
-  CODE_SIZE: 2,
-  LITE_RUNTIME: 3
-};
-
-/**
- * optional string java_package = 1;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaPackage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaPackage = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaPackage = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaPackage = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string java_outer_classname = 8;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaOuterClassname = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaOuterClassname = function(value) {
-  return jspb.Message.setField(this, 8, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaOuterClassname = function() {
-  return jspb.Message.setField(this, 8, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaOuterClassname = function() {
-  return jspb.Message.getField(this, 8) != null;
-};
-
-
-/**
- * optional bool java_multiple_files = 10;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaMultipleFiles = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaMultipleFiles = function(value) {
-  return jspb.Message.setField(this, 10, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaMultipleFiles = function() {
-  return jspb.Message.setField(this, 10, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaMultipleFiles = function() {
-  return jspb.Message.getField(this, 10) != null;
-};
-
-
-/**
- * optional bool java_generate_equals_and_hash = 20;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaGenerateEqualsAndHash = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 20, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaGenerateEqualsAndHash = function(value) {
-  return jspb.Message.setField(this, 20, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaGenerateEqualsAndHash = function() {
-  return jspb.Message.setField(this, 20, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaGenerateEqualsAndHash = function() {
-  return jspb.Message.getField(this, 20) != null;
-};
-
-
-/**
- * optional bool java_string_check_utf8 = 27;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaStringCheckUtf8 = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 27, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaStringCheckUtf8 = function(value) {
-  return jspb.Message.setField(this, 27, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaStringCheckUtf8 = function() {
-  return jspb.Message.setField(this, 27, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaStringCheckUtf8 = function() {
-  return jspb.Message.getField(this, 27) != null;
-};
-
-
-/**
- * optional OptimizeMode optimize_for = 9;
- * @return {!proto.google.protobuf.FileOptions.OptimizeMode}
- */
-proto.google.protobuf.FileOptions.prototype.getOptimizeFor = function() {
-  return /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (jspb.Message.getFieldWithDefault(this, 9, 1));
-};
-
-
-/**
- * @param {!proto.google.protobuf.FileOptions.OptimizeMode} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setOptimizeFor = function(value) {
-  return jspb.Message.setField(this, 9, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearOptimizeFor = function() {
-  return jspb.Message.setField(this, 9, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasOptimizeFor = function() {
-  return jspb.Message.getField(this, 9) != null;
-};
-
-
-/**
- * optional string go_package = 11;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getGoPackage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setGoPackage = function(value) {
-  return jspb.Message.setField(this, 11, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearGoPackage = function() {
-  return jspb.Message.setField(this, 11, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasGoPackage = function() {
-  return jspb.Message.getField(this, 11) != null;
-};
-
-
-/**
- * optional bool cc_generic_services = 16;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getCcGenericServices = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 16, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setCcGenericServices = function(value) {
-  return jspb.Message.setField(this, 16, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearCcGenericServices = function() {
-  return jspb.Message.setField(this, 16, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasCcGenericServices = function() {
-  return jspb.Message.getField(this, 16) != null;
-};
-
-
-/**
- * optional bool java_generic_services = 17;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getJavaGenericServices = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 17, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setJavaGenericServices = function(value) {
-  return jspb.Message.setField(this, 17, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearJavaGenericServices = function() {
-  return jspb.Message.setField(this, 17, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasJavaGenericServices = function() {
-  return jspb.Message.getField(this, 17) != null;
-};
-
-
-/**
- * optional bool py_generic_services = 18;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getPyGenericServices = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 18, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setPyGenericServices = function(value) {
-  return jspb.Message.setField(this, 18, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearPyGenericServices = function() {
-  return jspb.Message.setField(this, 18, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasPyGenericServices = function() {
-  return jspb.Message.getField(this, 18) != null;
-};
-
-
-/**
- * optional bool php_generic_services = 42;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getPhpGenericServices = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 42, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setPhpGenericServices = function(value) {
-  return jspb.Message.setField(this, 42, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearPhpGenericServices = function() {
-  return jspb.Message.setField(this, 42, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasPhpGenericServices = function() {
-  return jspb.Message.getField(this, 42) != null;
-};
-
-
-/**
- * optional bool deprecated = 23;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 23, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 23, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 23, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 23) != null;
-};
-
-
-/**
- * optional bool cc_enable_arenas = 31;
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.getCcEnableArenas = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 31, true));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setCcEnableArenas = function(value) {
-  return jspb.Message.setField(this, 31, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearCcEnableArenas = function() {
-  return jspb.Message.setField(this, 31, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasCcEnableArenas = function() {
-  return jspb.Message.getField(this, 31) != null;
-};
-
-
-/**
- * optional string objc_class_prefix = 36;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getObjcClassPrefix = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 36, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setObjcClassPrefix = function(value) {
-  return jspb.Message.setField(this, 36, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearObjcClassPrefix = function() {
-  return jspb.Message.setField(this, 36, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasObjcClassPrefix = function() {
-  return jspb.Message.getField(this, 36) != null;
-};
-
-
-/**
- * optional string csharp_namespace = 37;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getCsharpNamespace = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 37, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setCsharpNamespace = function(value) {
-  return jspb.Message.setField(this, 37, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearCsharpNamespace = function() {
-  return jspb.Message.setField(this, 37, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasCsharpNamespace = function() {
-  return jspb.Message.getField(this, 37) != null;
-};
-
-
-/**
- * optional string swift_prefix = 39;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getSwiftPrefix = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 39, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setSwiftPrefix = function(value) {
-  return jspb.Message.setField(this, 39, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearSwiftPrefix = function() {
-  return jspb.Message.setField(this, 39, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasSwiftPrefix = function() {
-  return jspb.Message.getField(this, 39) != null;
-};
-
-
-/**
- * optional string php_class_prefix = 40;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getPhpClassPrefix = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 40, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setPhpClassPrefix = function(value) {
-  return jspb.Message.setField(this, 40, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearPhpClassPrefix = function() {
-  return jspb.Message.setField(this, 40, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasPhpClassPrefix = function() {
-  return jspb.Message.getField(this, 40) != null;
-};
-
-
-/**
- * optional string php_namespace = 41;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getPhpNamespace = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 41, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setPhpNamespace = function(value) {
-  return jspb.Message.setField(this, 41, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearPhpNamespace = function() {
-  return jspb.Message.setField(this, 41, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasPhpNamespace = function() {
-  return jspb.Message.getField(this, 41) != null;
-};
-
-
-/**
- * optional string php_metadata_namespace = 44;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getPhpMetadataNamespace = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 44, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setPhpMetadataNamespace = function(value) {
-  return jspb.Message.setField(this, 44, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearPhpMetadataNamespace = function() {
-  return jspb.Message.setField(this, 44, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasPhpMetadataNamespace = function() {
-  return jspb.Message.getField(this, 44) != null;
-};
-
-
-/**
- * optional string ruby_package = 45;
- * @return {string}
- */
-proto.google.protobuf.FileOptions.prototype.getRubyPackage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 45, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.setRubyPackage = function(value) {
-  return jspb.Message.setField(this, 45, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearRubyPackage = function() {
-  return jspb.Message.setField(this, 45, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FileOptions.prototype.hasRubyPackage = function() {
-  return jspb.Message.getField(this, 45) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.FileOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.FileOptions} returns this
-*/
-proto.google.protobuf.FileOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.FileOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FileOptions} returns this
- */
-proto.google.protobuf.FileOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.MessageOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.MessageOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.MessageOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.MessageOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MessageOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    messageSetWireFormat: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
-    noStandardDescriptorAccessor: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
-    mapEntry: (f = jspb.Message.getBooleanField(msg, 7)) == null ? undefined : f,
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.MessageOptions.extensions, proto.google.protobuf.MessageOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.MessageOptions}
- */
-proto.google.protobuf.MessageOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.MessageOptions;
-  return proto.google.protobuf.MessageOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.MessageOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.MessageOptions}
- */
-proto.google.protobuf.MessageOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setMessageSetWireFormat(value);
-      break;
-    case 2:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setNoStandardDescriptorAccessor(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 7:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setMapEntry(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.MessageOptions.extensionsBinary,
-        proto.google.protobuf.MessageOptions.prototype.getExtension,
-        proto.google.protobuf.MessageOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.MessageOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.MessageOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.MessageOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MessageOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeBool(
-      1,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeBool(
-      2,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 7));
-  if (f != null) {
-    writer.writeBool(
-      7,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.MessageOptions.extensionsBinary, proto.google.protobuf.MessageOptions.prototype.getExtension);
-};
-
-
-/**
- * optional bool message_set_wire_format = 1;
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.getMessageSetWireFormat = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.setMessageSetWireFormat = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.clearMessageSetWireFormat = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.hasMessageSetWireFormat = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional bool no_standard_descriptor_accessor = 2;
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.getNoStandardDescriptorAccessor = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.setNoStandardDescriptorAccessor = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.clearNoStandardDescriptorAccessor = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.hasNoStandardDescriptorAccessor = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional bool deprecated = 3;
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional bool map_entry = 7;
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.getMapEntry = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 7, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.setMapEntry = function(value) {
-  return jspb.Message.setField(this, 7, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.clearMapEntry = function() {
-  return jspb.Message.setField(this, 7, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MessageOptions.prototype.hasMapEntry = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.MessageOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.MessageOptions} returns this
-*/
-proto.google.protobuf.MessageOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.MessageOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.MessageOptions} returns this
- */
-proto.google.protobuf.MessageOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.FieldOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FieldOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FieldOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FieldOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    ctype: jspb.Message.getFieldWithDefault(msg, 1, 0),
-    packed: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f,
-    jstype: jspb.Message.getFieldWithDefault(msg, 6, 0),
-    lazy: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
-    weak: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.FieldOptions.extensions, proto.google.protobuf.FieldOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FieldOptions}
- */
-proto.google.protobuf.FieldOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FieldOptions;
-  return proto.google.protobuf.FieldOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FieldOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FieldOptions}
- */
-proto.google.protobuf.FieldOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {!proto.google.protobuf.FieldOptions.CType} */ (reader.readEnum());
-      msg.setCtype(value);
-      break;
-    case 2:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setPacked(value);
-      break;
-    case 6:
-      var value = /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (reader.readEnum());
-      msg.setJstype(value);
-      break;
-    case 5:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setLazy(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 10:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setWeak(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.FieldOptions.extensionsBinary,
-        proto.google.protobuf.FieldOptions.prototype.getExtension,
-        proto.google.protobuf.FieldOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FieldOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FieldOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FieldOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {!proto.google.protobuf.FieldOptions.CType} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeEnum(
-      1,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeBool(
-      2,
-      f
-    );
-  }
-  f = /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeEnum(
-      6,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeBool(
-      5,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 10));
-  if (f != null) {
-    writer.writeBool(
-      10,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.FieldOptions.extensionsBinary, proto.google.protobuf.FieldOptions.prototype.getExtension);
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.FieldOptions.CType = {
-  STRING: 0,
-  CORD: 1,
-  STRING_PIECE: 2
-};
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.FieldOptions.JSType = {
-  JS_NORMAL: 0,
-  JS_STRING: 1,
-  JS_NUMBER: 2
-};
-
-/**
- * optional CType ctype = 1;
- * @return {!proto.google.protobuf.FieldOptions.CType}
- */
-proto.google.protobuf.FieldOptions.prototype.getCtype = function() {
-  return /** @type {!proto.google.protobuf.FieldOptions.CType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldOptions.CType} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setCtype = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearCtype = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasCtype = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional bool packed = 2;
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.getPacked = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setPacked = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearPacked = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasPacked = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional JSType jstype = 6;
- * @return {!proto.google.protobuf.FieldOptions.JSType}
- */
-proto.google.protobuf.FieldOptions.prototype.getJstype = function() {
-  return /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.FieldOptions.JSType} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setJstype = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearJstype = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasJstype = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-/**
- * optional bool lazy = 5;
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.getLazy = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setLazy = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearLazy = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasLazy = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional bool deprecated = 3;
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional bool weak = 10;
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.getWeak = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.setWeak = function(value) {
-  return jspb.Message.setField(this, 10, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearWeak = function() {
-  return jspb.Message.setField(this, 10, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.FieldOptions.prototype.hasWeak = function() {
-  return jspb.Message.getField(this, 10) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.FieldOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.FieldOptions} returns this
-*/
-proto.google.protobuf.FieldOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.FieldOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FieldOptions} returns this
- */
-proto.google.protobuf.FieldOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.OneofOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.OneofOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.OneofOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.OneofOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.OneofOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.OneofOptions.extensions, proto.google.protobuf.OneofOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.OneofOptions}
- */
-proto.google.protobuf.OneofOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.OneofOptions;
-  return proto.google.protobuf.OneofOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.OneofOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.OneofOptions}
- */
-proto.google.protobuf.OneofOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.OneofOptions.extensionsBinary,
-        proto.google.protobuf.OneofOptions.prototype.getExtension,
-        proto.google.protobuf.OneofOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.OneofOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.OneofOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.OneofOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.OneofOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.OneofOptions.extensionsBinary, proto.google.protobuf.OneofOptions.prototype.getExtension);
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.OneofOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.OneofOptions} returns this
-*/
-proto.google.protobuf.OneofOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.OneofOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.OneofOptions} returns this
- */
-proto.google.protobuf.OneofOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.EnumOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    allowAlias: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f,
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.EnumOptions.extensions, proto.google.protobuf.EnumOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumOptions}
- */
-proto.google.protobuf.EnumOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumOptions;
-  return proto.google.protobuf.EnumOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumOptions}
- */
-proto.google.protobuf.EnumOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 2:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setAllowAlias(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.EnumOptions.extensionsBinary,
-        proto.google.protobuf.EnumOptions.prototype.getExtension,
-        proto.google.protobuf.EnumOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeBool(
-      2,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.EnumOptions.extensionsBinary, proto.google.protobuf.EnumOptions.prototype.getExtension);
-};
-
-
-/**
- * optional bool allow_alias = 2;
- * @return {boolean}
- */
-proto.google.protobuf.EnumOptions.prototype.getAllowAlias = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.EnumOptions} returns this
- */
-proto.google.protobuf.EnumOptions.prototype.setAllowAlias = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumOptions} returns this
- */
-proto.google.protobuf.EnumOptions.prototype.clearAllowAlias = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumOptions.prototype.hasAllowAlias = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional bool deprecated = 3;
- * @return {boolean}
- */
-proto.google.protobuf.EnumOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.EnumOptions} returns this
- */
-proto.google.protobuf.EnumOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumOptions} returns this
- */
-proto.google.protobuf.EnumOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.EnumOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.EnumOptions} returns this
-*/
-proto.google.protobuf.EnumOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.EnumOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumOptions} returns this
- */
-proto.google.protobuf.EnumOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.EnumValueOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumValueOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumValueOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumValueOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValueOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.EnumValueOptions.extensions, proto.google.protobuf.EnumValueOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumValueOptions}
- */
-proto.google.protobuf.EnumValueOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumValueOptions;
-  return proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumValueOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumValueOptions}
- */
-proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.EnumValueOptions.extensionsBinary,
-        proto.google.protobuf.EnumValueOptions.prototype.getExtension,
-        proto.google.protobuf.EnumValueOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumValueOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumValueOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeBool(
-      1,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.EnumValueOptions.extensionsBinary, proto.google.protobuf.EnumValueOptions.prototype.getExtension);
-};
-
-
-/**
- * optional bool deprecated = 1;
- * @return {boolean}
- */
-proto.google.protobuf.EnumValueOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.EnumValueOptions} returns this
- */
-proto.google.protobuf.EnumValueOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.EnumValueOptions} returns this
- */
-proto.google.protobuf.EnumValueOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.EnumValueOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.EnumValueOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.EnumValueOptions} returns this
-*/
-proto.google.protobuf.EnumValueOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.EnumValueOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumValueOptions} returns this
- */
-proto.google.protobuf.EnumValueOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.ServiceOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.ServiceOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.ServiceOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.ServiceOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ServiceOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 33, false),
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.ServiceOptions.extensions, proto.google.protobuf.ServiceOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.ServiceOptions}
- */
-proto.google.protobuf.ServiceOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.ServiceOptions;
-  return proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.ServiceOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.ServiceOptions}
- */
-proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 33:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.ServiceOptions.extensionsBinary,
-        proto.google.protobuf.ServiceOptions.prototype.getExtension,
-        proto.google.protobuf.ServiceOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.ServiceOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.ServiceOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.ServiceOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ServiceOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 33));
-  if (f != null) {
-    writer.writeBool(
-      33,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.ServiceOptions.extensionsBinary, proto.google.protobuf.ServiceOptions.prototype.getExtension);
-};
-
-
-/**
- * optional bool deprecated = 33;
- * @return {boolean}
- */
-proto.google.protobuf.ServiceOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 33, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.ServiceOptions} returns this
- */
-proto.google.protobuf.ServiceOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 33, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.ServiceOptions} returns this
- */
-proto.google.protobuf.ServiceOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 33, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.ServiceOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 33) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.ServiceOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.ServiceOptions} returns this
-*/
-proto.google.protobuf.ServiceOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.ServiceOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.ServiceOptions} returns this
- */
-proto.google.protobuf.ServiceOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.MethodOptions.repeatedFields_ = [999];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.MethodOptions.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.MethodOptions.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.MethodOptions} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MethodOptions.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 33, false),
-    idempotencyLevel: jspb.Message.getFieldWithDefault(msg, 34, 0),
-    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
-    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
-  };
-
-  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
-      proto.google.protobuf.MethodOptions.extensions, proto.google.protobuf.MethodOptions.prototype.getExtension,
-      includeInstance);
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.MethodOptions}
- */
-proto.google.protobuf.MethodOptions.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.MethodOptions;
-  return proto.google.protobuf.MethodOptions.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.MethodOptions} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.MethodOptions}
- */
-proto.google.protobuf.MethodOptions.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 33:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 34:
-      var value = /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (reader.readEnum());
-      msg.setIdempotencyLevel(value);
-      break;
-    case 999:
-      var value = new proto.google.protobuf.UninterpretedOption;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
-      msg.addUninterpretedOption(value);
-      break;
-    default:
-      jspb.Message.readBinaryExtension(msg, reader,
-        proto.google.protobuf.MethodOptions.extensionsBinary,
-        proto.google.protobuf.MethodOptions.prototype.getExtension,
-        proto.google.protobuf.MethodOptions.prototype.setExtension);
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.MethodOptions.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.MethodOptions.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.MethodOptions} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.MethodOptions.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 33));
-  if (f != null) {
-    writer.writeBool(
-      33,
-      f
-    );
-  }
-  f = /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (jspb.Message.getField(message, 34));
-  if (f != null) {
-    writer.writeEnum(
-      34,
-      f
-    );
-  }
-  f = message.getUninterpretedOptionList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      999,
-      f,
-      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
-    );
-  }
-  jspb.Message.serializeBinaryExtensions(message, writer,
-    proto.google.protobuf.MethodOptions.extensionsBinary, proto.google.protobuf.MethodOptions.prototype.getExtension);
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.MethodOptions.IdempotencyLevel = {
-  IDEMPOTENCY_UNKNOWN: 0,
-  NO_SIDE_EFFECTS: 1,
-  IDEMPOTENT: 2
-};
-
-/**
- * optional bool deprecated = 33;
- * @return {boolean}
- */
-proto.google.protobuf.MethodOptions.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 33, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.MethodOptions} returns this
- */
-proto.google.protobuf.MethodOptions.prototype.setDeprecated = function(value) {
-  return jspb.Message.setField(this, 33, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodOptions} returns this
- */
-proto.google.protobuf.MethodOptions.prototype.clearDeprecated = function() {
-  return jspb.Message.setField(this, 33, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodOptions.prototype.hasDeprecated = function() {
-  return jspb.Message.getField(this, 33) != null;
-};
-
-
-/**
- * optional IdempotencyLevel idempotency_level = 34;
- * @return {!proto.google.protobuf.MethodOptions.IdempotencyLevel}
- */
-proto.google.protobuf.MethodOptions.prototype.getIdempotencyLevel = function() {
-  return /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (jspb.Message.getFieldWithDefault(this, 34, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.MethodOptions.IdempotencyLevel} value
- * @return {!proto.google.protobuf.MethodOptions} returns this
- */
-proto.google.protobuf.MethodOptions.prototype.setIdempotencyLevel = function(value) {
-  return jspb.Message.setField(this, 34, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.MethodOptions} returns this
- */
-proto.google.protobuf.MethodOptions.prototype.clearIdempotencyLevel = function() {
-  return jspb.Message.setField(this, 34, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.MethodOptions.prototype.hasIdempotencyLevel = function() {
-  return jspb.Message.getField(this, 34) != null;
-};
-
-
-/**
- * repeated UninterpretedOption uninterpreted_option = 999;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
- */
-proto.google.protobuf.MethodOptions.prototype.getUninterpretedOptionList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
- * @return {!proto.google.protobuf.MethodOptions} returns this
-*/
-proto.google.protobuf.MethodOptions.prototype.setUninterpretedOptionList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 999, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.MethodOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.MethodOptions} returns this
- */
-proto.google.protobuf.MethodOptions.prototype.clearUninterpretedOptionList = function() {
-  return this.setUninterpretedOptionList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.UninterpretedOption.repeatedFields_ = [2];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.UninterpretedOption.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.UninterpretedOption.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.UninterpretedOption} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UninterpretedOption.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    nameList: jspb.Message.toObjectList(msg.getNameList(),
-    proto.google.protobuf.UninterpretedOption.NamePart.toObject, includeInstance),
-    identifierValue: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    positiveIntValue: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
-    negativeIntValue: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
-    doubleValue: (f = jspb.Message.getOptionalFloatingPointField(msg, 6)) == null ? undefined : f,
-    stringValue: msg.getStringValue_asB64(),
-    aggregateValue: (f = jspb.Message.getField(msg, 8)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.UninterpretedOption.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.UninterpretedOption;
-  return proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.UninterpretedOption} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.UninterpretedOption}
- */
-proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 2:
-      var value = new proto.google.protobuf.UninterpretedOption.NamePart;
-      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader);
-      msg.addName(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setIdentifierValue(value);
-      break;
-    case 4:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.setPositiveIntValue(value);
-      break;
-    case 5:
-      var value = /** @type {number} */ (reader.readInt64());
-      msg.setNegativeIntValue(value);
-      break;
-    case 6:
-      var value = /** @type {number} */ (reader.readDouble());
-      msg.setDoubleValue(value);
-      break;
-    case 7:
-      var value = /** @type {!Uint8Array} */ (reader.readBytes());
-      msg.setStringValue(value);
-      break;
-    case 8:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setAggregateValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.UninterpretedOption.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.UninterpretedOption} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getNameList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeUint64(
-      4,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeInt64(
-      5,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeDouble(
-      6,
-      f
-    );
-  }
-  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 7));
-  if (f != null) {
-    writer.writeBytes(
-      7,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 8));
-  if (f != null) {
-    writer.writeString(
-      8,
-      f
-    );
-  }
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.UninterpretedOption.NamePart.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.UninterpretedOption.NamePart} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UninterpretedOption.NamePart.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    namePart: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    isExtension: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.UninterpretedOption.NamePart;
-  return proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.UninterpretedOption.NamePart} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setNamePart(value);
-      break;
-    case 2:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIsExtension(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.UninterpretedOption.NamePart} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeBool(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * required string name_part = 1;
- * @return {string}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.getNamePart = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.setNamePart = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.clearNamePart = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.hasNamePart = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * required bool is_extension = 2;
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.getIsExtension = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.setIsExtension = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.clearIsExtension = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.NamePart.prototype.hasIsExtension = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * repeated NamePart name = 2;
- * @return {!Array<!proto.google.protobuf.UninterpretedOption.NamePart>}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getNameList = function() {
-  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption.NamePart>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption.NamePart, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.UninterpretedOption.NamePart>} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
-*/
-proto.google.protobuf.UninterpretedOption.prototype.setNameList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.UninterpretedOption.NamePart=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
- */
-proto.google.protobuf.UninterpretedOption.prototype.addName = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.UninterpretedOption.NamePart, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearNameList = function() {
-  return this.setNameList([]);
-};
-
-
-/**
- * optional string identifier_value = 3;
- * @return {string}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getIdentifierValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setIdentifierValue = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearIdentifierValue = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasIdentifierValue = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional uint64 positive_int_value = 4;
- * @return {number}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getPositiveIntValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setPositiveIntValue = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearPositiveIntValue = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasPositiveIntValue = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional int64 negative_int_value = 5;
- * @return {number}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getNegativeIntValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setNegativeIntValue = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearNegativeIntValue = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasNegativeIntValue = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional double double_value = 6;
- * @return {number}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getDoubleValue = function() {
-  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 6, 0.0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setDoubleValue = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearDoubleValue = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasDoubleValue = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-/**
- * optional bytes string_value = 7;
- * @return {!(string|Uint8Array)}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getStringValue = function() {
-  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
-};
-
-
-/**
- * optional bytes string_value = 7;
- * This is a type-conversion wrapper around `getStringValue()`
- * @return {string}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getStringValue_asB64 = function() {
-  return /** @type {string} */ (jspb.Message.bytesAsB64(
-      this.getStringValue()));
-};
-
-
-/**
- * optional bytes string_value = 7;
- * Note that Uint8Array is not supported on all browsers.
- * @see http://caniuse.com/Uint8Array
- * This is a type-conversion wrapper around `getStringValue()`
- * @return {!Uint8Array}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getStringValue_asU8 = function() {
-  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
-      this.getStringValue()));
-};
-
-
-/**
- * @param {!(string|Uint8Array)} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setStringValue = function(value) {
-  return jspb.Message.setField(this, 7, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearStringValue = function() {
-  return jspb.Message.setField(this, 7, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasStringValue = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-/**
- * optional string aggregate_value = 8;
- * @return {string}
- */
-proto.google.protobuf.UninterpretedOption.prototype.getAggregateValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.setAggregateValue = function(value) {
-  return jspb.Message.setField(this, 8, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.UninterpretedOption} returns this
- */
-proto.google.protobuf.UninterpretedOption.prototype.clearAggregateValue = function() {
-  return jspb.Message.setField(this, 8, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.UninterpretedOption.prototype.hasAggregateValue = function() {
-  return jspb.Message.getField(this, 8) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.SourceCodeInfo.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.SourceCodeInfo.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.SourceCodeInfo.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.SourceCodeInfo} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceCodeInfo.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    locationList: jspb.Message.toObjectList(msg.getLocationList(),
-    proto.google.protobuf.SourceCodeInfo.Location.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.SourceCodeInfo}
- */
-proto.google.protobuf.SourceCodeInfo.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.SourceCodeInfo;
-  return proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.SourceCodeInfo} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.SourceCodeInfo}
- */
-proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new proto.google.protobuf.SourceCodeInfo.Location;
-      reader.readMessage(value,proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader);
-      msg.addLocation(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.SourceCodeInfo.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.SourceCodeInfo} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getLocationList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      1,
-      f,
-      proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter
-    );
-  }
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.SourceCodeInfo.Location.repeatedFields_ = [1,2,6];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.SourceCodeInfo.Location.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.SourceCodeInfo.Location} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceCodeInfo.Location.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    pathList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
-    spanList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
-    leadingComments: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    trailingComments: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
-    leadingDetachedCommentsList: (f = jspb.Message.getRepeatedField(msg, 6)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location}
- */
-proto.google.protobuf.SourceCodeInfo.Location.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.SourceCodeInfo.Location;
-  return proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.SourceCodeInfo.Location} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location}
- */
-proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addPath(values[i]);
-      }
-      break;
-    case 2:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addSpan(values[i]);
-      }
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLeadingComments(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTrailingComments(value);
-      break;
-    case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addLeadingDetachedComments(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.SourceCodeInfo.Location} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getPathList();
-  if (f.length > 0) {
-    writer.writePackedInt32(
-      1,
-      f
-    );
-  }
-  f = message.getSpanList();
-  if (f.length > 0) {
-    writer.writePackedInt32(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = message.getLeadingDetachedCommentsList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      6,
-      f
-    );
-  }
-};
-
-
-/**
- * repeated int32 path = 1;
- * @return {!Array<number>}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.getPathList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 1));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.setPathList = function(value) {
-  return jspb.Message.setField(this, 1, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.addPath = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.clearPathList = function() {
-  return this.setPathList([]);
-};
-
-
-/**
- * repeated int32 span = 2;
- * @return {!Array<number>}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.getSpanList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 2));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.setSpanList = function(value) {
-  return jspb.Message.setField(this, 2, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.addSpan = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.clearSpanList = function() {
-  return this.setSpanList([]);
-};
-
-
-/**
- * optional string leading_comments = 3;
- * @return {string}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.getLeadingComments = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.setLeadingComments = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.clearLeadingComments = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.hasLeadingComments = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional string trailing_comments = 4;
- * @return {string}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.getTrailingComments = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.setTrailingComments = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.clearTrailingComments = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.hasTrailingComments = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * repeated string leading_detached_comments = 6;
- * @return {!Array<string>}
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.getLeadingDetachedCommentsList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 6));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.setLeadingDetachedCommentsList = function(value) {
-  return jspb.Message.setField(this, 6, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.addLeadingDetachedComments = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 6, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
- */
-proto.google.protobuf.SourceCodeInfo.Location.prototype.clearLeadingDetachedCommentsList = function() {
-  return this.setLeadingDetachedCommentsList([]);
-};
-
-
-/**
- * repeated Location location = 1;
- * @return {!Array<!proto.google.protobuf.SourceCodeInfo.Location>}
- */
-proto.google.protobuf.SourceCodeInfo.prototype.getLocationList = function() {
-  return /** @type{!Array<!proto.google.protobuf.SourceCodeInfo.Location>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.SourceCodeInfo.Location, 1));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.SourceCodeInfo.Location>} value
- * @return {!proto.google.protobuf.SourceCodeInfo} returns this
-*/
-proto.google.protobuf.SourceCodeInfo.prototype.setLocationList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 1, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.SourceCodeInfo.Location=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.SourceCodeInfo.Location}
- */
-proto.google.protobuf.SourceCodeInfo.prototype.addLocation = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.SourceCodeInfo.Location, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.SourceCodeInfo} returns this
- */
-proto.google.protobuf.SourceCodeInfo.prototype.clearLocationList = function() {
-  return this.setLocationList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.GeneratedCodeInfo.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.GeneratedCodeInfo.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.GeneratedCodeInfo.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.GeneratedCodeInfo} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.GeneratedCodeInfo.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    annotationList: jspb.Message.toObjectList(msg.getAnnotationList(),
-    proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.GeneratedCodeInfo}
- */
-proto.google.protobuf.GeneratedCodeInfo.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.GeneratedCodeInfo;
-  return proto.google.protobuf.GeneratedCodeInfo.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.GeneratedCodeInfo} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.GeneratedCodeInfo}
- */
-proto.google.protobuf.GeneratedCodeInfo.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new proto.google.protobuf.GeneratedCodeInfo.Annotation;
-      reader.readMessage(value,proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader);
-      msg.addAnnotation(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.GeneratedCodeInfo.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.GeneratedCodeInfo.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.GeneratedCodeInfo} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.GeneratedCodeInfo.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getAnnotationList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      1,
-      f,
-      proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter
-    );
-  }
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    pathList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
-    sourceFile: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    begin: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    end: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.GeneratedCodeInfo.Annotation;
-  return proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addPath(values[i]);
-      }
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setSourceFile(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setBegin(value);
-      break;
-    case 4:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setEnd(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getPathList();
-  if (f.length > 0) {
-    writer.writePackedInt32(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeInt32(
-      3,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeInt32(
-      4,
-      f
-    );
-  }
-};
-
-
-/**
- * repeated int32 path = 1;
- * @return {!Array<number>}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getPathList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 1));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setPathList = function(value) {
-  return jspb.Message.setField(this, 1, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.addPath = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearPathList = function() {
-  return this.setPathList([]);
-};
-
-
-/**
- * optional string source_file = 2;
- * @return {string}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getSourceFile = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setSourceFile = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearSourceFile = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasSourceFile = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional int32 begin = 3;
- * @return {number}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getBegin = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setBegin = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearBegin = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasBegin = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional int32 end = 4;
- * @return {number}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getEnd = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setEnd = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearEnd = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasEnd = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * repeated Annotation annotation = 1;
- * @return {!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>}
- */
-proto.google.protobuf.GeneratedCodeInfo.prototype.getAnnotationList = function() {
-  return /** @type{!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.GeneratedCodeInfo.Annotation, 1));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>} value
- * @return {!proto.google.protobuf.GeneratedCodeInfo} returns this
-*/
-proto.google.protobuf.GeneratedCodeInfo.prototype.setAnnotationList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 1, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
- */
-proto.google.protobuf.GeneratedCodeInfo.prototype.addAnnotation = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.GeneratedCodeInfo.Annotation, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.GeneratedCodeInfo} returns this
- */
-proto.google.protobuf.GeneratedCodeInfo.prototype.clearAnnotationList = function() {
-  return this.setAnnotationList([]);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js
deleted file mode 100644
index 4ceb55a..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js
+++ /dev/null
@@ -1,200 +0,0 @@
-// source: google/protobuf/duration.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.Duration', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Duration = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Duration, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Duration.displayName = 'proto.google.protobuf.Duration';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Duration.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Duration.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Duration} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Duration.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    seconds: jspb.Message.getFieldWithDefault(msg, 1, 0),
-    nanos: jspb.Message.getFieldWithDefault(msg, 2, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Duration}
- */
-proto.google.protobuf.Duration.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Duration;
-  return proto.google.protobuf.Duration.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Duration} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Duration}
- */
-proto.google.protobuf.Duration.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt64());
-      msg.setSeconds(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNanos(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Duration.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Duration.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Duration} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Duration.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getSeconds();
-  if (f !== 0) {
-    writer.writeInt64(
-      1,
-      f
-    );
-  }
-  f = message.getNanos();
-  if (f !== 0) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int64 seconds = 1;
- * @return {number}
- */
-proto.google.protobuf.Duration.prototype.getSeconds = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Duration} returns this
- */
-proto.google.protobuf.Duration.prototype.setSeconds = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-/**
- * optional int32 nanos = 2;
- * @return {number}
- */
-proto.google.protobuf.Duration.prototype.getNanos = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Duration} returns this
- */
-proto.google.protobuf.Duration.prototype.setNanos = function(value) {
-  return jspb.Message.setProto3IntField(this, 2, value);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js
deleted file mode 100644
index 31392b4..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// source: google/protobuf/empty.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.Empty', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Empty = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Empty, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Empty.displayName = 'proto.google.protobuf.Empty';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Empty.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Empty.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Empty} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Empty.toObject = function(includeInstance, msg) {
-  var f, obj = {
-
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Empty}
- */
-proto.google.protobuf.Empty.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Empty;
-  return proto.google.protobuf.Empty.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Empty} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Empty}
- */
-proto.google.protobuf.Empty.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Empty.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Empty.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Empty} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Empty.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js
deleted file mode 100644
index ee7bda0..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js
+++ /dev/null
@@ -1,196 +0,0 @@
-// source: google/protobuf/field_mask.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.FieldMask', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FieldMask = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FieldMask.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.FieldMask, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FieldMask.displayName = 'proto.google.protobuf.FieldMask';
-}
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.FieldMask.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FieldMask.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FieldMask.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FieldMask} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldMask.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    pathsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FieldMask}
- */
-proto.google.protobuf.FieldMask.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FieldMask;
-  return proto.google.protobuf.FieldMask.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FieldMask} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FieldMask}
- */
-proto.google.protobuf.FieldMask.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addPaths(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FieldMask.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FieldMask.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FieldMask} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FieldMask.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getPathsList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * repeated string paths = 1;
- * @return {!Array<string>}
- */
-proto.google.protobuf.FieldMask.prototype.getPathsList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.FieldMask} returns this
- */
-proto.google.protobuf.FieldMask.prototype.setPathsList = function(value) {
-  return jspb.Message.setField(this, 1, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.FieldMask} returns this
- */
-proto.google.protobuf.FieldMask.prototype.addPaths = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.FieldMask} returns this
- */
-proto.google.protobuf.FieldMask.prototype.clearPathsList = function() {
-  return this.setPathsList([]);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js
deleted file mode 100644
index 1cc063c..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js
+++ /dev/null
@@ -1,170 +0,0 @@
-// source: google/protobuf/source_context.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.SourceContext', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.SourceContext = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.SourceContext, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.SourceContext.displayName = 'proto.google.protobuf.SourceContext';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.SourceContext.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.SourceContext.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.SourceContext} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceContext.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    fileName: jspb.Message.getFieldWithDefault(msg, 1, "")
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.SourceContext}
- */
-proto.google.protobuf.SourceContext.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.SourceContext;
-  return proto.google.protobuf.SourceContext.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.SourceContext} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.SourceContext}
- */
-proto.google.protobuf.SourceContext.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setFileName(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.SourceContext.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.SourceContext.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.SourceContext} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.SourceContext.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getFileName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string file_name = 1;
- * @return {string}
- */
-proto.google.protobuf.SourceContext.prototype.getFileName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.SourceContext} returns this
- */
-proto.google.protobuf.SourceContext.prototype.setFileName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js
deleted file mode 100644
index b1f2a9a..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js
+++ /dev/null
@@ -1,948 +0,0 @@
-// source: google/protobuf/struct.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.ListValue', null, proto);
-goog.exportSymbol('google.protobuf.NullValue', null, proto);
-goog.exportSymbol('google.protobuf.Struct', null, proto);
-goog.exportSymbol('google.protobuf.Value', null, proto);
-goog.exportSymbol('google.protobuf.Value.KindCase', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Struct = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Struct, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Struct.displayName = 'proto.google.protobuf.Struct';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Value = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.google.protobuf.Value.oneofGroups_);
-};
-goog.inherits(proto.google.protobuf.Value, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Value.displayName = 'proto.google.protobuf.Value';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.ListValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.ListValue.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.ListValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.ListValue.displayName = 'proto.google.protobuf.ListValue';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Struct.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Struct.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Struct} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Struct.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    fieldsMap: (f = msg.getFieldsMap()) ? f.toObject(includeInstance, proto.google.protobuf.Value.toObject) : []
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Struct}
- */
-proto.google.protobuf.Struct.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Struct;
-  return proto.google.protobuf.Struct.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Struct} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Struct}
- */
-proto.google.protobuf.Struct.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = msg.getFieldsMap();
-      reader.readMessage(value, function(message, reader) {
-        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.google.protobuf.Value.deserializeBinaryFromReader, "", new proto.google.protobuf.Value());
-         });
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Struct.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Struct.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Struct} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Struct.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getFieldsMap(true);
-  if (f && f.getLength() > 0) {
-    f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.google.protobuf.Value.serializeBinaryToWriter);
-  }
-};
-
-
-/**
- * map<string, Value> fields = 1;
- * @param {boolean=} opt_noLazyCreate Do not create the map if
- * empty, instead returning `undefined`
- * @return {!jspb.Map<string,!proto.google.protobuf.Value>}
- */
-proto.google.protobuf.Struct.prototype.getFieldsMap = function(opt_noLazyCreate) {
-  return /** @type {!jspb.Map<string,!proto.google.protobuf.Value>} */ (
-      jspb.Message.getMapField(this, 1, opt_noLazyCreate,
-      proto.google.protobuf.Value));
-};
-
-
-/**
- * Clears values from the map. The map will be non-null.
- * @return {!proto.google.protobuf.Struct} returns this
- */
-proto.google.protobuf.Struct.prototype.clearFieldsMap = function() {
-  this.getFieldsMap().clear();
-  return this;};
-
-
-
-/**
- * Oneof group definitions for this message. Each group defines the field
- * numbers belonging to that group. When of these fields' value is set, all
- * other fields in the group are cleared. During deserialization, if multiple
- * fields are encountered for a group, only the last value seen will be kept.
- * @private {!Array<!Array<number>>}
- * @const
- */
-proto.google.protobuf.Value.oneofGroups_ = [[1,2,3,4,5,6]];
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.Value.KindCase = {
-  KIND_NOT_SET: 0,
-  NULL_VALUE: 1,
-  NUMBER_VALUE: 2,
-  STRING_VALUE: 3,
-  BOOL_VALUE: 4,
-  STRUCT_VALUE: 5,
-  LIST_VALUE: 6
-};
-
-/**
- * @return {proto.google.protobuf.Value.KindCase}
- */
-proto.google.protobuf.Value.prototype.getKindCase = function() {
-  return /** @type {proto.google.protobuf.Value.KindCase} */(jspb.Message.computeOneofCase(this, proto.google.protobuf.Value.oneofGroups_[0]));
-};
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Value.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Value.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Value} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Value.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    nullValue: jspb.Message.getFieldWithDefault(msg, 1, 0),
-    numberValue: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),
-    stringValue: jspb.Message.getFieldWithDefault(msg, 3, ""),
-    boolValue: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),
-    structValue: (f = msg.getStructValue()) && proto.google.protobuf.Struct.toObject(includeInstance, f),
-    listValue: (f = msg.getListValue()) && proto.google.protobuf.ListValue.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Value}
- */
-proto.google.protobuf.Value.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Value;
-  return proto.google.protobuf.Value.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Value} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Value}
- */
-proto.google.protobuf.Value.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {!proto.google.protobuf.NullValue} */ (reader.readEnum());
-      msg.setNullValue(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readDouble());
-      msg.setNumberValue(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setStringValue(value);
-      break;
-    case 4:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setBoolValue(value);
-      break;
-    case 5:
-      var value = new proto.google.protobuf.Struct;
-      reader.readMessage(value,proto.google.protobuf.Struct.deserializeBinaryFromReader);
-      msg.setStructValue(value);
-      break;
-    case 6:
-      var value = new proto.google.protobuf.ListValue;
-      reader.readMessage(value,proto.google.protobuf.ListValue.deserializeBinaryFromReader);
-      msg.setListValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Value.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Value.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Value} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Value.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {!proto.google.protobuf.NullValue} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeEnum(
-      1,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeDouble(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeBool(
-      4,
-      f
-    );
-  }
-  f = message.getStructValue();
-  if (f != null) {
-    writer.writeMessage(
-      5,
-      f,
-      proto.google.protobuf.Struct.serializeBinaryToWriter
-    );
-  }
-  f = message.getListValue();
-  if (f != null) {
-    writer.writeMessage(
-      6,
-      f,
-      proto.google.protobuf.ListValue.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional NullValue null_value = 1;
- * @return {!proto.google.protobuf.NullValue}
- */
-proto.google.protobuf.Value.prototype.getNullValue = function() {
-  return /** @type {!proto.google.protobuf.NullValue} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.NullValue} value
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.setNullValue = function(value) {
-  return jspb.Message.setOneofField(this, 1, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearNullValue = function() {
-  return jspb.Message.setOneofField(this, 1, proto.google.protobuf.Value.oneofGroups_[0], undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasNullValue = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional double number_value = 2;
- * @return {number}
- */
-proto.google.protobuf.Value.prototype.getNumberValue = function() {
-  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.setNumberValue = function(value) {
-  return jspb.Message.setOneofField(this, 2, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearNumberValue = function() {
-  return jspb.Message.setOneofField(this, 2, proto.google.protobuf.Value.oneofGroups_[0], undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasNumberValue = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string string_value = 3;
- * @return {string}
- */
-proto.google.protobuf.Value.prototype.getStringValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.setStringValue = function(value) {
-  return jspb.Message.setOneofField(this, 3, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearStringValue = function() {
-  return jspb.Message.setOneofField(this, 3, proto.google.protobuf.Value.oneofGroups_[0], undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasStringValue = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional bool bool_value = 4;
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.getBoolValue = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.setBoolValue = function(value) {
-  return jspb.Message.setOneofField(this, 4, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearBoolValue = function() {
-  return jspb.Message.setOneofField(this, 4, proto.google.protobuf.Value.oneofGroups_[0], undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasBoolValue = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional Struct struct_value = 5;
- * @return {?proto.google.protobuf.Struct}
- */
-proto.google.protobuf.Value.prototype.getStructValue = function() {
-  return /** @type{?proto.google.protobuf.Struct} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.Struct, 5));
-};
-
-
-/**
- * @param {?proto.google.protobuf.Struct|undefined} value
- * @return {!proto.google.protobuf.Value} returns this
-*/
-proto.google.protobuf.Value.prototype.setStructValue = function(value) {
-  return jspb.Message.setOneofWrapperField(this, 5, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearStructValue = function() {
-  return this.setStructValue(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasStructValue = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional ListValue list_value = 6;
- * @return {?proto.google.protobuf.ListValue}
- */
-proto.google.protobuf.Value.prototype.getListValue = function() {
-  return /** @type{?proto.google.protobuf.ListValue} */ (
-    jspb.Message.getWrapperField(this, proto.google.protobuf.ListValue, 6));
-};
-
-
-/**
- * @param {?proto.google.protobuf.ListValue|undefined} value
- * @return {!proto.google.protobuf.Value} returns this
-*/
-proto.google.protobuf.Value.prototype.setListValue = function(value) {
-  return jspb.Message.setOneofWrapperField(this, 6, proto.google.protobuf.Value.oneofGroups_[0], value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Value} returns this
- */
-proto.google.protobuf.Value.prototype.clearListValue = function() {
-  return this.setListValue(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Value.prototype.hasListValue = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.ListValue.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.ListValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.ListValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.ListValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ListValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    valuesList: jspb.Message.toObjectList(msg.getValuesList(),
-    proto.google.protobuf.Value.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.ListValue}
- */
-proto.google.protobuf.ListValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.ListValue;
-  return proto.google.protobuf.ListValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.ListValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.ListValue}
- */
-proto.google.protobuf.ListValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new proto.google.protobuf.Value;
-      reader.readMessage(value,proto.google.protobuf.Value.deserializeBinaryFromReader);
-      msg.addValues(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.ListValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.ListValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.ListValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.ListValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValuesList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      1,
-      f,
-      proto.google.protobuf.Value.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * repeated Value values = 1;
- * @return {!Array<!proto.google.protobuf.Value>}
- */
-proto.google.protobuf.ListValue.prototype.getValuesList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Value>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Value, 1));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Value>} value
- * @return {!proto.google.protobuf.ListValue} returns this
-*/
-proto.google.protobuf.ListValue.prototype.setValuesList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 1, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Value=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Value}
- */
-proto.google.protobuf.ListValue.prototype.addValues = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.Value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.ListValue} returns this
- */
-proto.google.protobuf.ListValue.prototype.clearValuesList = function() {
-  return this.setValuesList([]);
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.NullValue = {
-  NULL_VALUE: 0
-};
-
-goog.object.extend(exports, proto);
-/* This code will be inserted into generated code for
- * google/protobuf/struct.proto. */
-
-/**
- * Typedef representing plain JavaScript values that can go into a
- *     Struct.
- * @typedef {null|number|string|boolean|Array|Object}
- */
-proto.google.protobuf.JavaScriptValue;
-
-
-/**
- * Converts this Value object to a plain JavaScript value.
- * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript
- *     value representing this Struct.
- */
-proto.google.protobuf.Value.prototype.toJavaScript = function() {
-  var kindCase = proto.google.protobuf.Value.KindCase;
-  switch (this.getKindCase()) {
-    case kindCase.NULL_VALUE:
-      return null;
-    case kindCase.NUMBER_VALUE:
-      return this.getNumberValue();
-    case kindCase.STRING_VALUE:
-      return this.getStringValue();
-    case kindCase.BOOL_VALUE:
-      return this.getBoolValue();
-    case kindCase.STRUCT_VALUE:
-      return this.getStructValue().toJavaScript();
-    case kindCase.LIST_VALUE:
-      return this.getListValue().toJavaScript();
-    default:
-      throw new Error('Unexpected struct type');
-  }
-};
-
-
-/**
- * Converts this JavaScript value to a new Value proto.
- * @param {!proto.google.protobuf.JavaScriptValue} value The value to
- *     convert.
- * @return {!proto.google.protobuf.Value} The newly constructed value.
- */
-proto.google.protobuf.Value.fromJavaScript = function(value) {
-  var ret = new proto.google.protobuf.Value();
-  switch (goog.typeOf(value)) {
-    case 'string':
-      ret.setStringValue(/** @type {string} */ (value));
-      break;
-    case 'number':
-      ret.setNumberValue(/** @type {number} */ (value));
-      break;
-    case 'boolean':
-      ret.setBoolValue(/** @type {boolean} */ (value));
-      break;
-    case 'null':
-      ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);
-      break;
-    case 'array':
-      ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(
-          /** @type{!Array} */ (value)));
-      break;
-    case 'object':
-      ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(
-          /** @type{!Object} */ (value)));
-      break;
-    default:
-      throw new Error('Unexpected struct type.');
-  }
-
-  return ret;
-};
-
-
-/**
- * Converts this ListValue object to a plain JavaScript array.
- * @return {!Array} a plain JavaScript array representing this List.
- */
-proto.google.protobuf.ListValue.prototype.toJavaScript = function() {
-  var ret = [];
-  var values = this.getValuesList();
-
-  for (var i = 0; i < values.length; i++) {
-    ret[i] = values[i].toJavaScript();
-  }
-
-  return ret;
-};
-
-
-/**
- * Constructs a ListValue protobuf from this plain JavaScript array.
- * @param {!Array} array a plain JavaScript array
- * @return {proto.google.protobuf.ListValue} a new ListValue object
- */
-proto.google.protobuf.ListValue.fromJavaScript = function(array) {
-  var ret = new proto.google.protobuf.ListValue();
-
-  for (var i = 0; i < array.length; i++) {
-    ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));
-  }
-
-  return ret;
-};
-
-
-/**
- * Converts this Struct object to a plain JavaScript object.
- * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a plain
- *     JavaScript object representing this Struct.
- */
-proto.google.protobuf.Struct.prototype.toJavaScript = function() {
-  var ret = {};
-
-  this.getFieldsMap().forEach(function(value, key) {
-    ret[key] = value.toJavaScript();
-  });
-
-  return ret;
-};
-
-
-/**
- * Constructs a Struct protobuf from this plain JavaScript object.
- * @param {!Object} obj a plain JavaScript object
- * @return {proto.google.protobuf.Struct} a new Struct object
- */
-proto.google.protobuf.Struct.fromJavaScript = function(obj) {
-  var ret = new proto.google.protobuf.Struct();
-  var map = ret.getFieldsMap();
-
-  for (var property in obj) {
-    var val = obj[property];
-    map.set(property, proto.google.protobuf.Value.fromJavaScript(val));
-  }
-
-  return ret;
-};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js
deleted file mode 100644
index 42ece50..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js
+++ /dev/null
@@ -1,236 +0,0 @@
-// source: google/protobuf/timestamp.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.Timestamp', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Timestamp = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Timestamp, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Timestamp.displayName = 'proto.google.protobuf.Timestamp';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Timestamp.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Timestamp.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Timestamp} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Timestamp.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    seconds: jspb.Message.getFieldWithDefault(msg, 1, 0),
-    nanos: jspb.Message.getFieldWithDefault(msg, 2, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Timestamp}
- */
-proto.google.protobuf.Timestamp.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Timestamp;
-  return proto.google.protobuf.Timestamp.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Timestamp} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Timestamp}
- */
-proto.google.protobuf.Timestamp.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt64());
-      msg.setSeconds(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNanos(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Timestamp.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Timestamp.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Timestamp} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Timestamp.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getSeconds();
-  if (f !== 0) {
-    writer.writeInt64(
-      1,
-      f
-    );
-  }
-  f = message.getNanos();
-  if (f !== 0) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int64 seconds = 1;
- * @return {number}
- */
-proto.google.protobuf.Timestamp.prototype.getSeconds = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Timestamp} returns this
- */
-proto.google.protobuf.Timestamp.prototype.setSeconds = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-/**
- * optional int32 nanos = 2;
- * @return {number}
- */
-proto.google.protobuf.Timestamp.prototype.getNanos = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Timestamp} returns this
- */
-proto.google.protobuf.Timestamp.prototype.setNanos = function(value) {
-  return jspb.Message.setProto3IntField(this, 2, value);
-};
-
-
-goog.object.extend(exports, proto);
-/* This code will be inserted into generated code for
- * google/protobuf/timestamp.proto. */
-
-/**
- * Returns a JavaScript 'Date' object corresponding to this Timestamp.
- * @return {!Date}
- */
-proto.google.protobuf.Timestamp.prototype.toDate = function() {
-  var seconds = this.getSeconds();
-  var nanos = this.getNanos();
-
-  return new Date((seconds * 1000) + (nanos / 1000000));
-};
-
-
-/**
- * Sets the value of this Timestamp object to be the given Date.
- * @param {!Date} value The value to set.
- */
-proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {
-  this.setSeconds(Math.floor(value.getTime() / 1000));
-  this.setNanos(value.getMilliseconds() * 1000000);
-};
-
-
-/**
- * Factory method that returns a Timestamp object with value equal to
- * the given Date.
- * @param {!Date} value The value to set.
- * @return {!proto.google.protobuf.Timestamp}
- */
-proto.google.protobuf.Timestamp.fromDate = function(value) {
-  var timestamp = new proto.google.protobuf.Timestamp();
-  timestamp.fromDate(value);
-  return timestamp;
-};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js
deleted file mode 100644
index e8bcb30..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js
+++ /dev/null
@@ -1,1706 +0,0 @@
-// source: google/protobuf/type.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js');
-goog.object.extend(proto, google_protobuf_any_pb);
-var google_protobuf_source_context_pb = require('google-protobuf/google/protobuf/source_context_pb.js');
-goog.object.extend(proto, google_protobuf_source_context_pb);
-goog.exportSymbol('google.protobuf.Enum', null, proto);
-goog.exportSymbol('google.protobuf.EnumValue', null, proto);
-goog.exportSymbol('google.protobuf.Field', null, proto);
-goog.exportSymbol('google.protobuf.Field.Cardinality', null, proto);
-goog.exportSymbol('google.protobuf.Field.Kind', null, proto);
-goog.exportSymbol('google.protobuf.Option', null, proto);
-goog.exportSymbol('google.protobuf.Syntax', null, proto);
-goog.exportSymbol('google.protobuf.Type', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Type = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Type.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.Type, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Type.displayName = 'proto.google.protobuf.Type';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Field = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Field.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.Field, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Field.displayName = 'proto.google.protobuf.Field';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Enum = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Enum.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.Enum, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Enum.displayName = 'proto.google.protobuf.Enum';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.EnumValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.EnumValue.repeatedFields_, null);
-};
-goog.inherits(proto.google.protobuf.EnumValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.EnumValue.displayName = 'proto.google.protobuf.EnumValue';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Option = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Option, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Option.displayName = 'proto.google.protobuf.Option';
-}
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.Type.repeatedFields_ = [2,3,4];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Type.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Type.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Type} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Type.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    fieldsList: jspb.Message.toObjectList(msg.getFieldsList(),
-    proto.google.protobuf.Field.toObject, includeInstance),
-    oneofsList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    proto.google.protobuf.Option.toObject, includeInstance),
-    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
-    syntax: jspb.Message.getFieldWithDefault(msg, 6, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Type}
- */
-proto.google.protobuf.Type.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Type;
-  return proto.google.protobuf.Type.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Type} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Type}
- */
-proto.google.protobuf.Type.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.Field;
-      reader.readMessage(value,proto.google.protobuf.Field.deserializeBinaryFromReader);
-      msg.addFields(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addOneofs(value);
-      break;
-    case 4:
-      var value = new proto.google.protobuf.Option;
-      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    case 5:
-      var value = new google_protobuf_source_context_pb.SourceContext;
-      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
-      msg.setSourceContext(value);
-      break;
-    case 6:
-      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
-      msg.setSyntax(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Type.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Type.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Type} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Type.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getFieldsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.Field.serializeBinaryToWriter
-    );
-  }
-  f = message.getOneofsList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      3,
-      f
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      4,
-      f,
-      proto.google.protobuf.Option.serializeBinaryToWriter
-    );
-  }
-  f = message.getSourceContext();
-  if (f != null) {
-    writer.writeMessage(
-      5,
-      f,
-      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
-    );
-  }
-  f = message.getSyntax();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      6,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Type.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * repeated Field fields = 2;
- * @return {!Array<!proto.google.protobuf.Field>}
- */
-proto.google.protobuf.Type.prototype.getFieldsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Field>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Field, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Field>} value
- * @return {!proto.google.protobuf.Type} returns this
-*/
-proto.google.protobuf.Type.prototype.setFieldsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Field=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Field}
- */
-proto.google.protobuf.Type.prototype.addFields = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.Field, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.clearFieldsList = function() {
-  return this.setFieldsList([]);
-};
-
-
-/**
- * repeated string oneofs = 3;
- * @return {!Array<string>}
- */
-proto.google.protobuf.Type.prototype.getOneofsList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.setOneofsList = function(value) {
-  return jspb.Message.setField(this, 3, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.addOneofs = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.clearOneofsList = function() {
-  return this.setOneofsList([]);
-};
-
-
-/**
- * repeated Option options = 4;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.Type.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 4));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.Type} returns this
-*/
-proto.google.protobuf.Type.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 4, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Type.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-/**
- * optional SourceContext source_context = 5;
- * @return {?proto.google.protobuf.SourceContext}
- */
-proto.google.protobuf.Type.prototype.getSourceContext = function() {
-  return /** @type{?proto.google.protobuf.SourceContext} */ (
-    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 5));
-};
-
-
-/**
- * @param {?proto.google.protobuf.SourceContext|undefined} value
- * @return {!proto.google.protobuf.Type} returns this
-*/
-proto.google.protobuf.Type.prototype.setSourceContext = function(value) {
-  return jspb.Message.setWrapperField(this, 5, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.clearSourceContext = function() {
-  return this.setSourceContext(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Type.prototype.hasSourceContext = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional Syntax syntax = 6;
- * @return {!proto.google.protobuf.Syntax}
- */
-proto.google.protobuf.Type.prototype.getSyntax = function() {
-  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Syntax} value
- * @return {!proto.google.protobuf.Type} returns this
- */
-proto.google.protobuf.Type.prototype.setSyntax = function(value) {
-  return jspb.Message.setProto3EnumField(this, 6, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.Field.repeatedFields_ = [9];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Field.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Field.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Field} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Field.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    kind: jspb.Message.getFieldWithDefault(msg, 1, 0),
-    cardinality: jspb.Message.getFieldWithDefault(msg, 2, 0),
-    number: jspb.Message.getFieldWithDefault(msg, 3, 0),
-    name: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    typeUrl: jspb.Message.getFieldWithDefault(msg, 6, ""),
-    oneofIndex: jspb.Message.getFieldWithDefault(msg, 7, 0),
-    packed: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    proto.google.protobuf.Option.toObject, includeInstance),
-    jsonName: jspb.Message.getFieldWithDefault(msg, 10, ""),
-    defaultValue: jspb.Message.getFieldWithDefault(msg, 11, "")
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Field}
- */
-proto.google.protobuf.Field.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Field;
-  return proto.google.protobuf.Field.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Field} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Field}
- */
-proto.google.protobuf.Field.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {!proto.google.protobuf.Field.Kind} */ (reader.readEnum());
-      msg.setKind(value);
-      break;
-    case 2:
-      var value = /** @type {!proto.google.protobuf.Field.Cardinality} */ (reader.readEnum());
-      msg.setCardinality(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNumber(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTypeUrl(value);
-      break;
-    case 7:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setOneofIndex(value);
-      break;
-    case 8:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setPacked(value);
-      break;
-    case 9:
-      var value = new proto.google.protobuf.Option;
-      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    case 10:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setJsonName(value);
-      break;
-    case 11:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDefaultValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Field.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Field.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Field} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Field.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getKind();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      1,
-      f
-    );
-  }
-  f = message.getCardinality();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      2,
-      f
-    );
-  }
-  f = message.getNumber();
-  if (f !== 0) {
-    writer.writeInt32(
-      3,
-      f
-    );
-  }
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = message.getTypeUrl();
-  if (f.length > 0) {
-    writer.writeString(
-      6,
-      f
-    );
-  }
-  f = message.getOneofIndex();
-  if (f !== 0) {
-    writer.writeInt32(
-      7,
-      f
-    );
-  }
-  f = message.getPacked();
-  if (f) {
-    writer.writeBool(
-      8,
-      f
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      9,
-      f,
-      proto.google.protobuf.Option.serializeBinaryToWriter
-    );
-  }
-  f = message.getJsonName();
-  if (f.length > 0) {
-    writer.writeString(
-      10,
-      f
-    );
-  }
-  f = message.getDefaultValue();
-  if (f.length > 0) {
-    writer.writeString(
-      11,
-      f
-    );
-  }
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.Field.Kind = {
-  TYPE_UNKNOWN: 0,
-  TYPE_DOUBLE: 1,
-  TYPE_FLOAT: 2,
-  TYPE_INT64: 3,
-  TYPE_UINT64: 4,
-  TYPE_INT32: 5,
-  TYPE_FIXED64: 6,
-  TYPE_FIXED32: 7,
-  TYPE_BOOL: 8,
-  TYPE_STRING: 9,
-  TYPE_GROUP: 10,
-  TYPE_MESSAGE: 11,
-  TYPE_BYTES: 12,
-  TYPE_UINT32: 13,
-  TYPE_ENUM: 14,
-  TYPE_SFIXED32: 15,
-  TYPE_SFIXED64: 16,
-  TYPE_SINT32: 17,
-  TYPE_SINT64: 18
-};
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.Field.Cardinality = {
-  CARDINALITY_UNKNOWN: 0,
-  CARDINALITY_OPTIONAL: 1,
-  CARDINALITY_REQUIRED: 2,
-  CARDINALITY_REPEATED: 3
-};
-
-/**
- * optional Kind kind = 1;
- * @return {!proto.google.protobuf.Field.Kind}
- */
-proto.google.protobuf.Field.prototype.getKind = function() {
-  return /** @type {!proto.google.protobuf.Field.Kind} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Field.Kind} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setKind = function(value) {
-  return jspb.Message.setProto3EnumField(this, 1, value);
-};
-
-
-/**
- * optional Cardinality cardinality = 2;
- * @return {!proto.google.protobuf.Field.Cardinality}
- */
-proto.google.protobuf.Field.prototype.getCardinality = function() {
-  return /** @type {!proto.google.protobuf.Field.Cardinality} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Field.Cardinality} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setCardinality = function(value) {
-  return jspb.Message.setProto3EnumField(this, 2, value);
-};
-
-
-/**
- * optional int32 number = 3;
- * @return {number}
- */
-proto.google.protobuf.Field.prototype.getNumber = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setNumber = function(value) {
-  return jspb.Message.setProto3IntField(this, 3, value);
-};
-
-
-/**
- * optional string name = 4;
- * @return {string}
- */
-proto.google.protobuf.Field.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 4, value);
-};
-
-
-/**
- * optional string type_url = 6;
- * @return {string}
- */
-proto.google.protobuf.Field.prototype.getTypeUrl = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setTypeUrl = function(value) {
-  return jspb.Message.setProto3StringField(this, 6, value);
-};
-
-
-/**
- * optional int32 oneof_index = 7;
- * @return {number}
- */
-proto.google.protobuf.Field.prototype.getOneofIndex = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setOneofIndex = function(value) {
-  return jspb.Message.setProto3IntField(this, 7, value);
-};
-
-
-/**
- * optional bool packed = 8;
- * @return {boolean}
- */
-proto.google.protobuf.Field.prototype.getPacked = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setPacked = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 8, value);
-};
-
-
-/**
- * repeated Option options = 9;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.Field.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 9));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.Field} returns this
-*/
-proto.google.protobuf.Field.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 9, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Field.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-/**
- * optional string json_name = 10;
- * @return {string}
- */
-proto.google.protobuf.Field.prototype.getJsonName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setJsonName = function(value) {
-  return jspb.Message.setProto3StringField(this, 10, value);
-};
-
-
-/**
- * optional string default_value = 11;
- * @return {string}
- */
-proto.google.protobuf.Field.prototype.getDefaultValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Field} returns this
- */
-proto.google.protobuf.Field.prototype.setDefaultValue = function(value) {
-  return jspb.Message.setProto3StringField(this, 11, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.Enum.repeatedFields_ = [2,3];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Enum.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Enum.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Enum} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Enum.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    enumvalueList: jspb.Message.toObjectList(msg.getEnumvalueList(),
-    proto.google.protobuf.EnumValue.toObject, includeInstance),
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    proto.google.protobuf.Option.toObject, includeInstance),
-    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
-    syntax: jspb.Message.getFieldWithDefault(msg, 5, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Enum}
- */
-proto.google.protobuf.Enum.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Enum;
-  return proto.google.protobuf.Enum.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Enum} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Enum}
- */
-proto.google.protobuf.Enum.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new proto.google.protobuf.EnumValue;
-      reader.readMessage(value,proto.google.protobuf.EnumValue.deserializeBinaryFromReader);
-      msg.addEnumvalue(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.Option;
-      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    case 4:
-      var value = new google_protobuf_source_context_pb.SourceContext;
-      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
-      msg.setSourceContext(value);
-      break;
-    case 5:
-      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
-      msg.setSyntax(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Enum.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Enum.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Enum} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Enum.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getEnumvalueList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      2,
-      f,
-      proto.google.protobuf.EnumValue.serializeBinaryToWriter
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      3,
-      f,
-      proto.google.protobuf.Option.serializeBinaryToWriter
-    );
-  }
-  f = message.getSourceContext();
-  if (f != null) {
-    writer.writeMessage(
-      4,
-      f,
-      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
-    );
-  }
-  f = message.getSyntax();
-  if (f !== 0.0) {
-    writer.writeEnum(
-      5,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Enum.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Enum} returns this
- */
-proto.google.protobuf.Enum.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * repeated EnumValue enumvalue = 2;
- * @return {!Array<!proto.google.protobuf.EnumValue>}
- */
-proto.google.protobuf.Enum.prototype.getEnumvalueList = function() {
-  return /** @type{!Array<!proto.google.protobuf.EnumValue>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumValue, 2));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.EnumValue>} value
- * @return {!proto.google.protobuf.Enum} returns this
-*/
-proto.google.protobuf.Enum.prototype.setEnumvalueList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 2, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.EnumValue=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.EnumValue}
- */
-proto.google.protobuf.Enum.prototype.addEnumvalue = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.EnumValue, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Enum} returns this
- */
-proto.google.protobuf.Enum.prototype.clearEnumvalueList = function() {
-  return this.setEnumvalueList([]);
-};
-
-
-/**
- * repeated Option options = 3;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.Enum.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 3));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.Enum} returns this
-*/
-proto.google.protobuf.Enum.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 3, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Enum.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.Enum} returns this
- */
-proto.google.protobuf.Enum.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-/**
- * optional SourceContext source_context = 4;
- * @return {?proto.google.protobuf.SourceContext}
- */
-proto.google.protobuf.Enum.prototype.getSourceContext = function() {
-  return /** @type{?proto.google.protobuf.SourceContext} */ (
-    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 4));
-};
-
-
-/**
- * @param {?proto.google.protobuf.SourceContext|undefined} value
- * @return {!proto.google.protobuf.Enum} returns this
-*/
-proto.google.protobuf.Enum.prototype.setSourceContext = function(value) {
-  return jspb.Message.setWrapperField(this, 4, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Enum} returns this
- */
-proto.google.protobuf.Enum.prototype.clearSourceContext = function() {
-  return this.setSourceContext(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Enum.prototype.hasSourceContext = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional Syntax syntax = 5;
- * @return {!proto.google.protobuf.Syntax}
- */
-proto.google.protobuf.Enum.prototype.getSyntax = function() {
-  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
-};
-
-
-/**
- * @param {!proto.google.protobuf.Syntax} value
- * @return {!proto.google.protobuf.Enum} returns this
- */
-proto.google.protobuf.Enum.prototype.setSyntax = function(value) {
-  return jspb.Message.setProto3EnumField(this, 5, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.google.protobuf.EnumValue.repeatedFields_ = [3];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.EnumValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.EnumValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.EnumValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    number: jspb.Message.getFieldWithDefault(msg, 2, 0),
-    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
-    proto.google.protobuf.Option.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.EnumValue}
- */
-proto.google.protobuf.EnumValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.EnumValue;
-  return proto.google.protobuf.EnumValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.EnumValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.EnumValue}
- */
-proto.google.protobuf.EnumValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setNumber(value);
-      break;
-    case 3:
-      var value = new proto.google.protobuf.Option;
-      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
-      msg.addOptions(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.EnumValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.EnumValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.EnumValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.EnumValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getNumber();
-  if (f !== 0) {
-    writer.writeInt32(
-      2,
-      f
-    );
-  }
-  f = message.getOptionsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      3,
-      f,
-      proto.google.protobuf.Option.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.EnumValue.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.EnumValue} returns this
- */
-proto.google.protobuf.EnumValue.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional int32 number = 2;
- * @return {number}
- */
-proto.google.protobuf.EnumValue.prototype.getNumber = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.EnumValue} returns this
- */
-proto.google.protobuf.EnumValue.prototype.setNumber = function(value) {
-  return jspb.Message.setProto3IntField(this, 2, value);
-};
-
-
-/**
- * repeated Option options = 3;
- * @return {!Array<!proto.google.protobuf.Option>}
- */
-proto.google.protobuf.EnumValue.prototype.getOptionsList = function() {
-  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 3));
-};
-
-
-/**
- * @param {!Array<!proto.google.protobuf.Option>} value
- * @return {!proto.google.protobuf.EnumValue} returns this
-*/
-proto.google.protobuf.EnumValue.prototype.setOptionsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 3, value);
-};
-
-
-/**
- * @param {!proto.google.protobuf.Option=} opt_value
- * @param {number=} opt_index
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.EnumValue.prototype.addOptions = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.google.protobuf.EnumValue} returns this
- */
-proto.google.protobuf.EnumValue.prototype.clearOptionsList = function() {
-  return this.setOptionsList([]);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Option.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Option.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Option} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Option.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    value: (f = msg.getValue()) && google_protobuf_any_pb.Any.toObject(includeInstance, f)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Option.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Option;
-  return proto.google.protobuf.Option.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Option} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Option}
- */
-proto.google.protobuf.Option.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = new google_protobuf_any_pb.Any;
-      reader.readMessage(value,google_protobuf_any_pb.Any.deserializeBinaryFromReader);
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Option.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Option.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Option} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Option.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getValue();
-  if (f != null) {
-    writer.writeMessage(
-      2,
-      f,
-      google_protobuf_any_pb.Any.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.google.protobuf.Option.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.Option} returns this
- */
-proto.google.protobuf.Option.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional Any value = 2;
- * @return {?proto.google.protobuf.Any}
- */
-proto.google.protobuf.Option.prototype.getValue = function() {
-  return /** @type{?proto.google.protobuf.Any} */ (
-    jspb.Message.getWrapperField(this, google_protobuf_any_pb.Any, 2));
-};
-
-
-/**
- * @param {?proto.google.protobuf.Any|undefined} value
- * @return {!proto.google.protobuf.Option} returns this
-*/
-proto.google.protobuf.Option.prototype.setValue = function(value) {
-  return jspb.Message.setWrapperField(this, 2, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.google.protobuf.Option} returns this
- */
-proto.google.protobuf.Option.prototype.clearValue = function() {
-  return this.setValue(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.google.protobuf.Option.prototype.hasValue = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * @enum {number}
- */
-proto.google.protobuf.Syntax = {
-  SYNTAX_PROTO2: 0,
-  SYNTAX_PROTO3: 1
-};
-
-goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js
deleted file mode 100644
index 75b7a26..0000000
--- a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js
+++ /dev/null
@@ -1,1410 +0,0 @@
-// source: google/protobuf/wrappers.proto
-/**
- * @fileoverview
- * @enhanceable
- * @suppress {missingRequire} reports error on implicit type usages.
- * @suppress {messageConventions} JS Compiler reports an error if a variable or
- *     field starts with 'MSG_' and isn't a translatable message.
- * @public
- */
-// GENERATED CODE -- DO NOT EDIT!
-/* eslint-disable */
-// @ts-nocheck
-
-var jspb = require('google-protobuf');
-var goog = jspb;
-var proto = {};
-
-goog.exportSymbol('google.protobuf.BoolValue', null, proto);
-goog.exportSymbol('google.protobuf.BytesValue', null, proto);
-goog.exportSymbol('google.protobuf.DoubleValue', null, proto);
-goog.exportSymbol('google.protobuf.FloatValue', null, proto);
-goog.exportSymbol('google.protobuf.Int32Value', null, proto);
-goog.exportSymbol('google.protobuf.Int64Value', null, proto);
-goog.exportSymbol('google.protobuf.StringValue', null, proto);
-goog.exportSymbol('google.protobuf.UInt32Value', null, proto);
-goog.exportSymbol('google.protobuf.UInt64Value', null, proto);
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.DoubleValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.DoubleValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.DoubleValue.displayName = 'proto.google.protobuf.DoubleValue';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.FloatValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.FloatValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.FloatValue.displayName = 'proto.google.protobuf.FloatValue';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Int64Value = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Int64Value, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Int64Value.displayName = 'proto.google.protobuf.Int64Value';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.UInt64Value = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.UInt64Value, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.UInt64Value.displayName = 'proto.google.protobuf.UInt64Value';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.Int32Value = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.Int32Value, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.Int32Value.displayName = 'proto.google.protobuf.Int32Value';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.UInt32Value = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.UInt32Value, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.UInt32Value.displayName = 'proto.google.protobuf.UInt32Value';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.BoolValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.BoolValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.BoolValue.displayName = 'proto.google.protobuf.BoolValue';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.StringValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.StringValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.StringValue.displayName = 'proto.google.protobuf.StringValue';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.google.protobuf.BytesValue = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.google.protobuf.BytesValue, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.google.protobuf.BytesValue.displayName = 'proto.google.protobuf.BytesValue';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.DoubleValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.DoubleValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.DoubleValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DoubleValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFloatingPointFieldWithDefault(msg, 1, 0.0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.DoubleValue}
- */
-proto.google.protobuf.DoubleValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.DoubleValue;
-  return proto.google.protobuf.DoubleValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.DoubleValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.DoubleValue}
- */
-proto.google.protobuf.DoubleValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readDouble());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.DoubleValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.DoubleValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.DoubleValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.DoubleValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0.0) {
-    writer.writeDouble(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional double value = 1;
- * @return {number}
- */
-proto.google.protobuf.DoubleValue.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 1, 0.0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.DoubleValue} returns this
- */
-proto.google.protobuf.DoubleValue.prototype.setValue = function(value) {
-  return jspb.Message.setProto3FloatField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.FloatValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.FloatValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.FloatValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FloatValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFloatingPointFieldWithDefault(msg, 1, 0.0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.FloatValue}
- */
-proto.google.protobuf.FloatValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.FloatValue;
-  return proto.google.protobuf.FloatValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.FloatValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.FloatValue}
- */
-proto.google.protobuf.FloatValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readFloat());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.FloatValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.FloatValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.FloatValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.FloatValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0.0) {
-    writer.writeFloat(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional float value = 1;
- * @return {number}
- */
-proto.google.protobuf.FloatValue.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 1, 0.0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.FloatValue} returns this
- */
-proto.google.protobuf.FloatValue.prototype.setValue = function(value) {
-  return jspb.Message.setProto3FloatField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Int64Value.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Int64Value.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Int64Value} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Int64Value.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Int64Value}
- */
-proto.google.protobuf.Int64Value.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Int64Value;
-  return proto.google.protobuf.Int64Value.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Int64Value} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Int64Value}
- */
-proto.google.protobuf.Int64Value.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt64());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Int64Value.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Int64Value.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Int64Value} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Int64Value.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0) {
-    writer.writeInt64(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int64 value = 1;
- * @return {number}
- */
-proto.google.protobuf.Int64Value.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Int64Value} returns this
- */
-proto.google.protobuf.Int64Value.prototype.setValue = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.UInt64Value.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.UInt64Value.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.UInt64Value} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UInt64Value.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.UInt64Value}
- */
-proto.google.protobuf.UInt64Value.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.UInt64Value;
-  return proto.google.protobuf.UInt64Value.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.UInt64Value} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.UInt64Value}
- */
-proto.google.protobuf.UInt64Value.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.UInt64Value.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.UInt64Value.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.UInt64Value} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UInt64Value.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0) {
-    writer.writeUint64(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional uint64 value = 1;
- * @return {number}
- */
-proto.google.protobuf.UInt64Value.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.UInt64Value} returns this
- */
-proto.google.protobuf.UInt64Value.prototype.setValue = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.Int32Value.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.Int32Value.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.Int32Value} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Int32Value.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.Int32Value}
- */
-proto.google.protobuf.Int32Value.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.Int32Value;
-  return proto.google.protobuf.Int32Value.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.Int32Value} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.Int32Value}
- */
-proto.google.protobuf.Int32Value.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readInt32());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.Int32Value.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.Int32Value.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.Int32Value} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.Int32Value.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0) {
-    writer.writeInt32(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional int32 value = 1;
- * @return {number}
- */
-proto.google.protobuf.Int32Value.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.Int32Value} returns this
- */
-proto.google.protobuf.Int32Value.prototype.setValue = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.UInt32Value.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.UInt32Value.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.UInt32Value} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UInt32Value.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.UInt32Value}
- */
-proto.google.protobuf.UInt32Value.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.UInt32Value;
-  return proto.google.protobuf.UInt32Value.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.UInt32Value} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.UInt32Value}
- */
-proto.google.protobuf.UInt32Value.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.UInt32Value.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.UInt32Value.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.UInt32Value} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.UInt32Value.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f !== 0) {
-    writer.writeUint32(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional uint32 value = 1;
- * @return {number}
- */
-proto.google.protobuf.UInt32Value.prototype.getValue = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.google.protobuf.UInt32Value} returns this
- */
-proto.google.protobuf.UInt32Value.prototype.setValue = function(value) {
-  return jspb.Message.setProto3IntField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.BoolValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.BoolValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.BoolValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.BoolValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.BoolValue}
- */
-proto.google.protobuf.BoolValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.BoolValue;
-  return proto.google.protobuf.BoolValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.BoolValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.BoolValue}
- */
-proto.google.protobuf.BoolValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.BoolValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.BoolValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.BoolValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.BoolValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f) {
-    writer.writeBool(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional bool value = 1;
- * @return {boolean}
- */
-proto.google.protobuf.BoolValue.prototype.getValue = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.google.protobuf.BoolValue} returns this
- */
-proto.google.protobuf.BoolValue.prototype.setValue = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.StringValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.StringValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.StringValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.StringValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: jspb.Message.getFieldWithDefault(msg, 1, "")
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.StringValue}
- */
-proto.google.protobuf.StringValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.StringValue;
-  return proto.google.protobuf.StringValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.StringValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.StringValue}
- */
-proto.google.protobuf.StringValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.StringValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.StringValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.StringValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.StringValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string value = 1;
- * @return {string}
- */
-proto.google.protobuf.StringValue.prototype.getValue = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.google.protobuf.StringValue} returns this
- */
-proto.google.protobuf.StringValue.prototype.setValue = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.google.protobuf.BytesValue.prototype.toObject = function(opt_includeInstance) {
-  return proto.google.protobuf.BytesValue.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.google.protobuf.BytesValue} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.BytesValue.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    value: msg.getValue_asB64()
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.google.protobuf.BytesValue}
- */
-proto.google.protobuf.BytesValue.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.google.protobuf.BytesValue;
-  return proto.google.protobuf.BytesValue.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.google.protobuf.BytesValue} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.google.protobuf.BytesValue}
- */
-proto.google.protobuf.BytesValue.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {!Uint8Array} */ (reader.readBytes());
-      msg.setValue(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.google.protobuf.BytesValue.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.google.protobuf.BytesValue.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.google.protobuf.BytesValue} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.google.protobuf.BytesValue.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getValue_asU8();
-  if (f.length > 0) {
-    writer.writeBytes(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional bytes value = 1;
- * @return {!(string|Uint8Array)}
- */
-proto.google.protobuf.BytesValue.prototype.getValue = function() {
-  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * optional bytes value = 1;
- * This is a type-conversion wrapper around `getValue()`
- * @return {string}
- */
-proto.google.protobuf.BytesValue.prototype.getValue_asB64 = function() {
-  return /** @type {string} */ (jspb.Message.bytesAsB64(
-      this.getValue()));
-};
-
-
-/**
- * optional bytes value = 1;
- * Note that Uint8Array is not supported on all browsers.
- * @see http://caniuse.com/Uint8Array
- * This is a type-conversion wrapper around `getValue()`
- * @return {!Uint8Array}
- */
-proto.google.protobuf.BytesValue.prototype.getValue_asU8 = function() {
-  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
-      this.getValue()));
-};
-
-
-/**
- * @param {!(string|Uint8Array)} value
- * @return {!proto.google.protobuf.BytesValue} returns this
- */
-proto.google.protobuf.BytesValue.prototype.setValue = function(value) {
-  return jspb.Message.setProto3BytesField(this, 1, value);
-};
-
-
-goog.object.extend(exports, proto);
