diff --git a/package-lock.json b/package-lock.json
index 923ba0b9806..59f1a5cb0b7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4123,8 +4123,9 @@
     },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
       "dev": true,
-      "license": "ISC",
       "dependencies": {
         "string-width": "^5.1.2",
         "string-width-cjs": "npm:string-width@^4.2.0",
@@ -4138,9 +4139,10 @@
       }
     },
     "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
-      "version": "6.0.1",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+      "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=12"
       },
@@ -4150,8 +4152,9 @@
     },
     "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
       "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-regex": "^6.0.1"
       },
@@ -4772,8 +4775,9 @@
     },
     "node_modules/@pkgjs/parseargs": {
       "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "engines": {
         "node": ">=14"
@@ -7360,42 +7364,6 @@
         "undici-types": "~5.26.4"
       }
     },
-    "node_modules/@storybook/core-common/node_modules/foreground-child": {
-      "version": "3.1.1",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/@storybook/core-common/node_modules/glob": {
-      "version": "10.3.10",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^2.3.5",
-        "minimatch": "^9.0.1",
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
-        "path-scurry": "^1.10.1"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/@storybook/core-common/node_modules/resolve-from": {
       "version": "5.0.0",
       "dev": true,
@@ -7404,17 +7372,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/@storybook/core-common/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/@storybook/core-events": {
       "version": "7.6.17",
       "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz",
@@ -16535,6 +16492,34 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/foreground-child": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+      "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/foreground-child/node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/fork-ts-checker-webpack-plugin": {
       "version": "6.5.3",
       "dev": true,
@@ -17022,6 +17007,26 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/glob-parent": {
       "version": "6.0.2",
       "dev": true,
@@ -17038,6 +17043,15 @@
       "dev": true,
       "license": "BSD-2-Clause"
     },
+    "node_modules/glob/node_modules/minipass": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
     "node_modules/global-dirs": {
       "version": "3.0.1",
       "dev": true,
@@ -19039,15 +19053,13 @@
       }
     },
     "node_modules/jackspeak": {
-      "version": "2.3.6",
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
       "dev": true,
-      "license": "BlueOak-1.0.0",
       "dependencies": {
         "@isaacs/cliui": "^8.0.2"
       },
-      "engines": {
-        "node": ">=14"
-      },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
       },
@@ -24484,9 +24496,9 @@
       }
     },
     "node_modules/package-json-from-dist": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
-      "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
       "dev": true
     },
     "node_modules/pad": {
@@ -28847,8 +28859,9 @@
     "node_modules/string-width-cjs": {
       "name": "string-width",
       "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -28860,8 +28873,9 @@
     },
     "node_modules/string-width-cjs/node_modules/emoji-regex": {
       "version": "8.0.0",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
     },
     "node_modules/string-width/node_modules/ansi-regex": {
       "version": "6.0.1",
@@ -28970,8 +28984,9 @@
     "node_modules/strip-ansi-cjs": {
       "name": "strip-ansi",
       "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -29166,53 +29181,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/sucrase/node_modules/foreground-child": {
-      "version": "3.1.1",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/sucrase/node_modules/glob": {
-      "version": "10.3.10",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^2.3.5",
-        "minimatch": "^9.0.1",
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
-        "path-scurry": "^1.10.1"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/sucrase/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/superagent": {
       "version": "7.1.5",
       "dev": true,
@@ -31193,6 +31161,46 @@
       "dev": true,
       "license": "Apache-2.0"
     },
+    "node_modules/ts-json-schema-generator": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-2.3.0.tgz",
+      "integrity": "sha512-t4lBQAwZc0sOJq9LJt3NgbznIcslVnm0JeEMFq8qIRklpMRY8jlYD0YmnRWbqBKANxkby91P1XanSSlSOFpUmg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.15",
+        "commander": "^12.0.0",
+        "glob": "^10.3.12",
+        "json5": "^2.2.3",
+        "normalize-path": "^3.0.0",
+        "safe-stable-stringify": "^2.4.3",
+        "tslib": "^2.6.2",
+        "typescript": "^5.4.5"
+      },
+      "bin": {
+        "ts-json-schema-generator": "bin/ts-json-schema-generator.js"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/ts-json-schema-generator/node_modules/commander": {
+      "version": "12.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+      "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+      "dev": true,
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/ts-json-schema-generator/node_modules/safe-stable-stringify": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+      "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/ts-toolbelt": {
       "version": "9.6.0",
       "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
@@ -34172,8 +34180,9 @@
     "node_modules/wrap-ansi-cjs": {
       "name": "wrap-ansi",
       "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
@@ -34188,13 +34197,15 @@
     },
     "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
       "version": "8.0.0",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
     },
     "node_modules/wrap-ansi-cjs/node_modules/string-width": {
       "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -35488,15 +35499,6 @@
         "node": ">= 16"
       }
     },
-    "web-common/node_modules/commander": {
-      "version": "12.1.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
-      "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
-      "dev": true,
-      "engines": {
-        "node": ">=18"
-      }
-    },
     "web-common/node_modules/deep-eql": {
       "version": "5.0.2",
       "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
@@ -35512,22 +35514,6 @@
       "dev": true,
       "license": "(MPL-2.0 OR Apache-2.0)"
     },
-    "web-common/node_modules/foreground-child": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
-      "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "web-common/node_modules/fs-extra": {
       "version": "10.1.0",
       "dev": true,
@@ -35541,41 +35527,6 @@
         "node": ">=12"
       }
     },
-    "web-common/node_modules/glob": {
-      "version": "10.4.5",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
-      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
-      "dev": true,
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^3.1.2",
-        "minimatch": "^9.0.4",
-        "minipass": "^7.1.2",
-        "package-json-from-dist": "^1.0.0",
-        "path-scurry": "^1.11.1"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "web-common/node_modules/jackspeak": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
-      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
-      "dev": true,
-      "dependencies": {
-        "@isaacs/cliui": "^8.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      },
-      "optionalDependencies": {
-        "@pkgjs/parseargs": "^0.11.0"
-      }
-    },
     "web-common/node_modules/json-schema-traverse": {
       "version": "1.0.0",
       "dev": true,
@@ -35609,15 +35560,6 @@
         "node": ">= 18"
       }
     },
-    "web-common/node_modules/minipass": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
-      "dev": true,
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
     "web-common/node_modules/orval": {
       "version": "6.12.0",
       "dev": true,
@@ -35657,27 +35599,6 @@
         "node": ">= 14.16"
       }
     },
-    "web-common/node_modules/safe-stable-stringify": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
-      "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "web-common/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "web-common/node_modules/svelte-preprocess": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-6.0.3.tgz",
@@ -35768,28 +35689,6 @@
         "node": ">=14.0.0"
       }
     },
-    "web-common/node_modules/ts-json-schema-generator": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-2.3.0.tgz",
-      "integrity": "sha512-t4lBQAwZc0sOJq9LJt3NgbznIcslVnm0JeEMFq8qIRklpMRY8jlYD0YmnRWbqBKANxkby91P1XanSSlSOFpUmg==",
-      "dev": true,
-      "dependencies": {
-        "@types/json-schema": "^7.0.15",
-        "commander": "^12.0.0",
-        "glob": "^10.3.12",
-        "json5": "^2.2.3",
-        "normalize-path": "^3.0.0",
-        "safe-stable-stringify": "^2.4.3",
-        "tslib": "^2.6.2",
-        "typescript": "^5.4.5"
-      },
-      "bin": {
-        "ts-json-schema-generator": "bin/ts-json-schema-generator.js"
-      },
-      "engines": {
-        "node": ">=18.0.0"
-      }
-    },
     "web-common/node_modules/vega-expression": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-5.1.1.tgz",
diff --git a/proto/gen/rill/runtime/v1/queries.pb.go b/proto/gen/rill/runtime/v1/queries.pb.go
index d8961601eeb..f42f790fe95 100644
--- a/proto/gen/rill/runtime/v1/queries.pb.go
+++ b/proto/gen/rill/runtime/v1/queries.pb.go
@@ -4348,7 +4348,7 @@ type ResolveComponentRequest struct {
 	InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`
 	// Component name
 	Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
-	// Optional args to pass to the data resolver and for resolving templating in the renderer properties
+	// Optional args for resolving templating in the renderer properties
 	Args *structpb.Struct `protobuf:"bytes,3,opt,name=args,proto3" json:"args,omitempty"`
 }
 
@@ -4413,12 +4413,8 @@ type ResolveComponentResponse struct {
 	// Show property with templating resolved for the provided args.
 	// If it resolves to false, the other fields are not set.
 	Show bool `protobuf:"varint,1,opt,name=show,proto3" json:"show,omitempty"`
-	// Schema of the resolved component data
-	Schema *StructType `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"`
-	// Resolved component data
-	Data []*structpb.Struct `protobuf:"bytes,3,rep,name=data,proto3" json:"data,omitempty"`
 	// Renderer properties with templating resolved for the provided args
-	RendererProperties *structpb.Struct `protobuf:"bytes,4,opt,name=renderer_properties,json=rendererProperties,proto3" json:"renderer_properties,omitempty"`
+	RendererProperties *structpb.Struct `protobuf:"bytes,2,opt,name=renderer_properties,json=rendererProperties,proto3" json:"renderer_properties,omitempty"`
 }
 
 func (x *ResolveComponentResponse) Reset() {
@@ -4460,20 +4456,6 @@ func (x *ResolveComponentResponse) GetShow() bool {
 	return false
 }
 
-func (x *ResolveComponentResponse) GetSchema() *StructType {
-	if x != nil {
-		return x.Schema
-	}
-	return nil
-}
-
-func (x *ResolveComponentResponse) GetData() []*structpb.Struct {
-	if x != nil {
-		return x.Data
-	}
-	return nil
-}
-
 func (x *ResolveComponentResponse) GetRendererProperties() *structpb.Struct {
 	if x != nil {
 		return x.RendererProperties
@@ -8599,22 +8581,183 @@ var file_rill_runtime_v1_queries_proto_rawDesc = []byte{
 	0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73,
 	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52,
-	0x04, 0x61, 0x72, 0x67, 0x73, 0x22, 0xda, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76,
-	0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54,
-	0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2b, 0x0a, 0x04, 0x64,
-	0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75,
-	0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x6e, 0x64,
-	0x65, 0x72, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12,
-	0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
-	0x65, 0x73, 0x22, 0x8f, 0x02, 0x0a, 0x1b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c,
-	0x6c, 0x75, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x04, 0x61, 0x72, 0x67, 0x73, 0x22, 0x78, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65,
+	0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65,
+	0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x6e,
+	0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22,
+	0x8f, 0x02, 0x0a, 0x1b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75, 0x70,
+	0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
+	0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a,
+	0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61,
+	0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68,
+	0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01,
+	0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d,
+	0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
+	0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
+	0x79, 0x22, 0xb6, 0x01, 0x0a, 0x1c, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c,
+	0x75, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73,
+	0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65,
+	0x6e, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e,
+	0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa5, 0x02, 0x0a, 0x11, 0x43,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70, 0x4b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x07,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12,
+	0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64,
+	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x09,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63,
+	0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10,
+	0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b,
+	0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x67, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x67, 0x67, 0x12, 0x0c, 0x0a, 0x01, 0x6b, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x01, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
+	0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
+	0x74, 0x79, 0x22, 0x6a, 0x0a, 0x12, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70, 0x4b,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x63, 0x61, 0x74, 0x65,
+	0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
+	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69,
+	0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x12, 0x63, 0x61, 0x74, 0x65,
+	0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x6e,
+	0x0a, 0x12, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d,
+	0x6d, 0x61, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x5f, 0x6b, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x4b, 0x48, 0x00, 0x52, 0x04, 0x74, 0x6f,
+	0x70, 0x4b, 0x12, 0x22, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74,
+	0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69,
+	0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x61, 0x73, 0x65, 0x22, 0x8a,
+	0x01, 0x0a, 0x04, 0x54, 0x6f, 0x70, 0x4b, 0x12, 0x35, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x4b, 0x2e,
+	0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x4b,
+	0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x16,
+	0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73,
+	0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
+	0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e,
+	0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+	0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+	0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63,
+	0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61,
+	0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61,
+	0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
+	0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61,
+	0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01,
+	0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+	0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
+	0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x2f, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x96, 0x02, 0x0a, 0x22, 0x43, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53,
+	0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12,
+	0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64,
+	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63,
+	0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10,
+	0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b,
+	0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
+	0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
+	0x74, 0x79, 0x22, 0x6f, 0x0a, 0x23, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63,
+	0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0f, 0x6e, 0x75, 0x6d,
+	0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d,
+	0x61, 0x72, 0x79, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d,
+	0x61, 0x72, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x0e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53,
+	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x5d, 0x0a, 0x16, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69,
+	0x63, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x62, 0x69, 0x6e, 0x73,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73, 0x48, 0x00, 0x52,
+	0x14, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,
+	0x6d, 0x42, 0x69, 0x6e, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x69,
+	0x73, 0x74, 0x69, 0x63, 0x73, 0x48, 0x00, 0x52, 0x11, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4d, 0x0a, 0x10, 0x6e, 0x75,
+	0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x4f, 0x75,
+	0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69,
+	0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x61, 0x73,
+	0x65, 0x22, 0xcc, 0x01, 0x0a, 0x14, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73,
+	0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x04, 0x62, 0x69,
+	0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72,
+	0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73, 0x2e,
+	0x42, 0x69, 0x6e, 0x52, 0x04, 0x62, 0x69, 0x6e, 0x73, 0x1a, 0x75, 0x0a, 0x03, 0x42, 0x69, 0x6e,
+	0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69,
+	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x6d, 0x69,
+	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f,
+	0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+	0x22, 0x91, 0x01, 0x0a, 0x11, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74,
+	0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65,
+	0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6d, 0x65, 0x61, 0x6e, 0x12, 0x10,
+	0x0a, 0x03, 0x71, 0x32, 0x35, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x71, 0x32, 0x35,
+	0x12, 0x10, 0x0a, 0x03, 0x71, 0x35, 0x30, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x71,
+	0x35, 0x30, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x37, 0x35, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52,
+	0x03, 0x71, 0x37, 0x35, 0x12, 0x0e, 0x0a, 0x02, 0x73, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01,
+	0x52, 0x02, 0x73, 0x64, 0x22, 0xd0, 0x01, 0x0a, 0x0f, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x6c,
+	0x69, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d,
+	0x65, 0x72, 0x69, 0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x2e, 0x4f, 0x75, 0x74,
+	0x6c, 0x69, 0x65, 0x72, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x1a, 0x77,
+	0x0a, 0x07, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63,
+	0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65,
+	0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03,
+	0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x01, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65,
+	0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e,
+	0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
 	0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
 	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
 	0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72,
@@ -8630,158 +8773,42 @@ var file_rill_runtime_v1_queries_proto_rawDesc = []byte{
 	0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f,
 	0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f,
 	0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f,
-	0x72, 0x69, 0x74, 0x79, 0x22, 0xb6, 0x01, 0x0a, 0x1c, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52,
-	0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
-	0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72,
-	0x61, 0x69, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa5, 0x02,
-	0x0a, 0x11, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70, 0x4b, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
-	0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27,
-	0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d,
-	0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
-	0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
-	0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x67,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x67, 0x67, 0x12, 0x0c, 0x0a, 0x01, 0x6b,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69,
-	0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69,
-	0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x6a, 0x0a, 0x12, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54,
-	0x6f, 0x70, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x63,
-	0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61,
-	0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67,
-	0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x12, 0x63,
-	0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72,
-	0x79, 0x22, 0x6e, 0x0a, 0x12, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c,
-	0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x5f, 0x6b,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x4b, 0x48, 0x00, 0x52,
-	0x04, 0x74, 0x6f, 0x70, 0x4b, 0x12, 0x22, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61,
-	0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x61,
-	0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x61, 0x73,
-	0x65, 0x22, 0x8a, 0x01, 0x0a, 0x04, 0x54, 0x6f, 0x70, 0x4b, 0x12, 0x35, 0x0a, 0x07, 0x65, 0x6e,
-	0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69,
-	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f,
-	0x70, 0x4b, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65,
-	0x73, 0x1a, 0x4b, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75,
-	0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e,
-	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8a,
-	0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75,
-	0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f,
-	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63,
-	0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61,
-	0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61,
-	0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
-	0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64,
-	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a,
-	0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c,
-	0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72,
-	0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x2f, 0x0a, 0x17, 0x43,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x96, 0x02, 0x0a,
-	0x22, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
-	0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
-	0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27,
-	0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d,
-	0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
-	0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
-	0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69,
-	0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69,
-	0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x6f, 0x0a, 0x23, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
-	0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0f,
-	0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53,
-	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53,
-	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x0e, 0x4e, 0x75, 0x6d, 0x65, 0x72,
-	0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x5d, 0x0a, 0x16, 0x6e, 0x75, 0x6d,
-	0x65, 0x72, 0x69, 0x63, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x62,
-	0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
-	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73,
-	0x48, 0x00, 0x52, 0x14, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f,
-	0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x6e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x74,
-	0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x48, 0x00, 0x52, 0x11, 0x6e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4d, 0x0a,
-	0x10, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72,
-	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69,
-	0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x6e, 0x75, 0x6d,
-	0x65, 0x72, 0x69, 0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x42, 0x06, 0x0a, 0x04,
-	0x63, 0x61, 0x73, 0x65, 0x22, 0xcc, 0x01, 0x0a, 0x14, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
-	0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69, 0x6e, 0x73, 0x12, 0x3d, 0x0a,
-	0x04, 0x62, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69,
-	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75,
-	0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x42, 0x69,
-	0x6e, 0x73, 0x2e, 0x42, 0x69, 0x6e, 0x52, 0x04, 0x62, 0x69, 0x6e, 0x73, 0x1a, 0x75, 0x0a, 0x03,
-	0x42, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c,
-	0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a,
-	0x08, 0x6d, 0x69, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
-	0x08, 0x6d, 0x69, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67,
-	0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x14, 0x0a,
-	0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f,
-	0x75, 0x6e, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x11, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53,
-	0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d,
-	0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x12, 0x0a,
-	0x04, 0x6d, 0x65, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6d, 0x65, 0x61,
-	0x6e, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x32, 0x35, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03,
-	0x71, 0x32, 0x35, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x35, 0x30, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01,
-	0x52, 0x03, 0x71, 0x35, 0x30, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x37, 0x35, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x01, 0x52, 0x03, 0x71, 0x37, 0x35, 0x12, 0x0e, 0x0a, 0x02, 0x73, 0x64, 0x18, 0x07, 0x20,
-	0x01, 0x28, 0x01, 0x52, 0x02, 0x73, 0x64, 0x22, 0xd0, 0x01, 0x0a, 0x0f, 0x4e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x08, 0x6f,
-	0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x73, 0x2e,
-	0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72,
-	0x73, 0x1a, 0x77, 0x0a, 0x07, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06,
-	0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x75,
-	0x63, 0x6b, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x01, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72,
-	0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65,
-	0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x16, 0x43,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65,
+	0x72, 0x69, 0x74, 0x79, 0x22, 0x54, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69,
+	0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52,
+	0x09, 0x74, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x22, 0xde, 0x02, 0x0a, 0x1d, 0x43,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74,
+	0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b,
+	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a,
+	0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64,
+	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64,
+	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62,
+	0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61,
+	0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74,
+	0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa,
+	0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61,
+	0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x10, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f,
+	0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x72,
+	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48,
+	0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0f,
+	0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12,
+	0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x6a, 0x0a, 0x1e, 0x43,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74,
+	0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a,
+	0x0f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x8d, 0x02, 0x0a, 0x19, 0x43, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
 	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74,
 	0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
@@ -8797,661 +8824,610 @@ var file_rill_runtime_v1_queries_proto_rawDesc = []byte{
 	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52,
 	0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70,
 	0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70,
-	0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x54, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x69, 0x6e,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61,
-	0x69, 0x6e, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x22, 0xde, 0x02,
-	0x0a, 0x1d, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48,
-	0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x66, 0x0a, 0x1a, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
+	0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
+	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
+	0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52,
+	0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22,
+	0x8a, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61,
+	0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63,
+	0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+	0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74,
+	0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74,
+	0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+	0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
+	0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26,
+	0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62,
+	0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
+	0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65,
+	0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x6a, 0x0a, 0x17,
+	0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x5f,
+	0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x53,
+	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x10, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67,
+	0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x86, 0x02, 0x0a, 0x10, 0x54, 0x69, 0x6d,
+	0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2c, 0x0a,
+	0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x03, 0x6d,
+	0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x46, 0x0a, 0x08, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69,
+	0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x49,
+	0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+	0x6c, 0x1a, 0x4e, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x16, 0x0a,
+	0x06, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d,
+	0x6f, 0x6e, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x63,
+	0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f,
+	0x73, 0x22, 0x8c, 0x02, 0x0a, 0x18, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64,
+	0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f,
+	0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12,
+	0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a,
+	0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74,
+	0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65,
+	0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52,
+	0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42,
+	0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
+	0x22, 0x71, 0x0a, 0x19, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e,
+	0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a,
+	0x13, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x6d,
+	0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74,
+	0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52,
+	0x12, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d,
+	0x61, 0x72, 0x79, 0x22, 0x8c, 0x05, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69,
+	0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 	0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
-	0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20,
+	0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x0b, 0x20,
 	0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a,
-	0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+	0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09,
 	0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61,
-	0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x08, 0x20,
+	0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x0d, 0x20,
 	0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68,
 	0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
 	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01,
-	0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x10, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72,
-	0x61, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4d, 0x65, 0x74, 0x68, 0x6f,
-	0x64, 0x52, 0x0f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4d, 0x65, 0x74, 0x68,
-	0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x6a,
-	0x0a, 0x1e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48,
-	0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x48, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d,
-	0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
-	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x8d, 0x02, 0x0a, 0x19, 0x43,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,
-	0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74,
-	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e,
-	0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f,
-	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62,
-	0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62,
-	0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f,
-	0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61,
-	0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a,
-	0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65,
-	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02,
-	0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a,
-	0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
-	0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x66, 0x0a, 0x1a, 0x43, 0x6f,
-	0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61,
-	0x72, 0x79, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61,
-	0x72, 0x79, 0x22, 0x8a, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d,
-	0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a,
-	0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c,
-	0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08,
-	0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
-	0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61,
-	0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d,
-	0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09,
-	0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x63, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
-	0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e,
-	0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22,
-	0x6a, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e,
-	0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x12, 0x74, 0x69,
-	0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e,
-	0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x10, 0x74, 0x69, 0x6d, 0x65, 0x52,
-	0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x86, 0x02, 0x0a, 0x10,
-	0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,
-	0x12, 0x2c, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x2c,
-	0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
-	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x46, 0x0a, 0x08,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a,
+	0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5b, 0x0a, 0x08, 0x6d,
+	0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e,
+	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
+	0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x61,
+	0x73, 0x75, 0x72, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x08,
+	0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x15, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01,
+	0x52, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
+	0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61,
+	0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
+	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65,
+	0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52,
+	0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x70, 0x69,
+	0x78, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a,
+	0x02, 0x28, 0x00, 0x52, 0x06, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x0b, 0x73,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
+	0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
+	0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
+	0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x1a, 0x62,
+	0x0a, 0x0c, 0x42, 0x61, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x12, 0x0e,
+	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27,
+	0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x65, 0x78, 0x70,
+	0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x71, 0x6c, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x71, 0x6c, 0x4e, 0x61,
+	0x6d, 0x65, 0x22, 0x57, 0x0a, 0x18, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65,
+	0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b,
+	0x0a, 0x06, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
 	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72,
-	0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x76, 0x61, 0x6c, 0x1a, 0x4e, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
-	0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
-	0x52, 0x06, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x06,
-	0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x69,
-	0x63, 0x72, 0x6f, 0x73, 0x22, 0x8c, 0x02, 0x0a, 0x18, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43,
-	0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-	0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72,
-	0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f,
-	0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53,
-	0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02,
-	0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a,
-	0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72,
-	0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72,
-	0x69, 0x74, 0x79, 0x22, 0x71, 0x0a, 0x19, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72,
-	0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x54, 0x0a, 0x13, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f,
-	0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
+	0x2e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x22, 0xb7, 0x01, 0x0a, 0x13,
+	0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61,
+	0x6e, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05,
+	0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03,
+	0x65, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
+	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69,
+	0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa9, 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x07,
+	0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e,
 	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61,
-	0x72, 0x79, 0x52, 0x12, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53,
-	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x8c, 0x05, 0x0a, 0x17, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+	0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x72,
+	0x6b, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x70, 0x61, 0x72, 0x6b,
+	0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x7a,
+	0x65, 0x22, 0x82, 0x01, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x74,
+	0x73, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03,
+	0x62, 0x69, 0x6e, 0x12, 0x31, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72,
+	0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, 0xe1, 0x01, 0x0a, 0x17, 0x54, 0x61, 0x62, 0x6c, 0x65,
+	0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
 	0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
 	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
 	0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72,
-	0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x0c, 0x20,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
+	0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20,
 	0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a,
 	0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
-	0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
 	0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f,
 	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72,
-	0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5b,
-	0x0a, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x35, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72,
-	0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63,
-	0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08,
-	0x01, 0x52, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x15, 0x74,
-	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72,
-	0x02, 0x10, 0x01, 0x52, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x43, 0x6f,
-	0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65,
-	0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72,
-	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54,
-	0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e,
-	0x67, 0x65, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1f, 0x0a,
-	0x06, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xfa,
-	0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x06, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x12, 0x28,
-	0x0a, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20,
-	0x01, 0x28, 0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x0a, 0x73, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f,
-	0x72, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f,
-	0x72, 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e,
-	0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e,
-	0x65, 0x1a, 0x62, 0x0a, 0x0c, 0x42, 0x61, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72,
-	0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
-	0x64, 0x12, 0x27, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a,
-	0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x71,
-	0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x71,
-	0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x57, 0x0a, 0x18, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54,
-	0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x3b, 0x0a, 0x06, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x22, 0xb7,
-	0x01, 0x0a, 0x13, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x54, 0x69, 0x6d,
-	0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
-	0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x47,
-	0x72, 0x61, 0x69, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa9, 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d,
-	0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x3a, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x56, 0x61, 0x6c,
-	0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x73,
-	0x70, 0x61, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d,
-	0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x70,
-	0x61, 0x72, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x69,
-	0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-	0x53, 0x69, 0x7a, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72,
-	0x69, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x52, 0x02, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x01, 0x52, 0x03, 0x62, 0x69, 0x6e, 0x12, 0x31, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64,
-	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
-	0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, 0xe1, 0x01, 0x0a, 0x17, 0x54, 0x61,
+	0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a,
+	0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x3c, 0x0a, 0x18, 0x54, 0x61,
 	0x62, 0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74,
-	0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
-	0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
-	0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
-	0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68,
-	0x65, 0x6d, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62,
-	0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62,
-	0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa,
-	0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d,
-	0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x3c, 0x0a,
-	0x18, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74,
-	0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x61, 0x72,
-	0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b,
-	0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xdd, 0x01, 0x0a, 0x13,
-	0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e,
+	0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x61, 0x72,
+	0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xdd, 0x01, 0x0a, 0x13, 0x54, 0x61, 0x62,
+	0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12,
+	0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64,
+	0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63,
+	0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10,
+	0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+	0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
+	0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x14, 0x54, 0x61, 0x62,
+	0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x47, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6c,
+	0x75, 0x6d, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f,
+	0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x66,
+	0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x6e, 0x0a, 0x13, 0x75, 0x6e,
+	0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55,
+	0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
+	0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x1a, 0x45, 0x0a, 0x17, 0x55, 0x6e,
+	0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73,
+	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+	0x01, 0x22, 0x6b, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75,
+	0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61,
+	0x72, 0x67, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x65, 0x6e,
+	0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x6c, 0x61, 0x72, 0x67, 0x65,
+	0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0xf9,
+	0x01, 0x0a, 0x10, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
 	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
 	0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
-	0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05,
+	0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+	0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x06,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27,
 	0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d,
-	0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+	0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
 	0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65,
 	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
 	0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x14,
-	0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
-	0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x0e, 0x70,
-	0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x6e, 0x0a,
-	0x13, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62,
-	0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x75, 0x6e, 0x73, 0x75, 0x70,
-	0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x1a, 0x45, 0x0a,
-	0x17, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x75,
-	0x6d, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43,
-	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x32, 0x0a,
-	0x15, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f,
-	0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x6c, 0x61,
-	0x72, 0x67, 0x65, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x6e, 0x67, 0x74,
-	0x68, 0x22, 0xf9, 0x01, 0x0a, 0x10, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
-	0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e,
-	0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
-	0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
-	0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63,
-	0x68, 0x65, 0x6d, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61,
-	0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x61,
-	0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
-	0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61,
-	0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69,
-	0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x40, 0x0a,
-	0x11, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a,
-	0x70, 0x0a, 0x0e, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72,
-	0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x41,
-	0x53, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
-	0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45,
-	0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x22, 0x0a,
-	0x1e, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45,
-	0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x49, 0x4e, 0x43, 0x54, 0x10,
-	0x02, 0x2a, 0x9e, 0x02, 0x0a, 0x1d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65,
-	0x77, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x53, 0x6f, 0x72, 0x74, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x2d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56,
-	0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53,
-	0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
-	0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x30, 0x0a, 0x2c, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43,
-	0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f,
-	0x4e, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x41, 0x53, 0x45,
-	0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x36, 0x0a, 0x32, 0x4d, 0x45, 0x54, 0x52,
-	0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49,
-	0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f,
-	0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02,
-	0x12, 0x2f, 0x0a, 0x2b, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57,
+	0x1d, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07,
+	0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a,
+	0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x40, 0x0a, 0x11, 0x54, 0x61,
+	0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x70, 0x0a, 0x0e,
+	0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x12, 0x1f,
+	0x0a, 0x1b, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52,
+	0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+	0x19, 0x0a, 0x15, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55,
+	0x52, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x55,
+	0x49, 0x4c, 0x54, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x4f,
+	0x55, 0x4e, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x49, 0x4e, 0x43, 0x54, 0x10, 0x02, 0x2a, 0x9e,
+	0x02, 0x0a, 0x1d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43, 0x6f,
+	0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65,
+	0x12, 0x31, 0x0a, 0x2d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57,
 	0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x52, 0x54,
-	0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10,
-	0x03, 0x12, 0x2f, 0x0a, 0x2b, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45,
-	0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x52,
-	0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41,
-	0x10, 0x04, 0x2a, 0xb0, 0x02, 0x0a, 0x20, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69,
-	0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x61, 0x73,
-	0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x30, 0x4d, 0x45, 0x54, 0x52, 0x49,
-	0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53,
-	0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
-	0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x33, 0x0a,
-	0x2f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f,
-	0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45,
-	0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45,
-	0x10, 0x01, 0x12, 0x39, 0x0a, 0x35, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49,
-	0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45,
-	0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
-	0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x32, 0x0a,
-	0x2e, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f,
-	0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45,
-	0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10,
-	0x03, 0x12, 0x32, 0x0a, 0x2e, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45,
-	0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41,
-	0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x4c, 0x5f, 0x44, 0x45,
-	0x4c, 0x54, 0x41, 0x10, 0x04, 0x2a, 0x6d, 0x0a, 0x0f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72,
-	0x61, 0x6d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x20, 0x0a, 0x1c, 0x48, 0x49, 0x53, 0x54,
-	0x4f, 0x47, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53,
-	0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x49,
-	0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x46,
-	0x44, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d,
-	0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, 0x49, 0x41, 0x47, 0x4e, 0x4f, 0x53, 0x54,
-	0x49, 0x43, 0x10, 0x02, 0x32, 0xab, 0x27, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1d,
-	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82,
-	0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x8b, 0x01, 0x0a, 0x0a,
-	0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c,
+	0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+	0x44, 0x10, 0x00, 0x12, 0x30, 0x0a, 0x2c, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56,
+	0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53,
+	0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x56, 0x41,
+	0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x36, 0x0a, 0x32, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53,
+	0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e,
+	0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
+	0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x2f, 0x0a,
+	0x2b, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f,
+	0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59,
+	0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10, 0x03, 0x12, 0x2f,
+	0x0a, 0x2b, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43,
+	0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54,
+	0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10, 0x04, 0x2a,
+	0xb0, 0x02, 0x0a, 0x20, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43,
+	0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
+	0x54, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x30, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f,
+	0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f,
+	0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53,
+	0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x33, 0x0a, 0x2f, 0x4d, 0x45,
+	0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
+	0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59,
+	0x50, 0x45, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12,
+	0x39, 0x0a, 0x35, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f,
+	0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55,
+	0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53,
+	0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x32, 0x0a, 0x2e, 0x4d, 0x45,
+	0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
+	0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x59,
+	0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10, 0x03, 0x12, 0x32,
+	0x0a, 0x2e, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43,
+	0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52,
+	0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41,
+	0x10, 0x04, 0x2a, 0x6d, 0x0a, 0x0f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4d,
+	0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x20, 0x0a, 0x1c, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52,
+	0x41, 0x4d, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x49, 0x53, 0x54, 0x4f,
+	0x47, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x46, 0x44, 0x10, 0x01,
+	0x12, 0x1f, 0x0a, 0x1b, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x45,
+	0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, 0x49, 0x41, 0x47, 0x4e, 0x4f, 0x53, 0x54, 0x49, 0x43, 0x10,
+	0x02, 0x32, 0xab, 0x27, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x12, 0x74, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1d, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75,
+	0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x69, 0x6c,
 	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65,
-	0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23,
-	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27,
-	0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72,
-	0x79, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x06, 0x45, 0x78,
-	0x70, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a,
-	0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f,
-	0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75,
-	0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x9b, 0x01, 0x0a,
-	0x0c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f,
-	0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93,
-	0x02, 0x38, 0x3a, 0x01, 0x2a, 0x22, 0x33, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
+	0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
 	0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
-	0x64, 0x7d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x70, 0x6f,
-	0x72, 0x74, 0x7d, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0xd2, 0x01, 0x0a, 0x16, 0x4d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56,
-	0x69, 0x65, 0x77, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56,
-	0x69, 0x65, 0x77, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01,
-	0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73,
-	0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71,
-	0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76,
-	0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69,
-	0x65, 0x77, 0x7d, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
-	0xc7, 0x01, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54,
-	0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+	0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x8b, 0x01, 0x0a, 0x0a, 0x51, 0x75, 0x65,
+	0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42,
+	0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75,
+	0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31,
+	0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x62,
+	0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72,
+	0x74, 0x12, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f,
+	0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69,
+	0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x9b, 0x01, 0x0a, 0x0c, 0x45, 0x78,
+	0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70,
+	0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, 0x3a,
+	0x01, 0x2a, 0x22, 0x33, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+	0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
+	0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x7d,
+	0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0xd2, 0x01, 0x0a, 0x16, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
 	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
-	0x54, 0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x58, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x52, 0x3a, 0x01, 0x2a, 0x22, 0x4d, 0x2f, 0x76, 0x31, 0x2f,
+	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
+	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01, 0x2a, 0x22, 0x4c,
+	0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72,
+	0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77,
+	0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x7d,
+	0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xc7, 0x01, 0x0a,
+	0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x70, 0x6c,
+	0x69, 0x73, 0x74, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65,
+	0x77, 0x54, 0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x70,
+	0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x82, 0xd3,
+	0xe4, 0x93, 0x02, 0x52, 0x3a, 0x01, 0x2a, 0x22, 0x4d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73,
+	0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+	0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x74,
+	0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x12, 0xd8, 0x01, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e,
+	0x12, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43, 0x6f,
+	0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d,
+	0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5a, 0x3a, 0x01, 0x2a, 0x22, 0x55, 0x2f, 0x76, 0x31, 0x2f,
 	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61,
 	0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f,
 	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d,
 	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x7d, 0x2f, 0x74, 0x6f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x12, 0xd8, 0x01, 0x0a, 0x15, 0x4d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69,
-	0x73, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65,
-	0x77, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
-	0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5a, 0x3a, 0x01, 0x2a, 0x22, 0x55, 0x2f,
-	0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69,
-	0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73,
-	0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x2d, 0x74, 0x6f, 0x70,
-	0x6c, 0x69, 0x73, 0x74, 0x12, 0xd3, 0x01, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d,
-	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65,
-	0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x53,
-	0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x82,
-	0xd3, 0xe4, 0x93, 0x02, 0x55, 0x3a, 0x01, 0x2a, 0x22, 0x50, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f,
-	0x74, 0x69, 0x6d, 0x65, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0xc3, 0x01, 0x0a, 0x11, 0x4d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73,
-	0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f,
-	0x74, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69,
+	0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x2d, 0x74, 0x6f, 0x70, 0x6c, 0x69, 0x73,
+	0x74, 0x12, 0xd3, 0x01, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65,
+	0x77, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x72, 0x69,
 	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a,
-	0x01, 0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-	0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
-	0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d,
-	0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76,
-	0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x73,
-	0x12, 0xbb, 0x01, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
-	0x52, 0x6f, 0x77, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69,
-	0x65, 0x77, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e,
+	0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72,
+	0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69,
+	0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x55, 0x3a, 0x01, 0x2a, 0x22, 0x50, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
+	0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
+	0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+	0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0xc3, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x12, 0x29, 0x2e,
 	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x52, 0x6f, 0x77, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x3a,
-	0x01, 0x2a, 0x22, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-	0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
-	0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d,
-	0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76,
-	0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x6f, 0x77, 0x73, 0x12, 0xd8,
-	0x01, 0x0a, 0x14, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69,
-	0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56,
-	0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5d, 0x3a, 0x01, 0x2a, 0x22,
-	0x58, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b,
+	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x74, 0x61, 0x6c,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01, 0x2a, 0x22,
+	0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b,
 	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65,
 	0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65,
 	0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x61, 0x6e, 0x67,
-	0x65, 0x2d, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0xc0, 0x01, 0x0a, 0x11, 0x4d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12,
-	0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68,
-	0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x12, 0xbb, 0x01,
+	0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x52, 0x6f, 0x77,
+	0x73, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x52,
+	0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c,
 	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x12, 0x4c,
-	0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72,
-	0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77,
-	0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0xc3, 0x01, 0x0a,
-	0x11, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x65, 0x61, 0x72,
-	0x63, 0x68, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
-	0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x65, 0x61, 0x72, 0x63,
-	0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02,
-	0x51, 0x3a, 0x01, 0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
-	0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x73, 0x65, 0x61, 0x72,
-	0x63, 0x68, 0x12, 0xb6, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x43, 0x6f,
-	0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76,
-	0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
-	0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3,
-	0xe4, 0x93, 0x02, 0x47, 0x3a, 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-	0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6d,
-	0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65,
-	0x6e, 0x74, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0xc7, 0x01, 0x0a, 0x14,
-	0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x49, 0x6e, 0x74, 0x65,
-	0x72, 0x76, 0x61, 0x6c, 0x12, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c,
-	0x6c, 0x75, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x3a, 0x01, 0x2a, 0x22,
+	0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b,
+	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65,
+	0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x6f, 0x77, 0x73, 0x12, 0xd8, 0x01, 0x0a, 0x14,
+	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x52,
+	0x61, 0x6e, 0x67, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69,
+	0x65, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
 	0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75,
-	0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x52, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x3a, 0x01, 0x2a, 0x22, 0x47, 0x2f, 0x76,
-	0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65,
-	0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
-	0x6c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
-	0x54, 0x6f, 0x70, 0x4b, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70,
-	0x4b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x54, 0x6f, 0x70, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82,
-	0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x01, 0x2a, 0x22, 0x3c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x6f,
-	0x70, 0x6b, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb0, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c,
-	0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82,
-	0xd3, 0xe4, 0x93, 0x02, 0x44, 0x12, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
-	0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
-	0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6e, 0x75, 0x6c, 0x6c, 0x2d,
-	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61,
-	0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xe0, 0x01, 0x0a, 0x1b, 0x43, 0x6f,
-	0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53,
-	0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
-	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75,
-	0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34,
-	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
-	0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x12, 0x4e, 0x2f, 0x76,
+	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77,
+	0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5d, 0x3a, 0x01, 0x2a, 0x22, 0x58, 0x2f, 0x76,
 	0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73,
 	0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65,
-	0x73, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x2d, 0x73, 0x74,
-	0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f,
-	0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb9, 0x01, 0x0a,
-	0x0f, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e,
-	0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61,
-	0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
-	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75,
-	0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x53, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4d, 0x12, 0x4b, 0x2f, 0x76, 0x31,
+	0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f,
+	0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x73,
+	0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0xc0, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29, 0x2e, 0x72,
+	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d,
+	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+	0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x12, 0x4c, 0x2f, 0x76, 0x31,
 	0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74,
 	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73,
-	0x2f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x73, 0x74, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x67,
-	0x72, 0x61, 0x69, 0x6e, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62,
-	0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xcc, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67,
-	0x72, 0x61, 0x6d, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65,
-	0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x12, 0x49, 0x2f, 0x76,
-	0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65,
-	0x73, 0x2f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67,
-	0x72, 0x61, 0x6d, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c,
-	0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xbc, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6c, 0x75,
-	0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x2a,
+	0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0xc3, 0x01, 0x0a, 0x11, 0x4d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12,
+	0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x65, 0x61,
+	0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01,
+	0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73,
+	0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71,
+	0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76,
+	0x69, 0x65, 0x77, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69,
+	0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12,
+	0xb6, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
+	0x6e, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x43, 0x6f,
+	0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29,
 	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67,
-	0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47, 0x12,
-	0x45, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b,
-	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65,
-	0x72, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x75, 0x67, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72,
-	0x61, 0x6d, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb8, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
-	0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c,
-	0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65,
-	0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x82,
-	0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x12, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
+	0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x47, 0x3a, 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
+	0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e,
+	0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x7d,
+	0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0xc7, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6c,
+	0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+	0x6c, 0x12, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75, 0x70,
+	0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x49, 0x6e,
+	0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52,
+	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x3a, 0x01, 0x2a, 0x22, 0x47, 0x2f, 0x76, 0x31, 0x2f, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x72,
+	0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2f, 0x74,
+	0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70,
+	0x4b, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f, 0x70, 0x4b, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
+	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x6f,
+	0x70, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x41, 0x3a, 0x01, 0x2a, 0x22, 0x3c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
 	0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
-	0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2d,
-	0x72, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x2f, 0x74, 0x61,
-	0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x7d, 0x12, 0xbe, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64,
-	0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x6f, 0x70, 0x6b, 0x2f,
+	0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x7d, 0x12, 0xb0, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75,
+	0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
 	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
-	0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64, 0x69,
-	0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52,
-	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x12, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74,
-	0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6c, 0x75,
-	0x6d, 0x6e, 0x2d, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2f, 0x74,
-	0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x7d, 0x12, 0xb6, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d,
-	0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x43, 0x6f, 0x75,
+	0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x44, 0x12, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+	0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
+	0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6e, 0x75, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xe0, 0x01, 0x0a, 0x1b, 0x43, 0x6f, 0x6c, 0x75, 0x6d,
+	0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74,
+	0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44,
+	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
+	0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x53,
+	0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x12, 0x4e, 0x2f, 0x76, 0x31, 0x2f, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x64,
+	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x76, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69,
+	0x73, 0x74, 0x69, 0x63, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61,
+	0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb9, 0x01, 0x0a, 0x0f, 0x43, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x2e,
+	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
+	0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54,
+	0x69, 0x6d, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x53, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4d, 0x12, 0x4b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+	0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x73, 0x6d,
+	0x61, 0x6c, 0x6c, 0x65, 0x73, 0x74, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x69,
+	0x6e, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xcc, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d,
+	0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63,
+	0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x12, 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x6e,
+	0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d,
+	0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x7d, 0x12, 0xbc, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52,
+	0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x2a, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
 	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
-	0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65,
-	0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3,
-	0xe4, 0x93, 0x02, 0x47, 0x3a, 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-	0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d,
-	0x65, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b,
-	0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xba, 0x01, 0x0a, 0x10,
+	0x52, 0x75, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47, 0x12, 0x45, 0x2f, 0x76,
+	0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73,
+	0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65,
+	0x73, 0x2f, 0x72, 0x75, 0x67, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x2f,
+	0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x7d, 0x12, 0xb8, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69,
+	0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
+	0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e,
+	0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x4c, 0x12, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+	0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
+	0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x61, 0x6e,
+	0x67, 0x65, 0x2d, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65,
+	0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xbe,
+	0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61,
+	0x6c, 0x69, 0x74, 0x79, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72,
+	0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c,
+	0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x82, 0xd3, 0xe4,
+	0x93, 0x02, 0x4c, 0x12, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+	0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d,
+	0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x2d,
+	0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x61, 0x62, 0x6c,
+	0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12,
+	0xb6, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d,
+	0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29,
+	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
+	0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x47, 0x3a, 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
+	0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62,
+	0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xba, 0x01, 0x0a, 0x10, 0x54, 0x61, 0x62,
+	0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x28, 0x2e,
+	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
 	0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79,
-	0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c,
-	0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c,
-	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62,
-	0x6c, 0x65, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x12, 0x49, 0x2f,
-	0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69,
-	0x65, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61,
-	0x6c, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62,
-	0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x54, 0x61, 0x62,
-	0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
-	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c,
-	0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x22, 0x47,
-	0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72,
-	0x69, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x66,
-	0x69, 0x6c, 0x65, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c,
-	0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x98, 0x01, 0x0a, 0x09, 0x54, 0x61, 0x62, 0x6c,
-	0x65, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43,
+	0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x12, 0x49, 0x2f, 0x76, 0x31, 0x2f,
+	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61,
+	0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f,
+	0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74,
+	0x79, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f,
+	0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72,
+	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54,
+	0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x22, 0x47, 0x2f, 0x76, 0x31,
+	0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73,
+	0x2f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+	0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x7d, 0x12, 0x98, 0x01, 0x0a, 0x09, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f,
+	0x77, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
 	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77,
-	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65,
-	0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3,
-	0xe4, 0x93, 0x02, 0x3e, 0x12, 0x3c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
-	0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x77, 0x73, 0x2f, 0x74,
-	0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x7d, 0x42, 0xbf, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x51, 0x75, 0x65, 0x72,
-	0x69, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68,
-	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f,
-	0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72,
-	0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02,
-	0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31,
-	0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c,
-	0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
-	0xea, 0x02, 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
-	0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x3e, 0x12, 0x3c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73,
+	0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71,
+	0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x77, 0x73, 0x2f, 0x74, 0x61, 0x62, 0x6c,
+	0x65, 0x73, 0x2f, 0x7b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42,
+	0xbf, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
+	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73,
+	0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c,
+	0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c,
+	0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69,
+	0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f,
+	0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2,
+	0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56,
+	0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11,
+	0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56,
+	0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -9708,105 +9684,103 @@ var file_rill_runtime_v1_queries_proto_depIdxs = []int32{
 	103, // 129: rill.runtime.v1.MetricsViewSearchRequest.having:type_name -> rill.runtime.v1.Expression
 	91,  // 130: rill.runtime.v1.MetricsViewSearchResponse.results:type_name -> rill.runtime.v1.MetricsViewSearchResponse.SearchResult
 	100, // 131: rill.runtime.v1.ResolveComponentRequest.args:type_name -> google.protobuf.Struct
-	99,  // 132: rill.runtime.v1.ResolveComponentResponse.schema:type_name -> rill.runtime.v1.StructType
-	100, // 133: rill.runtime.v1.ResolveComponentResponse.data:type_name -> google.protobuf.Struct
-	100, // 134: rill.runtime.v1.ResolveComponentResponse.renderer_properties:type_name -> google.protobuf.Struct
-	102, // 135: rill.runtime.v1.ColumnRollupIntervalResponse.start:type_name -> google.protobuf.Timestamp
-	102, // 136: rill.runtime.v1.ColumnRollupIntervalResponse.end:type_name -> google.protobuf.Timestamp
-	104, // 137: rill.runtime.v1.ColumnRollupIntervalResponse.interval:type_name -> rill.runtime.v1.TimeGrain
-	57,  // 138: rill.runtime.v1.ColumnTopKResponse.categorical_summary:type_name -> rill.runtime.v1.CategoricalSummary
-	58,  // 139: rill.runtime.v1.CategoricalSummary.top_k:type_name -> rill.runtime.v1.TopK
-	92,  // 140: rill.runtime.v1.TopK.entries:type_name -> rill.runtime.v1.TopK.Entry
-	63,  // 141: rill.runtime.v1.ColumnDescriptiveStatisticsResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
-	64,  // 142: rill.runtime.v1.NumericSummary.numeric_histogram_bins:type_name -> rill.runtime.v1.NumericHistogramBins
-	65,  // 143: rill.runtime.v1.NumericSummary.numeric_statistics:type_name -> rill.runtime.v1.NumericStatistics
-	66,  // 144: rill.runtime.v1.NumericSummary.numeric_outliers:type_name -> rill.runtime.v1.NumericOutliers
-	93,  // 145: rill.runtime.v1.NumericHistogramBins.bins:type_name -> rill.runtime.v1.NumericHistogramBins.Bin
-	94,  // 146: rill.runtime.v1.NumericOutliers.outliers:type_name -> rill.runtime.v1.NumericOutliers.Outlier
-	104, // 147: rill.runtime.v1.ColumnTimeGrainResponse.time_grain:type_name -> rill.runtime.v1.TimeGrain
-	3,   // 148: rill.runtime.v1.ColumnNumericHistogramRequest.histogram_method:type_name -> rill.runtime.v1.HistogramMethod
-	63,  // 149: rill.runtime.v1.ColumnNumericHistogramResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
-	63,  // 150: rill.runtime.v1.ColumnRugHistogramResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
-	75,  // 151: rill.runtime.v1.ColumnTimeRangeResponse.time_range_summary:type_name -> rill.runtime.v1.TimeRangeSummary
-	102, // 152: rill.runtime.v1.TimeRangeSummary.min:type_name -> google.protobuf.Timestamp
-	102, // 153: rill.runtime.v1.TimeRangeSummary.max:type_name -> google.protobuf.Timestamp
-	95,  // 154: rill.runtime.v1.TimeRangeSummary.interval:type_name -> rill.runtime.v1.TimeRangeSummary.Interval
-	57,  // 155: rill.runtime.v1.ColumnCardinalityResponse.categorical_summary:type_name -> rill.runtime.v1.CategoricalSummary
-	96,  // 156: rill.runtime.v1.ColumnTimeSeriesRequest.measures:type_name -> rill.runtime.v1.ColumnTimeSeriesRequest.BasicMeasure
-	80,  // 157: rill.runtime.v1.ColumnTimeSeriesRequest.time_range:type_name -> rill.runtime.v1.TimeSeriesTimeRange
-	81,  // 158: rill.runtime.v1.ColumnTimeSeriesResponse.rollup:type_name -> rill.runtime.v1.TimeSeriesResponse
-	102, // 159: rill.runtime.v1.TimeSeriesTimeRange.start:type_name -> google.protobuf.Timestamp
-	102, // 160: rill.runtime.v1.TimeSeriesTimeRange.end:type_name -> google.protobuf.Timestamp
-	104, // 161: rill.runtime.v1.TimeSeriesTimeRange.interval:type_name -> rill.runtime.v1.TimeGrain
-	82,  // 162: rill.runtime.v1.TimeSeriesResponse.results:type_name -> rill.runtime.v1.TimeSeriesValue
-	82,  // 163: rill.runtime.v1.TimeSeriesResponse.spark:type_name -> rill.runtime.v1.TimeSeriesValue
-	102, // 164: rill.runtime.v1.TimeSeriesValue.ts:type_name -> google.protobuf.Timestamp
-	100, // 165: rill.runtime.v1.TimeSeriesValue.records:type_name -> google.protobuf.Struct
-	87,  // 166: rill.runtime.v1.TableColumnsResponse.profile_columns:type_name -> rill.runtime.v1.ProfileColumn
-	97,  // 167: rill.runtime.v1.TableColumnsResponse.unsupported_columns:type_name -> rill.runtime.v1.TableColumnsResponse.UnsupportedColumnsEntry
-	100, // 168: rill.runtime.v1.TableRowsResponse.data:type_name -> google.protobuf.Struct
-	98,  // 169: rill.runtime.v1.MetricsViewFilter.Cond.in:type_name -> google.protobuf.Value
-	98,  // 170: rill.runtime.v1.MetricsViewSearchResponse.SearchResult.value:type_name -> google.protobuf.Value
-	98,  // 171: rill.runtime.v1.TopK.Entry.value:type_name -> google.protobuf.Value
-	4,   // 172: rill.runtime.v1.QueryService.Query:input_type -> rill.runtime.v1.QueryRequest
-	6,   // 173: rill.runtime.v1.QueryService.QueryBatch:input_type -> rill.runtime.v1.QueryBatchRequest
-	8,   // 174: rill.runtime.v1.QueryService.Export:input_type -> rill.runtime.v1.ExportRequest
-	10,  // 175: rill.runtime.v1.QueryService.ExportReport:input_type -> rill.runtime.v1.ExportReportRequest
-	14,  // 176: rill.runtime.v1.QueryService.MetricsViewAggregation:input_type -> rill.runtime.v1.MetricsViewAggregationRequest
-	26,  // 177: rill.runtime.v1.QueryService.MetricsViewToplist:input_type -> rill.runtime.v1.MetricsViewToplistRequest
-	28,  // 178: rill.runtime.v1.QueryService.MetricsViewComparison:input_type -> rill.runtime.v1.MetricsViewComparisonRequest
-	35,  // 179: rill.runtime.v1.QueryService.MetricsViewTimeSeries:input_type -> rill.runtime.v1.MetricsViewTimeSeriesRequest
-	37,  // 180: rill.runtime.v1.QueryService.MetricsViewTotals:input_type -> rill.runtime.v1.MetricsViewTotalsRequest
-	39,  // 181: rill.runtime.v1.QueryService.MetricsViewRows:input_type -> rill.runtime.v1.MetricsViewRowsRequest
-	45,  // 182: rill.runtime.v1.QueryService.MetricsViewTimeRange:input_type -> rill.runtime.v1.MetricsViewTimeRangeRequest
-	47,  // 183: rill.runtime.v1.QueryService.MetricsViewSchema:input_type -> rill.runtime.v1.MetricsViewSchemaRequest
-	49,  // 184: rill.runtime.v1.QueryService.MetricsViewSearch:input_type -> rill.runtime.v1.MetricsViewSearchRequest
-	51,  // 185: rill.runtime.v1.QueryService.ResolveComponent:input_type -> rill.runtime.v1.ResolveComponentRequest
-	53,  // 186: rill.runtime.v1.QueryService.ColumnRollupInterval:input_type -> rill.runtime.v1.ColumnRollupIntervalRequest
-	55,  // 187: rill.runtime.v1.QueryService.ColumnTopK:input_type -> rill.runtime.v1.ColumnTopKRequest
-	59,  // 188: rill.runtime.v1.QueryService.ColumnNullCount:input_type -> rill.runtime.v1.ColumnNullCountRequest
-	61,  // 189: rill.runtime.v1.QueryService.ColumnDescriptiveStatistics:input_type -> rill.runtime.v1.ColumnDescriptiveStatisticsRequest
-	67,  // 190: rill.runtime.v1.QueryService.ColumnTimeGrain:input_type -> rill.runtime.v1.ColumnTimeGrainRequest
-	69,  // 191: rill.runtime.v1.QueryService.ColumnNumericHistogram:input_type -> rill.runtime.v1.ColumnNumericHistogramRequest
-	71,  // 192: rill.runtime.v1.QueryService.ColumnRugHistogram:input_type -> rill.runtime.v1.ColumnRugHistogramRequest
-	73,  // 193: rill.runtime.v1.QueryService.ColumnTimeRange:input_type -> rill.runtime.v1.ColumnTimeRangeRequest
-	76,  // 194: rill.runtime.v1.QueryService.ColumnCardinality:input_type -> rill.runtime.v1.ColumnCardinalityRequest
-	78,  // 195: rill.runtime.v1.QueryService.ColumnTimeSeries:input_type -> rill.runtime.v1.ColumnTimeSeriesRequest
-	83,  // 196: rill.runtime.v1.QueryService.TableCardinality:input_type -> rill.runtime.v1.TableCardinalityRequest
-	85,  // 197: rill.runtime.v1.QueryService.TableColumns:input_type -> rill.runtime.v1.TableColumnsRequest
-	88,  // 198: rill.runtime.v1.QueryService.TableRows:input_type -> rill.runtime.v1.TableRowsRequest
-	5,   // 199: rill.runtime.v1.QueryService.Query:output_type -> rill.runtime.v1.QueryResponse
-	7,   // 200: rill.runtime.v1.QueryService.QueryBatch:output_type -> rill.runtime.v1.QueryBatchResponse
-	9,   // 201: rill.runtime.v1.QueryService.Export:output_type -> rill.runtime.v1.ExportResponse
-	11,  // 202: rill.runtime.v1.QueryService.ExportReport:output_type -> rill.runtime.v1.ExportReportResponse
-	15,  // 203: rill.runtime.v1.QueryService.MetricsViewAggregation:output_type -> rill.runtime.v1.MetricsViewAggregationResponse
-	27,  // 204: rill.runtime.v1.QueryService.MetricsViewToplist:output_type -> rill.runtime.v1.MetricsViewToplistResponse
-	29,  // 205: rill.runtime.v1.QueryService.MetricsViewComparison:output_type -> rill.runtime.v1.MetricsViewComparisonResponse
-	36,  // 206: rill.runtime.v1.QueryService.MetricsViewTimeSeries:output_type -> rill.runtime.v1.MetricsViewTimeSeriesResponse
-	38,  // 207: rill.runtime.v1.QueryService.MetricsViewTotals:output_type -> rill.runtime.v1.MetricsViewTotalsResponse
-	40,  // 208: rill.runtime.v1.QueryService.MetricsViewRows:output_type -> rill.runtime.v1.MetricsViewRowsResponse
-	46,  // 209: rill.runtime.v1.QueryService.MetricsViewTimeRange:output_type -> rill.runtime.v1.MetricsViewTimeRangeResponse
-	48,  // 210: rill.runtime.v1.QueryService.MetricsViewSchema:output_type -> rill.runtime.v1.MetricsViewSchemaResponse
-	50,  // 211: rill.runtime.v1.QueryService.MetricsViewSearch:output_type -> rill.runtime.v1.MetricsViewSearchResponse
-	52,  // 212: rill.runtime.v1.QueryService.ResolveComponent:output_type -> rill.runtime.v1.ResolveComponentResponse
-	54,  // 213: rill.runtime.v1.QueryService.ColumnRollupInterval:output_type -> rill.runtime.v1.ColumnRollupIntervalResponse
-	56,  // 214: rill.runtime.v1.QueryService.ColumnTopK:output_type -> rill.runtime.v1.ColumnTopKResponse
-	60,  // 215: rill.runtime.v1.QueryService.ColumnNullCount:output_type -> rill.runtime.v1.ColumnNullCountResponse
-	62,  // 216: rill.runtime.v1.QueryService.ColumnDescriptiveStatistics:output_type -> rill.runtime.v1.ColumnDescriptiveStatisticsResponse
-	68,  // 217: rill.runtime.v1.QueryService.ColumnTimeGrain:output_type -> rill.runtime.v1.ColumnTimeGrainResponse
-	70,  // 218: rill.runtime.v1.QueryService.ColumnNumericHistogram:output_type -> rill.runtime.v1.ColumnNumericHistogramResponse
-	72,  // 219: rill.runtime.v1.QueryService.ColumnRugHistogram:output_type -> rill.runtime.v1.ColumnRugHistogramResponse
-	74,  // 220: rill.runtime.v1.QueryService.ColumnTimeRange:output_type -> rill.runtime.v1.ColumnTimeRangeResponse
-	77,  // 221: rill.runtime.v1.QueryService.ColumnCardinality:output_type -> rill.runtime.v1.ColumnCardinalityResponse
-	79,  // 222: rill.runtime.v1.QueryService.ColumnTimeSeries:output_type -> rill.runtime.v1.ColumnTimeSeriesResponse
-	84,  // 223: rill.runtime.v1.QueryService.TableCardinality:output_type -> rill.runtime.v1.TableCardinalityResponse
-	86,  // 224: rill.runtime.v1.QueryService.TableColumns:output_type -> rill.runtime.v1.TableColumnsResponse
-	89,  // 225: rill.runtime.v1.QueryService.TableRows:output_type -> rill.runtime.v1.TableRowsResponse
-	199, // [199:226] is the sub-list for method output_type
-	172, // [172:199] is the sub-list for method input_type
-	172, // [172:172] is the sub-list for extension type_name
-	172, // [172:172] is the sub-list for extension extendee
-	0,   // [0:172] is the sub-list for field type_name
+	100, // 132: rill.runtime.v1.ResolveComponentResponse.renderer_properties:type_name -> google.protobuf.Struct
+	102, // 133: rill.runtime.v1.ColumnRollupIntervalResponse.start:type_name -> google.protobuf.Timestamp
+	102, // 134: rill.runtime.v1.ColumnRollupIntervalResponse.end:type_name -> google.protobuf.Timestamp
+	104, // 135: rill.runtime.v1.ColumnRollupIntervalResponse.interval:type_name -> rill.runtime.v1.TimeGrain
+	57,  // 136: rill.runtime.v1.ColumnTopKResponse.categorical_summary:type_name -> rill.runtime.v1.CategoricalSummary
+	58,  // 137: rill.runtime.v1.CategoricalSummary.top_k:type_name -> rill.runtime.v1.TopK
+	92,  // 138: rill.runtime.v1.TopK.entries:type_name -> rill.runtime.v1.TopK.Entry
+	63,  // 139: rill.runtime.v1.ColumnDescriptiveStatisticsResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
+	64,  // 140: rill.runtime.v1.NumericSummary.numeric_histogram_bins:type_name -> rill.runtime.v1.NumericHistogramBins
+	65,  // 141: rill.runtime.v1.NumericSummary.numeric_statistics:type_name -> rill.runtime.v1.NumericStatistics
+	66,  // 142: rill.runtime.v1.NumericSummary.numeric_outliers:type_name -> rill.runtime.v1.NumericOutliers
+	93,  // 143: rill.runtime.v1.NumericHistogramBins.bins:type_name -> rill.runtime.v1.NumericHistogramBins.Bin
+	94,  // 144: rill.runtime.v1.NumericOutliers.outliers:type_name -> rill.runtime.v1.NumericOutliers.Outlier
+	104, // 145: rill.runtime.v1.ColumnTimeGrainResponse.time_grain:type_name -> rill.runtime.v1.TimeGrain
+	3,   // 146: rill.runtime.v1.ColumnNumericHistogramRequest.histogram_method:type_name -> rill.runtime.v1.HistogramMethod
+	63,  // 147: rill.runtime.v1.ColumnNumericHistogramResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
+	63,  // 148: rill.runtime.v1.ColumnRugHistogramResponse.numeric_summary:type_name -> rill.runtime.v1.NumericSummary
+	75,  // 149: rill.runtime.v1.ColumnTimeRangeResponse.time_range_summary:type_name -> rill.runtime.v1.TimeRangeSummary
+	102, // 150: rill.runtime.v1.TimeRangeSummary.min:type_name -> google.protobuf.Timestamp
+	102, // 151: rill.runtime.v1.TimeRangeSummary.max:type_name -> google.protobuf.Timestamp
+	95,  // 152: rill.runtime.v1.TimeRangeSummary.interval:type_name -> rill.runtime.v1.TimeRangeSummary.Interval
+	57,  // 153: rill.runtime.v1.ColumnCardinalityResponse.categorical_summary:type_name -> rill.runtime.v1.CategoricalSummary
+	96,  // 154: rill.runtime.v1.ColumnTimeSeriesRequest.measures:type_name -> rill.runtime.v1.ColumnTimeSeriesRequest.BasicMeasure
+	80,  // 155: rill.runtime.v1.ColumnTimeSeriesRequest.time_range:type_name -> rill.runtime.v1.TimeSeriesTimeRange
+	81,  // 156: rill.runtime.v1.ColumnTimeSeriesResponse.rollup:type_name -> rill.runtime.v1.TimeSeriesResponse
+	102, // 157: rill.runtime.v1.TimeSeriesTimeRange.start:type_name -> google.protobuf.Timestamp
+	102, // 158: rill.runtime.v1.TimeSeriesTimeRange.end:type_name -> google.protobuf.Timestamp
+	104, // 159: rill.runtime.v1.TimeSeriesTimeRange.interval:type_name -> rill.runtime.v1.TimeGrain
+	82,  // 160: rill.runtime.v1.TimeSeriesResponse.results:type_name -> rill.runtime.v1.TimeSeriesValue
+	82,  // 161: rill.runtime.v1.TimeSeriesResponse.spark:type_name -> rill.runtime.v1.TimeSeriesValue
+	102, // 162: rill.runtime.v1.TimeSeriesValue.ts:type_name -> google.protobuf.Timestamp
+	100, // 163: rill.runtime.v1.TimeSeriesValue.records:type_name -> google.protobuf.Struct
+	87,  // 164: rill.runtime.v1.TableColumnsResponse.profile_columns:type_name -> rill.runtime.v1.ProfileColumn
+	97,  // 165: rill.runtime.v1.TableColumnsResponse.unsupported_columns:type_name -> rill.runtime.v1.TableColumnsResponse.UnsupportedColumnsEntry
+	100, // 166: rill.runtime.v1.TableRowsResponse.data:type_name -> google.protobuf.Struct
+	98,  // 167: rill.runtime.v1.MetricsViewFilter.Cond.in:type_name -> google.protobuf.Value
+	98,  // 168: rill.runtime.v1.MetricsViewSearchResponse.SearchResult.value:type_name -> google.protobuf.Value
+	98,  // 169: rill.runtime.v1.TopK.Entry.value:type_name -> google.protobuf.Value
+	4,   // 170: rill.runtime.v1.QueryService.Query:input_type -> rill.runtime.v1.QueryRequest
+	6,   // 171: rill.runtime.v1.QueryService.QueryBatch:input_type -> rill.runtime.v1.QueryBatchRequest
+	8,   // 172: rill.runtime.v1.QueryService.Export:input_type -> rill.runtime.v1.ExportRequest
+	10,  // 173: rill.runtime.v1.QueryService.ExportReport:input_type -> rill.runtime.v1.ExportReportRequest
+	14,  // 174: rill.runtime.v1.QueryService.MetricsViewAggregation:input_type -> rill.runtime.v1.MetricsViewAggregationRequest
+	26,  // 175: rill.runtime.v1.QueryService.MetricsViewToplist:input_type -> rill.runtime.v1.MetricsViewToplistRequest
+	28,  // 176: rill.runtime.v1.QueryService.MetricsViewComparison:input_type -> rill.runtime.v1.MetricsViewComparisonRequest
+	35,  // 177: rill.runtime.v1.QueryService.MetricsViewTimeSeries:input_type -> rill.runtime.v1.MetricsViewTimeSeriesRequest
+	37,  // 178: rill.runtime.v1.QueryService.MetricsViewTotals:input_type -> rill.runtime.v1.MetricsViewTotalsRequest
+	39,  // 179: rill.runtime.v1.QueryService.MetricsViewRows:input_type -> rill.runtime.v1.MetricsViewRowsRequest
+	45,  // 180: rill.runtime.v1.QueryService.MetricsViewTimeRange:input_type -> rill.runtime.v1.MetricsViewTimeRangeRequest
+	47,  // 181: rill.runtime.v1.QueryService.MetricsViewSchema:input_type -> rill.runtime.v1.MetricsViewSchemaRequest
+	49,  // 182: rill.runtime.v1.QueryService.MetricsViewSearch:input_type -> rill.runtime.v1.MetricsViewSearchRequest
+	51,  // 183: rill.runtime.v1.QueryService.ResolveComponent:input_type -> rill.runtime.v1.ResolveComponentRequest
+	53,  // 184: rill.runtime.v1.QueryService.ColumnRollupInterval:input_type -> rill.runtime.v1.ColumnRollupIntervalRequest
+	55,  // 185: rill.runtime.v1.QueryService.ColumnTopK:input_type -> rill.runtime.v1.ColumnTopKRequest
+	59,  // 186: rill.runtime.v1.QueryService.ColumnNullCount:input_type -> rill.runtime.v1.ColumnNullCountRequest
+	61,  // 187: rill.runtime.v1.QueryService.ColumnDescriptiveStatistics:input_type -> rill.runtime.v1.ColumnDescriptiveStatisticsRequest
+	67,  // 188: rill.runtime.v1.QueryService.ColumnTimeGrain:input_type -> rill.runtime.v1.ColumnTimeGrainRequest
+	69,  // 189: rill.runtime.v1.QueryService.ColumnNumericHistogram:input_type -> rill.runtime.v1.ColumnNumericHistogramRequest
+	71,  // 190: rill.runtime.v1.QueryService.ColumnRugHistogram:input_type -> rill.runtime.v1.ColumnRugHistogramRequest
+	73,  // 191: rill.runtime.v1.QueryService.ColumnTimeRange:input_type -> rill.runtime.v1.ColumnTimeRangeRequest
+	76,  // 192: rill.runtime.v1.QueryService.ColumnCardinality:input_type -> rill.runtime.v1.ColumnCardinalityRequest
+	78,  // 193: rill.runtime.v1.QueryService.ColumnTimeSeries:input_type -> rill.runtime.v1.ColumnTimeSeriesRequest
+	83,  // 194: rill.runtime.v1.QueryService.TableCardinality:input_type -> rill.runtime.v1.TableCardinalityRequest
+	85,  // 195: rill.runtime.v1.QueryService.TableColumns:input_type -> rill.runtime.v1.TableColumnsRequest
+	88,  // 196: rill.runtime.v1.QueryService.TableRows:input_type -> rill.runtime.v1.TableRowsRequest
+	5,   // 197: rill.runtime.v1.QueryService.Query:output_type -> rill.runtime.v1.QueryResponse
+	7,   // 198: rill.runtime.v1.QueryService.QueryBatch:output_type -> rill.runtime.v1.QueryBatchResponse
+	9,   // 199: rill.runtime.v1.QueryService.Export:output_type -> rill.runtime.v1.ExportResponse
+	11,  // 200: rill.runtime.v1.QueryService.ExportReport:output_type -> rill.runtime.v1.ExportReportResponse
+	15,  // 201: rill.runtime.v1.QueryService.MetricsViewAggregation:output_type -> rill.runtime.v1.MetricsViewAggregationResponse
+	27,  // 202: rill.runtime.v1.QueryService.MetricsViewToplist:output_type -> rill.runtime.v1.MetricsViewToplistResponse
+	29,  // 203: rill.runtime.v1.QueryService.MetricsViewComparison:output_type -> rill.runtime.v1.MetricsViewComparisonResponse
+	36,  // 204: rill.runtime.v1.QueryService.MetricsViewTimeSeries:output_type -> rill.runtime.v1.MetricsViewTimeSeriesResponse
+	38,  // 205: rill.runtime.v1.QueryService.MetricsViewTotals:output_type -> rill.runtime.v1.MetricsViewTotalsResponse
+	40,  // 206: rill.runtime.v1.QueryService.MetricsViewRows:output_type -> rill.runtime.v1.MetricsViewRowsResponse
+	46,  // 207: rill.runtime.v1.QueryService.MetricsViewTimeRange:output_type -> rill.runtime.v1.MetricsViewTimeRangeResponse
+	48,  // 208: rill.runtime.v1.QueryService.MetricsViewSchema:output_type -> rill.runtime.v1.MetricsViewSchemaResponse
+	50,  // 209: rill.runtime.v1.QueryService.MetricsViewSearch:output_type -> rill.runtime.v1.MetricsViewSearchResponse
+	52,  // 210: rill.runtime.v1.QueryService.ResolveComponent:output_type -> rill.runtime.v1.ResolveComponentResponse
+	54,  // 211: rill.runtime.v1.QueryService.ColumnRollupInterval:output_type -> rill.runtime.v1.ColumnRollupIntervalResponse
+	56,  // 212: rill.runtime.v1.QueryService.ColumnTopK:output_type -> rill.runtime.v1.ColumnTopKResponse
+	60,  // 213: rill.runtime.v1.QueryService.ColumnNullCount:output_type -> rill.runtime.v1.ColumnNullCountResponse
+	62,  // 214: rill.runtime.v1.QueryService.ColumnDescriptiveStatistics:output_type -> rill.runtime.v1.ColumnDescriptiveStatisticsResponse
+	68,  // 215: rill.runtime.v1.QueryService.ColumnTimeGrain:output_type -> rill.runtime.v1.ColumnTimeGrainResponse
+	70,  // 216: rill.runtime.v1.QueryService.ColumnNumericHistogram:output_type -> rill.runtime.v1.ColumnNumericHistogramResponse
+	72,  // 217: rill.runtime.v1.QueryService.ColumnRugHistogram:output_type -> rill.runtime.v1.ColumnRugHistogramResponse
+	74,  // 218: rill.runtime.v1.QueryService.ColumnTimeRange:output_type -> rill.runtime.v1.ColumnTimeRangeResponse
+	77,  // 219: rill.runtime.v1.QueryService.ColumnCardinality:output_type -> rill.runtime.v1.ColumnCardinalityResponse
+	79,  // 220: rill.runtime.v1.QueryService.ColumnTimeSeries:output_type -> rill.runtime.v1.ColumnTimeSeriesResponse
+	84,  // 221: rill.runtime.v1.QueryService.TableCardinality:output_type -> rill.runtime.v1.TableCardinalityResponse
+	86,  // 222: rill.runtime.v1.QueryService.TableColumns:output_type -> rill.runtime.v1.TableColumnsResponse
+	89,  // 223: rill.runtime.v1.QueryService.TableRows:output_type -> rill.runtime.v1.TableRowsResponse
+	197, // [197:224] is the sub-list for method output_type
+	170, // [170:197] is the sub-list for method input_type
+	170, // [170:170] is the sub-list for extension type_name
+	170, // [170:170] is the sub-list for extension extendee
+	0,   // [0:170] is the sub-list for field type_name
 }
 
 func init() { file_rill_runtime_v1_queries_proto_init() }
diff --git a/proto/gen/rill/runtime/v1/queries.pb.validate.go b/proto/gen/rill/runtime/v1/queries.pb.validate.go
index 21ec60d8e96..5ce1e8a07f5 100644
--- a/proto/gen/rill/runtime/v1/queries.pb.validate.go
+++ b/proto/gen/rill/runtime/v1/queries.pb.validate.go
@@ -9733,69 +9733,6 @@ func (m *ResolveComponentResponse) validate(all bool) error {
 
 	// no validation rules for Show
 
-	if all {
-		switch v := interface{}(m.GetSchema()).(type) {
-		case interface{ ValidateAll() error }:
-			if err := v.ValidateAll(); err != nil {
-				errors = append(errors, ResolveComponentResponseValidationError{
-					field:  "Schema",
-					reason: "embedded message failed validation",
-					cause:  err,
-				})
-			}
-		case interface{ Validate() error }:
-			if err := v.Validate(); err != nil {
-				errors = append(errors, ResolveComponentResponseValidationError{
-					field:  "Schema",
-					reason: "embedded message failed validation",
-					cause:  err,
-				})
-			}
-		}
-	} else if v, ok := interface{}(m.GetSchema()).(interface{ Validate() error }); ok {
-		if err := v.Validate(); err != nil {
-			return ResolveComponentResponseValidationError{
-				field:  "Schema",
-				reason: "embedded message failed validation",
-				cause:  err,
-			}
-		}
-	}
-
-	for idx, item := range m.GetData() {
-		_, _ = idx, item
-
-		if all {
-			switch v := interface{}(item).(type) {
-			case interface{ ValidateAll() error }:
-				if err := v.ValidateAll(); err != nil {
-					errors = append(errors, ResolveComponentResponseValidationError{
-						field:  fmt.Sprintf("Data[%v]", idx),
-						reason: "embedded message failed validation",
-						cause:  err,
-					})
-				}
-			case interface{ Validate() error }:
-				if err := v.Validate(); err != nil {
-					errors = append(errors, ResolveComponentResponseValidationError{
-						field:  fmt.Sprintf("Data[%v]", idx),
-						reason: "embedded message failed validation",
-						cause:  err,
-					})
-				}
-			}
-		} else if v, ok := interface{}(item).(interface{ Validate() error }); ok {
-			if err := v.Validate(); err != nil {
-				return ResolveComponentResponseValidationError{
-					field:  fmt.Sprintf("Data[%v]", idx),
-					reason: "embedded message failed validation",
-					cause:  err,
-				}
-			}
-		}
-
-	}
-
 	if all {
 		switch v := interface{}(m.GetRendererProperties()).(type) {
 		case interface{ ValidateAll() error }:
diff --git a/proto/gen/rill/runtime/v1/resources.pb.go b/proto/gen/rill/runtime/v1/resources.pb.go
index c0bbc96b3d2..a4446cba4a6 100644
--- a/proto/gen/rill/runtime/v1/resources.pb.go
+++ b/proto/gen/rill/runtime/v1/resources.pb.go
@@ -5088,8 +5088,6 @@ type ComponentSpec struct {
 
 	DisplayName        string               `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
 	Description        string               `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"`
-	Resolver           string               `protobuf:"bytes,2,opt,name=resolver,proto3" json:"resolver,omitempty"`
-	ResolverProperties *structpb.Struct     `protobuf:"bytes,3,opt,name=resolver_properties,json=resolverProperties,proto3" json:"resolver_properties,omitempty"`
 	Renderer           string               `protobuf:"bytes,4,opt,name=renderer,proto3" json:"renderer,omitempty"`
 	RendererProperties *structpb.Struct     `protobuf:"bytes,5,opt,name=renderer_properties,json=rendererProperties,proto3" json:"renderer_properties,omitempty"`
 	Input              []*ComponentVariable `protobuf:"bytes,8,rep,name=input,proto3" json:"input,omitempty"`
@@ -5144,20 +5142,6 @@ func (x *ComponentSpec) GetDescription() string {
 	return ""
 }
 
-func (x *ComponentSpec) GetResolver() string {
-	if x != nil {
-		return x.Resolver
-	}
-	return ""
-}
-
-func (x *ComponentSpec) GetResolverProperties() *structpb.Struct {
-	if x != nil {
-		return x.ResolverProperties
-	}
-	return nil
-}
-
 func (x *ComponentSpec) GetRenderer() string {
 	if x != nil {
 		return x.Renderer
@@ -5371,8 +5355,9 @@ type CanvasSpec struct {
 	unknownFields protoimpl.UnknownFields
 
 	DisplayName   string               `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
-	Columns       uint32               `protobuf:"varint,2,opt,name=columns,proto3" json:"columns,omitempty"`
-	Gap           uint32               `protobuf:"varint,3,opt,name=gap,proto3" json:"gap,omitempty"`
+	MaxWidth      uint32               `protobuf:"varint,2,opt,name=max_width,json=maxWidth,proto3" json:"max_width,omitempty"`
+	Theme         string               `protobuf:"bytes,7,opt,name=theme,proto3" json:"theme,omitempty"`
+	EmbeddedTheme *ThemeSpec           `protobuf:"bytes,8,opt,name=embedded_theme,json=embeddedTheme,proto3" json:"embedded_theme,omitempty"`
 	Variables     []*ComponentVariable `protobuf:"bytes,5,rep,name=variables,proto3" json:"variables,omitempty"`
 	Items         []*CanvasItem        `protobuf:"bytes,4,rep,name=items,proto3" json:"items,omitempty"`
 	SecurityRules []*SecurityRule      `protobuf:"bytes,6,rep,name=security_rules,json=securityRules,proto3" json:"security_rules,omitempty"`
@@ -5417,18 +5402,25 @@ func (x *CanvasSpec) GetDisplayName() string {
 	return ""
 }
 
-func (x *CanvasSpec) GetColumns() uint32 {
+func (x *CanvasSpec) GetMaxWidth() uint32 {
 	if x != nil {
-		return x.Columns
+		return x.MaxWidth
 	}
 	return 0
 }
 
-func (x *CanvasSpec) GetGap() uint32 {
+func (x *CanvasSpec) GetTheme() string {
 	if x != nil {
-		return x.Gap
+		return x.Theme
 	}
-	return 0
+	return ""
+}
+
+func (x *CanvasSpec) GetEmbeddedTheme() *ThemeSpec {
+	if x != nil {
+		return x.EmbeddedTheme
+	}
+	return nil
 }
 
 func (x *CanvasSpec) GetVariables() []*ComponentVariable {
@@ -7872,263 +7864,261 @@ var file_rill_runtime_v1_resources_proto_rawDesc = []byte{
 	0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
 	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
 	0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74,
-	0x65, 0x22, 0xd6, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53,
+	0x65, 0x22, 0xf0, 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53,
 	0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e,
 	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c,
 	0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
 	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
-	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f,
-	0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f,
-	0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72,
-	0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6e, 0x64,
+	0x65, 0x72, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6e, 0x64,
+	0x65, 0x72, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72,
+	0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f,
-	0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a,
-	0x0a, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65,
-	0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
-	0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
-	0x52, 0x12, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
-	0x74, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56,
-	0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3a,
-	0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
-	0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
-	0x6c, 0x65, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68,
-	0x6f, 0x77, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x2a,
-	0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e,
-	0x76, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e,
-	0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x22, 0x4f, 0x0a, 0x0e, 0x43, 0x6f,
-	0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x0a,
-	0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63,
-	0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0x78, 0x0a, 0x11, 0x43,
-	0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
-	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61,
-	0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
-	0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
-	0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6d, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12,
-	0x2f, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
+	0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x6e, 0x64,
+	0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x38,
+	0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e,
 	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63,
-	0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73,
-	0x74, 0x61, 0x74, 0x65, 0x22, 0x96, 0x02, 0x0a, 0x0a, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53,
-	0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c,
-	0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
-	0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73,
-	0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x67,
-	0x61, 0x70, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18,
-	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
-	0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61,
-	0x62, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d,
-	0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72,
-	0x69, 0x74, 0x79, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d,
-	0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x49, 0x0a,
-	0x0b, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0a,
-	0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
-	0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x76,
-	0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0xd5, 0x01, 0x0a, 0x0a, 0x43, 0x61, 0x6e,
-	0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f,
-	0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70,
-	0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64,
-	0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, 0x76, 0x61,
-	0x73, 0x12, 0x11, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x01,
-	0x78, 0x88, 0x01, 0x01, 0x12, 0x11, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48,
-	0x01, 0x52, 0x01, 0x79, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x88,
-	0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x0d, 0x48, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42,
-	0x04, 0x0a, 0x02, 0x5f, 0x78, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x79, 0x42, 0x08, 0x0a, 0x06, 0x5f,
-	0x77, 0x69, 0x64, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
-	0x22, 0x64, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2c, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e,
-	0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x70, 0x65, 0x63, 0x52,
-	0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xb1, 0x02, 0x0a, 0x07, 0x41, 0x50, 0x49, 0x53, 0x70,
-	0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48,
-	0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65,
-	0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
-	0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72,
-	0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x6e,
-	0x61, 0x70, 0x69, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72,
-	0x79, 0x12, 0x46, 0x0a, 0x12, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x70, 0x61, 0x72,
-	0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x11, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x50,
-	0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x17, 0x6f, 0x70, 0x65,
-	0x6e, 0x61, 0x70, 0x69, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x63,
-	0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
-	0x75, 0x63, 0x74, 0x52, 0x15, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0a, 0x0a, 0x08, 0x41, 0x50,
-	0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x66, 0x55, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04,
-	0x63, 0x72, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e,
-	0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e,
-	0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72,
-	0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x5f,
-	0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65,
-	0x5a, 0x6f, 0x6e, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x45, 0x72,
+	0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
+	0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70,
+	0x75, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
+	0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x6f, 0x75,
+	0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x0a, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69,
+	0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61,
+	0x6e, 0x76, 0x61, 0x73, 0x22, 0x4f, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
+	0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f,
+	0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c,
+	0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d,
+	0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69,
+	0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0x78, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65,
+	0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12,
+	0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79,
+	0x70, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75,
+	0x65, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22,
+	0x6d, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x70, 0x65,
+	0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73,
+	0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74,
+	0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
+	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76,
+	0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xe0,
+	0x02, 0x0a, 0x0a, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a,
+	0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65,
+	0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12, 0x14, 0x0a,
+	0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x68,
+	0x65, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f,
+	0x74, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69,
+	0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68,
+	0x65, 0x6d, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0d, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
+	0x64, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62,
+	0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
+	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
+	0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76,
+	0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73,
+	0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73,
+	0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75,
+	0x6c, 0x65, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65,
+	0x73, 0x22, 0x49, 0x0a, 0x0b, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65,
+	0x12, 0x3a, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+	0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65,
+	0x63, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0xd5, 0x01, 0x0a,
+	0x0a, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x63,
+	0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+	0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66,
+	0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x08,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43,
+	0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x11, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x00, 0x52, 0x01, 0x78, 0x88, 0x01, 0x01, 0x12, 0x11, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x01, 0x79, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x77,
+	0x69, 0x64, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x05, 0x77, 0x69,
+	0x64, 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
+	0x88, 0x01, 0x01, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x78, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x79, 0x42,
+	0x08, 0x0a, 0x06, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x68, 0x65,
+	0x69, 0x67, 0x68, 0x74, 0x22, 0x64, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2c, 0x0a, 0x04, 0x73,
+	0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c,
+	0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53,
+	0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61,
+	0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x74,
+	0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xb1, 0x02, 0x0a, 0x07, 0x41,
+	0x50, 0x49, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76,
+	0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76,
+	0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70,
+	0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76,
+	0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f,
+	0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x53, 0x75,
+	0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x12, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
+	0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x11, 0x6f, 0x70, 0x65, 0x6e,
+	0x61, 0x70, 0x69, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a,
+	0x17, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x15, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0a,
+	0x0a, 0x08, 0x41, 0x50, 0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x53,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x5f, 0x75,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x66,
+	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
+	0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
+	0x12, 0x12, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x63, 0x72, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x73,
+	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x69,
+	0x63, 0x6b, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+	0x74, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0a, 0x50, 0x61, 0x72,
+	0x73, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44,
+	0x0a, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x4c, 0x6f, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x63, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+	0x22, 0x50, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72,
 	0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a,
-	0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x74,
-	0x61, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x50, 0x0a, 0x0f,
-	0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12,
-	0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f,
-	0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
-	0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4b,
-	0x0a, 0x0f, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x45, 0x72, 0x72, 0x6f,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a,
+	0x0d, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x50, 0x61,
+	0x74, 0x68, 0x22, 0x4b, 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79,
+	0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
+	0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x22,
+	0x2a, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f,
 	0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64,
-	0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x2a, 0x0a, 0x0e, 0x45,
-	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x72, 0x4c,
-	0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x78, 0x0a, 0x0b, 0x43,
-	0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x12, 0x32, 0x0a, 0x04, 0x73, 0x70,
-	0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e,
-	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
-	0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x35,
-	0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
-	0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e,
-	0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05,
-	0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8c, 0x04, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
-	0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65,
-	0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12,
-	0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53,
-	0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e,
-	0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12,
-	0x31, 0x0a, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f,
-	0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x74,
-	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
-	0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
-	0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72,
-	0x67, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63,
-	0x74, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73,
-	0x12, 0x77, 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x66,
-	0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
-	0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53,
-	0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72,
-	0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
-	0x52, 0x17, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d,
-	0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f,
-	0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
+	0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x43,
+	0x68, 0x61, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c,
+	0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22,
+	0x78, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x12, 0x32,
+	0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72,
+	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43,
+	0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70,
+	0x65, 0x63, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61,
+	0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8c, 0x04, 0x0a, 0x0d, 0x43, 0x6f,
+	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64,
+	0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69,
+	0x76, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
+	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+	0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
+	0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
+	0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+	0x09, 0x52, 0x13, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70,
+	0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
+	0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69,
+	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
+	0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+	0x41, 0x72, 0x67, 0x73, 0x12, 0x77, 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
+	0x65, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
+	0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72,
+	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+	0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
+	0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45,
+	0x6e, 0x74, 0x72, 0x79, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,
+	0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3d, 0x0a,
+	0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+	0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+	0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x1c,
+	0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61,
+	0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
 	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
 	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x70,
-	0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
-	0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x3a, 0x02, 0x38, 0x01, 0x22, 0x2d, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x68,
-	0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x65, 0x63, 0x48,
-	0x61, 0x73, 0x68, 0x2a, 0x8a, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c,
-	0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x43, 0x4f, 0x4e,
-	0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50,
-	0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x43,
-	0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x44,
-	0x4c, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c,
-	0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47,
-	0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f,
-	0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x03,
-	0x2a, 0xab, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70,
-	0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x23, 0x45, 0x58,
-	0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e,
-	0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
-	0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43,
-	0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4e,
-	0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45,
-	0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
-	0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x58, 0x50, 0x4c, 0x4f,
+	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2d, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e,
+	0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70,
+	0x65, 0x63, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73,
+	0x70, 0x65, 0x63, 0x48, 0x61, 0x73, 0x68, 0x2a, 0x8a, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f,
+	0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x52,
+	0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+	0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a,
+	0x15, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+	0x53, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f,
+	0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e,
+	0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43,
+	0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49,
+	0x4e, 0x47, 0x10, 0x03, 0x2a, 0xab, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65,
+	0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27,
+	0x0a, 0x23, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52,
+	0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f,
 	0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f,
-	0x44, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0xae,
-	0x01, 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65,
-	0x77, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x45, 0x42,
-	0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
-	0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57,
-	0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x10,
-	0x01, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x45, 0x42,
-	0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e,
-	0x53, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52,
-	0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x50, 0x49, 0x56, 0x4f, 0x54,
-	0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x45,
-	0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41, 0x53, 0x10, 0x04, 0x2a,
-	0xdc, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x72, 0x74, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53,
-	0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
-	0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52,
-	0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55,
-	0x45, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53,
-	0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54,
-	0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f,
-	0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x5f, 0x50, 0x45,
-	0x52, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x58, 0x50, 0x4c, 0x4f,
-	0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x4c,
-	0x54, 0x41, 0x5f, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x04, 0x12, 0x1f, 0x0a,
-	0x1b, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59,
-	0x50, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x2a, 0x85,
-	0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f,
-	0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
-	0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f,
-	0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x10, 0x01, 0x12,
-	0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41,
-	0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x53,
-	0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45,
-	0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x42, 0xc1, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72,
-	0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0e,
-	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
-	0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c,
-	0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
-	0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02,
-	0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74,
-	0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75,
-	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c,
-	0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
-	0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52,
-	0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50,
+	0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f,
+	0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x45,
+	0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f,
+	0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e,
+	0x10, 0x03, 0x2a, 0xae, 0x01, 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x57, 0x65,
+	0x62, 0x56, 0x69, 0x65, 0x77, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45,
+	0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x58, 0x50, 0x4c, 0x4f,
+	0x52, 0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x45, 0x58, 0x50, 0x4c,
+	0x4f, 0x52, 0x45, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45,
+	0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x44,
+	0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58,
+	0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x50,
+	0x49, 0x56, 0x4f, 0x54, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52,
+	0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41,
+	0x53, 0x10, 0x04, 0x2a, 0xdc, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x53,
+	0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x50, 0x4c, 0x4f,
+	0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53,
+	0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58,
+	0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
+	0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x50, 0x4c, 0x4f,
+	0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52,
+	0x43, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52,
+	0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x54,
+	0x41, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45,
+	0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45,
+	0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x5f, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10,
+	0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52,
+	0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e,
+	0x10, 0x05, 0x2a, 0x85, 0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54,
+	0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+	0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45,
+	0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53,
+	0x53, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e,
+	0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x1a,
+	0x0a, 0x16, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54,
+	0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x42, 0xc1, 0x01, 0x0a, 0x13, 0x63,
+	0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+	0x76, 0x31, 0x42, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f,
+	0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75,
+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+	0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e,
+	0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c,
+	0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52,
+	0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47,
+	0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, 0x6c,
+	0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -8374,14 +8364,14 @@ var file_rill_runtime_v1_resources_proto_depIdxs = []int32{
 	98,  // 123: rill.runtime.v1.ThemeSpec.secondary_color:type_name -> rill.runtime.v1.Color
 	63,  // 124: rill.runtime.v1.Component.spec:type_name -> rill.runtime.v1.ComponentSpec
 	64,  // 125: rill.runtime.v1.Component.state:type_name -> rill.runtime.v1.ComponentState
-	93,  // 126: rill.runtime.v1.ComponentSpec.resolver_properties:type_name -> google.protobuf.Struct
-	93,  // 127: rill.runtime.v1.ComponentSpec.renderer_properties:type_name -> google.protobuf.Struct
-	65,  // 128: rill.runtime.v1.ComponentSpec.input:type_name -> rill.runtime.v1.ComponentVariable
-	65,  // 129: rill.runtime.v1.ComponentSpec.output:type_name -> rill.runtime.v1.ComponentVariable
-	63,  // 130: rill.runtime.v1.ComponentState.valid_spec:type_name -> rill.runtime.v1.ComponentSpec
-	99,  // 131: rill.runtime.v1.ComponentVariable.default_value:type_name -> google.protobuf.Value
-	67,  // 132: rill.runtime.v1.Canvas.spec:type_name -> rill.runtime.v1.CanvasSpec
-	68,  // 133: rill.runtime.v1.Canvas.state:type_name -> rill.runtime.v1.CanvasState
+	93,  // 126: rill.runtime.v1.ComponentSpec.renderer_properties:type_name -> google.protobuf.Struct
+	65,  // 127: rill.runtime.v1.ComponentSpec.input:type_name -> rill.runtime.v1.ComponentVariable
+	65,  // 128: rill.runtime.v1.ComponentSpec.output:type_name -> rill.runtime.v1.ComponentVariable
+	63,  // 129: rill.runtime.v1.ComponentState.valid_spec:type_name -> rill.runtime.v1.ComponentSpec
+	99,  // 130: rill.runtime.v1.ComponentVariable.default_value:type_name -> google.protobuf.Value
+	67,  // 131: rill.runtime.v1.Canvas.spec:type_name -> rill.runtime.v1.CanvasSpec
+	68,  // 132: rill.runtime.v1.Canvas.state:type_name -> rill.runtime.v1.CanvasState
+	60,  // 133: rill.runtime.v1.CanvasSpec.embedded_theme:type_name -> rill.runtime.v1.ThemeSpec
 	65,  // 134: rill.runtime.v1.CanvasSpec.variables:type_name -> rill.runtime.v1.ComponentVariable
 	69,  // 135: rill.runtime.v1.CanvasSpec.items:type_name -> rill.runtime.v1.CanvasItem
 	22,  // 136: rill.runtime.v1.CanvasSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule
diff --git a/proto/gen/rill/runtime/v1/resources.pb.validate.go b/proto/gen/rill/runtime/v1/resources.pb.validate.go
index 8543df817c0..df359e13202 100644
--- a/proto/gen/rill/runtime/v1/resources.pb.validate.go
+++ b/proto/gen/rill/runtime/v1/resources.pb.validate.go
@@ -9603,37 +9603,6 @@ func (m *ComponentSpec) validate(all bool) error {
 
 	// no validation rules for Description
 
-	// no validation rules for Resolver
-
-	if all {
-		switch v := interface{}(m.GetResolverProperties()).(type) {
-		case interface{ ValidateAll() error }:
-			if err := v.ValidateAll(); err != nil {
-				errors = append(errors, ComponentSpecValidationError{
-					field:  "ResolverProperties",
-					reason: "embedded message failed validation",
-					cause:  err,
-				})
-			}
-		case interface{ Validate() error }:
-			if err := v.Validate(); err != nil {
-				errors = append(errors, ComponentSpecValidationError{
-					field:  "ResolverProperties",
-					reason: "embedded message failed validation",
-					cause:  err,
-				})
-			}
-		}
-	} else if v, ok := interface{}(m.GetResolverProperties()).(interface{ Validate() error }); ok {
-		if err := v.Validate(); err != nil {
-			return ComponentSpecValidationError{
-				field:  "ResolverProperties",
-				reason: "embedded message failed validation",
-				cause:  err,
-			}
-		}
-	}
-
 	// no validation rules for Renderer
 
 	if all {
@@ -10254,9 +10223,38 @@ func (m *CanvasSpec) validate(all bool) error {
 
 	// no validation rules for DisplayName
 
-	// no validation rules for Columns
+	// no validation rules for MaxWidth
+
+	// no validation rules for Theme
 
-	// no validation rules for Gap
+	if all {
+		switch v := interface{}(m.GetEmbeddedTheme()).(type) {
+		case interface{ ValidateAll() error }:
+			if err := v.ValidateAll(); err != nil {
+				errors = append(errors, CanvasSpecValidationError{
+					field:  "EmbeddedTheme",
+					reason: "embedded message failed validation",
+					cause:  err,
+				})
+			}
+		case interface{ Validate() error }:
+			if err := v.Validate(); err != nil {
+				errors = append(errors, CanvasSpecValidationError{
+					field:  "EmbeddedTheme",
+					reason: "embedded message failed validation",
+					cause:  err,
+				})
+			}
+		}
+	} else if v, ok := interface{}(m.GetEmbeddedTheme()).(interface{ Validate() error }); ok {
+		if err := v.Validate(); err != nil {
+			return CanvasSpecValidationError{
+				field:  "EmbeddedTheme",
+				reason: "embedded message failed validation",
+				cause:  err,
+			}
+		}
+	}
 
 	for idx, item := range m.GetVariables() {
 		_, _ = idx, item
diff --git a/proto/gen/rill/runtime/v1/runtime.swagger.yaml b/proto/gen/rill/runtime/v1/runtime.swagger.yaml
index d095d23cc90..fab0abe7171 100644
--- a/proto/gen/rill/runtime/v1/runtime.swagger.yaml
+++ b/proto/gen/rill/runtime/v1/runtime.swagger.yaml
@@ -1133,7 +1133,7 @@ paths:
             properties:
               args:
                 type: object
-                title: Optional args to pass to the data resolver and for resolving templating in the renderer properties
+                title: Optional args for resolving templating in the renderer properties
       tags:
         - QueryService
   /v1/instances/{instanceId}/queries/descriptive-statistics/tables/{tableName}:
@@ -3477,12 +3477,13 @@ definitions:
     properties:
       displayName:
         type: string
-      columns:
-        type: integer
-        format: int64
-      gap:
+      maxWidth:
         type: integer
         format: int64
+      theme:
+        type: string
+      embeddedTheme:
+        $ref: '#/definitions/v1ThemeSpec'
       variables:
         type: array
         items:
@@ -3832,10 +3833,6 @@ definitions:
         type: string
       description:
         type: string
-      resolver:
-        type: string
-      resolverProperties:
-        type: object
       renderer:
         type: string
       rendererProperties:
@@ -5893,14 +5890,6 @@ definitions:
         description: |-
           Show property with templating resolved for the provided args.
           If it resolves to false, the other fields are not set.
-      schema:
-        $ref: '#/definitions/v1StructType'
-        title: Schema of the resolved component data
-      data:
-        type: array
-        items:
-          type: object
-        title: Resolved component data
       rendererProperties:
         type: object
         title: Renderer properties with templating resolved for the provided args
diff --git a/proto/rill/runtime/v1/queries.proto b/proto/rill/runtime/v1/queries.proto
index 3235922a9f5..b687ad6082c 100644
--- a/proto/rill/runtime/v1/queries.proto
+++ b/proto/rill/runtime/v1/queries.proto
@@ -779,7 +779,7 @@ message ResolveComponentRequest {
   string instance_id = 1;
   // Component name
   string component = 2;
-  // Optional args to pass to the data resolver and for resolving templating in the renderer properties
+  // Optional args for resolving templating in the renderer properties
   google.protobuf.Struct args = 3;
 }
 
@@ -787,12 +787,8 @@ message ResolveComponentResponse {
   // Show property with templating resolved for the provided args.
   // If it resolves to false, the other fields are not set.
   bool show = 1;
-  // Schema of the resolved component data
-  StructType schema = 2;
-  // Resolved component data
-  repeated google.protobuf.Struct data = 3;
   // Renderer properties with templating resolved for the provided args
-  google.protobuf.Struct renderer_properties = 4;
+  google.protobuf.Struct renderer_properties = 2;
 }
 
 // **********
diff --git a/proto/rill/runtime/v1/resources.proto b/proto/rill/runtime/v1/resources.proto
index e0e60d567f7..7f50127512a 100644
--- a/proto/rill/runtime/v1/resources.proto
+++ b/proto/rill/runtime/v1/resources.proto
@@ -671,8 +671,6 @@ message Component {
 message ComponentSpec {
   string display_name = 1;
   string description = 7;
-  string resolver = 2;
-  google.protobuf.Struct resolver_properties = 3;
   string renderer = 4;
   google.protobuf.Struct renderer_properties = 5;
   repeated ComponentVariable input = 8;
@@ -698,8 +696,9 @@ message Canvas {
 
 message CanvasSpec {
   string display_name = 1;
-  uint32 columns = 2;
-  uint32 gap = 3;
+  uint32 max_width = 2;
+  string theme = 7;
+  ThemeSpec embedded_theme = 8;
   repeated ComponentVariable variables = 5;
   repeated CanvasItem items = 4;
   repeated SecurityRule security_rules = 6;
diff --git a/runtime/compilers/rillv1/connectors.go b/runtime/compilers/rillv1/connectors.go
index 1abdd2a919e..95fdbd7dd02 100644
--- a/runtime/compilers/rillv1/connectors.go
+++ b/runtime/compilers/rillv1/connectors.go
@@ -81,8 +81,6 @@ func (a *connectorAnalyzer) analyzeResource(ctx context.Context, r *Resource) {
 		a.trackConnector(r.MigrationSpec.Connector, r, false)
 	} else if r.APISpec != nil {
 		a.analyzeResourceWithResolver(r, r.APISpec.Resolver, r.APISpec.ResolverProperties)
-	} else if r.ComponentSpec != nil {
-		a.analyzeResourceWithResolver(r, r.ComponentSpec.Resolver, r.ComponentSpec.ResolverProperties)
 	} else if r.AlertSpec != nil {
 		a.analyzeResourceNotifiers(r, r.AlertSpec.Notifiers)
 	} else if r.ReportSpec != nil {
diff --git a/runtime/compilers/rillv1/data/component-template-v1.json b/runtime/compilers/rillv1/data/component-template-v1.json
index 2fd19c3b92b..2c865bfec44 100644
--- a/runtime/compilers/rillv1/data/component-template-v1.json
+++ b/runtime/compilers/rillv1/data/component-template-v1.json
@@ -5,25 +5,75 @@
     "ChartProperties": {
       "additionalProperties": false,
       "properties": {
-        "color": {
+        "config": {
+          "$ref": "#/definitions/ChartConfig"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "config"
+      ],
+      "type": "object"
+    },
+    "ChartConfig": {
+      "additionalProperties": false,
+      "properties": {
+        "metrics_view": {
           "type": "string"
         },
         "x": {
+          "$ref": "#/definitions/FieldConfig"
+        },
+        "y": {
+          "$ref": "#/definitions/FieldConfig"
+        },
+        "color": {
+          "oneOf": [
+            {
+              "$ref": "#/definitions/FieldConfig"
+            },
+            {
+              "type": "string"
+            }
+          ]
+        },
+        "tooltip": {
+          "$ref": "#/definitions/FieldConfig"
+        }
+      },
+      "required": [
+        "metrics_view"
+      ],
+      "type": "object"
+    },
+    "FieldConfig": {
+      "additionalProperties": false,
+      "properties": {
+        "field": {
           "type": "string"
         },
-        "xLabel": {
+        "title": {
           "type": "string"
         },
-        "y": {
+        "format": {
           "type": "string"
         },
-        "yLabel": {
+        "type": {
+          "type": "string",
+          "enum": ["quantitative", "ordinal", "nominal", "temporal", "geojson"]
+        },
+        "timeUnit": {
           "type": "string"
         }
       },
       "required": [
-        "x",
-        "y"
+        "field",
+        "type"
       ],
       "type": "object"
     },
@@ -35,6 +85,12 @@
         },
         "url": {
           "type": "string"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
         }
       },
       "required": [
@@ -71,6 +127,12 @@
         },
         "time_range": {
           "type": "string"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
         }
       },
       "required": [
@@ -100,6 +162,12 @@
         },
         "css": {
           "type": "object"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
         }
       },
       "required": [
@@ -218,6 +286,12 @@
         },
         "time_range": {
           "type": "string"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
         }
       },
       "required": [
@@ -265,6 +339,20 @@
           ],
           "type": "object"
         },
+        {
+          "additionalProperties": false,
+          "properties": {
+            "vega_lite": {
+              "spec": {
+                "type": "string"
+              }
+            }
+          },
+          "required": [
+            "vega_lite"
+          ],
+          "type": "object"
+        },
         {
           "additionalProperties": false,
           "properties": {
diff --git a/runtime/compilers/rillv1/parse_canvas.go b/runtime/compilers/rillv1/parse_canvas.go
index c020b3f3473..d88c419864f 100644
--- a/runtime/compilers/rillv1/parse_canvas.go
+++ b/runtime/compilers/rillv1/parse_canvas.go
@@ -13,8 +13,8 @@ type CanvasYAML struct {
 	commonYAML  `yaml:",inline"`         // Not accessed here, only setting it so we can use KnownFields for YAML parsing
 	DisplayName string                   `yaml:"display_name"`
 	Title       string                   `yaml:"title"` // Deprecated: use display_name
-	Columns     uint32                   `yaml:"columns"`
-	Gap         uint32                   `yaml:"gap"`
+	MaxWidth    uint32                   `yaml:"max_width"`
+	Theme       yaml.Node                `yaml:"theme"` // Name (string) or inline theme definition (map)
 	Variables   []*ComponentVariableYAML `yaml:"variables"`
 	Items       []*struct {
 		Component yaml.Node `yaml:"component"` // Can be a name (string) or inline component definition (map)
@@ -47,6 +47,16 @@ func (p *Parser) parseCanvas(node *Node) error {
 		tmp.DisplayName = tmp.Title
 	}
 
+	// Parse theme if present.
+	// If it returns a themeSpec, it will be inserted as a separate resource later in this function.
+	themeName, themeSpec, err := p.parseThemeRef(&tmp.Theme)
+	if err != nil {
+		return err
+	}
+	if themeName != "" && themeSpec == nil {
+		node.Refs = append(node.Refs, ResourceName{Kind: ResourceKindTheme, Name: themeName})
+	}
+
 	// Parse variable definitions.
 	var variables []*runtimev1.ComponentVariable
 	if len(tmp.Variables) > 0 {
@@ -61,7 +71,7 @@ func (p *Parser) parseCanvas(node *Node) error {
 
 	// Parse items.
 	// Each item can either reference an externally defined component by name or define a component inline.
-	items := make([]*runtimev1.CanvasItem, len(tmp.Items))
+	var items []*runtimev1.CanvasItem
 	var inlineComponentDefs []*componentDef
 	for i, item := range tmp.Items {
 		if item == nil {
@@ -78,14 +88,14 @@ func (p *Parser) parseCanvas(node *Node) error {
 			inlineComponentDefs = append(inlineComponentDefs, inlineComponentDef)
 		}
 
-		items[i] = &runtimev1.CanvasItem{
+		items = append(items, &runtimev1.CanvasItem{
 			Component:       component,
 			DefinedInCanvas: inlineComponentDef != nil,
 			X:               item.X,
 			Y:               item.Y,
 			Width:           item.Width,
 			Height:          item.Height,
-		}
+		})
 
 		node.Refs = append(node.Refs, ResourceName{Kind: ResourceKindComponent, Name: component})
 	}
@@ -108,12 +118,12 @@ func (p *Parser) parseCanvas(node *Node) error {
 	}
 	// NOTE: After calling insertResource, an error must not be returned. Any validation should be done before calling it.
 
-	r.CanvasSpec.DisplayName = tmp.DisplayName
 	if r.CanvasSpec.DisplayName == "" {
 		r.CanvasSpec.DisplayName = ToDisplayName(node.Name)
 	}
-	r.CanvasSpec.Columns = tmp.Columns
-	r.CanvasSpec.Gap = tmp.Gap
+	r.CanvasSpec.MaxWidth = tmp.MaxWidth
+	r.CanvasSpec.Theme = themeName
+	r.CanvasSpec.EmbeddedTheme = themeSpec
 	r.CanvasSpec.Variables = variables
 	r.CanvasSpec.Items = items
 	r.CanvasSpec.SecurityRules = rules
diff --git a/runtime/compilers/rillv1/parse_component.go b/runtime/compilers/rillv1/parse_component.go
index be00bed8dfd..3d48158498b 100644
--- a/runtime/compilers/rillv1/parse_component.go
+++ b/runtime/compilers/rillv1/parse_component.go
@@ -3,7 +3,6 @@ package rillv1
 import (
 	"errors"
 	"fmt"
-	"strings"
 
 	runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1"
 	"github.com/santhosh-tekuri/jsonschema/v5"
@@ -25,9 +24,7 @@ type ComponentYAML struct {
 	Subtitle    string                    `yaml:"subtitle"` // Deprecated: use description
 	Input       []*ComponentVariableYAML  `yaml:"input"`
 	Output      *ComponentVariableYAML    `yaml:"output"`
-	Data        *DataYAML                 `yaml:"data"`
 	Show        string                    `yaml:"show"`
-	VegaLite    *string                   `yaml:"vega_lite"`
 	Other       map[string]map[string]any `yaml:",inline" mapstructure:",remain"` // Generic renderer: can only have one key
 }
 
@@ -82,28 +79,10 @@ func (p *Parser) parseComponentYAML(tmp *ComponentYAML) (*runtimev1.ComponentSpe
 		tmp.Description = tmp.Subtitle
 	}
 
-	// Parse the data YAML
-	var refs []ResourceName
-	var resolver string
-	var resolverProps *structpb.Struct
-	if tmp.Data != nil {
-		var err error
-		resolver, resolverProps, refs, err = p.parseDataYAML(tmp.Data, "")
-		if err != nil {
-			return nil, nil, err
-		}
-	}
-
 	// Discover and validate the renderer
 	n := 0
 	var renderer string
 	var rendererProps *structpb.Struct
-	if tmp.VegaLite != nil {
-		n++
-
-		renderer = "vega_lite"
-		rendererProps = must(structpb.NewStruct(map[string]any{"spec": strings.TrimSpace(*tmp.VegaLite)}))
-	}
 	if len(tmp.Other) == 1 {
 		n++
 		var props map[string]any
@@ -111,8 +90,9 @@ func (p *Parser) parseComponentYAML(tmp *ComponentYAML) (*runtimev1.ComponentSpe
 			break
 		}
 
+		// nolint // TODO: Activate validation later when in production
 		if err := componentTemplateSchema.Validate(map[string]any{renderer: props}); err != nil {
-			return nil, nil, fmt.Errorf(`failed to validate renderer %q: %w`, renderer, err)
+			// return nil, nil, fmt.Errorf(`failed to validate renderer %q: %w`, renderer, err)
 		}
 
 		propsPB, err := structpb.NewStruct(props)
@@ -125,6 +105,19 @@ func (p *Parser) parseComponentYAML(tmp *ComponentYAML) (*runtimev1.ComponentSpe
 		n += len(tmp.Other)
 	}
 
+	// We generally treat the renderer props as untyped, but since "metrics_view" is a very common field,
+	// and adding it to refs generally makes for nicer error messages, we specifically search for and link it here.
+	var refs []ResourceName
+	for k, v := range rendererProps.Fields {
+		if k == "metrics_view" {
+			name := v.GetStringValue()
+			if name != "" {
+				refs = append(refs, ResourceName{Kind: ResourceKindMetricsView, Name: name})
+			}
+			break
+		}
+	}
+
 	// Check there is exactly one renderer
 	if n == 0 {
 		return nil, nil, errors.New(`missing renderer configuration`)
@@ -160,8 +153,6 @@ func (p *Parser) parseComponentYAML(tmp *ComponentYAML) (*runtimev1.ComponentSpe
 	spec := &runtimev1.ComponentSpec{
 		DisplayName:        tmp.DisplayName,
 		Description:        tmp.Description,
-		Resolver:           resolver,
-		ResolverProperties: resolverProps,
 		Renderer:           renderer,
 		RendererProperties: rendererProps,
 		Input:              input,
@@ -192,10 +183,3 @@ func (y *ComponentVariableYAML) Proto() (*runtimev1.ComponentVariable, error) {
 		DefaultValue: val,
 	}, nil
 }
-
-func must[T any](v T, err error) T {
-	if err != nil {
-		panic(err)
-	}
-	return v
-}
diff --git a/runtime/compilers/rillv1/parse_explore.go b/runtime/compilers/rillv1/parse_explore.go
index 93d5276fc8e..a8f27b6acf9 100644
--- a/runtime/compilers/rillv1/parse_explore.go
+++ b/runtime/compilers/rillv1/parse_explore.go
@@ -154,7 +154,7 @@ func (p *Parser) parseExplore(node *Node) error {
 
 	// Parse theme if present.
 	// If it returns a themeSpec, it will be inserted as a separate resource later in this function.
-	themeName, themeSpec, err := p.parseExploreTheme(&tmp.Theme)
+	themeName, themeSpec, err := p.parseThemeRef(&tmp.Theme)
 	if err != nil {
 		return err
 	}
@@ -275,24 +275,21 @@ func (p *Parser) parseExplore(node *Node) error {
 	r.ExploreSpec.DimensionsSelector = dimensionsSelector
 	r.ExploreSpec.Measures = measures
 	r.ExploreSpec.MeasuresSelector = measuresSelector
+	r.ExploreSpec.Theme = themeName
+	r.ExploreSpec.EmbeddedTheme = themeSpec
 	r.ExploreSpec.TimeRanges = timeRanges
 	r.ExploreSpec.TimeZones = tmp.TimeZones
 	r.ExploreSpec.DefaultPreset = defaultPreset
 	r.ExploreSpec.EmbedsHidePivot = tmp.Embeds.HidePivot
 	r.ExploreSpec.SecurityRules = rules
 
-	if themeName != "" && themeSpec == nil {
-		r.ExploreSpec.Theme = themeName
-	}
-
-	if themeSpec != nil {
-		r.ExploreSpec.EmbeddedTheme = themeSpec
-	}
-
 	return nil
 }
 
-func (p *Parser) parseExploreTheme(n *yaml.Node) (string, *runtimev1.ThemeSpec, error) {
+// parseThemeRef parses a theme from a YAML node.
+// It accepts either a reference to a theme by name or an inline definition of a theme.
+// It returns either a theme name or a theme spec, not both.
+func (p *Parser) parseThemeRef(n *yaml.Node) (string, *runtimev1.ThemeSpec, error) {
 	if n == nil || n.IsZero() {
 		return "", nil, nil
 	}
diff --git a/runtime/compilers/rillv1/parser_test.go b/runtime/compilers/rillv1/parser_test.go
index 48b59a1d01c..1299445f727 100644
--- a/runtime/compilers/rillv1/parser_test.go
+++ b/runtime/compilers/rillv1/parser_test.go
@@ -1542,6 +1542,18 @@ theme: t1
 		`explores/e2.yaml`: `
 type: explore
 metrics_view: missing
+theme:
+  colors:
+    primary: red
+`,
+		// Canvas referencing the external theme resource
+		`canvases/c1.yaml`: `
+type: canvas
+theme: t1
+`,
+		// Canvas that defines an inline theme
+		`canvases/c2.yaml`: `
+type: canvas
 theme:
   colors:
     primary: red
@@ -1601,6 +1613,31 @@ theme:
 				},
 			},
 		},
+		{
+			Name:  ResourceName{Kind: ResourceKindCanvas, Name: "c1"},
+			Paths: []string{"/canvases/c1.yaml"},
+			Refs:  []ResourceName{{Kind: ResourceKindTheme, Name: "t1"}},
+			CanvasSpec: &runtimev1.CanvasSpec{
+				DisplayName: "C1",
+				Theme:       "t1",
+			},
+		},
+		{
+			Name:  ResourceName{Kind: ResourceKindCanvas, Name: "c2"},
+			Paths: []string{"/canvases/c2.yaml"},
+			CanvasSpec: &runtimev1.CanvasSpec{
+				DisplayName: "C2",
+				EmbeddedTheme: &runtimev1.ThemeSpec{
+					PrimaryColor: &runtimev1.Color{
+						Red:   1,
+						Green: 0,
+						Blue:  0,
+						Alpha: 1,
+					},
+					PrimaryColorRaw: "red",
+				},
+			},
+		},
 	}
 
 	p, err := Parse(ctx, repo, "", "", "duckdb")
@@ -1627,34 +1664,24 @@ func TestComponentsAndCanvas(t *testing.T) {
 		`rill.yaml`: ``,
 		`components/c1.yaml`: fmt.Sprintf(`
 type: component
-data:
-  api: MetricsViewAggregation
-  args:
-    metrics_view: foo
-vega_lite: >
-  %s
+vega_lite:
+  spec: '%s'
 `, vegaLiteSpec),
 		`components/c2.yaml`: fmt.Sprintf(`
 type: component
-data:
-  api: MetricsViewAggregation
-  args:
-    metrics_view: bar
-vega_lite: >
-  %s
+vega_lite:
+  spec: '%s'
 `, vegaLiteSpec),
 		`components/c3.yaml`: `
 type: component
-data:
-  metrics_sql: SELECT 1
-line_chart:
-  x: time
-  y: total_sales
+kpi:
+  metrics_view: foo
+  measure: bar
+  time_range: P1W
 `,
 		`canvases/d1.yaml`: `
 type: canvas
-columns: 4
-gap: 3
+max_width: 4
 items:
 - component: c1
 - component: c2
@@ -1670,11 +1697,8 @@ items:
 		{
 			Name:  ResourceName{Kind: ResourceKindComponent, Name: "c1"},
 			Paths: []string{"/components/c1.yaml"},
-			Refs:  []ResourceName{{Kind: ResourceKindAPI, Name: "MetricsViewAggregation"}},
 			ComponentSpec: &runtimev1.ComponentSpec{
 				DisplayName:        "C1",
-				Resolver:           "api",
-				ResolverProperties: must(structpb.NewStruct(map[string]any{"api": "MetricsViewAggregation", "args": map[string]any{"metrics_view": "foo"}})),
 				Renderer:           "vega_lite",
 				RendererProperties: must(structpb.NewStruct(map[string]any{"spec": vegaLiteSpec})),
 			},
@@ -1682,11 +1706,8 @@ items:
 		{
 			Name:  ResourceName{Kind: ResourceKindComponent, Name: "c2"},
 			Paths: []string{"/components/c2.yaml"},
-			Refs:  []ResourceName{{Kind: ResourceKindAPI, Name: "MetricsViewAggregation"}},
 			ComponentSpec: &runtimev1.ComponentSpec{
 				DisplayName:        "C2",
-				Resolver:           "api",
-				ResolverProperties: must(structpb.NewStruct(map[string]any{"api": "MetricsViewAggregation", "args": map[string]any{"metrics_view": "bar"}})),
 				Renderer:           "vega_lite",
 				RendererProperties: must(structpb.NewStruct(map[string]any{"spec": vegaLiteSpec})),
 			},
@@ -1694,12 +1715,11 @@ items:
 		{
 			Name:  ResourceName{Kind: ResourceKindComponent, Name: "c3"},
 			Paths: []string{"/components/c3.yaml"},
+			Refs:  []ResourceName{{Kind: ResourceKindMetricsView, Name: "foo"}},
 			ComponentSpec: &runtimev1.ComponentSpec{
 				DisplayName:        "C3",
-				Resolver:           "metrics_sql",
-				ResolverProperties: must(structpb.NewStruct(map[string]any{"sql": "SELECT 1"})),
-				Renderer:           "line_chart",
-				RendererProperties: must(structpb.NewStruct(map[string]any{"x": "time", "y": "total_sales"})),
+				Renderer:           "kpi",
+				RendererProperties: must(structpb.NewStruct(map[string]any{"metrics_view": "foo", "measure": "bar", "time_range": "P1W"})),
 			},
 		},
 		{
@@ -1721,8 +1741,7 @@ items:
 			},
 			CanvasSpec: &runtimev1.CanvasSpec{
 				DisplayName: "D1",
-				Columns:     4,
-				Gap:         3,
+				MaxWidth:    4,
 				Items: []*runtimev1.CanvasItem{
 					{Component: "c1"},
 					{Component: "c2", Width: asPtr(uint32(1)), Height: asPtr(uint32(2))},
@@ -2229,3 +2248,10 @@ func normalizeJSON(t *testing.T, s string) string {
 	require.NoError(t, err)
 	return string(b)
 }
+
+func must[T any](v T, err error) T {
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
diff --git a/runtime/server/components.go b/runtime/server/components.go
index 569854bfa38..172bdaba9b9 100644
--- a/runtime/server/components.go
+++ b/runtime/server/components.go
@@ -2,17 +2,13 @@ package server
 
 import (
 	"context"
-	"encoding/json"
 	"errors"
-	"io"
-	"net/http"
 	"strconv"
 
 	runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1"
 	"github.com/rilldata/rill/runtime"
 	"github.com/rilldata/rill/runtime/compilers/rillv1"
 	"github.com/rilldata/rill/runtime/drivers"
-	"github.com/rilldata/rill/runtime/pkg/httputil"
 	"github.com/rilldata/rill/runtime/pkg/observability"
 	"github.com/rilldata/rill/runtime/server/auth"
 	"go.opentelemetry.io/otel/attribute"
@@ -106,119 +102,9 @@ func (s *Server) ResolveComponent(ctx context.Context, req *runtimev1.ResolveCom
 		}
 	}
 
-	// Call the component's data resolver
-	var schema *runtimev1.StructType
-	var data []*structpb.Struct
-	if spec.Resolver != "" {
-		res, err := s.runtime.Resolve(ctx, &runtime.ResolveOptions{
-			InstanceID:         req.InstanceId,
-			Resolver:           spec.Resolver,
-			ResolverProperties: spec.ResolverProperties.AsMap(),
-			Args:               req.Args.AsMap(),
-			Claims:             auth.GetClaims(ctx).SecurityClaims(),
-		})
-		if err != nil {
-			return nil, status.Error(codes.InvalidArgument, err.Error())
-		}
-		defer res.Close()
-
-		schema = res.Schema()
-		for {
-			row, err := res.Next()
-			if err != nil {
-				if errors.Is(err, io.EOF) {
-					break
-				}
-				return nil, status.Error(codes.Internal, err.Error())
-			}
-
-			pb, err := structpb.NewStruct(row)
-			if err != nil {
-				return nil, status.Errorf(codes.Internal, "failed to convert row to struct: %s", err.Error())
-			}
-
-			data = append(data, pb)
-		}
-	}
-
 	// Return the response
 	return &runtimev1.ResolveComponentResponse{
 		Show:               true,
-		Schema:             schema,
-		Data:               data,
 		RendererProperties: rendererProps,
 	}, nil
 }
-
-// componentDataHandler handles requests to resolve a component's data.
-// Deprecated: Use ResolveComponent instead.
-func (s *Server) componentDataHandler(w http.ResponseWriter, req *http.Request) error {
-	// Parse path parameters
-	ctx := req.Context()
-	instanceID := req.PathValue("instance_id")
-	component := req.PathValue("name")
-
-	// Check if user has access to query for component data (we use the ReadAPI permission for this for now)
-	if !auth.GetClaims(req.Context()).CanInstance(instanceID, auth.ReadAPI) {
-		return httputil.Errorf(http.StatusForbidden, "does not have access to component data")
-	}
-
-	// Parse args from the request body and URL query
-	args := make(map[string]any)
-	body, err := io.ReadAll(req.Body)
-	if err != nil {
-		return httputil.Errorf(http.StatusBadRequest, "failed to read request body: %w", err)
-	}
-	if len(body) > 0 { // For POST requests
-		if err := json.Unmarshal(body, &args); err != nil {
-			return httputil.Errorf(http.StatusBadRequest, "failed to unmarshal request body: %w", err)
-		}
-	}
-	for k, v := range req.URL.Query() {
-		// Set only the first value so that client does need to put array accessors in templates.
-		args[k] = v[0]
-	}
-
-	// Find the component spec
-	ctrl, err := s.runtime.Controller(ctx, instanceID)
-	if err != nil {
-		return httputil.Error(http.StatusInternalServerError, err)
-	}
-	rs, err := ctrl.Get(ctx, &runtimev1.ResourceName{Kind: runtime.ResourceKindComponent, Name: component}, false)
-	if err != nil {
-		if errors.Is(err, drivers.ErrResourceNotFound) {
-			return httputil.Errorf(http.StatusNotFound, "component with name %q not found", component)
-		}
-		return httputil.Error(http.StatusInternalServerError, err)
-	}
-	componentSpec := rs.GetComponent().State.ValidSpec
-	if componentSpec == nil {
-		return httputil.Errorf(http.StatusBadRequest, "component %q is invalid", component)
-	}
-
-	// Call the component's data resolver
-	res, err := s.runtime.Resolve(ctx, &runtime.ResolveOptions{
-		InstanceID:         instanceID,
-		Resolver:           componentSpec.Resolver,
-		ResolverProperties: componentSpec.ResolverProperties.AsMap(),
-		Args:               args,
-		Claims:             auth.GetClaims(ctx).SecurityClaims(),
-	})
-	if err != nil {
-		return httputil.Error(http.StatusBadRequest, err)
-	}
-	defer res.Close()
-
-	// Write the response
-	data, err := res.MarshalJSON()
-	if err != nil {
-		return httputil.Error(http.StatusInternalServerError, err)
-	}
-	w.Header().Set("Content-Type", "application/json")
-	_, err = w.Write(data)
-	if err != nil {
-		return httputil.Error(http.StatusInternalServerError, err)
-	}
-
-	return nil
-}
diff --git a/runtime/server/server.go b/runtime/server/server.go
index 57692f357c9..5942f730c4e 100644
--- a/runtime/server/server.go
+++ b/runtime/server/server.go
@@ -215,10 +215,6 @@ func (s *Server) HTTPHandler(ctx context.Context, registerAdditionalHandlers fun
 	// Add handler for combined OpenAPI spec of custom APIs
 	observability.MuxHandle(httpMux, "/v1/instances/{instance_id}/api/openapi", observability.Middleware("runtime", s.logger, auth.HTTPMiddleware(s.aud, httputil.Handler(s.combinedOpenAPISpec))))
 
-	// Add handler for resolving component data
-	// NOTE: Deprecated in favor of the ResolveComponent RPC.
-	observability.MuxHandle(httpMux, "/v1/instances/{instance_id}/components/{name}/data", observability.Middleware("runtime", s.logger, auth.HTTPMiddleware(s.aud, httputil.Handler(s.componentDataHandler))))
-
 	// Serving static assets
 	observability.MuxHandle(httpMux, "/v1/instances/{instance_id}/assets/{path...}", observability.Middleware("runtime", s.logger, auth.HTTPMiddleware(s.aud, httputil.Handler(s.assetsHandler))))
 
diff --git a/web-admin/src/features/embeds/CanvasEmbed.svelte b/web-admin/src/features/embeds/CanvasEmbed.svelte
index 8074c2fef40..c5074ae2a87 100644
--- a/web-admin/src/features/embeds/CanvasEmbed.svelte
+++ b/web-admin/src/features/embeds/CanvasEmbed.svelte
@@ -8,15 +8,14 @@
   export let instanceId: string;
   export let canvasName: string;
 
+  // TODO: Remove later
+  let columns = 20;
+  let gap = 1;
   $: canvasQuery = useResource(instanceId, canvasName, ResourceKind.Canvas);
 
   $: canvas = $canvasQuery.data?.canvas.spec;
 
-  $: ({
-    items = [],
-    columns,
-    gap,
-  } = canvas || { items: [], columns: 24, gap: 2 });
+  $: ({ items = [] } = canvas || { items: [], columns: 24, gap: 2 });
 </script>
 
-<CanvasDashboardEmbed {canvasName} {columns} {items} {gap} />
+<CanvasDashboardEmbed {columns} {items} {gap} />
diff --git a/web-admin/src/routes/[organization]/[project]/-/dashboards/[dashboard]/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/dashboards/[dashboard]/+page.svelte
index 8beae7c7d86..eb75686caef 100644
--- a/web-admin/src/routes/[organization]/[project]/-/dashboards/[dashboard]/+page.svelte
+++ b/web-admin/src/routes/[organization]/[project]/-/dashboards/[dashboard]/+page.svelte
@@ -14,11 +14,10 @@
 
   $: canvas = $canvasQuery.data?.canvas.spec;
 
-  $: ({
-    items = [],
-    columns,
-    gap,
-  } = canvas || { items: [], columns: 24, gap: 2 });
+  // TODO: Remove later
+  let columns = 20;
+  let gap = 1;
+  $: ({ items = [] } = canvas || { items: [], columns: 24, gap: 2 });
 </script>
 
-<CanvasDashboardEmbed {canvasName} {columns} {items} {gap} />
+<CanvasDashboardEmbed {columns} {items} {gap} />
diff --git a/web-common/package.json b/web-common/package.json
index 774d9cc5dbe..cf756eca95c 100644
--- a/web-common/package.json
+++ b/web-common/package.json
@@ -6,7 +6,7 @@
     "lint": "prettier --check . && eslint .",
     "format": "prettier --write .",
     "generate:runtime-client": "orval && tsx src/runtime-client/add-signal-argument.ts src/runtime-client/gen/query-service/query-service.ts src/runtime-client/gen/runtime-service/runtime-service.ts",
-    "generate:template-schema": "ts-json-schema-generator -p src/features/templates/types.ts -t TemplateSpec -o ../runtime/compilers/rillv1/data/component-template-v1.json",
+    "generate:template-schema": "ts-json-schema-generator --path 'src/features/canvas/components/types.ts' --type TemplateSpec -o ../runtime/compilers/rillv1/data/component-template-v1.json",
     "test": "vitest run",
     "coverage": "vitest run --coverage",
     "test:watch": "vitest",
diff --git a/web-common/src/components/chip/core/Chip.svelte b/web-common/src/components/chip/core/Chip.svelte
index 4bec61da5d2..52109ae3415 100644
--- a/web-common/src/components/chip/core/Chip.svelte
+++ b/web-common/src/components/chip/core/Chip.svelte
@@ -1,12 +1,12 @@
 <script lang="ts">
   import { builderActions, getAttrs, type Builder } from "bits-ui";
   import { createEventDispatcher, getContext } from "svelte";
-  import { slideRight } from "../../../lib/transitions";
   import type { Writable } from "svelte/store";
-  import Tooltip from "../../tooltip/Tooltip.svelte";
+  import { slideRight } from "../../../lib/transitions";
   import CancelCircle from "../../icons/CancelCircle.svelte";
-  import TooltipContent from "../../tooltip/TooltipContent.svelte";
   import CaretDownIcon from "../../icons/CaretDownIcon.svelte";
+  import Tooltip from "../../tooltip/Tooltip.svelte";
+  import TooltipContent from "../../tooltip/TooltipContent.svelte";
 
   export let removable = false;
   export let active = false;
@@ -15,6 +15,7 @@
   export let exclude = false;
   export let grab = false;
   export let compact = false;
+  export let fullWidth = false;
   export let builders: Builder[] = [];
   export let caret = builders.length > 0;
   export let slideDuration = 150;
@@ -44,6 +45,7 @@
     class:grab
     class:exclude
     class:compact
+    class:fullWidth
     class:pointer-events-none={readOnly && !allowPointerEvents}
     aria-label={label}
     {...getAttrs(builders)}
@@ -78,7 +80,7 @@
         on:click
         on:mousedown
         aria-label={label}
-        class="text-inherit w-full select-none flex items-center gap-x-1 px-0.5"
+        class="text-inherit w-full select-none flex items-center justify-between gap-x-1 px-0.5"
       >
         <slot name="body" />
 
@@ -169,4 +171,8 @@
   .compact {
     @apply py-0;
   }
+
+  .fullWidth {
+    @apply w-full;
+  }
 </style>
diff --git a/web-common/src/components/color-picker/ColorInput.svelte b/web-common/src/components/color-picker/ColorInput.svelte
index 2a35b82866a..4f40a4a1b71 100644
--- a/web-common/src/components/color-picker/ColorInput.svelte
+++ b/web-common/src/components/color-picker/ColorInput.svelte
@@ -1,12 +1,13 @@
 <script lang="ts">
   import * as Popover from "@rilldata/web-common/components/popover";
-  import ColorSlider from "./ColorSlider.svelte";
   import InputLabel from "../forms/InputLabel.svelte";
+  import ColorSlider from "./ColorSlider.svelte";
 
   export let stringColor: string | undefined;
   export let label: string;
   export let disabled = false;
   export let onChange: (color: string) => void;
+  export let small = false;
 
   let open = false;
 
@@ -184,6 +185,7 @@
 
 <div
   class="color-wrapper"
+  class:small
   class:pointer-events-none={disabled}
   class:bg-gray-50={disabled}
   class:text-gray-400={disabled}
@@ -198,7 +200,7 @@
       />
     </Popover.Trigger>
 
-    <Popover.Content class="w-[270px]  space-y-2" align="start" sideOffset={10}>
+    <Popover.Content class="w-[270px] space-y-2" align="start" sideOffset={10}>
       <div class="space-y-1">
         <InputLabel label="Hue" id="hue" />
         <ColorSlider
@@ -229,6 +231,7 @@
   </Popover.Root>
 
   <input
+    class:small
     bind:value={stringColor}
     {disabled}
     on:keydown={(e) => {
@@ -243,7 +246,7 @@
     }}
   />
 
-  <p class:text-gray-500={!disabled}>{label}</p>
+  <p class:small class:text-gray-500={!disabled}>{label}</p>
 </div>
 
 <style lang="postcss">
@@ -258,6 +261,10 @@
     @apply flex gap-x-3;
   }
 
+  .color-wrapper.small {
+    @apply h-6 text-xs;
+  }
+
   .color-wrapper:focus-within {
     @apply border-primary-500 ring-2 ring-primary-100;
   }
@@ -266,8 +273,16 @@
     @apply text-sm;
   }
 
+  p.small {
+    @apply text-xs;
+  }
+
   input {
     @apply w-full text-sm;
     @apply outline-none border-0 bg-transparent;
   }
+
+  input.small {
+    @apply text-xs;
+  }
 </style>
diff --git a/web-common/src/components/forms/FieldSwitcher.svelte b/web-common/src/components/forms/FieldSwitcher.svelte
index 7ec949ec6e5..7801c3e5c3c 100644
--- a/web-common/src/components/forms/FieldSwitcher.svelte
+++ b/web-common/src/components/forms/FieldSwitcher.svelte
@@ -2,9 +2,10 @@
   export let fields: string[];
   export let selected: number = -1;
   export let onClick: (i: number, value: string) => void = () => {};
+  export let small = false;
 </script>
 
-<div class="option-wrapper">
+<div class:small class="option-wrapper">
   {#each fields as field, i (field)}
     <button
       on:click={() => onClick(i, field)}
@@ -29,6 +30,10 @@
     @apply flex h-6 text-sm w-fit mb-1 rounded-[2px];
   }
 
+  .option-wrapper.small {
+    @apply h-5 text-xs;
+  }
+
   .option-wrapper > .selected {
     @apply border-primary-500 z-50 text-primary-500;
   }
diff --git a/web-common/src/components/forms/Input.svelte b/web-common/src/components/forms/Input.svelte
index 00bafa8b9d7..2d986778647 100644
--- a/web-common/src/components/forms/Input.svelte
+++ b/web-common/src/components/forms/Input.svelte
@@ -8,7 +8,7 @@
 
   const voidFunction = () => {};
 
-  export let value: string | undefined;
+  export let value: number | string | undefined;
   export let id = "";
   export let label = "";
   export let description = "";
@@ -23,6 +23,7 @@
   export let truncate = false;
   export let width: string = "100%";
   export let size: "sm" | "md" | "lg" = "lg";
+  export let labelGap = 1;
   export let selected: number = -1;
   export let full = false;
   export let multiline = false;
@@ -59,6 +60,7 @@
     },
   ) => void = voidFunction;
   export let onEscape: () => void = voidFunction;
+  export let inputType: "text" | "number" = "text";
   export let onFieldSwitch: (i: number, value: string) => void = voidFunction;
 
   let hitEnter = false;
@@ -67,7 +69,7 @@
   let selectElement: HTMLButtonElement | undefined;
   let focus = false;
 
-  $: type = secret && !showPassword ? "password" : "text";
+  $: type = secret && !showPassword ? "password" : inputType;
 
   onMount(() => {
     if (claimFocusOnMount) {
@@ -107,7 +109,7 @@
 </script>
 
 <div
-  class="component-wrapper {additionalClass}"
+  class="component-wrapper gap-y-{labelGap} {additionalClass}"
   class:w-full={full}
   style:width
 >
@@ -118,6 +120,7 @@
       {id}
       {hint}
       {link}
+      small={size === "sm"}
       capitalize={capitalizeLabel}
     >
       <slot name="mode-switch" slot="mode-switch" />
@@ -140,7 +143,7 @@
         </span>
       {/if}
 
-      {#if multiline}
+      {#if multiline && typeof value !== "number"}
         <div
           {id}
           contenteditable
@@ -158,7 +161,7 @@
         />
       {:else}
         <input
-          title={value}
+          title={label}
           {id}
           {type}
           {placeholder}
@@ -194,7 +197,7 @@
         </button>
       {/if}
     </div>
-  {:else}
+  {:else if typeof value !== "number"}
     <Select
       {disabled}
       {enableSearch}
@@ -207,7 +210,8 @@
       bind:value
       {options}
       {onChange}
-      fontSize={14}
+      {size}
+      fontSize={size === "sm" ? 12 : 14}
       {truncate}
       placeholder={disabled ? disabledMessage : placeholder}
     />
@@ -234,11 +238,12 @@
 
 <style lang="postcss">
   .component-wrapper {
-    @apply flex  flex-col gap-y-1 h-fit justify-center;
+    @apply flex  flex-col h-fit justify-center;
   }
 
   .sm {
     height: 24px;
+    font-size: 12px;
   }
 
   .md {
diff --git a/web-common/src/components/forms/InputLabel.svelte b/web-common/src/components/forms/InputLabel.svelte
index 9598e959ef5..148bd8874ab 100644
--- a/web-common/src/components/forms/InputLabel.svelte
+++ b/web-common/src/components/forms/InputLabel.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
+  import InfoCircle from "../icons/InfoCircle.svelte";
   import Tooltip from "../tooltip/Tooltip.svelte";
   import TooltipContent from "../tooltip/TooltipContent.svelte";
-  import InfoCircle from "../icons/InfoCircle.svelte";
 
   export let id: string;
   export let label: string;
@@ -9,10 +9,15 @@
   export let optional = false;
   export let capitalize = true;
   export let link: string | undefined = undefined;
+  export let small = false;
 </script>
 
 <div class="label-wrapper">
-  <label for={id} class="line-clamp-1" class:capitalize>
+  <label
+    for={id}
+    class="line-clamp-1 {small ? 'text-xs' : 'text-sm'}"
+    class:capitalize
+  >
     {label}
     {#if optional}
       <span class="text-gray-500 text-[12px] font-normal">(optional)</span>
@@ -41,6 +46,6 @@
   }
 
   label {
-    @apply text-sm font-medium text-gray-800;
+    @apply font-medium text-gray-800;
   }
 </style>
diff --git a/web-common/src/components/forms/Select.svelte b/web-common/src/components/forms/Select.svelte
index a5c870c7915..aa2111f88d1 100644
--- a/web-common/src/components/forms/Select.svelte
+++ b/web-common/src/components/forms/Select.svelte
@@ -1,8 +1,8 @@
 <script lang="ts">
-  import { InfoIcon } from "lucide-svelte";
-  import { createEventDispatcher } from "svelte";
   import * as Select from "@rilldata/web-common/components/select";
   import * as Tooltip from "@rilldata/web-common/components/tooltip-v2";
+  import { InfoIcon } from "lucide-svelte";
+  import { createEventDispatcher } from "svelte";
   import DataTypeIcon from "../data-types/DataTypeIcon.svelte";
   import Search from "../search/Search.svelte";
 
@@ -12,6 +12,7 @@
   export let id: string;
   export let label: string = "";
   export let lockTooltip: string = "";
+  export let size: "sm" | "md" | "lg" = "lg";
   export let options: {
     value: string;
     label: string;
@@ -87,8 +88,8 @@
       {lockable}
       {lockTooltip}
       bind:el={selectElement}
-      class="flex px-3 gap-x-2 max-w-full {width &&
-        `w-[${width}px]`} {ringFocus &&
+      class="flex px-3 gap-x-2 max-w-full {size === 'sm' ? 'h-6' : ''} {width &&
+        `w-[${width}px]`}  {ringFocus &&
         'focus:ring-2 focus:ring-primary-100'} {truncate
         ? 'break-all overflow-hidden'
         : ''}"
diff --git a/web-common/src/components/select/select-trigger.svelte b/web-common/src/components/select/select-trigger.svelte
index fbe5f55c97a..a573fd0b1b1 100644
--- a/web-common/src/components/select/select-trigger.svelte
+++ b/web-common/src/components/select/select-trigger.svelte
@@ -1,8 +1,8 @@
 <script lang="ts">
-  import { Select as SelectPrimitive } from "bits-ui";
-  import CaretDownIcon from "../icons/CaretDownIcon.svelte";
   import { cn } from "@rilldata/web-common/lib/shadcn";
+  import { Select as SelectPrimitive } from "bits-ui";
   import { Lock, UnlockIcon } from "lucide-svelte";
+  import CaretDownIcon from "../icons/CaretDownIcon.svelte";
   import Tooltip from "../tooltip/Tooltip.svelte";
   import TooltipContent from "../tooltip/TooltipContent.svelte";
 
diff --git a/web-common/src/features/canvas-components/render/VegaLiteRenderer.svelte b/web-common/src/components/vega/VegaLiteRenderer.svelte
similarity index 93%
rename from web-common/src/features/canvas-components/render/VegaLiteRenderer.svelte
rename to web-common/src/components/vega/VegaLiteRenderer.svelte
index 510bfcbdeaf..6c3c638cdb8 100644
--- a/web-common/src/features/canvas-components/render/VegaLiteRenderer.svelte
+++ b/web-common/src/components/vega/VegaLiteRenderer.svelte
@@ -1,16 +1,16 @@
 <script lang="ts">
   import CancelCircle from "@rilldata/web-common/components/icons/CancelCircle.svelte";
-  import { getRillTheme } from "@rilldata/web-common/features/canvas-components/render/vega-config";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { get } from "svelte/store";
   import {
+    type EmbedOptions,
     type SignalListeners,
     VegaLite,
     type View,
     type VisualizationSpec,
-    type EmbedOptions,
   } from "svelte-vega";
-  import type { ExpressionFunction, VLTooltipFormatter } from "../types";
+  import { get } from "svelte/store";
+  import type { ExpressionFunction, VLTooltipFormatter } from "./types";
+  import { getRillTheme } from "./vega-config";
   import { VegaLiteTooltipHandler } from "./vega-tooltip";
 
   export let data: Record<string, unknown> = {};
@@ -27,7 +27,7 @@
   let jwt = get(runtime).jwt;
 
   $: width = contentRect.width;
-  $: height = contentRect.height * 0.95 - 80;
+  $: height = contentRect.height - 10;
 
   $: if (viewVL && tooltipFormatter) {
     const handler = new VegaLiteTooltipHandler(tooltipFormatter);
@@ -64,8 +64,7 @@
 <div
   bind:contentRect
   class:bg-white={canvasDashboard}
-  class:px-4={canvasDashboard}
-  class:pb-2={canvasDashboard}
+  class:px-2={canvasDashboard}
   class="overflow-hidden size-full flex flex-col items-center justify-center"
 >
   {#if error}
diff --git a/web-common/src/features/canvas-components/render/VegaRenderer.svelte b/web-common/src/components/vega/VegaRenderer.svelte
similarity index 99%
rename from web-common/src/features/canvas-components/render/VegaRenderer.svelte
rename to web-common/src/components/vega/VegaRenderer.svelte
index 0645175dbc7..f8d5756cca2 100644
--- a/web-common/src/features/canvas-components/render/VegaRenderer.svelte
+++ b/web-common/src/components/vega/VegaRenderer.svelte
@@ -1,18 +1,18 @@
 <script lang="ts">
   import CancelCircle from "@rilldata/web-common/components/icons/CancelCircle.svelte";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { get } from "svelte/store";
+  import { onDestroy } from "svelte";
   import {
+    type EmbedOptions,
     type SignalListeners,
     Vega,
     type View,
     type VisualizationSpec,
-    type EmbedOptions,
   } from "svelte-vega";
-  import type { ExpressionFunction, VLTooltipFormatter } from "../types";
-  import { VegaLiteTooltipHandler } from "./vega-tooltip";
-  import { onDestroy } from "svelte";
+  import { get } from "svelte/store";
+  import type { ExpressionFunction, VLTooltipFormatter } from "./types";
   import { getRillTheme } from "./vega-config";
+  import { VegaLiteTooltipHandler } from "./vega-tooltip";
 
   export let data: Record<string, unknown> = {};
   export let spec: VisualizationSpec;
diff --git a/web-common/src/features/canvas-components/types.ts b/web-common/src/components/vega/types.ts
similarity index 93%
rename from web-common/src/features/canvas-components/types.ts
rename to web-common/src/components/vega/types.ts
index 1415c54030c..a0e2ac311fe 100644
--- a/web-common/src/features/canvas-components/types.ts
+++ b/web-common/src/components/vega/types.ts
@@ -1,5 +1,6 @@
 import { TDDChart } from "@rilldata/web-common/features/dashboards/time-dimension-details/types";
 
+// TODO: Consolidate with Canvas components types
 /**
  * Type definitions for common chart types supported by Vega
  */
diff --git a/web-common/src/features/canvas-components/render/vega-config.ts b/web-common/src/components/vega/vega-config.ts
similarity index 98%
rename from web-common/src/features/canvas-components/render/vega-config.ts
rename to web-common/src/components/vega/vega-config.ts
index 27935d3841e..d3c3b566eb0 100644
--- a/web-common/src/features/canvas-components/render/vega-config.ts
+++ b/web-common/src/components/vega/vega-config.ts
@@ -51,6 +51,7 @@ export const getRillTheme: (isCustomDashboard: boolean) => Config = (
   shape: { stroke: defaultMarkColor },
   symbol: { fill: defaultMarkColor },
 
+  legend: { orient: "top" },
   axisY: {
     orient: "right",
     gridColor: gridColor,
diff --git a/web-common/src/features/canvas-components/render/vega-signals.ts b/web-common/src/components/vega/vega-signals.ts
similarity index 100%
rename from web-common/src/features/canvas-components/render/vega-signals.ts
rename to web-common/src/components/vega/vega-signals.ts
diff --git a/web-common/src/features/canvas-components/render/vega-tooltip.ts b/web-common/src/components/vega/vega-tooltip.ts
similarity index 96%
rename from web-common/src/features/canvas-components/render/vega-tooltip.ts
rename to web-common/src/components/vega/vega-tooltip.ts
index 48c8dd72ed5..c754dea8447 100644
--- a/web-common/src/features/canvas-components/render/vega-tooltip.ts
+++ b/web-common/src/components/vega/vega-tooltip.ts
@@ -1,13 +1,13 @@
-import {
-  mouseLocationToBoundingRect,
-  placeElement,
-} from "@rilldata/web-common/lib/place-element";
 import type {
   Alignment,
   Location,
 } from "@rilldata/web-common/lib/place-element";
+import {
+  mouseLocationToBoundingRect,
+  placeElement,
+} from "@rilldata/web-common/lib/place-element";
 import type { View } from "svelte-vega";
-import type { VLTooltipFormatter } from "../types";
+import type { VLTooltipFormatter } from "./types";
 
 const TOOLTIP_ID = "rill-vg-tooltip";
 
diff --git a/web-common/src/features/canvas-components/ComponentDataDisplay.svelte b/web-common/src/features/canvas-components/ComponentDataDisplay.svelte
deleted file mode 100644
index 49563ca3e57..00000000000
--- a/web-common/src/features/canvas-components/ComponentDataDisplay.svelte
+++ /dev/null
@@ -1,69 +0,0 @@
-<script lang="ts">
-  import CancelCircle from "@rilldata/web-common/components/icons/CancelCircle.svelte";
-  import PreviewTable from "@rilldata/web-common/components/preview-table/PreviewTable.svelte";
-  import { useVariableInputParams } from "@rilldata/web-common/features/canvas/variables-store";
-  import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
-  import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
-  import {
-    createQueryServiceResolveComponent,
-    type V1ComponentSpecResolverProperties,
-    type V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { getContext } from "svelte";
-
-  export let componentName: string;
-  export let tablePercentage = 0.45;
-  export let resolverProperties: V1ComponentSpecResolverProperties | undefined;
-  export let input: V1ComponentVariable[] | undefined;
-
-  const canvasName = getContext("rill::canvas:name") as string;
-
-  $: ({ instanceId } = $runtime);
-
-  $: inputVariableParams = useVariableInputParams(canvasName, input);
-
-  $: componentDataQuery = resolverProperties
-    ? createQueryServiceResolveComponent(instanceId, componentName, {
-        args: $inputVariableParams,
-      })
-    : null;
-
-  $: componentData = $componentDataQuery?.data?.data;
-  $: isFetching = $componentDataQuery?.isFetching ?? false;
-  $: errorMessage = $componentDataQuery?.error?.response?.data?.message;
-</script>
-
-{#if resolverProperties}
-  <div
-    class="w-full h-48 relative flex-none border rounded-[2px] overflow-hidden"
-    style:height="{tablePercentage * 100}%"
-  >
-    {#if isFetching}
-      <div class="flex flex-col gap-y-2 size-full justify-center items-center">
-        <Spinner size="2em" status={EntityStatus.Running} />
-        <div>Loading component data</div>
-      </div>
-    {:else if errorMessage}
-      <div class="size-full flex flex-col items-center justify-center">
-        <div class="flex items-center gap-x-2 text-lg">
-          <CancelCircle /> Error fetching data from SQL
-        </div>
-        <div class="text-sm">{errorMessage}</div>
-      </div>
-    {:else if componentData}
-      <PreviewTable
-        rows={componentData}
-        name={componentName}
-        columnNames={Object.keys(componentData[0]).map((key) => ({
-          type: "VARCHAR",
-          name: key,
-        }))}
-      />
-    {:else}
-      <p class="text-lg size-full grid place-content-center">
-        Update or add SQL to view data
-      </p>
-    {/if}
-  </div>
-{/if}
diff --git a/web-common/src/features/canvas-components/ComponentStatusDisplay.svelte b/web-common/src/features/canvas-components/ComponentStatusDisplay.svelte
deleted file mode 100644
index 70f942725d4..00000000000
--- a/web-common/src/features/canvas-components/ComponentStatusDisplay.svelte
+++ /dev/null
@@ -1,47 +0,0 @@
-<script lang="ts">
-  import CancelCircle from "@rilldata/web-common/components/icons/CancelCircle.svelte";
-  import {
-    chartPromptsStore,
-    ChartPromptStatus,
-  } from "@rilldata/web-common/features/canvas-components/prompt/chartPrompt";
-  import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
-  import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
-
-  export let componentName: string;
-  export let isFetching: boolean;
-
-  $: chartPrompt = chartPromptsStore.getStatusForChart(componentName);
-</script>
-
-<!-- TODO: handle prompt error -->
-<div class="size-full flex items-center justify-center">
-  {#if $chartPrompt && $chartPrompt?.status === ChartPromptStatus.Error}
-    <div class="flex flex-col gap-y-2 text-red-600 items-center justify-center">
-      <CancelCircle size="16px" />
-      <div class="flex flex-col gap-y-2">
-        <div>Failed to generate chart using AI</div>
-        <div>Using prompt: "{$chartPrompt.prompt}"</div>
-        <div>{$chartPrompt.error}</div>
-      </div>
-    </div>
-  {:else if $chartPrompt && $chartPrompt.status !== ChartPromptStatus.Idle}
-    <div class="flex flex-col gap-y-2 items-center justify-center">
-      <Spinner size="16px" status={EntityStatus.Running} />
-      <div class="flex flex-col gap-y-2">
-        <div>
-          Generating {$chartPrompt.status === ChartPromptStatus.GeneratingData
-            ? "data"
-            : "chart spec"} using AI
-        </div>
-        <div>Using prompt: "{$chartPrompt.prompt}"</div>
-      </div>
-    </div>
-  {:else if isFetching}
-    <div class="flex flex-col gap-y-2 items-center justify-center">
-      <Spinner size="16px" status={EntityStatus.Running} />
-      <div>Loading chart data</div>
-    </div>
-  {:else}
-    <slot />
-  {/if}
-</div>
diff --git a/web-common/src/features/canvas-components/ComponentsHeader.svelte b/web-common/src/features/canvas-components/ComponentsHeader.svelte
deleted file mode 100644
index f41978fa9e9..00000000000
--- a/web-common/src/features/canvas-components/ComponentsHeader.svelte
+++ /dev/null
@@ -1,58 +0,0 @@
-<script lang="ts">
-  import { goto } from "$app/navigation";
-  import { Button } from "@rilldata/web-common/components/button";
-  import PanelCTA from "@rilldata/web-common/components/panel/PanelCTA.svelte";
-  import GenerateVegaSpecPrompt from "@rilldata/web-common/features/canvas-components/prompt/GenerateVegaSpecPrompt.svelte";
-  import {
-    extractFileName,
-    splitFolderAndFileName,
-  } from "@rilldata/web-common/features/entity-management/file-path-utils";
-  import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
-  import { handleEntityRename } from "@rilldata/web-common/features/entity-management/ui-actions";
-  import { WorkspaceHeader } from "@rilldata/web-common/layout/workspace";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-
-  export let filePath: string;
-  export let hasUnsavedChanges: boolean;
-
-  let fileName: string;
-  $: [, fileName] = splitFolderAndFileName(filePath);
-  $: ({ instanceId } = $runtime);
-  $: componentName = extractFileName(filePath);
-
-  async function handleNameChange(newTitle: string) {
-    const newRoute = await handleEntityRename(
-      instanceId,
-      newTitle,
-      filePath,
-      componentName,
-    );
-
-    if (newRoute) await goto(newRoute);
-  }
-
-  let generateOpen = false;
-</script>
-
-<WorkspaceHeader
-  resourceKind={ResourceKind.Component}
-  onTitleChange={handleNameChange}
-  titleInput={fileName}
-  {hasUnsavedChanges}
-  {filePath}
-  showInspectorToggle={false}
->
-  <svelte:fragment slot="cta">
-    <PanelCTA side="right">
-      <Button type="secondary" on:click={() => (generateOpen = true)}
-        >Generate using AI</Button
-      >
-    </PanelCTA>
-  </svelte:fragment>
-</WorkspaceHeader>
-
-<GenerateVegaSpecPrompt
-  bind:open={generateOpen}
-  chart={componentName}
-  {filePath}
-/>
diff --git a/web-common/src/features/canvas-components/chartYaml.ts b/web-common/src/features/canvas-components/chartYaml.ts
deleted file mode 100644
index 2510087a2ca..00000000000
--- a/web-common/src/features/canvas-components/chartYaml.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import type { V1ComponentSpec } from "@rilldata/web-common/runtime-client";
-import { Document, parse } from "yaml";
-
-export function getChartYaml(
-  vegaLite: string | undefined,
-  resolver: string | undefined,
-  resolverProperties: Record<string, any> | undefined,
-) {
-  const doc = new Document();
-  doc.commentBefore = ` Component YAML\n Reference documentation: https://docs.rilldata.com/reference/project-files/components`;
-  doc.set("type", "component");
-
-  // TODO: more fields from resolverProperties
-  if (resolver === "sql") {
-    doc.set("data", { sql: (resolverProperties?.sql as string) ?? "" });
-  } else if (resolver === "metrics_sql") {
-    doc.set("data", { metrics_sql: (resolverProperties?.sql as string) ?? "" });
-  } else if (resolver === "api") {
-    doc.set("data", { api: (resolverProperties?.api as string) ?? "" });
-  }
-
-  doc.set("vega_lite", vegaLite ?? "{}");
-
-  return doc.toString();
-}
-
-export function parseChartYaml(chartContent: string): V1ComponentSpec {
-  const chartYaml = parse(chartContent);
-
-  let resolver = "";
-  const resolverProperties: Record<string, string> = {};
-
-  if (chartYaml.data?.sql) {
-    resolver = "sql";
-    resolverProperties.sql = chartYaml.data?.sql;
-  } else if (chartYaml.data?.metrics_sql) {
-    resolver = "metrics_sql";
-    resolverProperties.sql = chartYaml.data?.metrics_sql;
-  } else if (chartYaml.data?.api) {
-    resolver = "api";
-    resolverProperties.api = chartYaml.data?.api;
-  }
-
-  return {
-    displayName: chartYaml.title,
-    renderer: "chart",
-    rendererProperties: {
-      spec: chartYaml.vegaLiteSpec,
-    },
-    resolver,
-    resolverProperties,
-  };
-}
diff --git a/web-common/src/features/canvas-components/editor/ComponentsEditor.svelte b/web-common/src/features/canvas-components/editor/ComponentsEditor.svelte
deleted file mode 100644
index 94c8a0b9edc..00000000000
--- a/web-common/src/features/canvas-components/editor/ComponentsEditor.svelte
+++ /dev/null
@@ -1,40 +0,0 @@
-<script lang="ts">
-  import type { EditorView } from "@codemirror/view";
-  import { customYAMLwithJSONandSQL } from "@rilldata/web-common/components/editor/presets/yamlWithJsonAndSql";
-  import ComponentsEditorContainer from "@rilldata/web-common/features/canvas-components/editor/ComponentsEditorContainer.svelte";
-  import { fileArtifacts } from "@rilldata/web-common/features/entity-management/file-artifacts";
-  import { mapParseErrorsToLines } from "@rilldata/web-common/features/metrics-views/errors";
-  import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import Editor from "../../editor/Editor.svelte";
-
-  export let filePath: string;
-
-  let editor: EditorView;
-
-  $: ({ instanceId } = $runtime);
-
-  $: fileArtifact = fileArtifacts.getFileArtifact(filePath);
-
-  $: ({ autoSave, remoteContent } = fileArtifact);
-
-  $: allErrors = fileArtifact.getAllErrors(queryClient, instanceId);
-
-  $: lineBasedRuntimeErrors = mapParseErrorsToLines(
-    $allErrors,
-    $remoteContent ?? "",
-  );
-  /** display the main error (the first in this array) at the bottom */
-  $: mainError = lineBasedRuntimeErrors?.at(0);
-</script>
-
-<ComponentsEditorContainer
-  error={$remoteContent?.length ? mainError : undefined}
->
-  <Editor
-    {fileArtifact}
-    extensions={[customYAMLwithJSONandSQL]}
-    bind:editor
-    bind:autoSave={$autoSave}
-  />
-</ComponentsEditorContainer>
diff --git a/web-common/src/features/canvas-components/editor/ComponentsEditorContainer.svelte b/web-common/src/features/canvas-components/editor/ComponentsEditorContainer.svelte
deleted file mode 100644
index c80ea17fbca..00000000000
--- a/web-common/src/features/canvas-components/editor/ComponentsEditorContainer.svelte
+++ /dev/null
@@ -1,38 +0,0 @@
-<!-- @component 
-The full size container is meant to be embedded in a Workspace.svelte component.
-It will show an error message if passed in.
--->
-
-<script lang="ts">
-  import type { LineStatus } from "@rilldata/web-common/components/editor/line-status/state";
-  import CancelCircle from "@rilldata/web-common/components/icons/CancelCircle.svelte";
-  import { LIST_SLIDE_DURATION } from "@rilldata/web-common/layout/config";
-  import type { V1ParseError } from "@rilldata/web-common/runtime-client";
-  import { slide } from "svelte/transition";
-
-  export let error: LineStatus | V1ParseError | undefined = undefined;
-</script>
-
-<div
-  class="flex flex-col size-full bg-white border rounded-[2px] overflow-hidden"
->
-  <div
-    class="overflow-auto size-full border-white"
-    class:border-b-hidden={error}
-    class:border-red-500={error}
-  >
-    <slot />
-  </div>
-
-  {#if error}
-    <div
-      role="status"
-      transition:slide={{ duration: LIST_SLIDE_DURATION }}
-      class="m-2 editor-error ui-editor-text-error ui-editor-bg-error border border-red-500 border-l-4 px-2 py-2 max-h-72"
-    >
-      <div class="flex gap-x-2 items-center">
-        <CancelCircle />{error.message}
-      </div>
-    </div>
-  {/if}
-</div>
diff --git a/web-common/src/features/canvas-components/prompt/ChartPromptHistoryDisplay.svelte b/web-common/src/features/canvas-components/prompt/ChartPromptHistoryDisplay.svelte
deleted file mode 100644
index 608fe0db980..00000000000
--- a/web-common/src/features/canvas-components/prompt/ChartPromptHistoryDisplay.svelte
+++ /dev/null
@@ -1,31 +0,0 @@
-<script lang="ts">
-  import { Button } from "@rilldata/web-common/components/button";
-  import RefreshIcon from "@rilldata/web-common/components/icons/RefreshIcon.svelte";
-  import { chartPromptsStore } from "@rilldata/web-common/features/canvas-components/prompt/chartPrompt";
-  import { createEventDispatcher } from "svelte";
-
-  export let entityName: string;
-
-  const dispatch = createEventDispatcher();
-
-  $: chartPromptHistory = chartPromptsStore.getHistoryForEntity(entityName);
-</script>
-
-{#if $chartPromptHistory.length}
-  <div class="flex flex-col py-2">
-    <div class="text-sm">Prompt history:</div>
-    {#each $chartPromptHistory as history}
-      <div class="flex flex-row items-center text-xs">
-        <Button
-          type="secondary"
-          compact
-          noStroke
-          on:click={() => dispatch("reuse-prompt", history.prompt)}
-        >
-          <RefreshIcon size="14px" />
-        </Button>
-        <span>{history.prompt}</span>
-      </div>
-    {/each}
-  </div>
-{/if}
diff --git a/web-common/src/features/canvas-components/prompt/GenerateChartYAMLPrompt.svelte b/web-common/src/features/canvas-components/prompt/GenerateChartYAMLPrompt.svelte
deleted file mode 100644
index e00a9af5abd..00000000000
--- a/web-common/src/features/canvas-components/prompt/GenerateChartYAMLPrompt.svelte
+++ /dev/null
@@ -1,55 +0,0 @@
-<script lang="ts">
-  import { Button } from "@rilldata/web-common/components/button";
-  import * as Dialog from "@rilldata/web-common/components/dialog-v2";
-  import Input from "@rilldata/web-common/components/forms/Input.svelte";
-  import ChartPromptHistoryDisplay from "@rilldata/web-common/features/canvas-components/prompt/ChartPromptHistoryDisplay.svelte";
-  import { createFullChartGenerator } from "@rilldata/web-common/features/canvas-components/prompt/generateChart";
-  import { useAllFileNames } from "@rilldata/web-common/features/entity-management/file-selectors";
-  import { getName } from "@rilldata/web-common/features/entity-management/name-utils";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
-
-  export let open: boolean;
-  export let table: string = "";
-  export let connector: string = "";
-  export let metricsView: string = "";
-
-  $: ({ instanceId } = $runtime);
-
-  let prompt: string;
-
-  $: chartFileNames = useAllFileNames(queryClient, instanceId);
-  $: generateVegaConfig = createFullChartGenerator(instanceId);
-
-  async function createVegaConfig() {
-    open = false;
-    await generateVegaConfig(
-      prompt,
-      {
-        table,
-        connector,
-        metricsView,
-      },
-      getName(`${table || metricsView}_chart`, $chartFileNames.data ?? []),
-    );
-  }
-</script>
-
-<Dialog.Root bind:open>
-  <Dialog.Content>
-    <Dialog.Title>
-      Generate component yaml for "{table || metricsView}" using AI</Dialog.Title
-    >
-
-    <Input bind:value={prompt} label="Prompt" />
-    <ChartPromptHistoryDisplay
-      entityName={table || metricsView}
-      on:reuse-prompt={({ detail }) => {
-        prompt = detail;
-      }}
-    />
-    <div class="ml-auto">
-      <Button on:click={createVegaConfig} large type="primary">Generate</Button>
-    </div>
-  </Dialog.Content>
-</Dialog.Root>
diff --git a/web-common/src/features/canvas-components/prompt/GenerateVegaSpecPrompt.svelte b/web-common/src/features/canvas-components/prompt/GenerateVegaSpecPrompt.svelte
deleted file mode 100644
index 4da16ab0db9..00000000000
--- a/web-common/src/features/canvas-components/prompt/GenerateVegaSpecPrompt.svelte
+++ /dev/null
@@ -1,40 +0,0 @@
-<script lang="ts">
-  import { Button } from "@rilldata/web-common/components/button";
-  import * as Dialog from "@rilldata/web-common/components/dialog-v2";
-  import Input from "@rilldata/web-common/components/forms/Input.svelte";
-  import ChartPromptHistoryDisplay from "@rilldata/web-common/features/canvas-components/prompt/ChartPromptHistoryDisplay.svelte";
-  import { createChartGenerator } from "@rilldata/web-common/features/canvas-components/prompt/generateChart";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-
-  export let open: boolean;
-  export let chart: string;
-  export let filePath: string;
-
-  let prompt: string;
-
-  $: ({ instanceId } = $runtime);
-
-  $: generateVegaConfig = createChartGenerator(instanceId, chart, filePath);
-
-  async function createVegaConfig() {
-    open = false;
-    await generateVegaConfig(prompt);
-  }
-</script>
-
-<Dialog.Root bind:open>
-  <Dialog.Content>
-    <Dialog.Title>Generate vega config using AI</Dialog.Title>
-
-    <Input bind:value={prompt} label="Prompt" />
-    <ChartPromptHistoryDisplay
-      entityName={chart}
-      on:reuse-prompt={({ detail }) => {
-        prompt = detail;
-      }}
-    />
-    <div class="ml-auto">
-      <Button on:click={createVegaConfig} large type="primary">Generate</Button>
-    </div>
-  </Dialog.Content>
-</Dialog.Root>
diff --git a/web-common/src/features/canvas-components/prompt/chartPrompt.ts b/web-common/src/features/canvas-components/prompt/chartPrompt.ts
deleted file mode 100644
index 87f5ee179ef..00000000000
--- a/web-common/src/features/canvas-components/prompt/chartPrompt.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import { localStorageStore } from "@rilldata/web-common/lib/store-utils";
-import { derived, get, type Readable, writable } from "svelte/store";
-
-export enum ChartPromptStatus {
-  Idle,
-  GeneratingData,
-  GeneratingChartSpec,
-  Error,
-}
-
-export type ChartPrompt = {
-  entityName: string;
-  chartName: string;
-  prompt: string;
-  time: number;
-  status: ChartPromptStatus;
-  error?: string;
-};
-
-export type ChartPromptHistory = {
-  entities: Record<string, Array<ChartPrompt>>;
-  count: number;
-};
-
-export class ChartPromptsStore {
-  private readonly history = localStorageStore<ChartPromptHistory>(
-    "chart-prompt",
-    {
-      entities: {},
-      count: 0,
-    },
-  );
-
-  private readonly chartStatus = writable<Record<string, ChartPrompt>>({});
-
-  public constructor(private readonly maxHistoryCount: number) {}
-
-  public getStatusForChart(
-    chartName: string,
-  ): Readable<ChartPrompt | undefined> {
-    return derived(this.chartStatus, (cs) => cs[chartName]);
-  }
-
-  public getHistoryForEntity(entityName: string): Readable<Array<ChartPrompt>> {
-    return derived(this.history, (h) => h.entities[entityName] ?? []);
-  }
-
-  public startPrompt(entityName: string, chartName: string, prompt: string) {
-    const chartPrompt: ChartPrompt = {
-      entityName,
-      chartName,
-      prompt,
-      time: Date.now(),
-      status:
-        entityName === chartName
-          ? ChartPromptStatus.GeneratingData
-          : ChartPromptStatus.GeneratingChartSpec,
-    };
-    this.chartStatus.update((cs) => {
-      cs[chartName] = chartPrompt;
-      return cs;
-    });
-    this.addToHistory(entityName, chartPrompt);
-  }
-
-  public updatePromptStatus(chartName: string, status: ChartPromptStatus) {
-    this.chartStatus.update((cs) => {
-      if (cs[chartName]) cs[chartName].status = status;
-      return cs;
-    });
-    this.history.update((h) => {
-      if (!h.entities[chartName]?.length) return h;
-      h.entities[chartName][0].status = status;
-
-      return h;
-    });
-  }
-
-  public setPromptError(chartName: string, error: string) {
-    this.chartStatus.update((cs) => {
-      if (cs[chartName]) {
-        cs[chartName].status = ChartPromptStatus.Error;
-        cs[chartName].error = error;
-      }
-      return cs;
-    });
-    this.history.update((h) => {
-      if (!h.entities[chartName]?.length) return h;
-      h.entities[chartName][0].status = ChartPromptStatus.Error;
-
-      return h;
-    });
-  }
-
-  private addToHistory(entityName: string, newEntry: ChartPrompt) {
-    let history = get(this.history);
-    history.entities[entityName] ??= [];
-
-    const existingPromptIdx = history.entities[entityName].findIndex(
-      (p) => p.prompt === newEntry.prompt,
-    );
-    if (existingPromptIdx >= 0) {
-      history.entities[entityName].splice(existingPromptIdx, 1);
-    }
-    history.entities[entityName].unshift(newEntry);
-
-    while (history.count >= this.maxHistoryCount) {
-      history = this.removeOldestHistoryEvent(history);
-    }
-
-    this.history.set(history);
-  }
-
-  private removeOldestHistoryEvent(history: ChartPromptHistory) {
-    let oldestPrompt: ChartPrompt | undefined;
-    let oldestEntity: string | undefined;
-
-    for (const entity in history) {
-      if (history.entities[entity].length === 0) continue;
-      const prompt =
-        history.entities[entity][history.entities[entity].length - 1];
-      if (!oldestPrompt || prompt.time < oldestPrompt.time) {
-        oldestPrompt = prompt;
-        oldestEntity = entity;
-      }
-    }
-
-    if (oldestEntity) {
-      history.entities[oldestEntity].pop();
-      history.count--;
-    }
-
-    return history;
-  }
-}
-
-export const chartPromptsStore = new ChartPromptsStore(10);
diff --git a/web-common/src/features/canvas-components/prompt/chartPromptStatus.ts b/web-common/src/features/canvas-components/prompt/chartPromptStatus.ts
deleted file mode 100644
index c6dc0195401..00000000000
--- a/web-common/src/features/canvas-components/prompt/chartPromptStatus.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { ChartPromptStatus } from "@rilldata/web-common/features/canvas-components/prompt/chartPrompt";
-import { type Readable, type Updater, writable } from "svelte/store";
-
-export type ChartPromptState = {
-  charts: Record<string, ChartPromptStatus>;
-};
-export type ChartPromptStore = Readable<ChartPromptState> &
-  ReturnType<typeof chartPromptStoreActions>;
-
-function chartPromptStoreActions(
-  update: (this: void, updater: Updater<ChartPromptState>) => void,
-) {
-  return {
-    setStatus(chartPath: string, status: ChartPromptStatus) {
-      update((s) => {
-        s.charts[chartPath] = status;
-        return s;
-      });
-    },
-
-    deleteStatus(chartPath: string) {
-      update((s) => {
-        delete s.charts[chartPath];
-        return s;
-      });
-    },
-  };
-}
-
-function createChartPromptStore(): ChartPromptStore {
-  const { subscribe, update } = writable<ChartPromptState>({
-    charts: {},
-  });
-
-  return {
-    subscribe,
-    ...chartPromptStoreActions(update),
-  };
-}
-
-export const chartPromptStore = createChartPromptStore();
diff --git a/web-common/src/features/canvas-components/prompt/generateChart.spec.ts b/web-common/src/features/canvas-components/prompt/generateChart.spec.ts
deleted file mode 100644
index 7c7b88ec22e..00000000000
--- a/web-common/src/features/canvas-components/prompt/generateChart.spec.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { getChartYaml } from "@rilldata/web-common/features/canvas-components/chartYaml";
-import { describe, expect, it } from "vitest";
-
-const VegaLiteSpec = `{
-  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
-  "description": "A simple bar chart with embedded data.",
-  "mark": "bar",
-  "encoding": {
-    "x": {"field": "time", "type": "nominal", "axis": {"labelAngle": 0}},
-    "y": {"field": "total_sales", "type": "quantitative"}
-  }
-}`;
-
-describe("getComponentYaml", () => {
-  it("multi line sql", () => {
-    expect(
-      getChartYaml(VegaLiteSpec, "sql", {
-        sql: `select * from AdBids
-where publisher is not null`,
-      }),
-    ).toEqual(`# Component YAML
-# Reference documentation: https://docs.rilldata.com/reference/project-files/components
-
-type: component
-data:
-  sql: |-
-    select * from AdBids
-    where publisher is not null
-vega_lite: |-
-${VegaLiteSpec.replace(/^/gm, "  ")}
-`);
-  });
-
-  it("multi line metrics sql", () => {
-    expect(
-      getChartYaml(VegaLiteSpec, "metrics_sql", {
-        sql: `select * from AdBids
-where publisher is not null`,
-      }),
-    ).toEqual(`# Component YAML
-# Reference documentation: https://docs.rilldata.com/reference/project-files/components
-
-type: component
-data:
-  metrics_sql: |-
-    select * from AdBids
-    where publisher is not null
-vega_lite: |-
-${VegaLiteSpec.replace(/^/gm, "  ")}
-`);
-  });
-});
diff --git a/web-common/src/features/canvas-components/prompt/generateChart.ts b/web-common/src/features/canvas-components/prompt/generateChart.ts
deleted file mode 100644
index e79eb7e872e..00000000000
--- a/web-common/src/features/canvas-components/prompt/generateChart.ts
+++ /dev/null
@@ -1,166 +0,0 @@
-import { goto } from "$app/navigation";
-import {
-  getChartYaml,
-  parseChartYaml,
-} from "@rilldata/web-common/features/canvas-components/chartYaml";
-import {
-  ChartPromptStatus,
-  chartPromptsStore,
-} from "@rilldata/web-common/features/canvas-components/prompt/chartPrompt";
-import { useComponent } from "@rilldata/web-common/features/canvas-components/selectors";
-import { getFileAPIPathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers";
-import { EntityType } from "@rilldata/web-common/features/entity-management/types";
-import {
-  type V1ComponentSpec,
-  createRuntimeServiceGenerateRenderer,
-  createRuntimeServiceGenerateResolver,
-  createRuntimeServiceGetFile,
-  runtimeServicePutFile,
-} from "@rilldata/web-common/runtime-client";
-import { get } from "svelte/store";
-
-export function createChartGenerator(
-  instanceId: string,
-  chart: string,
-  filePath: string,
-) {
-  const generateVegaConfig = createRuntimeServiceGenerateRenderer();
-  const chartQuery = useComponent(instanceId, chart);
-  const chartContent = createRuntimeServiceGetFile(instanceId, {
-    path: filePath,
-  });
-  // TODO: update for new API
-
-  return async (prompt: string) => {
-    try {
-      const [resolver, resolverProperties] = tryParseChart(
-        get(chartQuery).data?.component?.spec,
-        get(chartContent).data?.blob,
-      );
-      chartPromptsStore.startPrompt(chart, chart, prompt);
-      const resp = await get(generateVegaConfig).mutateAsync({
-        instanceId,
-        data: {
-          prompt,
-          resolver,
-          resolverProperties,
-        },
-      });
-      chartPromptsStore.updatePromptStatus(chart, ChartPromptStatus.Idle);
-      await runtimeServicePutFile(instanceId, {
-        path: filePath,
-        blob: getChartYaml(
-          resp.rendererProperties?.spec,
-          resolver,
-          resolverProperties,
-        ),
-      });
-    } catch (e) {
-      chartPromptsStore.setPromptError(
-        chart,
-        e.message ?? e.response.data?.message,
-      );
-    }
-  };
-}
-
-export function createFullChartGenerator(instanceId: string) {
-  const generateResolver = createRuntimeServiceGenerateResolver();
-  const generateVegaConfig = createRuntimeServiceGenerateRenderer();
-
-  return async (
-    prompt: string,
-    {
-      table,
-      connector,
-      metricsView,
-    }: { table?: string; connector?: string; metricsView?: string },
-    newChartName: string,
-  ) => {
-    const filePath = getFileAPIPathFromNameAndType(
-      newChartName,
-      EntityType.Chart,
-    );
-    try {
-      // add an empty chart
-      await runtimeServicePutFile(instanceId, {
-        path: filePath,
-        blob: `type: component`,
-      });
-      chartPromptsStore.startPrompt(
-        (table || metricsView) ?? "",
-        newChartName,
-        prompt,
-      );
-      await goto(`/files/${filePath}`);
-      const resolverResp = await get(generateResolver).mutateAsync({
-        instanceId,
-        data: {
-          table,
-          connector,
-          metricsView,
-          prompt,
-        },
-      });
-
-      // add a chart with just the resolver
-      await runtimeServicePutFile(instanceId, {
-        path: filePath,
-        blob: getChartYaml(
-          "{}",
-          resolverResp.resolver,
-          resolverResp.resolverProperties,
-        ),
-      });
-      chartPromptsStore.updatePromptStatus(
-        newChartName,
-        ChartPromptStatus.GeneratingChartSpec,
-      );
-      const resp = await get(generateVegaConfig).mutateAsync({
-        instanceId,
-        data: {
-          prompt,
-          resolver: resolverResp.resolver,
-          resolverProperties: resolverResp.resolverProperties,
-        },
-      });
-
-      chartPromptsStore.updatePromptStatus(
-        newChartName,
-        ChartPromptStatus.Idle,
-      );
-      await runtimeServicePutFile(instanceId, {
-        path: filePath,
-        blob: getChartYaml(
-          resp.rendererProperties?.spec,
-          resolverResp.resolver,
-          resolverResp.resolverProperties,
-        ),
-      });
-    } catch (e) {
-      chartPromptsStore.setPromptError(
-        newChartName,
-        e.message ?? e.response.data?.message,
-      );
-    }
-  };
-}
-
-function tryParseChart(
-  chartSpec: V1ComponentSpec | undefined,
-  chartContent: string | undefined,
-): [resolver: string, resolverProperties: Record<string, string>] {
-  if (!chartSpec?.resolver && chartContent) {
-    try {
-      chartSpec = parseChartYaml(chartContent);
-    } catch {
-      throw new Error(
-        "Failed to parse yaml. Please fix it before trying to generate chart spec.",
-      );
-    }
-  }
-  if (chartSpec?.resolver) {
-    return [chartSpec.resolver, chartSpec.resolverProperties ?? {}];
-  }
-  throw new Error("Chart is invalid");
-}
diff --git a/web-common/src/features/canvas-components/selectors.ts b/web-common/src/features/canvas-components/selectors.ts
deleted file mode 100644
index dc4b610641d..00000000000
--- a/web-common/src/features/canvas-components/selectors.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {
-  ResourceKind,
-  useResource,
-} from "@rilldata/web-common/features/entity-management/resource-selectors";
-
-export const useComponent = (instanceId: string, componentName: string) => {
-  return useResource(instanceId, componentName, ResourceKind.Component);
-};
diff --git a/web-common/src/features/canvas/AddComponentMenu.svelte b/web-common/src/features/canvas/AddComponentMenu.svelte
deleted file mode 100644
index 1f692c63ca2..00000000000
--- a/web-common/src/features/canvas/AddComponentMenu.svelte
+++ /dev/null
@@ -1,88 +0,0 @@
-<script lang="ts">
-  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
-  import Search from "@rilldata/web-common/components/search/Search.svelte";
-  import {
-    ResourceKind,
-    useClientFilteredResources,
-  } from "@rilldata/web-common/features/entity-management/resource-selectors";
-  import { ChevronDown, Plus } from "lucide-svelte";
-  import { runtime } from "../../runtime-client/runtime-store";
-  import { getNameFromFile } from "../entity-management/entity-mappers";
-  // import { featureFlags } from "../feature-flags";
-  import Button from "@rilldata/web-common/components/button/Button.svelte";
-  import { createResourceFile } from "../file-explorer/new-files";
-
-  // const { ai } = featureFlags;
-
-  export let addComponent: (componentName: string) => void;
-
-  let open = false;
-  let value = "";
-
-  $: ({ instanceId } = $runtime);
-
-  // We want to get only valid components here. Hence using ListResources API
-  $: componentsQuery = useClientFilteredResources(
-    instanceId,
-    ResourceKind.Component,
-  );
-  $: componentFileNames =
-    $componentsQuery.data
-      ?.filter((c) => !c.component?.spec?.definedInCanvas)
-      .map((c) => c.meta?.name?.name ?? "") ?? [];
-
-  async function handleAddComponent() {
-    const newFilePath = await createResourceFile(ResourceKind.Component);
-
-    if (!newFilePath) return;
-
-    const componentName = getNameFromFile(newFilePath);
-
-    if (componentName) {
-      addComponent(componentName);
-    }
-  }
-</script>
-
-<DropdownMenu.Root bind:open typeahead={false}>
-  <DropdownMenu.Trigger asChild let:builder>
-    <Button builders={[builder]} type="secondary">
-      <Plus class="flex items-center justify-center" size="16px" />
-      <div class="flex gap-x-1 items-center">
-        Add component
-        <ChevronDown size="14px" />
-      </div>
-    </Button>
-  </DropdownMenu.Trigger>
-  <DropdownMenu.Content class="flex flex-col gap-y-1 ">
-    <DropdownMenu.Group>
-      <!-- <DropdownMenu.Item disabled>
-        Generate chart
-        {#if $ai}
-          with AI
-          <WandIcon class="w-3 h-3" />
-        {/if}
-      </DropdownMenu.Item> -->
-      <DropdownMenu.Item on:click={handleAddComponent}>
-        Create new component
-      </DropdownMenu.Item>
-    </DropdownMenu.Group>
-
-    <DropdownMenu.Separator />
-    <div class="px-1">
-      <Search bind:value />
-    </div>
-    <DropdownMenu.Separator />
-
-    <DropdownMenu.Label class="text-[11px] text-gray-500 py-0">
-      EXISTING COMPONENTS
-    </DropdownMenu.Label>
-    <DropdownMenu.Group>
-      {#each componentFileNames.filter( (n) => n.startsWith(value), ) as componentName (componentName)}
-        <DropdownMenu.Item on:click={() => addComponent(componentName)}>
-          {componentName}
-        </DropdownMenu.Item>
-      {/each}
-    </DropdownMenu.Group>
-  </DropdownMenu.Content>
-</DropdownMenu.Root>
diff --git a/web-common/src/features/canvas/Canvas.svelte b/web-common/src/features/canvas/Canvas.svelte
new file mode 100644
index 00000000000..1ccab605fae
--- /dev/null
+++ b/web-common/src/features/canvas/Canvas.svelte
@@ -0,0 +1,99 @@
+<script lang="ts">
+  import CanvasDashboardPreview from "@rilldata/web-common/features/canvas/CanvasDashboardPreview.svelte";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import type { Vector } from "@rilldata/web-common/features/canvas/types";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import type { V1CanvasSpec } from "@rilldata/web-common/runtime-client";
+  import { parseDocument } from "yaml";
+
+  export let fileArtifact: FileArtifact;
+
+  const { canvasEntity, validSpecStore } = getCanvasStateManagers();
+  $: selectedIndex = canvasEntity?.selectedComponentIndex;
+
+  let showGrid = true;
+
+  // TODO: Remove later when we move to new tiling system
+  const columns = 24;
+  const gap = 1;
+
+  let spec: V1CanvasSpec = {
+    items: [],
+  };
+
+  $: ({
+    saveLocalContent: updateComponentFile,
+    autoSave,
+    updateEditorContent,
+    editorContent,
+    remoteContent,
+  } = fileArtifact);
+
+  $: spec = structuredClone($validSpecStore?.data ?? spec);
+
+  $: ({ items = [] } = spec);
+
+  async function handleDeleteEvent(
+    e: CustomEvent<{
+      index: number;
+    }>,
+  ) {
+    if (!e.detail.index) return;
+    await deleteComponent(e.detail.index);
+  }
+
+  async function deleteComponent(index: number) {
+    const parsedDocument = parseDocument(
+      $editorContent ?? $remoteContent ?? "",
+    );
+
+    const items = parsedDocument.get("items") as any;
+    if (!items) return;
+    items.delete(index);
+    updateEditorContent(parsedDocument.toString(), true);
+    if ($autoSave) await updateComponentFile();
+  }
+
+  async function handlePreviewUpdate(
+    e: CustomEvent<{
+      index: number;
+      position: Vector;
+      dimensions: Vector;
+    }>,
+  ) {
+    const parsedDocument = parseDocument(
+      $editorContent ?? $remoteContent ?? "",
+    );
+    const items = parsedDocument.get("items") as any;
+
+    const node = items.get(e.detail.index);
+
+    node.set("width", e.detail.dimensions[0]);
+    node.set("height", e.detail.dimensions[1]);
+    node.set("x", e.detail.position[0]);
+    node.set("y", e.detail.position[1]);
+
+    updateEditorContent(parsedDocument.toString(), true);
+
+    if ($autoSave) await updateComponentFile();
+  }
+</script>
+
+<CanvasDashboardPreview
+  {gap}
+  {items}
+  {columns}
+  {showGrid}
+  selectedIndex={$selectedIndex}
+  on:update={handlePreviewUpdate}
+  on:delete={handleDeleteEvent}
+/>
+
+<svelte:window
+  on:keydown={async (e) => {
+    if (e.target !== document.body || $selectedIndex === null) return;
+    if (e.key === "Delete" || e.key === "Backspace") {
+      await deleteComponent($selectedIndex);
+    }
+  }}
+/>
diff --git a/web-common/src/features/canvas/CanvasDashboardEmbed.svelte b/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
index d8bb50345d1..205016be4b5 100644
--- a/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
+++ b/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
@@ -1,25 +1,17 @@
 <script lang="ts">
-  import {
-    type V1CanvasItem,
-    type V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
+  import CanvasFilters from "@rilldata/web-common/features/canvas/filters/CanvasFilters.svelte";
+  import { type V1CanvasItem } from "@rilldata/web-common/runtime-client";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { setContext } from "svelte";
   import Component from "./Component.svelte";
   import * as defaults from "./constants";
   import DashboardWrapper from "./DashboardWrapper.svelte";
-  import { canvasVariablesStore } from "./variables-store";
 
-  export let canvasName: string;
   export let columns = 20;
   export let items: V1CanvasItem[];
-  export let gap = 4;
+  export let gap = 1;
   export let chartView = false;
-  export let variables: V1ComponentVariable[] = [];
 
   let contentRect: DOMRectReadOnly = new DOMRectReadOnly(0, 0, 0, 0);
-  setContext("rill::canvas:name", canvasName);
-
   $: ({ instanceId } = $runtime);
 
   const dashboardWidth = chartView
@@ -36,12 +28,15 @@
     const bottom = Number(el.height) + Number(el.y);
     return Math.max(max, bottom);
   }, 0);
-
-  $: if (variables.length && canvasName) {
-    canvasVariablesStore.init(canvasName, variables);
-  }
 </script>
 
+<div
+  id="header"
+  class="border-b w-fit min-w-full flex flex-col bg-slate-50 slide"
+>
+  <CanvasFilters />
+</div>
+
 <DashboardWrapper
   bind:contentRect
   {scale}
diff --git a/web-common/src/features/canvas/CanvasDashboardPreview.svelte b/web-common/src/features/canvas/CanvasDashboardPreview.svelte
index cb819254cfc..bc55bdea981 100644
--- a/web-common/src/features/canvas/CanvasDashboardPreview.svelte
+++ b/web-common/src/features/canvas/CanvasDashboardPreview.svelte
@@ -1,9 +1,8 @@
 <script lang="ts">
-  import { canvasVariablesStore } from "@rilldata/web-common/features/canvas/variables-store";
-  import type {
-    V1CanvasItem,
-    V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
+  import CanvasFilters from "@rilldata/web-common/features/canvas/filters/CanvasFilters.svelte";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { navigationOpen } from "@rilldata/web-common/layout/navigation/Navigation.svelte";
+  import type { V1CanvasItem } from "@rilldata/web-common/runtime-client";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
   import { createEventDispatcher } from "svelte";
   import * as defaults from "./constants";
@@ -15,16 +14,15 @@
   const dispatch = createEventDispatcher();
   const zeroVector = [0, 0] as [0, 0];
 
-  export let canvasDashboardName: string;
   export let columns: number | undefined;
   export let items: V1CanvasItem[];
   export let gap: number | undefined;
-  export let variables: V1ComponentVariable[];
   export let showGrid = false;
   export let snap = true;
-  export let selectedComponentName: string | null;
   export let selectedIndex: number | null = null;
 
+  const { canvasEntity } = getCanvasStateManagers();
+
   let contentRect: DOMRectReadOnly = new DOMRectReadOnly(0, 0, 0, 0);
   let scrollOffset = 0;
   let changing = false;
@@ -37,6 +35,8 @@
 
   $: ({ instanceId } = $runtime);
 
+  $: extraLeftPadding = !$navigationOpen;
+
   $: gridWidth = contentRect.width;
   $: scale = gridWidth / defaults.DASHBOARD_WIDTH;
 
@@ -63,9 +63,6 @@
   $: finalDrag = vector.multiply(getCell(dragPosition, snap), gridVector);
 
   $: finalResize = vector.multiply(getCell(resizeDimenions, snap), gridVector);
-  $: if (variables.length) {
-    canvasVariablesStore.init(canvasDashboardName, variables);
-  }
 
   function handleMouseUp() {
     if (selectedIndex === null || !changing) return;
@@ -134,7 +131,7 @@
     mousePosition = startMouse;
 
     selectedIndex = index;
-    selectedComponentName = items[index].component ?? null;
+    canvasEntity.setSelectedComponentIndex(selectedIndex);
     changing = true;
   }
 
@@ -165,7 +162,7 @@
 
   function deselect() {
     selectedIndex = null;
-    selectedComponentName = null;
+    canvasEntity.setSelectedComponentIndex(selectedIndex);
   }
 
   $: maxBottom = items.reduce((max, el) => {
@@ -176,6 +173,14 @@
 
 <svelte:window on:mousemove={handleMouseMove} on:mouseup={handleMouseUp} />
 
+<div
+  id="header"
+  class="border-b w-fit min-w-full flex flex-col bg-slate-50 slide"
+  class:left-shift={extraLeftPadding}
+>
+  <CanvasFilters />
+</div>
+
 <DashboardWrapper
   bind:contentRect
   {changing}
@@ -190,6 +195,9 @@
   on:click={deselect}
   on:scroll={handleScroll}
 >
+  <section
+    class="flex relative justify-between gap-x-4 py-4 pb-6 px-4"
+  ></section>
   {#each items as component, i (i)}
     {@const selected = i === selectedIndex}
     {@const interacting = selected && changing}
diff --git a/web-common/src/features/canvas/CanvasEditor.svelte b/web-common/src/features/canvas/CanvasEditor.svelte
new file mode 100644
index 00000000000..41d97db1e8c
--- /dev/null
+++ b/web-common/src/features/canvas/CanvasEditor.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+  import { yaml } from "@codemirror/lang-yaml";
+  import type { EditorView } from "@codemirror/view";
+  import { setLineStatuses } from "@rilldata/web-common/components/editor/line-status";
+  import type { LineStatus } from "@rilldata/web-common/components/editor/line-status/state";
+  import { canvasEntities } from "@rilldata/web-common/features/canvas/stores/canvas-entities";
+  import Editor from "@rilldata/web-common/features/editor/Editor.svelte";
+  import { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+
+  export let canvasName: string;
+  export let fileArtifact: FileArtifact;
+  export let autoSave: boolean;
+  export let lineBasedRuntimeErrors: LineStatus[];
+
+  let editor: EditorView;
+
+  /** If the errors change, run the following transaction. */
+  $: if (editor) setLineStatuses(lineBasedRuntimeErrors, editor);
+</script>
+
+<Editor
+  bind:autoSave
+  bind:editor
+  onSave={(content) => {
+    // Remove the canvas entity so that everything is reset to defaults next time user navigates to it
+    canvasEntities.removeCanvas(canvasName);
+
+    // Reset local persisted dashboard state for the metrics view
+    if (!content?.length) {
+      setLineStatuses([], editor);
+    }
+  }}
+  {fileArtifact}
+  extensions={[yaml()]}
+/>
diff --git a/web-common/src/features/canvas/CanvasThemeProvider.svelte b/web-common/src/features/canvas/CanvasThemeProvider.svelte
new file mode 100644
index 00000000000..475e4413793
--- /dev/null
+++ b/web-common/src/features/canvas/CanvasThemeProvider.svelte
@@ -0,0 +1,26 @@
+<script lang="ts">
+  import { page } from "$app/stores";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { setTheme } from "@rilldata/web-common/features/themes/actions";
+  import { useTheme } from "@rilldata/web-common/features/themes/selectors";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { onMount } from "svelte";
+
+  const { validSpecStore } = getCanvasStateManagers();
+  $: themeFromUrl = $page.url.searchParams.get("theme");
+
+  let theme: ReturnType<typeof useTheme>;
+  $: themeName = themeFromUrl ?? $validSpecStore?.data?.theme;
+  $: if (themeName) theme = useTheme($runtime.instanceId, themeName);
+
+  $: setTheme(
+    $theme?.data?.theme?.spec ?? $validSpecStore?.data?.embeddedTheme,
+  );
+
+  onMount(() => {
+    // Handle the case where we have data in cache but the dashboard is not mounted yet
+    setTheme($theme?.data?.theme?.spec ?? $validSpecStore?.data?.embeddedTheme);
+  });
+</script>
+
+<slot />
diff --git a/web-common/src/features/canvas/Chart.svelte b/web-common/src/features/canvas/Chart.svelte
deleted file mode 100644
index 19a6b871dea..00000000000
--- a/web-common/src/features/canvas/Chart.svelte
+++ /dev/null
@@ -1,53 +0,0 @@
-<script lang="ts">
-  import {
-    createQueryServiceResolveComponent,
-    type V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { getContext } from "svelte";
-  import type { View, VisualizationSpec } from "svelte-vega";
-  import VegaLiteRenderer from "../canvas-components/render/VegaLiteRenderer.svelte";
-  import { useVariableInputParams } from "./variables-store";
-
-  export let componentName: string;
-  export let chartView: boolean;
-  export let input: V1ComponentVariable[] | undefined;
-
-  let viewVL: View;
-  let error: string | null = null;
-  let parsedVegaSpec: VisualizationSpec | null = null;
-
-  $: ({ instanceId } = $runtime);
-
-  $: canvasName = getContext("rill::canvas:name") as string;
-  $: inputVariableParams = useVariableInputParams(canvasName, input);
-
-  $: componentDataQuery = createQueryServiceResolveComponent(
-    instanceId,
-    componentName,
-    { args: $inputVariableParams },
-  );
-  $: vegaSpec = $componentDataQuery?.data?.rendererProperties?.spec;
-  $: data = $componentDataQuery?.data?.data;
-
-  $: try {
-    if (typeof vegaSpec === "string") {
-      parsedVegaSpec = JSON.parse(vegaSpec) as VisualizationSpec;
-    } else {
-      parsedVegaSpec = vegaSpec ?? null;
-    }
-  } catch (e: unknown) {
-    error = JSON.stringify(e);
-  }
-</script>
-
-{#if parsedVegaSpec}
-  <VegaLiteRenderer
-    bind:viewVL
-    canvasDashboard
-    {error}
-    {chartView}
-    data={{ table: data }}
-    spec={parsedVegaSpec}
-  />
-{/if}
diff --git a/web-common/src/features/canvas/Component.svelte b/web-common/src/features/canvas/Component.svelte
index 426a89c8cbe..80d6b934660 100644
--- a/web-common/src/features/canvas/Component.svelte
+++ b/web-common/src/features/canvas/Component.svelte
@@ -1,5 +1,4 @@
 <script lang="ts" context="module">
-  import TemplateRenderer from "@rilldata/web-common/features/templates/TemplateRenderer.svelte";
   import { builderActions, getAttrs, type Builder } from "bits-ui";
   import type { ComponentType } from "svelte";
   import { onMount } from "svelte";
@@ -7,8 +6,8 @@
     ResourceKind,
     useResource,
   } from "../entity-management/resource-selectors";
-  import Chart from "./Chart.svelte";
   import type ResizeHandle from "./ResizeHandle.svelte";
+  import ComponentRenderer from "@rilldata/web-common/features/canvas/components/ComponentRenderer.svelte";
 
   const options = [0, 0.5, 1];
   const allSides = options
@@ -41,15 +40,11 @@
   );
   $: ({ data: componentResource } = $resourceQuery);
 
-  $: ({
-    renderer,
-    rendererProperties,
-    resolverProperties,
-    input,
-    output,
-    displayName,
-    description,
-  } = componentResource?.component?.spec ?? {});
+  $: ({ renderer, rendererProperties } =
+    componentResource?.component?.spec ?? {});
+
+  $: title = rendererProperties?.title;
+  $: description = rendererProperties?.description;
 
   let ResizeHandleComponent: ComponentType<ResizeHandle>;
 
@@ -93,31 +88,22 @@
     {/if}
 
     <div
-      class="size-full overflow-hidden flex flex-col gap-y-1 flex-none"
+      class="size-full overflow-hidden flex flex-col flex-none"
       class:shadow-lg={interacting}
       style:border-radius="{radius}px"
     >
-      {#if displayName || description}
-        <div class="w-full h-fit flex flex-col pb-2">
-          {#if displayName}
-            <h1 class="text-slate-900">{displayName}</h1>
+      {#if title || description}
+        <div class="w-full h-fit flex flex-col border-b bg-white p-2">
+          {#if title}
+            <h1 class="text-slate-700">{title}</h1>
           {/if}
           {#if description}
             <h2 class="text-slate-600 leading-none">{description}</h2>
           {/if}
         </div>
       {/if}
-      {#if renderer === "vega_lite" && rendererProperties?.spec && resolverProperties}
-        <Chart {componentName} {chartView} {input} />
-      {:else if renderer && rendererProperties}
-        <TemplateRenderer
-          {chartView}
-          {renderer}
-          {input}
-          {output}
-          {resolverProperties}
-          {componentName}
-        />
+      {#if renderer && rendererProperties}
+        <ComponentRenderer {renderer} {componentName} />
       {/if}
     </div>
   </div>
@@ -129,12 +115,12 @@
   }
 
   h1 {
-    font-size: 18px;
-    font-weight: 600;
+    font-size: 16px;
+    font-weight: 500;
   }
 
   h2 {
-    font-size: 14px;
+    font-size: 12px;
     font-weight: 400;
   }
 </style>
diff --git a/web-common/src/features/canvas/CreateCanvasDialog.svelte b/web-common/src/features/canvas/CreateCanvasDialog.svelte
new file mode 100644
index 00000000000..b3240a20b83
--- /dev/null
+++ b/web-common/src/features/canvas/CreateCanvasDialog.svelte
@@ -0,0 +1,78 @@
+<!--
+ To be used later when we have all the components in place.
+ This dialog will be used as a quickstart option.
+ -->
+
+<script lang="ts">
+  import * as AlertDialog from "@rilldata/web-common/components/alert-dialog";
+  import Button from "@rilldata/web-common/components/button/Button.svelte";
+  import Select from "@rilldata/web-common/components/forms/Select.svelte";
+  import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import type { V1Resource } from "@rilldata/web-common/runtime-client";
+  import { createResourceFile } from "../file-explorer/new-files";
+
+  export let open = false;
+  export let metricsViews: V1Resource[];
+  export let wrapNavigation: (path: string | undefined) => Promise<void>;
+
+  let selectedMetricsView: V1Resource | undefined = undefined;
+
+  $: metricsViewOptions = metricsViews.map((resource) => ({
+    value: resource.meta?.name?.name ?? "",
+    label: resource.meta?.name?.name ?? "",
+  }));
+
+  async function createResource() {
+    if (selectedMetricsView) {
+      const newFilePath = await createResourceFile(
+        ResourceKind.Canvas,
+        selectedMetricsView,
+      );
+      await wrapNavigation(newFilePath);
+    }
+  }
+</script>
+
+<AlertDialog.Root bind:open>
+  <AlertDialog.Content>
+    <AlertDialog.Title>
+      Which metrics view should this dashboard reference?
+    </AlertDialog.Title>
+
+    <AlertDialog.Description>
+      This will determine the measures and dimensions you can explore on this
+      dashboard.
+    </AlertDialog.Description>
+
+    <Select
+      sameWidth
+      options={metricsViewOptions}
+      fontSize={14}
+      placeholder="Select a metrics view"
+      id="metrics-explore-selection"
+      onChange={(value) => {
+        selectedMetricsView = metricsViews.find(
+          (resource) => resource.meta?.name?.name === value,
+        );
+      }}
+    />
+
+    <AlertDialog.Footer>
+      <AlertDialog.Cancel asChild let:builder>
+        <Button large builders={[builder]} type="secondary">Cancel</Button>
+      </AlertDialog.Cancel>
+
+      <AlertDialog.Action asChild let:builder>
+        <Button
+          disabled={!selectedMetricsView}
+          large
+          builders={[builder]}
+          type="primary"
+          on:click={createResource}
+        >
+          Continue
+        </Button>
+      </AlertDialog.Action>
+    </AlertDialog.Footer>
+  </AlertDialog.Content>
+</AlertDialog.Root>
diff --git a/web-common/src/features/canvas/DashboardWrapper.svelte b/web-common/src/features/canvas/DashboardWrapper.svelte
index 58ce62ad6ee..394895809d4 100644
--- a/web-common/src/features/canvas/DashboardWrapper.svelte
+++ b/web-common/src/features/canvas/DashboardWrapper.svelte
@@ -25,7 +25,7 @@
 </script>
 
 <div
-  class="size-full bg-gray-100 flex justify-center overflow-y-auto"
+  class="dashboard-theme-boundary size-full bg-gray-100 flex justify-center overflow-y-auto"
   on:scroll
 >
   <div
diff --git a/web-common/src/features/canvas/components/AddComponentMenu.svelte b/web-common/src/features/canvas/components/AddComponentMenu.svelte
new file mode 100644
index 00000000000..d0374d34556
--- /dev/null
+++ b/web-common/src/features/canvas/components/AddComponentMenu.svelte
@@ -0,0 +1,42 @@
+<script lang="ts">
+  import Button from "@rilldata/web-common/components/button/Button.svelte";
+  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
+  import type { CanvasComponentType } from "@rilldata/web-common/features/canvas/components/types";
+  import { ChevronDown, Plus } from "lucide-svelte";
+
+  export let addComponent: (componentName: CanvasComponentType) => void;
+
+  let open = false;
+
+  const menuItems: {
+    id: CanvasComponentType;
+    label: string;
+  }[] = [
+    { id: "markdown", label: "Text" },
+    { id: "kpi", label: "KPI" },
+    { id: "image", label: "Image" },
+    { id: "bar_chart", label: "Chart" },
+    { id: "table", label: "Table" },
+  ];
+</script>
+
+<DropdownMenu.Root bind:open typeahead={false}>
+  <DropdownMenu.Trigger asChild let:builder>
+    <Button builders={[builder]} type="secondary">
+      <Plus class="flex items-center justify-center" size="16px" />
+      <div class="flex gap-x-1 items-center">
+        Add component
+        <ChevronDown size="14px" />
+      </div>
+    </Button>
+  </DropdownMenu.Trigger>
+  <DropdownMenu.Content class="flex flex-col gap-y-1 ">
+    <DropdownMenu.Group>
+      {#each menuItems as item}
+        <DropdownMenu.Item on:click={() => addComponent(item.id)}>
+          {item.label}
+        </DropdownMenu.Item>
+      {/each}
+    </DropdownMenu.Group>
+  </DropdownMenu.Content>
+</DropdownMenu.Root>
diff --git a/web-common/src/features/canvas/components/BaseCanvasComponent.ts b/web-common/src/features/canvas/components/BaseCanvasComponent.ts
new file mode 100644
index 00000000000..1239b284892
--- /dev/null
+++ b/web-common/src/features/canvas/components/BaseCanvasComponent.ts
@@ -0,0 +1,88 @@
+import type { ChartType } from "@rilldata/web-common/features/canvas/components/charts/types";
+import type {
+  CanvasComponent,
+  ComponentSize,
+} from "@rilldata/web-common/features/canvas/components/types";
+import { getParsedDocument } from "@rilldata/web-common/features/canvas/inspector/selectors";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { get, writable, type Writable } from "svelte/store";
+
+// A base class that implements all the store logic
+export abstract class BaseCanvasComponent<T> implements CanvasComponent<T> {
+  specStore: Writable<T>;
+  pathInYAML: (string | number)[] = [];
+  fileArtifact: FileArtifact;
+
+  // Let child classes define these
+  abstract minSize: ComponentSize;
+  abstract defaultSize: ComponentSize;
+  abstract isValid(spec: T): boolean;
+  abstract inputParams(): InputParams<T>;
+  abstract newComponentSpec(
+    metrics_view: string,
+    measure: string,
+    dimension: string,
+  ): T;
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[],
+    defaultSpec: T,
+    initialSpec: Partial<T> = {},
+  ) {
+    // Initialize the store with merged spec
+    const mergedSpec = { ...defaultSpec, ...initialSpec };
+    this.specStore = writable(mergedSpec);
+    this.pathInYAML = path;
+    this.fileArtifact = fileArtifact;
+  }
+
+  private async updateYAML(newSpec: T): Promise<void> {
+    const parseDocumentStore = getParsedDocument(this.fileArtifact);
+    const parsedDocument = get(parseDocumentStore);
+
+    const { updateEditorContent, saveLocalContent } = this.fileArtifact;
+
+    // Update the Item
+    parsedDocument.setIn(this.pathInYAML, newSpec);
+
+    // Save the updated document
+    updateEditorContent(parsedDocument.toString(), true);
+    await saveLocalContent();
+  }
+
+  async setSpec(newSpec: T): Promise<void> {
+    if (this.isValid(newSpec)) {
+      await this.updateYAML(newSpec);
+    }
+    this.specStore.set(newSpec);
+  }
+
+  // TODO: Add stricter type definition for keys and value deriving from spec
+  async updateProperty(key: string, value: unknown): Promise<void> {
+    const currentSpec = get(this.specStore);
+    const newSpec = { ...currentSpec, [key]: value };
+    if (this.isValid(newSpec)) {
+      await this.updateYAML(newSpec);
+    }
+    this.specStore.set(newSpec);
+  }
+
+  async updateChartType(key: ChartType) {
+    const currentSpec = get(this.specStore);
+    const parentSpec = { [key]: currentSpec };
+    const parentPath = this.pathInYAML.slice(0, -1);
+
+    const parseDocumentStore = getParsedDocument(this.fileArtifact);
+    const parsedDocument = get(parseDocumentStore);
+
+    const { updateEditorContent, saveLocalContent } = this.fileArtifact;
+
+    parsedDocument.setIn(parentPath, parentSpec);
+
+    // Save the updated document
+    updateEditorContent(parsedDocument.toString(), true);
+    await saveLocalContent();
+  }
+}
diff --git a/web-common/src/features/canvas/components/ComponentRenderer.svelte b/web-common/src/features/canvas/components/ComponentRenderer.svelte
new file mode 100644
index 00000000000..fe7ce7dbfef
--- /dev/null
+++ b/web-common/src/features/canvas/components/ComponentRenderer.svelte
@@ -0,0 +1,39 @@
+<script lang="ts">
+  import { Chart } from "./charts";
+  import { Image } from "./image";
+  import { KPI } from "./kpi";
+  import { Markdown } from "./markdown";
+  import { Table } from "./table";
+
+  import {
+    createQueryServiceResolveComponent,
+    type V1ComponentSpecRendererProperties,
+  } from "@rilldata/web-common/runtime-client";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+
+  export let renderer: string;
+  export let componentName: string;
+
+  $: componentQuery = createQueryServiceResolveComponent(
+    $runtime.instanceId,
+    componentName,
+    { args: {} },
+  );
+  $: componentData = $componentQuery?.data;
+  $: rendererProperties =
+    componentData?.rendererProperties as V1ComponentSpecRendererProperties;
+</script>
+
+{#if rendererProperties}
+  {#if renderer === "kpi"}
+    <KPI {rendererProperties} />
+  {:else if renderer === "table"}
+    <Table {rendererProperties} />
+  {:else if renderer === "markdown"}
+    <Markdown {rendererProperties} />
+  {:else if renderer === "image"}
+    <Image {rendererProperties} />
+  {:else}
+    <Chart {rendererProperties} {renderer} />
+  {/if}
+{/if}
diff --git a/web-common/src/features/templates/README.md b/web-common/src/features/canvas/components/README.md
similarity index 100%
rename from web-common/src/features/templates/README.md
rename to web-common/src/features/canvas/components/README.md
diff --git a/web-common/src/features/canvas/components/charts/Chart.svelte b/web-common/src/features/canvas/components/charts/Chart.svelte
new file mode 100644
index 00000000000..08d742714ca
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/Chart.svelte
@@ -0,0 +1,43 @@
+<script lang="ts">
+  import VegaLiteRenderer from "@rilldata/web-common/components/vega/VegaLiteRenderer.svelte";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
+  import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
+  import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import type { View } from "svelte-vega";
+  import { getChartData } from "./selector";
+  import type { ChartConfig, ChartType } from "./types";
+  import { generateSpec } from "./util";
+
+  export let rendererProperties: V1ComponentSpecRendererProperties;
+  export let renderer: string;
+
+  let stateManagers = getCanvasStateManagers();
+
+  const instanceId = $runtime.instanceId;
+  $: chartConfig = rendererProperties as ChartConfig;
+  $: chartType = renderer as ChartType;
+
+  let viewVL: View;
+
+  $: data = getChartData(stateManagers, instanceId, chartConfig);
+  $: spec = generateSpec(chartType, chartConfig, $data);
+</script>
+
+{#if chartConfig?.x}
+  {#if $data.isFetching}
+    <div class="flex items-center h-full w-full">
+      <Spinner status={EntityStatus.Running} size="16px" />
+    </div>
+  {:else if $data.error}
+    <div class="text-red-500">{$data.error.message}</div>
+  {:else}
+    <VegaLiteRenderer
+      bind:viewVL
+      canvasDashboard
+      data={{ "metrics-view": $data.data }}
+      {spec}
+    />
+  {/if}
+{/if}
diff --git a/web-common/src/features/canvas/components/charts/bar-chart/index.ts b/web-common/src/features/canvas/components/charts/bar-chart/index.ts
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/web-common/src/features/canvas/components/charts/bar-chart/spec.ts b/web-common/src/features/canvas/components/charts/bar-chart/spec.ts
new file mode 100644
index 00000000000..8dfa500779b
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/bar-chart/spec.ts
@@ -0,0 +1,61 @@
+import type { ChartConfig } from "@rilldata/web-common/features/canvas/components/charts/types";
+import type { VisualizationSpec } from "svelte-vega";
+import type { ChartDataResult } from "../selector";
+
+export function generateVLBarChartSpec(
+  config: ChartConfig,
+  data: ChartDataResult,
+): VisualizationSpec {
+  return {
+    $schema: "https://vega.github.io/schema/vega-lite/v5.json",
+    mark: "bar",
+    width: "container",
+    autosize: { type: "fit" },
+    data: { name: "metrics-view" },
+    encoding: {
+      ...(config.x && {
+        x: {
+          field: config.x.field,
+          title: data.fields[config.x.field]?.displayName || config.x.field,
+          type: config.x.type,
+          ...(config.x.timeUnit && { timeUnit: config.x.timeUnit }),
+        },
+      }),
+      ...(config.y && {
+        y: {
+          field: config.y.field,
+          title: data.fields[config.y.field]?.displayName || config.y.field,
+          type: config.y.type,
+          ...(config.y.timeUnit && { timeUnit: config.y.timeUnit }),
+        },
+      }),
+      ...(config.color &&
+        typeof config.color === "object" && {
+          color: {
+            field: config.color.field,
+            title:
+              data.fields[config.color.field]?.displayName ||
+              config.color.field,
+            type: config.color.type,
+            ...(config.color.timeUnit && {
+              timeUnit: config.color.timeUnit,
+            }),
+          },
+        }),
+      ...(config.color &&
+        typeof config.color === "string" && {
+          color: { value: config.color },
+        }),
+      ...(config.color &&
+        typeof config.color === "object" &&
+        config.x && {
+          xOffset: {
+            field: config.color.field,
+            title:
+              data.fields[config.color.field]?.displayName ||
+              config.color.field,
+          },
+        }),
+    },
+  };
+}
diff --git a/web-common/src/features/canvas/components/charts/index.ts b/web-common/src/features/canvas/components/charts/index.ts
new file mode 100644
index 00000000000..a762662fc40
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/index.ts
@@ -0,0 +1,74 @@
+import { BaseCanvasComponent } from "@rilldata/web-common/features/canvas/components/BaseCanvasComponent";
+import type { ChartConfig } from "@rilldata/web-common/features/canvas/components/charts/types";
+import {
+  commonOptions,
+  getFilterOptions,
+} from "@rilldata/web-common/features/canvas/components/util";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { type ComponentCommonProperties } from "../types";
+
+export { default as Chart } from "./Chart.svelte";
+
+export type ChartSpec = ComponentCommonProperties & ChartConfig;
+
+export class ChartComponent extends BaseCanvasComponent<ChartSpec> {
+  minSize = { width: 4, height: 4 };
+  defaultSize = { width: 12, height: 8 };
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[] = [],
+    initialSpec: Partial<ChartSpec> = {},
+  ) {
+    const defaultSpec: ChartSpec = {
+      metrics_view: "",
+      title: "",
+      description: "",
+      time_range: "P1D",
+    };
+    super(fileArtifact, path, defaultSpec, initialSpec);
+  }
+
+  isValid(spec: ChartSpec): boolean {
+    return (
+      typeof spec.metrics_view === "string" &&
+      Boolean(spec.x || spec.y) &&
+      typeof spec.time_range === "string"
+    );
+  }
+
+  inputParams(): InputParams<ChartSpec> {
+    return {
+      component: {
+        metrics_view: { type: "metrics", label: "Metrics view" },
+        time_range: { type: "rill_time", label: "Time Range" },
+        x: { type: "positional", label: "X-axis" },
+        y: { type: "positional", label: "Y-axis" },
+        color: { type: "mark", label: "Color", meta: { type: "color" } },
+        tooltip: { type: "tooltip", label: "Tooltip", showInUI: false },
+        ...commonOptions,
+      },
+      filter: getFilterOptions(),
+    };
+  }
+
+  newComponentSpec(
+    metrics_view: string,
+    measure: string,
+    dimension: string,
+  ): ChartSpec {
+    return {
+      metrics_view,
+      x: {
+        type: "nominal",
+        field: dimension,
+      },
+      y: {
+        type: "quantitative",
+        field: measure,
+      },
+      time_range: "PT24H",
+    };
+  }
+}
diff --git a/web-common/src/features/canvas/components/charts/line-chart/spec.ts b/web-common/src/features/canvas/components/charts/line-chart/spec.ts
new file mode 100644
index 00000000000..e72e549b098
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/line-chart/spec.ts
@@ -0,0 +1,51 @@
+import type { ChartConfig } from "@rilldata/web-common/features/canvas/components/charts/types";
+import type { VisualizationSpec } from "svelte-vega";
+import type { ChartDataResult } from "../selector";
+
+export function generateVLLineChartSpec(
+  config: ChartConfig,
+  data: ChartDataResult,
+): VisualizationSpec {
+  return {
+    $schema: "https://vega.github.io/schema/vega-lite/v5.json",
+    mark: "line",
+    width: "container",
+    autosize: { type: "fit" },
+    data: { name: "metrics-view" },
+    encoding: {
+      ...(config.x && {
+        x: {
+          field: config.x.field,
+          title: data.fields[config.x.field]?.displayName || config.x.field,
+          type: config.x.type,
+          ...(config.x.timeUnit && { timeUnit: config.x.timeUnit }),
+        },
+      }),
+      ...(config.y && {
+        y: {
+          field: config.y.field,
+          title: data.fields[config.y.field]?.displayName || config.y.field,
+          type: config.y.type,
+          ...(config.y.timeUnit && { timeUnit: config.y.timeUnit }),
+        },
+      }),
+      ...(config.color &&
+        typeof config.color === "object" && {
+          color: {
+            field: config.color.field,
+            title:
+              data.fields[config.color.field]?.displayName ||
+              config.color.field,
+            type: config.color.type,
+            ...(config.color.timeUnit && {
+              timeUnit: config.color.timeUnit,
+            }),
+          },
+        }),
+      ...(config.color &&
+        typeof config.color === "string" && {
+          color: { value: config.color },
+        }),
+    },
+  };
+}
diff --git a/web-common/src/features/canvas/components/charts/selector.ts b/web-common/src/features/canvas/components/charts/selector.ts
new file mode 100644
index 00000000000..31eac8177c0
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/selector.ts
@@ -0,0 +1,129 @@
+import type { ChartConfig } from "@rilldata/web-common/features/canvas/components/charts/types";
+import { useStartEndTime } from "@rilldata/web-common/features/canvas/components/kpi/selector";
+import type { StateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+import {
+  createQueryServiceMetricsViewAggregation,
+  type MetricsViewSpecDimensionV2,
+  type MetricsViewSpecMeasureV2,
+  type V1MetricsViewAggregationDimension,
+  type V1MetricsViewAggregationMeasure,
+  type V1MetricsViewAggregationResponse,
+  type V1MetricsViewAggregationResponseDataItem,
+} from "@rilldata/web-common/runtime-client";
+import type { HTTPError } from "@rilldata/web-common/runtime-client/fetchWrapper";
+import type { CreateQueryResult } from "@tanstack/svelte-query";
+import { derived, type Readable } from "svelte/store";
+import { useMeasureDimensionSpec } from "../selectors";
+
+export type ChartDataResult = {
+  data: V1MetricsViewAggregationResponseDataItem[];
+  isFetching: boolean;
+  fields: Record<
+    string,
+    MetricsViewSpecMeasureV2 | MetricsViewSpecDimensionV2 | undefined
+  >;
+  error?: HTTPError;
+};
+
+export function getChartData(
+  ctx: StateManagers,
+  instanceId: string,
+  config: ChartConfig,
+): Readable<ChartDataResult> {
+  const chartDataQuery = createChartDataQuery(ctx, instanceId, config);
+
+  const fields: { name: string; type: "measure" | "dimension" }[] = [];
+  if (config.y?.field) fields.push({ name: config.y.field, type: "measure" });
+  if (config.x?.field) fields.push({ name: config.x.field, type: "dimension" });
+  if (typeof config.color === "object" && config.color?.field) {
+    fields.push({ name: config.color.field, type: "dimension" });
+  }
+
+  const specQueries = useMeasureDimensionSpec(
+    instanceId,
+    config.metrics_view,
+    fields,
+  );
+
+  return derived(
+    [chartDataQuery, ...specQueries],
+    ([chartData, ...specResults]) => {
+      const isFetching =
+        specResults.some((q) => q?.isFetching) || chartData.isFetching;
+      const error = chartData.isError
+        ? chartData.error
+        : specResults.find((q) => q?.isError)?.error;
+
+      // For convenience, match each field to its corresponding data.
+      const resultMap = fields.reduce(
+        (acc, f, i) => {
+          acc[f.name] = specResults[i]?.data;
+          return acc;
+        },
+        {} as Record<
+          string,
+          MetricsViewSpecMeasureV2 | MetricsViewSpecDimensionV2 | undefined
+        >,
+      );
+
+      return {
+        data: chartData?.data?.data || [],
+        isFetching,
+        error,
+        fields: resultMap,
+      };
+    },
+  );
+}
+
+export function createChartDataQuery(
+  ctx: StateManagers,
+  instanceId: string,
+  config: ChartConfig,
+  limit = "500",
+  offset = "0",
+): CreateQueryResult<V1MetricsViewAggregationResponse, HTTPError> {
+  let measures: V1MetricsViewAggregationMeasure[] = [];
+  if (config.y?.field) {
+    measures = [{ name: config.y?.field }];
+  }
+
+  let dimensions: V1MetricsViewAggregationDimension[] = [];
+
+  if (config.x?.field) {
+    dimensions = [{ name: config.x?.field }];
+  }
+  if (typeof config.color === "object" && config.color?.field) {
+    dimensions = [...dimensions, { name: config.color.field }];
+  }
+
+  return derived(
+    [
+      ctx.runtime,
+      useStartEndTime(instanceId, config.metrics_view, config.time_range),
+    ],
+    ([runtime, timeRange], set) =>
+      createQueryServiceMetricsViewAggregation(
+        runtime.instanceId,
+        config.metrics_view,
+        {
+          measures,
+          dimensions,
+          where: undefined,
+          timeRange: {
+            start: timeRange?.data?.start?.toISOString() || undefined,
+            end: timeRange?.data?.end?.toISOString() || undefined,
+          },
+          limit,
+          offset,
+        },
+        {
+          query: {
+            enabled: !!timeRange.data,
+            queryClient: ctx.queryClient,
+            keepPreviousData: true,
+          },
+        },
+      ).subscribe(set),
+  );
+}
diff --git a/web-common/src/features/canvas/components/charts/stacked-bar/spec.ts b/web-common/src/features/canvas/components/charts/stacked-bar/spec.ts
new file mode 100644
index 00000000000..ea405afe0e4
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/stacked-bar/spec.ts
@@ -0,0 +1,51 @@
+import type { ChartConfig } from "@rilldata/web-common/features/canvas/components/charts/types";
+import type { VisualizationSpec } from "svelte-vega";
+import type { ChartDataResult } from "../selector";
+
+export function generateVLStackedBarChartSpec(
+  config: ChartConfig,
+  data: ChartDataResult,
+): VisualizationSpec {
+  return {
+    $schema: "https://vega.github.io/schema/vega-lite/v5.json",
+    mark: "bar",
+    width: "container",
+    data: { name: "metrics-view" },
+    autosize: { type: "fit" },
+    encoding: {
+      ...(config.x && {
+        x: {
+          field: config.x.field,
+          title: data.fields[config.x.field]?.displayName || config.x.field,
+          type: config.x.type,
+          ...(config.x.timeUnit && { timeUnit: config.x.timeUnit }),
+        },
+      }),
+      ...(config.y && {
+        y: {
+          field: config.y.field,
+          title: data.fields[config.y.field]?.displayName || config.y.field,
+          type: config.y.type,
+          ...(config.y.timeUnit && { timeUnit: config.y.timeUnit }),
+        },
+      }),
+      ...(config.color &&
+        typeof config.color === "object" && {
+          color: {
+            field: config.color.field,
+            title:
+              data.fields[config.color.field]?.displayName ||
+              config.color.field,
+            type: config.color.type,
+            ...(config.color.timeUnit && {
+              timeUnit: config.color.timeUnit,
+            }),
+          },
+        }),
+      ...(config.color &&
+        typeof config.color === "string" && {
+          color: { value: config.color },
+        }),
+    },
+  };
+}
diff --git a/web-common/src/features/canvas/components/charts/types.ts b/web-common/src/features/canvas/components/charts/types.ts
new file mode 100644
index 00000000000..4ab51c96bb2
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/types.ts
@@ -0,0 +1,27 @@
+import type { ComponentType, SvelteComponent } from "svelte";
+
+export interface FieldConfig {
+  field: string;
+  label?: string;
+  format?: string;
+  type: "quantitative" | "ordinal" | "nominal" | "temporal" | "geojson";
+  timeUnit?: string; // For temporal fields
+}
+
+export interface ChartConfig {
+  metrics_view: string;
+  x?: FieldConfig;
+  y?: FieldConfig;
+  color?: FieldConfig | string;
+  tooltip?: FieldConfig;
+  // Temp options
+  time_range: string;
+}
+
+export type ChartType = "line_chart" | "bar_chart" | "stacked_bar";
+
+export interface ChartMetadata {
+  type: ChartType;
+  icon: ComponentType<SvelteComponent>;
+  title: string;
+}
diff --git a/web-common/src/features/canvas/components/charts/util.ts b/web-common/src/features/canvas/components/charts/util.ts
new file mode 100644
index 00000000000..b4f9e0b06d8
--- /dev/null
+++ b/web-common/src/features/canvas/components/charts/util.ts
@@ -0,0 +1,31 @@
+import BarChart from "@rilldata/web-common/components/icons/BarChart.svelte";
+import LineChart from "@rilldata/web-common/components/icons/LineChart.svelte";
+import StackedBar from "@rilldata/web-common/components/icons/StackedBar.svelte";
+import { generateVLBarChartSpec } from "./bar-chart/spec";
+import { generateVLLineChartSpec } from "./line-chart/spec";
+import { generateVLStackedBarChartSpec } from "./stacked-bar/spec";
+
+import type { ChartDataResult } from "./selector";
+import type { ChartConfig, ChartMetadata, ChartType } from "./types";
+
+export function generateSpec(
+  chartType: ChartType,
+  chartConfig: ChartConfig,
+  data: ChartDataResult,
+) {
+  if (data.isFetching || data.error) return {};
+  switch (chartType) {
+    case "bar_chart":
+      return generateVLBarChartSpec(chartConfig, data);
+    case "stacked_bar":
+      return generateVLStackedBarChartSpec(chartConfig, data);
+    case "line_chart":
+      return generateVLLineChartSpec(chartConfig, data);
+  }
+}
+
+export const chartMetadata: ChartMetadata[] = [
+  { type: "line_chart", title: "Line", icon: LineChart },
+  { type: "bar_chart", title: "Bar", icon: BarChart },
+  { type: "stacked_bar", title: "Stacked Bar", icon: StackedBar },
+];
diff --git a/web-common/src/features/templates/image/Image.svelte b/web-common/src/features/canvas/components/image/Image.svelte
similarity index 96%
rename from web-common/src/features/templates/image/Image.svelte
rename to web-common/src/features/canvas/components/image/Image.svelte
index 13755209f3e..e5aa6eaf768 100644
--- a/web-common/src/features/templates/image/Image.svelte
+++ b/web-common/src/features/canvas/components/image/Image.svelte
@@ -3,11 +3,10 @@
   import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
   import httpClient from "@rilldata/web-common/runtime-client/http-client";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { get } from "svelte/store";
 
   export let rendererProperties: V1ComponentSpecRendererProperties;
 
-  const instanceId = get(runtime).instanceId;
+  const instanceId = $runtime.instanceId;
   const DEFAULT_IMAGE_PROPERTIES: ImageProperties = {
     url: "",
     css: {
diff --git a/web-common/src/features/canvas/components/image/index.ts b/web-common/src/features/canvas/components/image/index.ts
new file mode 100644
index 00000000000..a9e6a7991a6
--- /dev/null
+++ b/web-common/src/features/canvas/components/image/index.ts
@@ -0,0 +1,47 @@
+import { BaseCanvasComponent } from "@rilldata/web-common/features/canvas/components/BaseCanvasComponent";
+import { type ComponentCommonProperties } from "@rilldata/web-common/features/canvas/components/types";
+import { commonOptions } from "@rilldata/web-common/features/canvas/components/util";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+
+export { default as Image } from "./Image.svelte";
+
+export interface ImageSpec extends ComponentCommonProperties {
+  url: string;
+}
+
+export class ImageComponent extends BaseCanvasComponent<ImageSpec> {
+  minSize = { width: 1, height: 1 };
+  defaultSize = { width: 5, height: 5 };
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[] = [],
+    initialSpec: Partial<ImageSpec> = {},
+  ) {
+    const defaultSpec: ImageSpec = {
+      url: "",
+    };
+    super(fileArtifact, path, defaultSpec, initialSpec);
+  }
+
+  isValid(spec: ImageSpec): boolean {
+    return typeof spec.url === "string" && spec.url.trim().length > 0;
+  }
+
+  inputParams(): InputParams<ImageSpec> {
+    return {
+      component: {
+        url: { type: "text", label: "URL" },
+        ...commonOptions,
+      },
+      filter: [],
+    };
+  }
+
+  newComponentSpec(): ImageSpec {
+    return {
+      url: "https://cdn.prod.website-files.com/659ddac460dbacbdc813b204/660b0f85094eb576187342cf_rill_logo_sq_gradient.svg",
+    };
+  }
+}
diff --git a/web-common/src/features/canvas/components/kpi/KPI.svelte b/web-common/src/features/canvas/components/kpi/KPI.svelte
new file mode 100644
index 00000000000..3a82703b75a
--- /dev/null
+++ b/web-common/src/features/canvas/components/kpi/KPI.svelte
@@ -0,0 +1,192 @@
+<script lang="ts">
+  import { SimpleDataGraphic } from "@rilldata/web-common/components/data-graphic/elements";
+  import { ChunkedLine } from "@rilldata/web-common/components/data-graphic/marks";
+  import PercentageChange from "@rilldata/web-common/components/data-types/PercentageChange.svelte";
+  import {
+    MainAreaColorGradientDark,
+    MainAreaColorGradientLight,
+    MainLineColor,
+  } from "@rilldata/web-common/features/dashboards/time-series/chart-colors";
+  import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
+  import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
+  import { createMeasureValueFormatter } from "@rilldata/web-common/lib/number-formatting/format-measure-value";
+  import { FormatPreset } from "@rilldata/web-common/lib/number-formatting/humanizer-types";
+  import { formatMeasurePercentageDifference } from "@rilldata/web-common/lib/number-formatting/percentage-formatter";
+  import { humaniseISODuration } from "@rilldata/web-common/lib/time/ranges/iso-ranges";
+  import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { useQueryClient } from "@tanstack/svelte-query";
+  import { extent } from "d3-array";
+  import type { KPISpec } from ".";
+  import { useMetricsViewSpecMeasure } from "../selectors";
+  import {
+    useKPIComparisonTotal,
+    useKPISparkline,
+    useKPITotals,
+  } from "./selector";
+
+  export let rendererProperties: V1ComponentSpecRendererProperties;
+
+  const queryClient = useQueryClient();
+  let containerWidth: number;
+  let containerHeight: number;
+
+  $: instanceId = $runtime?.instanceId;
+  $: kpiProperties = rendererProperties as KPISpec;
+
+  $: ({
+    metrics_view: metricsViewName,
+    measure: measureName,
+    time_range: timeRange,
+    sparkline: showSparkline,
+    comparison_range: comparisonTimeRange,
+  } = kpiProperties);
+
+  $: measureQuery = useMetricsViewSpecMeasure(
+    instanceId,
+    metricsViewName,
+    measureName,
+  );
+
+  $: measure = $measureQuery?.data;
+
+  $: measureValue = useKPITotals(
+    instanceId,
+    metricsViewName,
+    measureName,
+    timeRange.toUpperCase(),
+  );
+
+  $: comparisonValue = useKPIComparisonTotal(
+    instanceId,
+    metricsViewName,
+    measureName,
+    comparisonTimeRange?.toUpperCase(),
+    timeRange.toUpperCase(),
+    undefined,
+    queryClient,
+  );
+
+  $: sparkline = useKPISparkline(
+    instanceId,
+    metricsViewName,
+    measureName,
+    timeRange.toUpperCase(),
+    undefined,
+    queryClient,
+  );
+
+  $: sparkData = $sparkline?.data || [];
+
+  const focusedAreaGradient: [string, string] = [
+    MainAreaColorGradientDark,
+    MainAreaColorGradientLight,
+  ];
+
+  $: [yMin, yMax] = extent(sparkData, (d) => d[measureName]);
+  $: [xMin, xMax] = extent(sparkData, (d) => d["ts"]);
+
+  $: measureValueFormatter = measure
+    ? createMeasureValueFormatter<null>(measure, "big-number")
+    : () => "no data";
+
+  $: measureValueFormatted =
+    measureValueFormatter($measureValue.data) ?? "no data";
+
+  $: comparisonPercChange =
+    $comparisonValue.data &&
+    $measureValue.data !== undefined &&
+    $measureValue.data !== null
+      ? ($measureValue.data - $comparisonValue.data) / $comparisonValue.data
+      : undefined;
+
+  $: measureIsPercentage = measure?.formatPreset === FormatPreset.PERCENTAGE;
+
+  function getFormattedDiff(comparisonValue) {
+    const delta = $measureValue.data - comparisonValue;
+    return `${delta >= 0 ? "+" : ""}${measureValueFormatter(delta)}`;
+  }
+</script>
+
+{#if measure}
+  <div
+    bind:clientWidth={containerWidth}
+    bind:clientHeight={containerHeight}
+    class="flex flex-col h-full w-full bg-white p-4"
+  >
+    <div class="flex justify-between items-center mb-2">
+      <span class="font-semibold text-lg truncate pr-2"
+        >{measure?.displayName || measureName}</span
+      >
+      {#if comparisonTimeRange && $comparisonValue.data}
+        <span class="text-sm text-gray-500">
+          vs last {humaniseISODuration(
+            comparisonTimeRange?.toUpperCase(),
+            false,
+          )}
+        </span>
+      {/if}
+    </div>
+
+    <div class="flex justify-between items-center mb-2">
+      <span class="text-2xl font-light">{measureValueFormatted}</span>
+      {#if $comparisonValue.data}
+        <div class="flex items-baseline gap-x-3 text-sm">
+          <div
+            role="complementary"
+            class="w-fit max-w-full overflow-hidden text-ellipsis ui-copy-inactive"
+            class:font-semibold={$measureValue.data >= 0}
+          >
+            {#if $comparisonValue.data != null}
+              {getFormattedDiff($comparisonValue.data)}
+            {:else}
+              <span class="ui-copy-disabled-faint italic" style:font-size=".9em"
+                >no change</span
+              >
+            {/if}
+          </div>
+          {#if comparisonPercChange != null && !measureIsPercentage}
+            <div
+              role="complementary"
+              class="w-fit ui-copy-inactive"
+              class:text-red-500={$measureValue.data < 0}
+            >
+              <PercentageChange
+                tabularNumber={false}
+                value={formatMeasurePercentageDifference(comparisonPercChange)}
+              />
+            </div>
+          {/if}
+        </div>
+      {/if}
+    </div>
+
+    {#if containerHeight && containerWidth && showSparkline && sparkData.length}
+      <SimpleDataGraphic
+        height={containerHeight - 90}
+        width={containerWidth - 16}
+        overflowHidden={false}
+        top={10}
+        bottom={0}
+        right={10}
+        left={0}
+        {xMin}
+        {xMax}
+        {yMin}
+        {yMax}
+      >
+        <ChunkedLine
+          lineColor={MainLineColor}
+          areaGradientColors={focusedAreaGradient}
+          data={sparkData}
+          xAccessor="ts"
+          yAccessor={measureName}
+        />
+      </SimpleDataGraphic>
+    {/if}
+  </div>
+{:else}
+  <div class="flex items-center justify-center w-24">
+    <Spinner status={EntityStatus.Running} />
+  </div>
+{/if}
diff --git a/web-common/src/features/canvas/components/kpi/index.ts b/web-common/src/features/canvas/components/kpi/index.ts
new file mode 100644
index 00000000000..96c27ade821
--- /dev/null
+++ b/web-common/src/features/canvas/components/kpi/index.ts
@@ -0,0 +1,70 @@
+import { BaseCanvasComponent } from "@rilldata/web-common/features/canvas/components/BaseCanvasComponent";
+import {
+  commonOptions,
+  getFilterOptions,
+} from "@rilldata/web-common/features/canvas/components/util";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { type ComponentCommonProperties } from "../types";
+
+export { default as KPI } from "./KPI.svelte";
+
+export interface KPISpec extends ComponentCommonProperties {
+  metrics_view: string;
+  measure: string;
+  time_range: string;
+  sparkline?: boolean;
+  comparison_range?: string;
+}
+
+export class KPIComponent extends BaseCanvasComponent<KPISpec> {
+  minSize = { width: 2, height: 2 };
+  defaultSize = { width: 8, height: 4 };
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[] = [],
+    initialSpec: Partial<KPISpec> = {},
+  ) {
+    const defaultSpec: KPISpec = {
+      metrics_view: "",
+      measure: "",
+      time_range: "PT24H",
+      sparkline: true,
+    };
+    super(fileArtifact, path, defaultSpec, initialSpec);
+  }
+
+  isValid(spec: KPISpec): boolean {
+    return (
+      typeof spec.measure === "string" && typeof spec.time_range === "string"
+    );
+  }
+
+  inputParams(): InputParams<KPISpec> {
+    return {
+      component: {
+        metrics_view: { type: "metrics", label: "Metrics view" },
+        measure: { type: "measure", label: "Measure" },
+        sparkline: { type: "boolean", optional: true, label: "Sparkline" },
+        time_range: { type: "rill_time", label: "Time Range" },
+        comparison_range: {
+          type: "rill_time",
+          label: "Comparison Range",
+          optional: true,
+        },
+        ...commonOptions,
+      },
+      filter: getFilterOptions(),
+    };
+  }
+
+  newComponentSpec(metrics_view: string, measure: string): KPISpec {
+    return {
+      metrics_view,
+      measure,
+      time_range: "PT24H",
+      sparkline: true,
+    };
+  }
+}
diff --git a/web-common/src/features/templates/kpi/selector.ts b/web-common/src/features/canvas/components/kpi/selector.ts
similarity index 98%
rename from web-common/src/features/templates/kpi/selector.ts
rename to web-common/src/features/canvas/components/kpi/selector.ts
index 80df2869890..5d4774e00bf 100644
--- a/web-common/src/features/templates/kpi/selector.ts
+++ b/web-common/src/features/canvas/components/kpi/selector.ts
@@ -14,7 +14,6 @@ export function useKPITotals(
   metricsViewName: string,
   measure: string,
   timeRange: string,
-  whereSql: string | undefined,
 ) {
   return createQueryServiceMetricsViewAggregation(
     instanceId,
@@ -22,7 +21,6 @@ export function useKPITotals(
     {
       measures: [{ name: measure }],
       timeRange: { isoDuration: timeRange },
-      whereSql,
     },
     {
       query: {
diff --git a/web-common/src/features/templates/markdown/Markdown.svelte b/web-common/src/features/canvas/components/markdown/Markdown.svelte
similarity index 80%
rename from web-common/src/features/templates/markdown/Markdown.svelte
rename to web-common/src/features/canvas/components/markdown/Markdown.svelte
index 6642662ba66..ce7b9cd10d3 100644
--- a/web-common/src/features/templates/markdown/Markdown.svelte
+++ b/web-common/src/features/canvas/components/markdown/Markdown.svelte
@@ -1,8 +1,8 @@
 <script lang="ts">
-  import DOMPurify from "dompurify";
-  import { marked } from "marked";
   import type { MarkdownProperties } from "@rilldata/web-common/features/templates/types";
   import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
+  import DOMPurify from "dompurify";
+  import { marked } from "marked";
 
   export let rendererProperties: V1ComponentSpecRendererProperties;
 
@@ -15,10 +15,17 @@
 </script>
 
 <div
-  class="markdown size-full items-center flex justify-center"
+  class="markdown size-full items-center flex justify-center bg-white"
   style={styleString}
 >
   {#await marked(markdownProperties.content) then content}
     {@html DOMPurify.sanitize(content)}
   {/await}
 </div>
+
+<style lang="postcss">
+  :global(.markdown h1) {
+    font-size: 2em;
+    font-weight: 500;
+  }
+</style>
diff --git a/web-common/src/features/canvas/components/markdown/index.ts b/web-common/src/features/canvas/components/markdown/index.ts
new file mode 100644
index 00000000000..1704098a00b
--- /dev/null
+++ b/web-common/src/features/canvas/components/markdown/index.ts
@@ -0,0 +1,49 @@
+import { BaseCanvasComponent } from "@rilldata/web-common/features/canvas/components/BaseCanvasComponent";
+import { commonOptions } from "@rilldata/web-common/features/canvas/components/util";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { type ComponentCommonProperties } from "../types";
+
+export { default as Markdown } from "./Markdown.svelte";
+
+export interface MarkdownSpec extends ComponentCommonProperties {
+  content: string;
+}
+
+export class MarkdownCanvasComponent extends BaseCanvasComponent<MarkdownSpec> {
+  minSize = { width: 1, height: 1 };
+  defaultSize = { width: 6, height: 2 };
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[] = [],
+    initialSpec: Partial<MarkdownSpec> = {},
+  ) {
+    const defaultSpec: MarkdownSpec = {
+      title: "",
+      description: "",
+      content: "Your text",
+    };
+    super(fileArtifact, path, defaultSpec, initialSpec);
+  }
+
+  isValid(spec: MarkdownSpec): boolean {
+    return typeof spec.content === "string" && spec.content.trim().length > 0;
+  }
+
+  inputParams(): InputParams<MarkdownSpec> {
+    return {
+      component: {
+        content: { type: "textArea" },
+        ...commonOptions,
+      },
+      filter: [],
+    };
+  }
+
+  newComponentSpec(): MarkdownSpec {
+    return {
+      content: "Markdown Text",
+    };
+  }
+}
diff --git a/web-common/src/features/canvas/components/selectors.ts b/web-common/src/features/canvas/components/selectors.ts
new file mode 100644
index 00000000000..81a308d6c50
--- /dev/null
+++ b/web-common/src/features/canvas/components/selectors.ts
@@ -0,0 +1,40 @@
+import { useMetricsViewValidSpec } from "@rilldata/web-common/features/dashboards/selectors";
+
+export const useMetricsViewSpecMeasure = (
+  instanceId: string,
+  metricsViewName: string,
+  measureName: string,
+) =>
+  useMetricsViewValidSpec(instanceId, metricsViewName, (meta) =>
+    meta?.measures?.find((measure) => measure.name === measureName),
+  );
+
+export const useMetricsViewSpecDimension = (
+  instanceId: string,
+  metricsViewName: string,
+  dimensionName: string,
+) =>
+  useMetricsViewValidSpec(instanceId, metricsViewName, (meta) =>
+    meta?.dimensions?.find(
+      (dimension) =>
+        dimension.name === dimensionName || dimension.column === dimensionName,
+    ),
+  );
+
+export function useMeasureDimensionSpec(
+  instanceId: string,
+  metricsViewName: string,
+  fields: { name: string; type: "dimension" | "measure" }[],
+) {
+  return fields.map((field) => {
+    if (field.type === "measure") {
+      return useMetricsViewSpecMeasure(instanceId, metricsViewName, field.name);
+    } else {
+      return useMetricsViewSpecDimension(
+        instanceId,
+        metricsViewName,
+        field.name,
+      );
+    }
+  });
+}
diff --git a/web-common/src/features/templates/table/TableRenderer.svelte b/web-common/src/features/canvas/components/table/TableRenderer.svelte
similarity index 99%
rename from web-common/src/features/templates/table/TableRenderer.svelte
rename to web-common/src/features/canvas/components/table/TableRenderer.svelte
index 8c13f90f6af..bbb361c5a00 100644
--- a/web-common/src/features/templates/table/TableRenderer.svelte
+++ b/web-common/src/features/canvas/components/table/TableRenderer.svelte
@@ -426,8 +426,8 @@
 
   .table-wrapper {
     @apply overflow-auto h-fit max-h-full w-fit max-w-full;
-    @apply border z-40;
-    width: calc(100% - 5px);
+    @apply bg-white border z-40;
+    width: 100%;
   }
 
   /* Pin header */
@@ -445,11 +445,6 @@
     @apply border-r border-b relative;
   }
 
-  th:last-of-type,
-  td:last-of-type {
-    @apply border-r-0;
-  }
-
   th,
   td {
     @apply whitespace-nowrap text-xs;
diff --git a/web-common/src/features/templates/table/TableTemplate.svelte b/web-common/src/features/canvas/components/table/TableTemplate.svelte
similarity index 95%
rename from web-common/src/features/templates/table/TableTemplate.svelte
rename to web-common/src/features/canvas/components/table/TableTemplate.svelte
index adf831da84e..92273aac1e9 100644
--- a/web-common/src/features/templates/table/TableTemplate.svelte
+++ b/web-common/src/features/canvas/components/table/TableTemplate.svelte
@@ -7,13 +7,13 @@
     type PivotState,
   } from "@rilldata/web-common/features/dashboards/pivot/types";
   import { createStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers";
-  import TableRenderer from "@rilldata/web-common/features/templates/table/TableRenderer.svelte";
   import type { TableProperties } from "@rilldata/web-common/features/templates/types";
   import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
   import { useQueryClient } from "@tanstack/svelte-query";
   import { type Readable, writable } from "svelte/store";
   import { getTableConfig, hasValidTableSchema } from "./selector";
+  import TableRenderer from "./TableRenderer.svelte";
 
   export let rendererProperties: V1ComponentSpecRendererProperties;
 
@@ -78,7 +78,7 @@
   }
 </script>
 
-<div class="overflow-y-scroll">
+<div class="overflow-y-auto">
   {#if !isValidSchema}
     <div>{$tableSchema.error}</div>
   {:else if pivotDataStore && pivotConfig && $pivotConfig}
diff --git a/web-common/src/features/canvas/components/table/index.ts b/web-common/src/features/canvas/components/table/index.ts
new file mode 100644
index 00000000000..114ca2ddf21
--- /dev/null
+++ b/web-common/src/features/canvas/components/table/index.ts
@@ -0,0 +1,85 @@
+import { BaseCanvasComponent } from "@rilldata/web-common/features/canvas/components/BaseCanvasComponent";
+import {
+  commonOptions,
+  getFilterOptions,
+} from "@rilldata/web-common/features/canvas/components/util";
+import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { type ComponentCommonProperties } from "../types";
+
+export { default as Table } from "./TableTemplate.svelte";
+
+export interface TableSpec extends ComponentCommonProperties {
+  metrics_view: string;
+  time_range: string;
+  measures: string[];
+  comparison_range?: string;
+  row_dimensions?: string[];
+  col_dimensions?: string[];
+}
+
+export class TableCanvasComponent extends BaseCanvasComponent<TableSpec> {
+  minSize = { width: 2, height: 2 };
+  defaultSize = { width: 16, height: 10 };
+
+  constructor(
+    fileArtifact: FileArtifact,
+    path: (string | number)[] = [],
+    initialSpec: Partial<TableSpec> = {},
+  ) {
+    const defaultSpec: TableSpec = {
+      metrics_view: "",
+      measures: [],
+      time_range: "",
+      comparison_range: "",
+      row_dimensions: [],
+      col_dimensions: [],
+    };
+    super(fileArtifact, path, defaultSpec, initialSpec);
+  }
+
+  isValid(spec: TableSpec): boolean {
+    return (
+      typeof spec.time_range === "string" &&
+      ((Array.isArray(spec.measures) && spec.measures.length > 0) ||
+        (Array.isArray(spec.row_dimensions) &&
+          spec.row_dimensions.length > 0) ||
+        (Array.isArray(spec.col_dimensions) && spec.col_dimensions.length > 0))
+    );
+  }
+
+  inputParams(): InputParams<TableSpec> {
+    return {
+      component: {
+        metrics_view: { type: "metrics", label: "Metrics view" },
+        measures: { type: "multi_measures", label: "Measures" },
+        col_dimensions: {
+          type: "multi_dimensions",
+          label: "Column dimensions",
+        },
+        row_dimensions: { type: "multi_dimensions", label: "Row dimensions" },
+        time_range: { type: "rill_time", label: "Time range" },
+        comparison_range: {
+          type: "rill_time",
+          label: "Comparison range",
+          optional: true,
+        },
+        ...commonOptions,
+      },
+      filter: getFilterOptions(),
+    };
+  }
+
+  newComponentSpec(
+    metrics_view: string,
+    measure: string,
+    dimension: string,
+  ): TableSpec {
+    return {
+      metrics_view,
+      measures: [measure],
+      row_dimensions: [dimension],
+      time_range: "PT24H",
+    };
+  }
+}
diff --git a/web-common/src/features/templates/table/selector.ts b/web-common/src/features/canvas/components/table/selector.ts
similarity index 98%
rename from web-common/src/features/templates/table/selector.ts
rename to web-common/src/features/canvas/components/table/selector.ts
index 35b2d2aa1a4..05d8a3a9487 100644
--- a/web-common/src/features/templates/table/selector.ts
+++ b/web-common/src/features/canvas/components/table/selector.ts
@@ -1,3 +1,4 @@
+import { useStartEndTime } from "@rilldata/web-common/features/canvas/components/kpi/selector";
 import { canEnablePivotComparison } from "@rilldata/web-common/features/dashboards/pivot/pivot-utils";
 import {
   COMPARISON_DELTA,
@@ -10,7 +11,6 @@ import {
   useMetricsViewValidSpec,
 } from "@rilldata/web-common/features/dashboards/selectors";
 import { createAndExpression } from "@rilldata/web-common/features/dashboards/stores/filter-utils";
-import { useStartEndTime } from "@rilldata/web-common/features/templates/kpi/selector";
 import type { TableProperties } from "@rilldata/web-common/features/templates/types";
 import {
   validateDimensions,
diff --git a/web-common/src/features/canvas/components/types.ts b/web-common/src/features/canvas/components/types.ts
new file mode 100644
index 00000000000..2e179f57bc2
--- /dev/null
+++ b/web-common/src/features/canvas/components/types.ts
@@ -0,0 +1,113 @@
+import type { Writable } from "svelte/store";
+import type { InputParams } from "../inspector/types";
+import type { ChartConfig, ChartType } from "./charts/types";
+import type { ImageSpec } from "./image";
+import type { KPISpec } from "./kpi";
+import type { MarkdownSpec } from "./markdown";
+import type { TableSpec } from "./table";
+
+// First, let's create a union type for all possible specs
+export type ComponentSpec =
+  | ChartConfig
+  | TableSpec
+  | ImageSpec
+  | KPISpec
+  | MarkdownSpec;
+
+// The CanvasComponent interface is generic over the spec type.
+export interface CanvasComponent<T> {
+  /**
+   * Svelte writable for the spec
+   */
+  specStore: Writable<T>;
+
+  /**
+   * Path in the YAML where the component is stored
+   */
+  pathInYAML: (string | number)[];
+
+  /**
+   * Minimum allowed size for the component
+   * container on the canvas
+   */
+  minSize: ComponentSize;
+
+  /**
+   * The default size of the container when the component
+   * is added to the canvas
+   */
+  defaultSize: ComponentSize;
+
+  /**
+   * The minimum condition needed for the spec to be valid
+   * for the given component and to be rendered on the canvas
+   */
+  isValid(spec: T): boolean;
+
+  /**
+   * A map of input params which will be used in the visual
+   * UI builder
+   */
+  inputParams(): InputParams<T>;
+
+  /**
+   * Get the spec when the component is added to the canvas
+   */
+  newComponentSpec(metrics_view: string, measure: string, dimension: string): T;
+
+  /**
+   * Update the spec store with the new values
+   */
+  updateProperty(key: string, value: unknown): Promise<void>;
+
+  /**
+   * Set the spec store with the new values
+   */
+  setSpec(spec: T): Promise<void>;
+}
+
+export interface ComponentCommonProperties {
+  title?: string;
+  description?: string;
+}
+
+export interface ComponentSize {
+  width: number;
+  height: number;
+}
+
+export type CanvasComponentType =
+  | ChartType
+  | "markdown"
+  | "kpi"
+  | "image"
+  | "table";
+
+interface LineChart {
+  line_chart: ChartConfig;
+}
+
+interface BarChart {
+  bar_chart: ChartConfig;
+}
+
+export type ChartTemplates = LineChart | BarChart;
+export interface KPITemplateT {
+  kpi: KPISpec;
+}
+export interface MarkdownTemplateT {
+  markdown: MarkdownSpec;
+}
+export interface ImageTemplateT {
+  image: ImageSpec;
+}
+export interface TableTemplateT {
+  table: TableSpec;
+}
+
+export type TemplateSpec =
+  | ChartTemplates
+  | KPITemplateT
+  | TableTemplateT
+  | MarkdownTemplateT
+  | ImageTemplateT;
diff --git a/web-common/src/features/canvas/components/util.ts b/web-common/src/features/canvas/components/util.ts
new file mode 100644
index 00000000000..35dd86ddf75
--- /dev/null
+++ b/web-common/src/features/canvas/components/util.ts
@@ -0,0 +1,125 @@
+import type {
+  ComponentInputParam,
+  FilterInputParam,
+  FilterInputTypes,
+} from "@rilldata/web-common/features/canvas/inspector/types";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { ChartComponent } from "./charts";
+import { ImageComponent } from "./image";
+import { KPIComponent } from "./kpi";
+import { MarkdownCanvasComponent } from "./markdown";
+import { TableCanvasComponent } from "./table";
+import type { CanvasComponentType, ComponentCommonProperties } from "./types";
+
+export const commonOptions: Record<
+  keyof ComponentCommonProperties,
+  ComponentInputParam
+> = {
+  title: { type: "text", optional: true, showInUI: true, label: "Title" },
+  description: {
+    type: "text",
+    optional: true,
+    showInUI: true,
+    label: "Description",
+  },
+  // position: { type: "text", showInUI: false },
+};
+
+export function getFilterOptions(
+  includeComparisonRange = true,
+): Partial<Record<FilterInputTypes, FilterInputParam>> {
+  const options: Partial<Record<FilterInputTypes, FilterInputParam>> = {
+    time_range: { type: "time_range", label: "Time Range" },
+    dimension_filters: {
+      type: "dimension_filters",
+      label: "Dimension Filters",
+    },
+  };
+  if (includeComparisonRange) {
+    options.comparison_range = {
+      type: "comparison_range",
+      label: "Comparison Range",
+    };
+  }
+  return options;
+}
+
+export const getComponentObj = (
+  fileArtifact: FileArtifact,
+  path: (string | number)[],
+  type: CanvasComponentType,
+  params: Record<string, unknown>,
+) => {
+  switch (type) {
+    case "markdown":
+      return new MarkdownCanvasComponent(fileArtifact, path, params);
+    case "kpi":
+      return new KPIComponent(fileArtifact, path, params);
+    case "image":
+      return new ImageComponent(fileArtifact, path, params);
+    case "table":
+      return new TableCanvasComponent(fileArtifact, path, params);
+    default:
+      return new ChartComponent(fileArtifact, path, params);
+  }
+};
+
+export type CanvasComponentObj = ReturnType<typeof getComponentObj>;
+
+// TODO: Apply DRY
+export function isCanvasComponentType(
+  value: string | undefined,
+): value is CanvasComponentType {
+  if (!value) return false;
+  return [
+    "line_chart",
+    "bar_chart",
+    "stacked_bar",
+    "markdown",
+    "kpi",
+    "image",
+    "table",
+  ].includes(value as CanvasComponentType);
+}
+
+export function isChartComponentType(
+  value: string | undefined,
+): value is CanvasComponentType {
+  if (!value) return false;
+  return ["line_chart", "bar_chart", "stacked_bar"].includes(
+    value as CanvasComponentType,
+  );
+}
+
+export function getComponentRegistry(
+  fileArtifact: FileArtifact,
+): Record<CanvasComponentType, CanvasComponentObj> {
+  return {
+    kpi: new KPIComponent(fileArtifact),
+    markdown: new MarkdownCanvasComponent(fileArtifact),
+    table: new TableCanvasComponent(fileArtifact),
+    image: new ImageComponent(fileArtifact),
+    bar_chart: new ChartComponent(fileArtifact),
+    line_chart: new ChartComponent(fileArtifact),
+    stacked_bar: new ChartComponent(fileArtifact),
+  };
+}
+
+// TODO: Move to config
+const displayMap: Record<CanvasComponentType, string> = {
+  kpi: "KPI",
+  markdown: "Markdown",
+  table: "Table",
+  image: "Image",
+  bar_chart: "Chart",
+  line_chart: "Chart",
+  stacked_bar: "Chart",
+};
+
+export function getHeaderForComponent(componentType: string | undefined) {
+  if (!componentType) return "Component";
+  if (!displayMap[componentType as CanvasComponentType]) {
+    return "Component";
+  }
+  return displayMap[componentType as CanvasComponentType];
+}
diff --git a/web-common/src/features/canvas/constants.ts b/web-common/src/features/canvas/constants.ts
index 57bb5932ce9..cac65410b17 100644
--- a/web-common/src/features/canvas/constants.ts
+++ b/web-common/src/features/canvas/constants.ts
@@ -1,4 +1,4 @@
-export const DASHBOARD_WIDTH = 1600;
+export const DASHBOARD_WIDTH = 1200;
 export const COMPONENT_RADIUS = 0.08;
 export const FONT_SIZE = 40;
 export const COMPONENT_WIDTH = 1;
diff --git a/web-common/src/features/canvas/filters/CanvasComparisonPill.svelte b/web-common/src/features/canvas/filters/CanvasComparisonPill.svelte
new file mode 100644
index 00000000000..273fa7e689f
--- /dev/null
+++ b/web-common/src/features/canvas/filters/CanvasComparisonPill.svelte
@@ -0,0 +1,131 @@
+<script lang="ts">
+  import Label from "@rilldata/web-common/components/forms/Label.svelte";
+  import Switch from "@rilldata/web-common/components/forms/Switch.svelte";
+  import { getComparisonOptionsForCanvas } from "@rilldata/web-common/features/canvas/filters/util";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { Comparison } from "@rilldata/web-common/features/dashboards/time-controls/super-pill/components";
+  import {
+    TimeComparisonOption,
+    TimeRangePreset,
+    type DashboardTimeControls,
+    type TimeRange,
+  } from "@rilldata/web-common/lib/time/types";
+  import { DateTime, Interval } from "luxon";
+
+  export let allTimeRange: TimeRange;
+  export let selectedTimeRange: DashboardTimeControls | undefined;
+  export let selectedComparisonTimeRange: DashboardTimeControls | undefined;
+
+  const { canvasEntity } = getCanvasStateManagers();
+
+  const { timeControls } = canvasEntity;
+
+  $: showTimeComparison = timeControls.showTimeComparison;
+  $: activeTimeZone = timeControls?.selectedTimezone;
+
+  $: interval = selectedTimeRange
+    ? Interval.fromDateTimes(
+        DateTime.fromJSDate(selectedTimeRange.start).setZone($activeTimeZone),
+        DateTime.fromJSDate(selectedTimeRange.end).setZone($activeTimeZone),
+      )
+    : Interval.fromDateTimes(allTimeRange.start, allTimeRange.end);
+
+  $: activeTimeGrain = selectedTimeRange?.interval;
+
+  $: comparisonOptions = getComparisonOptionsForCanvas(selectedTimeRange);
+
+  function onSelectComparisonRange(
+    name: TimeComparisonOption,
+    start: Date,
+    end: Date,
+  ) {
+    timeControls.setSelectedComparisonRange({
+      name,
+      start,
+      end,
+    });
+
+    if (!$showTimeComparison) {
+      timeControls.displayTimeComparison(!$showTimeComparison);
+    }
+  }
+
+  $: disabled =
+    selectedTimeRange?.name === TimeRangePreset.ALL_TIME || undefined;
+</script>
+
+<div
+  class="wrapper"
+  title={disabled && "Comparison not available when viewing all time range"}
+>
+  <button
+    {disabled}
+    class="flex gap-x-1.5 cursor-pointer"
+    on:click={() => {
+      timeControls.displayTimeComparison(!$showTimeComparison);
+    }}
+  >
+    <div class="pointer-events-none flex items-center gap-x-1.5">
+      <Switch
+        checked={$showTimeComparison}
+        id="comparing"
+        small
+        disabled={disabled ?? false}
+      />
+
+      <Label class="font-normal text-xs cursor-pointer" for="comparing">
+        <span class:opacity-50={disabled}>Comparing</span>
+      </Label>
+    </div>
+  </button>
+  {#if activeTimeGrain && interval.isValid}
+    <Comparison
+      maxDate={DateTime.fromJSDate(allTimeRange.end)}
+      minDate={DateTime.fromJSDate(allTimeRange.start)}
+      timeComparisonOptionsState={comparisonOptions}
+      selectedComparison={selectedComparisonTimeRange}
+      showComparison={$showTimeComparison}
+      currentInterval={interval}
+      grain={activeTimeGrain}
+      zone={$activeTimeZone}
+      {onSelectComparisonRange}
+      disabled={disabled ?? false}
+    />
+  {/if}
+</div>
+
+<style lang="postcss">
+  .wrapper {
+    @apply flex w-fit;
+    @apply h-7 rounded-full;
+    @apply overflow-hidden select-none;
+  }
+
+  :global(.wrapper > button) {
+    @apply border;
+  }
+
+  :global(.wrapper > button:not(:first-child)) {
+    @apply -ml-[1px];
+  }
+
+  :global(.wrapper > button) {
+    @apply border;
+    @apply px-2 flex items-center justify-center bg-white;
+  }
+
+  :global(.wrapper > button:first-child) {
+    @apply pl-2.5 rounded-l-full;
+  }
+  :global(.wrapper > button:last-child) {
+    @apply pr-2.5 rounded-r-full;
+  }
+
+  :global(.wrapper > button:hover:not(:disabled)) {
+    @apply bg-gray-50 cursor-pointer;
+  }
+
+  :global(.wrapper > [data-state="open"]) {
+    @apply bg-gray-50 border-gray-400 z-50;
+  }
+</style>
diff --git a/web-common/src/features/canvas/filters/CanvasFilters.svelte b/web-common/src/features/canvas/filters/CanvasFilters.svelte
new file mode 100644
index 00000000000..f59a3dc3b02
--- /dev/null
+++ b/web-common/src/features/canvas/filters/CanvasFilters.svelte
@@ -0,0 +1,41 @@
+<script lang="ts">
+  import Calendar from "@rilldata/web-common/components/icons/Calendar.svelte";
+  import CanvasGrainSelector from "@rilldata/web-common/features/canvas/filters/CanvasGrainSelector.svelte";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { TimeRangePreset } from "@rilldata/web-common/lib/time/types";
+  import CanvasComparisonPill from "./CanvasComparisonPill.svelte";
+  import CanvasSuperPill from "./CanvasSuperPill.svelte";
+
+  const { canvasEntity } = getCanvasStateManagers();
+  const { timeControls } = canvasEntity;
+
+  $: selectedTimeRange = timeControls.selectedTimeRange;
+  $: selectedComparisonTimeRange = timeControls?.selectedComparisonTimeRange;
+  $: activeTimeZone = timeControls.selectedTimezone;
+
+  const allTimeRange = {
+    name: TimeRangePreset.ALL_TIME,
+    start: new Date(0),
+    end: new Date(),
+  };
+</script>
+
+<div class="flex flex-col gap-y-2 w-full h-20 justify-center ml-2">
+  <div class="flex flex-row flex-wrap gap-x-2 gap-y-1.5 items-center">
+    <Calendar size="16px" />
+    <CanvasSuperPill
+      {allTimeRange}
+      selectedTimeRange={$selectedTimeRange}
+      activeTimeZone={$activeTimeZone}
+    />
+    <CanvasComparisonPill
+      {allTimeRange}
+      selectedTimeRange={$selectedTimeRange}
+      selectedComparisonTimeRange={$selectedComparisonTimeRange}
+    />
+    <CanvasGrainSelector
+      selectedTimeRange={$selectedTimeRange}
+      selectedComparisonTimeRange={$selectedComparisonTimeRange}
+    />
+  </div>
+</div>
diff --git a/web-common/src/features/canvas/filters/CanvasGrainSelector.svelte b/web-common/src/features/canvas/filters/CanvasGrainSelector.svelte
new file mode 100644
index 00000000000..f878e53e672
--- /dev/null
+++ b/web-common/src/features/canvas/filters/CanvasGrainSelector.svelte
@@ -0,0 +1,119 @@
+<script lang="ts">
+  import Chip from "@rilldata/web-common/components/chip/core/Chip.svelte";
+  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { TIME_GRAIN } from "@rilldata/web-common/lib/time/config";
+  import {
+    getAllowedTimeGrains,
+    isGrainBigger,
+  } from "@rilldata/web-common/lib/time/grains";
+  import type {
+    AvailableTimeGrain,
+    DashboardTimeControls,
+    TimeGrain,
+    TimeRange,
+  } from "@rilldata/web-common/lib/time/types";
+  import { V1TimeGrain } from "@rilldata/web-common/runtime-client";
+
+  export let selectedTimeRange: DashboardTimeControls | undefined;
+  export let selectedComparisonTimeRange: DashboardTimeControls | undefined;
+
+  const { canvasEntity } = getCanvasStateManagers();
+
+  let timeGrainOptions: TimeGrain[];
+  // TODO: Change this
+  let minTimeGrain = V1TimeGrain.TIME_GRAIN_UNSPECIFIED;
+  let open = false;
+
+  $: timeGrainOptions =
+    selectedTimeRange?.start && selectedTimeRange?.end
+      ? getAllowedTimeGrains(
+          new Date(selectedTimeRange.start),
+          new Date(selectedTimeRange.end),
+        )
+      : [];
+
+  $: baseTimeRange = selectedTimeRange?.start &&
+    selectedTimeRange?.end && {
+      name: selectedTimeRange?.name,
+      start: selectedTimeRange.start,
+      end: selectedTimeRange.end,
+    };
+
+  $: activeTimeGrain = selectedTimeRange?.interval;
+  $: activeTimeGrainLabel =
+    activeTimeGrain && TIME_GRAIN[activeTimeGrain as AvailableTimeGrain]?.label;
+
+  $: capitalizedLabel = activeTimeGrainLabel
+    ?.split(" ")
+    .map((word) => {
+      return word.charAt(0).toUpperCase() + word.slice(1);
+    })
+    .join(" ");
+
+  $: timeGrains = minTimeGrain
+    ? timeGrainOptions
+        .filter((timeGrain) => !isGrainBigger(minTimeGrain, timeGrain.grain))
+        .map((timeGrain) => {
+          return {
+            main: timeGrain.label,
+            key: timeGrain.grain,
+          };
+        })
+    : [];
+
+  function onTimeGrainSelect(timeGrain: V1TimeGrain) {
+    if (baseTimeRange) {
+      makeTimeSeriesTimeRangeAndUpdateAppState(
+        baseTimeRange,
+        timeGrain,
+        selectedComparisonTimeRange,
+      );
+    }
+  }
+
+  function makeTimeSeriesTimeRangeAndUpdateAppState(
+    timeRange: TimeRange,
+    timeGrain: V1TimeGrain,
+    /** we should only reset the comparison range when the user has explicitly chosen a new
+     * time range. Otherwise, the current comparison state should continue to be the
+     * source of truth.
+     */
+    comparisonTimeRange: DashboardTimeControls | undefined,
+  ) {
+    canvasEntity.timeControls.selectTimeRange(
+      timeRange,
+      timeGrain,
+      comparisonTimeRange,
+    );
+  }
+</script>
+
+{#if activeTimeGrain && timeGrainOptions.length && minTimeGrain}
+  <DropdownMenu.Root bind:open>
+    <DropdownMenu.Trigger asChild let:builder>
+      <Chip
+        type="time"
+        builders={[builder]}
+        active={open}
+        label="Select a time grain"
+      >
+        <div slot="body" class="flex gap-x-2 items-center">
+          <span>by {capitalizedLabel}</span>
+        </div>
+      </Chip>
+    </DropdownMenu.Trigger>
+    <DropdownMenu.Content class="min-w-40" align="start">
+      {#each timeGrains as option (option.key)}
+        <DropdownMenu.CheckboxItem
+          role="menuitem"
+          checked={option.key === activeTimeGrain}
+          class="text-xs cursor-pointer"
+          on:click={() => onTimeGrainSelect(option.key)}
+        >
+          {option.main}
+        </DropdownMenu.CheckboxItem>
+      {/each}
+    </DropdownMenu.Content>
+  </DropdownMenu.Root>
+{/if}
diff --git a/web-common/src/features/canvas/filters/CanvasSuperPill.svelte b/web-common/src/features/canvas/filters/CanvasSuperPill.svelte
new file mode 100644
index 00000000000..6530a993d07
--- /dev/null
+++ b/web-common/src/features/canvas/filters/CanvasSuperPill.svelte
@@ -0,0 +1,255 @@
+<script lang="ts">
+  import { getTimeRangeForCanvas } from "@rilldata/web-common/features/canvas/filters/util";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import { getPanRangeForTimeRange } from "@rilldata/web-common/features/dashboards/state-managers/selectors/charts";
+  import {
+    ALL_TIME_RANGE_ALIAS,
+    CUSTOM_TIME_RANGE_ALIAS,
+    deriveInterval,
+    type ISODurationString,
+    type NamedRange,
+    type RangeBuckets,
+  } from "@rilldata/web-common/features/dashboards/time-controls/new-time-controls";
+  import * as Elements from "@rilldata/web-common/features/dashboards/time-controls/super-pill/components";
+  import { initLocalUserPreferenceStore } from "@rilldata/web-common/features/dashboards/user-preferences";
+  import { DEFAULT_TIME_RANGES } from "@rilldata/web-common/lib/time/config";
+  import { getDefaultTimeGrain } from "@rilldata/web-common/lib/time/grains";
+  import {
+    TimeComparisonOption,
+    TimeRangePreset,
+    type DashboardTimeControls,
+    type TimeRange,
+  } from "@rilldata/web-common/lib/time/types";
+  import type { V1TimeGrain } from "@rilldata/web-common/runtime-client";
+  import { DateTime, Interval } from "luxon";
+
+  export let allTimeRange: TimeRange;
+  export let selectedTimeRange: DashboardTimeControls | undefined;
+  export let activeTimeZone: string;
+
+  const ctx = getCanvasStateManagers();
+  const { canvasName, canvasEntity } = ctx;
+  const { timeControls } = canvasEntity;
+
+  $: localUserPreferences = initLocalUserPreferenceStore($canvasName);
+
+  // $: canvasSpec = $validSpecStore.data;
+
+  $: selectedRange = selectedTimeRange?.name ?? ALL_TIME_RANGE_ALIAS;
+
+  // TODO: Add default timeRange to resource
+  // $: defaultTimeRange = $validSpecStore?.data?.defaultPreset?.timeRange;
+  let defaultTimeRange = "PT24H";
+
+  $: interval = selectedTimeRange
+    ? Interval.fromDateTimes(
+        DateTime.fromJSDate(selectedTimeRange.start).setZone(activeTimeZone),
+        DateTime.fromJSDate(selectedTimeRange.end).setZone(activeTimeZone),
+      )
+    : Interval.fromDateTimes(allTimeRange.start, allTimeRange.end);
+
+  // TODO: Add timezone key to resource
+  // $: availableTimeZones = canvasSpec?.timeZones ?? [];
+  let availableTimeZones = [
+    "America/Los_Angeles",
+    "America/New_York",
+    "Europe/London",
+    "Asia/Kolkata",
+  ];
+
+  $: ({
+    latestWindowTimeRanges,
+    periodToDateRanges,
+    previousCompleteDateRanges,
+    showDefaultItem,
+  } = getTimeRangeForCanvas(activeTimeZone));
+
+  $: ranges = <RangeBuckets>{
+    latest: latestWindowTimeRanges.map((range) => ({
+      range: range.name,
+      label: range.label,
+    })),
+    periodToDate: periodToDateRanges.map((range) => ({
+      range: range.name,
+      label: range.label,
+    })),
+    previous: previousCompleteDateRanges.map((range) => ({
+      range: range.name,
+      label: range.label,
+    })),
+  };
+
+  $: activeTimeGrain = selectedTimeRange?.interval;
+
+  function onSelectTimeZone(timeZone: string) {
+    if (!interval.isValid) return;
+
+    if (selectedRange === "CUSTOM") {
+      selectRange({
+        name: TimeRangePreset.CUSTOM,
+        start: interval.start
+          ?.setZone(timeZone, { keepLocalTime: true })
+          .toJSDate(),
+        end: interval.end
+          ?.setZone(timeZone, { keepLocalTime: true })
+          .toJSDate(),
+      });
+    }
+
+    timeControls.setTimeZone(timeZone);
+    localUserPreferences.set({ timeZone });
+  }
+
+  function onSelectRange(name: NamedRange | ISODurationString) {
+    if (!allTimeRange?.end) {
+      return;
+    }
+
+    if (name === ALL_TIME_RANGE_ALIAS) {
+      makeTimeSeriesTimeRangeAndUpdateAppState(
+        allTimeRange,
+        "TIME_GRAIN_DAY",
+        undefined,
+      );
+      return;
+    }
+
+    const interval = deriveInterval(
+      name,
+      DateTime.fromJSDate(allTimeRange.end),
+    );
+    if (!interval?.isValid) return;
+
+    const baseTimeRange: TimeRange = {
+      name: name as TimeRangePreset,
+      start: interval.start.toJSDate(),
+      end: interval.end.toJSDate(),
+    };
+
+    selectRange(baseTimeRange);
+  }
+
+  function selectRange(range: TimeRange) {
+    const defaultTimeGrain = getDefaultTimeGrain(range.start, range.end).grain;
+
+    const comparisonOption = DEFAULT_TIME_RANGES[range.name as TimeRangePreset]
+      ?.defaultComparison as TimeComparisonOption;
+
+    // Get valid option for the new time range
+    const validComparison = allTimeRange && comparisonOption;
+
+    makeTimeSeriesTimeRangeAndUpdateAppState(range, defaultTimeGrain, {
+      name: validComparison,
+    } as DashboardTimeControls);
+  }
+
+  function makeTimeSeriesTimeRangeAndUpdateAppState(
+    timeRange: TimeRange,
+    timeGrain: V1TimeGrain,
+    /** we should only reset the comparison range when the user has explicitly chosen a new
+     * time range. Otherwise, the current comparison state should continue to be the
+     * source of truth.
+     */
+    comparisonTimeRange: DashboardTimeControls | undefined,
+  ) {
+    timeControls.selectTimeRange(timeRange, timeGrain, comparisonTimeRange);
+  }
+
+  function onPan(direction: "left" | "right") {
+    const getPanRange = getPanRangeForTimeRange(
+      selectedTimeRange,
+      activeTimeZone,
+    );
+    const panRange = getPanRange(direction);
+    if (!panRange) return;
+    const { start, end } = panRange;
+
+    const timeRange = {
+      name: CUSTOM_TIME_RANGE_ALIAS,
+      start: start,
+      end: end,
+    };
+
+    const comparisonTimeRange = {
+      name: TimeComparisonOption.CONTIGUOUS,
+    } as DashboardTimeControls; // FIXME wrong typecasting across application
+
+    if (!activeTimeGrain) return;
+    timeControls.selectTimeRange(
+      timeRange as TimeRange,
+      activeTimeGrain,
+      comparisonTimeRange,
+    );
+  }
+</script>
+
+<div class="wrapper">
+  <Elements.Nudge canPanLeft canPanRight {onPan} direction="left" />
+  <Elements.Nudge canPanLeft canPanRight {onPan} direction="right" />
+  {#if interval.isValid && activeTimeGrain}
+    <Elements.RangePicker
+      minDate={DateTime.fromJSDate(allTimeRange.start)}
+      maxDate={DateTime.fromJSDate(allTimeRange.end)}
+      {ranges}
+      {showDefaultItem}
+      {defaultTimeRange}
+      selected={selectedRange}
+      grain={activeTimeGrain}
+      {onSelectRange}
+      {interval}
+      zone={activeTimeZone}
+      applyCustomRange={(interval) => {
+        selectRange({
+          name: TimeRangePreset.CUSTOM,
+          start: interval.start.toJSDate(),
+          end: interval.end.toJSDate(),
+        });
+      }}
+    />
+  {/if}
+
+  {#if availableTimeZones.length}
+    <Elements.Zone
+      watermark={allTimeRange?.end ?? new Date()}
+      {activeTimeZone}
+      {availableTimeZones}
+      {onSelectTimeZone}
+    />
+  {/if}
+</div>
+
+<style lang="postcss">
+  .wrapper {
+    @apply flex w-fit;
+    @apply h-[26px] rounded-full;
+    @apply overflow-hidden;
+  }
+
+  :global(.wrapper > button) {
+    @apply border;
+  }
+
+  :global(.wrapper > button:not(:first-child)) {
+    @apply -ml-[1px];
+  }
+
+  :global(.wrapper > button) {
+    @apply border;
+    @apply px-2 flex items-center justify-center bg-white;
+  }
+
+  :global(.wrapper > button:first-child) {
+    @apply pl-2.5 rounded-l-full;
+  }
+  :global(.wrapper > button:last-child) {
+    @apply pr-2.5 rounded-r-full;
+  }
+
+  :global(.wrapper > button:hover:not(:disabled)) {
+    @apply bg-gray-50 cursor-pointer;
+  }
+
+  :global(.wrapper > [data-state="open"]) {
+    @apply bg-gray-50 border-gray-400 z-50;
+  }
+</style>
diff --git a/web-common/src/features/canvas/filters/util.ts b/web-common/src/features/canvas/filters/util.ts
new file mode 100644
index 00000000000..b012ecbee47
--- /dev/null
+++ b/web-common/src/features/canvas/filters/util.ts
@@ -0,0 +1,107 @@
+import {
+  getAvailableComparisonsForTimeRange,
+  getComparisonRange,
+} from "@rilldata/web-common/lib/time/comparisons";
+import {
+  LATEST_WINDOW_TIME_RANGES,
+  PERIOD_TO_DATE_RANGES,
+  PREVIOUS_COMPLETE_DATE_RANGES,
+} from "@rilldata/web-common/lib/time/config";
+import { getChildTimeRanges } from "@rilldata/web-common/lib/time/ranges";
+import {
+  TimeComparisonOption,
+  TimeRangePreset,
+  type DashboardTimeControls,
+} from "@rilldata/web-common/lib/time/types";
+import { V1TimeGrain } from "@rilldata/web-common/runtime-client";
+
+export function getTimeRangeForCanvas(
+  selectedTimezone: string,
+  defaultTimeRange?: string,
+) {
+  const allTimeRange = {
+    name: TimeRangePreset.ALL_TIME,
+    start: new Date(0),
+    end: new Date(),
+  };
+
+  const latestWindowTimeRanges = LATEST_WINDOW_TIME_RANGES;
+  const periodToDateRanges = PERIOD_TO_DATE_RANGES;
+  const previousCompleteDateRanges = PREVIOUS_COMPLETE_DATE_RANGES;
+  const hasDefaultInRanges =
+    !!defaultTimeRange &&
+    (defaultTimeRange in LATEST_WINDOW_TIME_RANGES ||
+      defaultTimeRange in PERIOD_TO_DATE_RANGES ||
+      defaultTimeRange in PREVIOUS_COMPLETE_DATE_RANGES);
+
+  return {
+    latestWindowTimeRanges: getChildTimeRanges(
+      allTimeRange.start,
+      allTimeRange.end,
+      latestWindowTimeRanges,
+      V1TimeGrain.TIME_GRAIN_UNSPECIFIED,
+      selectedTimezone,
+    ),
+    periodToDateRanges: getChildTimeRanges(
+      allTimeRange.start,
+      allTimeRange.end,
+      periodToDateRanges,
+      V1TimeGrain.TIME_GRAIN_UNSPECIFIED,
+      selectedTimezone,
+    ),
+    previousCompleteDateRanges: getChildTimeRanges(
+      allTimeRange.start,
+      allTimeRange.end,
+      previousCompleteDateRanges,
+      V1TimeGrain.TIME_GRAIN_UNSPECIFIED,
+      selectedTimezone,
+    ),
+    showDefaultItem: !!defaultTimeRange && !hasDefaultInRanges,
+  };
+}
+
+export function getComparisonOptionsForCanvas(
+  selectedTimeRange: DashboardTimeControls | undefined,
+) {
+  if (!selectedTimeRange) {
+    return [];
+  }
+  const allTimeRange = {
+    name: TimeRangePreset.ALL_TIME,
+    start: new Date(0),
+    end: new Date(),
+  };
+
+  let allOptions = [...Object.values(TimeComparisonOption)];
+
+  if (
+    selectedTimeRange?.name &&
+    selectedTimeRange?.name in PREVIOUS_COMPLETE_DATE_RANGES
+  ) {
+    // Previous complete ranges should only have previous period.
+    // Other options dont make sense with our current wording of the comparison ranges.
+    allOptions = [TimeComparisonOption.CONTIGUOUS, TimeComparisonOption.CUSTOM];
+  }
+
+  const timeComparisonOptions = getAvailableComparisonsForTimeRange(
+    allTimeRange.start,
+    allTimeRange.end,
+    selectedTimeRange.start,
+    selectedTimeRange.end,
+    allOptions,
+  );
+
+  return timeComparisonOptions.map((co, i) => {
+    const comparisonTimeRange = getComparisonRange(
+      selectedTimeRange.start,
+      selectedTimeRange.end,
+      co,
+    );
+    return {
+      name: co,
+      key: i,
+      start: comparisonTimeRange.start,
+      end: comparisonTimeRange.end,
+    };
+  });
+}
diff --git a/web-common/src/features/canvas/inspector/ChartTypeSelector.svelte b/web-common/src/features/canvas/inspector/ChartTypeSelector.svelte
new file mode 100644
index 00000000000..81ad27ece35
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/ChartTypeSelector.svelte
@@ -0,0 +1,51 @@
+<script lang="ts">
+  import { Button } from "@rilldata/web-common/components/button";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+
+  import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
+  import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
+  import type { ChartMetadata } from "@rilldata/web-common/features/canvas/components/charts/types";
+  import { chartMetadata } from "@rilldata/web-common/features/canvas/components/charts/util";
+  import { type CanvasComponentType } from "@rilldata/web-common/features/canvas/components/types";
+  import { type CanvasComponentObj } from "@rilldata/web-common/features/canvas/components/util";
+
+  export let componentType: CanvasComponentType;
+  export let component: CanvasComponentObj;
+
+  async function selectChartType(chartType: ChartMetadata) {
+    component.updateChartType(chartType.type);
+  }
+</script>
+
+<div class="section">
+  <InputLabel small label="Chart type" id="chart-components" />
+  <div class="chart-icons">
+    {#each chartMetadata as chart}
+      <Tooltip distance={8} location="right">
+        <Button
+          square
+          small
+          type="secondary"
+          selected={componentType === chart.type}
+          on:click={() => selectChartType(chart)}
+        >
+          <svelte:component this={chart.icon} size="20px" />
+        </Button>
+        <TooltipContent slot="tooltip-content">
+          {chart.title}
+        </TooltipContent>
+      </Tooltip>
+    {/each}
+  </div>
+</div>
+
+<style lang="postcss">
+  .section {
+    @apply px-5 flex flex-col gap-y-2 pt-2;
+    @apply border-t border-gray-200;
+  }
+
+  .chart-icons {
+    @apply flex border-2 px-2 py-1 gap-x-4;
+  }
+</style>
diff --git a/web-common/src/features/canvas/inspector/ComponentsEditor.svelte b/web-common/src/features/canvas/inspector/ComponentsEditor.svelte
new file mode 100644
index 00000000000..ccbe0b90059
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/ComponentsEditor.svelte
@@ -0,0 +1,47 @@
+<script lang="ts">
+  import {
+    getHeaderForComponent,
+    isCanvasComponentType,
+  } from "@rilldata/web-common/features/canvas/components/util";
+  import ParamMapper from "@rilldata/web-common/features/canvas/inspector/ParamMapper.svelte";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import {
+    ResourceKind,
+    useResourceV2,
+  } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import SidebarWrapper from "@rilldata/web-common/features/visual-editing/SidebarWrapper.svelte";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+
+  export let selectedComponentName: string;
+  export let fileArtifact: FileArtifact;
+
+  // TODO: Avoid resource query if possible
+  $: resourceQuery = useResourceV2(
+    $runtime.instanceId,
+    selectedComponentName,
+    ResourceKind.Component,
+  );
+
+  $: ({ data: componentResource } = $resourceQuery);
+
+  $: ({ renderer, rendererProperties } =
+    componentResource?.component?.spec ?? {});
+</script>
+
+<SidebarWrapper
+  type="secondary"
+  disableHorizontalPadding
+  title={getHeaderForComponent(renderer)}
+>
+  {#if isCanvasComponentType(renderer) && rendererProperties}
+    <ParamMapper
+      {fileArtifact}
+      componentType={renderer}
+      paramValues={rendererProperties}
+    />
+  {:else}
+    <div>
+      Unknown Component {renderer}
+    </div>
+  {/if}
+</SidebarWrapper>
diff --git a/web-common/src/features/canvas/inspector/FieldSelectorDropdown.svelte b/web-common/src/features/canvas/inspector/FieldSelectorDropdown.svelte
new file mode 100644
index 00000000000..6fa49e11c4c
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/FieldSelectorDropdown.svelte
@@ -0,0 +1,219 @@
+<script lang="ts">
+  import { Chip } from "@rilldata/web-common/components/chip";
+  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+  import Search from "@rilldata/web-common/components/search/Search.svelte";
+  import {
+    getDimensionDisplayName,
+    getMeasureDisplayName,
+  } from "@rilldata/web-common/features/dashboards/filters/getDisplayName";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { MinusIcon, PlusIcon } from "lucide-svelte";
+  import {
+    useAllDimensionFromMetric,
+    useAllSimpleMeasureFromMetric,
+  } from "./selectors";
+
+  export let metricName: string;
+  export let label: string | undefined = undefined;
+  export let id: string;
+  export let selectedItem: string | undefined = undefined;
+  export let type: "measure" | "dimension";
+  export let searchableItems: string[] | undefined = undefined;
+  export let onSelect: (item: string) => void = () => {};
+  export let onMultiSelect: (items: string[]) => void = () => {};
+  export let multi = false;
+  export let selectedItems: string[] | undefined = undefined;
+
+  $: allDimensions = useAllDimensionFromMetric($runtime.instanceId, metricName);
+  $: allFilteredMeasures = useAllSimpleMeasureFromMetric(
+    $runtime.instanceId,
+    metricName,
+  );
+
+  $: items =
+    type === "measure"
+      ? ($allFilteredMeasures?.data?.map((m) => m.name as string) ?? [])
+      : ($allDimensions?.data?.map((d) => d.name || (d.column as string)) ??
+        []);
+
+  $: displayMap =
+    type === "measure"
+      ? Object.fromEntries(
+          $allFilteredMeasures?.data?.map((m) => [
+            m.name,
+            getMeasureDisplayName(m),
+          ]) ?? [],
+        )
+      : Object.fromEntries(
+          $allDimensions?.data?.map((d) => [
+            d.name || d.column,
+            getDimensionDisplayName(d),
+          ]) ?? [],
+        );
+
+  let open = false;
+  let searchValue = "";
+
+  // This Set keeps track of the “in-progress” selection while dropdown is open.
+  let selectedProxy = new Set(multi ? selectedItems : selectedItem);
+
+  $: filteredItems = (
+    searchableItems && searchValue ? searchableItems : items
+  ).filter((item) => {
+    const matchesSearch =
+      displayMap[item]?.toLowerCase().includes(searchValue.toLowerCase()) ||
+      item.toLowerCase().includes(searchValue.toLowerCase());
+    // For single-select, remove the already selected item from the list
+    if (!multi && selectedItem && item === selectedItem) return false;
+    return matchesSearch;
+  });
+</script>
+
+<div class="flex flex-col gap-y-2 pt-1">
+  {#if !multi && label}
+    <div class="flex items-center gap-x-2">
+      <InputLabel small {label} {id} />
+    </div>
+  {/if}
+
+  {#if multi}
+    <DropdownMenu.Root
+      bind:open
+      typeahead={false}
+      closeOnItemClick={true}
+      onOpenChange={() => {
+        // Reset our proxy whenever the menu opens (or closes)
+        if (!open) {
+          selectedProxy = new Set(selectedItems);
+        }
+      }}
+    >
+      <DropdownMenu.Trigger asChild let:builder>
+        <div class="flex justify-between gap-x-2">
+          {#if label}
+            <InputLabel small {label} {id} />
+          {/if}
+          <button use:builder.action {...builder} class="text-sm px-2 h-6">
+            <PlusIcon size="14px" />
+          </button>
+        </div>
+      </DropdownMenu.Trigger>
+
+      <DropdownMenu.Content class="p-0 w-[300px]">
+        <div class="p-3 pb-1">
+          <Search bind:value={searchValue} autofocus={false} />
+        </div>
+
+        <div class="max-h-64 overflow-y-auto">
+          {#each filteredItems as item (item)}
+            <DropdownMenu.CheckboxItem
+              checked={selectedProxy.has(item)}
+              class="pl-8 mx-1"
+              on:click={() => {
+                if (selectedProxy.has(item)) {
+                  selectedProxy.delete(item);
+                } else {
+                  selectedProxy.add(item);
+                }
+                selectedProxy = selectedProxy;
+                onMultiSelect(Array.from(selectedProxy));
+              }}
+            >
+              <slot {item}>
+                {displayMap[item] || item}
+              </slot>
+            </DropdownMenu.CheckboxItem>
+          {:else}
+            {#if searchValue}
+              <div class="ui-copy-disabled text-center p-2 w-full">
+                no results
+              </div>
+            {/if}
+          {/each}
+        </div>
+      </DropdownMenu.Content>
+    </DropdownMenu.Root>
+  {:else}
+    <DropdownMenu.Root
+      bind:open
+      typeahead={false}
+      closeOnItemClick={false}
+      onOpenChange={() => {
+        if (!open) {
+          selectedProxy = new Set(selectedItem);
+        }
+      }}
+    >
+      <DropdownMenu.Trigger asChild let:builder>
+        <Chip fullWidth caret {type} builders={[builder]}>
+          <span class="font-bold truncate" slot="body">
+            {#if selectedItem}
+              {displayMap[selectedItem] || selectedItem}
+            {:else}
+              Select a {type} field
+            {/if}
+          </span>
+        </Chip>
+      </DropdownMenu.Trigger>
+
+      <DropdownMenu.Content sameWidth class="p-0">
+        <div class="p-3 pb-1">
+          <Search bind:value={searchValue} autofocus={false} />
+        </div>
+        <div class="max-h-64 overflow-y-auto">
+          {#each filteredItems as item (item)}
+            <DropdownMenu.Item
+              class="pl-8 mx-1"
+              on:click={() => {
+                onSelect(item);
+                open = false;
+              }}
+            >
+              <slot {item}>
+                {displayMap[item] || item}
+              </slot>
+            </DropdownMenu.Item>
+          {:else}
+            {#if searchValue}
+              <div class="ui-copy-disabled text-center p-2 w-full">
+                no results
+              </div>
+            {/if}
+          {/each}
+        </div>
+      </DropdownMenu.Content>
+    </DropdownMenu.Root>
+  {/if}
+
+  {#if multi && selectedItems && selectedItems.length > 0}
+    <div class="flex flex-col gap-1">
+      {#each selectedItems as item}
+        <div class="flex items-center justify-between gap-x-2">
+          <div class="flex-1">
+            <Chip fullWidth {type}>
+              <span class="font-bold truncate" slot="body">
+                {displayMap[item] || item}
+              </span>
+            </Chip>
+          </div>
+          <button
+            class=" px-2 py-1 text-xs"
+            on:click={() => {
+              selectedProxy.delete(item);
+              onMultiSelect(Array.from(selectedProxy));
+            }}
+          >
+            <MinusIcon size="14px" />
+          </button>
+        </div>
+      {/each}
+    </div>
+  {/if}
+</div>
+
+<style lang="postcss">
+  .open {
+    @apply ring-2 ring-primary-100 border-primary-600;
+  }
+</style>
diff --git a/web-common/src/features/canvas/inspector/MarkSelector.svelte b/web-common/src/features/canvas/inspector/MarkSelector.svelte
new file mode 100644
index 00000000000..b08bd9bd3fa
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/MarkSelector.svelte
@@ -0,0 +1,65 @@
+<script lang="ts">
+  import ColorInput from "@rilldata/web-common/components/color-picker/ColorInput.svelte";
+  import FieldSwitcher from "@rilldata/web-common/components/forms/FieldSwitcher.svelte";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+  import type { FieldConfig } from "../components/charts/types";
+  import FieldSelectorDropdown from "./FieldSelectorDropdown.svelte";
+
+  export let key: string;
+  export let label: string;
+  export let metricsView: string;
+  export let value: FieldConfig | string;
+  export let onChange: (updatedConfig: FieldConfig | string) => void;
+
+  $: selected = !value || typeof value === "string" ? 0 : 1;
+
+  // TODO: Replace with theme primary color
+  $: color = typeof value === "string" ? value : "rgb(117, 126, 255)";
+
+  function updateFieldConfig(field: string) {
+    const updatedConfig: FieldConfig = {
+      field,
+      type: "nominal",
+    };
+    onChange(updatedConfig);
+  }
+</script>
+
+<div class="space-y-2">
+  <InputLabel small {label} id={key} />
+
+  <FieldSwitcher
+    small
+    fields={["value", "Split by"]}
+    {selected}
+    onClick={(_, field) => {
+      if (field === "value") {
+        selected = 0;
+        onChange(color);
+      } else if (field === "Split by") {
+        selected = 1;
+      }
+    }}
+  />
+
+  {#if selected === 0}
+    <ColorInput
+      small
+      stringColor={color}
+      label=""
+      onChange={(color) => {
+        onChange(color);
+      }}
+    />
+  {:else if selected === 1}
+    <FieldSelectorDropdown
+      metricName={metricsView}
+      id={`${key}-field`}
+      type="dimension"
+      selectedItem={typeof value === "string" ? undefined : value?.field}
+      onSelect={async (field) => {
+        updateFieldConfig(field);
+      }}
+    />
+  {/if}
+</div>
diff --git a/web-common/src/features/canvas/inspector/MetricSelectorDropdown.svelte b/web-common/src/features/canvas/inspector/MetricSelectorDropdown.svelte
new file mode 100644
index 00000000000..405aaa8f71e
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/MetricSelectorDropdown.svelte
@@ -0,0 +1,53 @@
+<script lang="ts">
+  import Input from "@rilldata/web-common/components/forms/Input.svelte";
+  import { type CanvasComponentObj } from "@rilldata/web-common/features/canvas/components/util";
+  import type { ComponentInputParam } from "@rilldata/web-common/features/canvas/inspector/types";
+  import { isString } from "@rilldata/web-common/features/canvas/util";
+  import {
+    ResourceKind,
+    useFilteredResources,
+  } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+
+  export let component: CanvasComponentObj;
+  export let key: string;
+  export let inputParam: ComponentInputParam;
+
+  $: ({ instanceId } = $runtime);
+
+  $: spec = component.specStore;
+
+  $: metricsViewsQuery = useFilteredResources(
+    instanceId,
+    ResourceKind.MetricsView,
+  );
+  $: metricsViews = $metricsViewsQuery?.data ?? [];
+
+  $: metricsViewNames = metricsViews
+    .map((view) => view.meta?.name?.name)
+    .filter(isString);
+
+  $: metricsView =
+    "metrics_view" in $spec ? $spec.metrics_view : metricsViewNames[0];
+</script>
+
+<Input
+  hint="View documentation"
+  link="https://docs.rilldata.com/reference/project-files/metrics-view"
+  label={inputParam.label}
+  capitalizeLabel={false}
+  bind:value={metricsView}
+  sameWidth
+  size="sm"
+  labelGap={2}
+  options={metricsViewNames.map((name) => ({
+    label: name,
+    value: name,
+  }))}
+  onBlur={() => {
+    component.updateProperty(key, metricsView);
+  }}
+  onChange={() => {
+    component.updateProperty(key, metricsView);
+  }}
+/>
diff --git a/web-common/src/features/canvas/inspector/PageEditor.svelte b/web-common/src/features/canvas/inspector/PageEditor.svelte
new file mode 100644
index 00000000000..003cc3f499f
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/PageEditor.svelte
@@ -0,0 +1,119 @@
+<script lang="ts">
+  import Input from "@rilldata/web-common/components/forms/Input.svelte";
+  import { DASHBOARD_WIDTH } from "@rilldata/web-common/features/canvas/constants";
+  import { getParsedDocument } from "@rilldata/web-common/features/canvas/inspector/selectors";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import {
+    ResourceKind,
+    useFilteredResources,
+  } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import SidebarWrapper from "@rilldata/web-common/features/visual-editing/SidebarWrapper.svelte";
+  import ThemeInput from "@rilldata/web-common/features/visual-editing/ThemeInput.svelte";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { YAMLMap } from "yaml";
+
+  export let updateProperties: (
+    newRecord: Record<string, unknown>,
+    removeProperties?: Array<string | string[]>,
+  ) => Promise<void>;
+  export let fileArtifact: FileArtifact;
+
+  const { validSpecStore } = getCanvasStateManagers();
+
+  $: ({ instanceId } = $runtime);
+
+  $: parsedDocument = getParsedDocument(fileArtifact);
+
+  $: rawTitle = $parsedDocument.get("title");
+  $: rawDisplayName = $parsedDocument.get("display_name");
+  $: rawTheme = $parsedDocument.get("theme");
+  $: maxWidth = DASHBOARD_WIDTH; //Add property
+
+  $: title = stringGuard(rawTitle) || stringGuard(rawDisplayName);
+
+  $: themesQuery = useFilteredResources(instanceId, ResourceKind.Theme);
+
+  $: themeNames = ($themesQuery?.data ?? [])
+    .map((theme) => theme.meta?.name?.name ?? "")
+    .filter((string) => !string.endsWith("--theme"));
+
+  $: theme = !rawTheme
+    ? undefined
+    : typeof rawTheme === "string"
+      ? rawTheme
+      : rawTheme instanceof YAMLMap
+        ? $validSpecStore?.data?.embeddedTheme
+        : undefined;
+
+  function stringGuard(value: unknown | undefined): string {
+    return value && typeof value === "string" ? value : "";
+  }
+</script>
+
+<SidebarWrapper type="secondary" disableHorizontalPadding title="Canvas">
+  <div class="page-param">
+    <Input
+      hint="Shown in global header and when deployed to Rill Cloud"
+      capitalizeLabel={false}
+      size="sm"
+      labelGap={2}
+      label="Display name"
+      bind:value={title}
+      onBlur={async () => {
+        await updateProperties({ display_name: title }, ["title"]);
+      }}
+      onEnter={async () => {
+        await updateProperties({ display_name: title });
+      }}
+    />
+  </div>
+  <div class="page-param">
+    <Input
+      hint="Max width for the canvas"
+      capitalizeLabel={false}
+      size="sm"
+      labelGap={2}
+      label="Max width"
+      inputType="number"
+      bind:value={maxWidth}
+      onBlur={async () => {
+        await updateProperties({ display_name: title }, ["title"]);
+      }}
+      onEnter={async () => {
+        await updateProperties({ display_name: title });
+      }}
+    />
+  </div>
+  <div class="page-param">
+    <ThemeInput
+      small
+      {theme}
+      {themeNames}
+      onThemeChange={async (value) => {
+        if (!value) {
+          await updateProperties({}, ["theme"]);
+        } else {
+          await updateProperties({ theme: value });
+        }
+      }}
+      onColorChange={async (primary, secondary) => {
+        await updateProperties({
+          theme: {
+            colors: {
+              primary,
+              secondary,
+            },
+          },
+        });
+      }}
+    />
+  </div>
+</SidebarWrapper>
+
+<style lang="postcss">
+  .page-param {
+    @apply py-3 px-5;
+    @apply border-t border-gray-200;
+  }
+</style>
diff --git a/web-common/src/features/canvas/inspector/ParamMapper.svelte b/web-common/src/features/canvas/inspector/ParamMapper.svelte
new file mode 100644
index 00000000000..cb437058ae3
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/ParamMapper.svelte
@@ -0,0 +1,187 @@
+<script lang="ts">
+  import Input from "@rilldata/web-common/components/forms/Input.svelte";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+  import Switch from "@rilldata/web-common/components/forms/Switch.svelte";
+  import ChartTypeSelector from "@rilldata/web-common/features/canvas/inspector/ChartTypeSelector.svelte";
+  import MetricSelectorDropdown from "@rilldata/web-common/features/canvas/inspector/MetricSelectorDropdown.svelte";
+  import FieldSelectorDropdown from "./FieldSelectorDropdown.svelte";
+  import PositionalFieldConfig from "./PositionalFieldConfig.svelte";
+
+  import {
+    getComponentObj,
+    isChartComponentType,
+  } from "@rilldata/web-common/features/canvas/components/util";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+
+  import MarkSelector from "@rilldata/web-common/features/canvas/inspector/MarkSelector.svelte";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import { type V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
+  import { onMount } from "svelte";
+  import type { CanvasComponentType } from "../components/types";
+
+  export let componentType: CanvasComponentType;
+  export let paramValues: V1ComponentSpecRendererProperties;
+  export let fileArtifact: FileArtifact;
+
+  const { canvasEntity } = getCanvasStateManagers();
+  $: selectedComponentIndexStore = canvasEntity?.selectedComponentIndex;
+  $: selectedComponentIndex = $selectedComponentIndexStore ?? 0;
+  $: path = ["items", selectedComponentIndex, "component", componentType];
+
+  $: localParamValues = localParamValues || {};
+  let oldParamValuesRef: V1ComponentSpecRendererProperties = {};
+
+  // TODO: Make this robust possibly a store.
+  $: if (JSON.stringify(paramValues) !== JSON.stringify(oldParamValuesRef)) {
+    localParamValues = structuredClone(paramValues) || {};
+    oldParamValuesRef = paramValues;
+  }
+
+  onMount(() => {
+    localParamValues = structuredClone(paramValues) || {};
+  });
+
+  $: component = getComponentObj(
+    fileArtifact,
+    path,
+    componentType,
+    paramValues,
+  );
+  $: inputParams = component.inputParams().component;
+  $: spec = component.specStore;
+
+  $: metricsView = "metrics_view" in $spec ? $spec.metrics_view : null;
+</script>
+
+{#if isChartComponentType(componentType)}
+  <ChartTypeSelector {component} {componentType} />
+{/if}
+
+{#key selectedComponentIndex}
+  <div>
+    {#each Object.entries(inputParams) as [key, config]}
+      {#if config.showInUI !== false}
+        <div class="component-param">
+          <!-- TEXT, NUMBER, RILL_TIME -->
+          {#if config.type === "text" || config.type === "number" || config.type === "rill_time"}
+            <Input
+              inputType={config.type === "number" ? "number" : "text"}
+              capitalizeLabel={false}
+              textClass="text-sm"
+              size="sm"
+              labelGap={2}
+              optional={!!config.optional}
+              label={config.label ?? key}
+              bind:value={localParamValues[key]}
+              onBlur={async () => {
+                component.updateProperty(key, localParamValues[key]);
+              }}
+              onEnter={async () => {
+                component.updateProperty(key, localParamValues[key]);
+              }}
+            />
+
+            <!-- METRICS SELECTOR -->
+          {:else if config.type === "metrics"}
+            <MetricSelectorDropdown {component} {key} inputParam={config} />
+
+            <!-- MEASURE / DIMENSION -->
+          {:else if metricsView && (config.type === "measure" || config.type === "dimension")}
+            <FieldSelectorDropdown
+              label={config.label ?? key}
+              metricName={metricsView}
+              id={key}
+              type={config.type}
+              selectedItem={localParamValues[key]}
+              onSelect={async (field) => {
+                component.updateProperty(key, field);
+              }}
+            />
+
+            <!-- MULTIPLE MEASURE / MULTIPLE DIMENSION -->
+          {:else if metricsView && (config.type === "multi_measures" || config.type === "multi_dimensions")}
+            <FieldSelectorDropdown
+              multi
+              label={config.label ?? key}
+              metricName={metricsView}
+              id={key}
+              type={config.type === "multi_measures" ? "measure" : "dimension"}
+              selectedItems={localParamValues[key]}
+              onMultiSelect={async (field) => {
+                component.updateProperty(key, field);
+              }}
+            />
+
+            <!-- BOOLEAN SWITCH -->
+          {:else if config.type === "boolean"}
+            <div class="flex items-center justify-between py-2">
+              <InputLabel
+                small
+                label={config.label ?? key}
+                optional={!!config.optional}
+                id={key}
+              />
+              <Switch
+                bind:checked={localParamValues[key]}
+                on:click={async () => {
+                  component.updateProperty(key, !paramValues[key]);
+                }}
+                small
+              />
+            </div>
+
+            <!-- TEXT AREA -->
+          {:else if config.type === "textArea"}
+            <InputLabel
+              small
+              label={config.label ?? key}
+              optional={!!config.optional}
+              id={key}
+            />
+            <textarea
+              class="w-full p-2 border border-gray-300 rounded-sm"
+              rows="4"
+              bind:value={localParamValues[key]}
+              on:blur={async () => {
+                component.updateProperty(key, localParamValues[key]);
+              }}
+              placeholder={config.label ?? key}
+            />
+
+            <!-- POSITIONAL CONFIG -->
+          {:else if metricsView && config.type === "positional"}
+            <PositionalFieldConfig
+              {key}
+              {config}
+              {metricsView}
+              value={localParamValues[key] || {}}
+              onChange={(updatedConfig) => {
+                localParamValues[key] = updatedConfig;
+                component.updateProperty(key, updatedConfig);
+              }}
+            />
+            <!-- COLOR CONFIG -->
+          {:else if metricsView && config.type === "mark"}
+            <MarkSelector
+              label={config.label ?? key}
+              {key}
+              {metricsView}
+              value={localParamValues[key] || {}}
+              onChange={(updatedConfig) => {
+                localParamValues[key] = updatedConfig;
+                component.updateProperty(key, updatedConfig);
+              }}
+            />
+          {/if}
+        </div>
+      {/if}
+    {/each}
+  </div>
+{/key}
+
+<style lang="postcss">
+  .component-param {
+    @apply py-3 px-5;
+    @apply border-t border-gray-200;
+  }
+</style>
diff --git a/web-common/src/features/canvas/inspector/PositionalFieldConfig.svelte b/web-common/src/features/canvas/inspector/PositionalFieldConfig.svelte
new file mode 100644
index 00000000000..ff18bd71279
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/PositionalFieldConfig.svelte
@@ -0,0 +1,34 @@
+<script lang="ts">
+  import type { FieldConfig } from "../components/charts/types";
+  import FieldSelectorDropdown from "./FieldSelectorDropdown.svelte";
+
+  export let key: string;
+  export let config: { label?: string };
+  export let metricsView: string;
+  export let value: FieldConfig;
+  export let onChange: (updatedConfig: FieldConfig) => void;
+
+  $: isDimension = key === "x";
+
+  function updateFieldConfig(field: string) {
+    const updatedConfig: FieldConfig = {
+      ...value,
+      field,
+      type: isDimension ? "nominal" : "quantitative",
+    };
+    onChange(updatedConfig);
+  }
+</script>
+
+<div class="space-y-2">
+  <FieldSelectorDropdown
+    label={config.label || key}
+    metricName={metricsView}
+    id={`${key}-field`}
+    type={isDimension ? "dimension" : "measure"}
+    selectedItem={value?.field}
+    onSelect={async (field) => {
+      updateFieldConfig(field);
+    }}
+  />
+</div>
diff --git a/web-common/src/features/canvas/inspector/VisualCanvasEditing.svelte b/web-common/src/features/canvas/inspector/VisualCanvasEditing.svelte
new file mode 100644
index 00000000000..efa4f864e10
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/VisualCanvasEditing.svelte
@@ -0,0 +1,72 @@
+<script lang="ts">
+  import { replaceState } from "$app/navigation";
+  import ComponentsEditor from "@rilldata/web-common/features/canvas/inspector/ComponentsEditor.svelte";
+  import PageEditor from "@rilldata/web-common/features/canvas/inspector/PageEditor.svelte";
+  import { getCanvasStateManagers } from "@rilldata/web-common/features/canvas/state-managers/state-managers";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import { Inspector } from "@rilldata/web-common/layout/workspace";
+  import { parseDocument } from "yaml";
+
+  export let fileArtifact: FileArtifact;
+
+  const { validSpecStore, canvasEntity } = getCanvasStateManagers();
+
+  $: ({
+    editorContent,
+    remoteContent,
+    updateEditorContent,
+    saveLocalContent,
+    path,
+  } = fileArtifact);
+
+  $: parsedDocument = parseDocument($editorContent ?? $remoteContent ?? "");
+  $: selectedComponentIndex = canvasEntity.selectedComponentIndex;
+
+  $: selectedComponentName =
+    $selectedComponentIndex !== null
+      ? $validSpecStore?.data?.items?.[$selectedComponentIndex]?.component
+      : null;
+
+  async function updateProperties(
+    newRecord: Record<string, unknown>,
+    removeProperties?: Array<string | string[]>,
+  ) {
+    Object.entries(newRecord).forEach(([property, value]) => {
+      if (!value) {
+        parsedDocument.delete(property);
+      } else {
+        parsedDocument.set(property, value);
+      }
+    });
+
+    if (removeProperties) {
+      removeProperties.forEach((prop) => {
+        try {
+          if (Array.isArray(prop)) {
+            parsedDocument.deleteIn(prop);
+          } else {
+            parsedDocument.delete(prop);
+          }
+        } catch (e) {
+          console.warn(e);
+        }
+      });
+    }
+
+    killState();
+    updateEditorContent(parsedDocument.toString(), true);
+    await saveLocalContent();
+  }
+
+  function killState() {
+    replaceState(window.location.origin + window.location.pathname, {});
+  }
+</script>
+
+<Inspector minWidth={280} filePath={path}>
+  {#if selectedComponentName}
+    <ComponentsEditor {fileArtifact} {selectedComponentName} />
+  {:else}
+    <PageEditor {fileArtifact} {updateProperties} />
+  {/if}
+</Inspector>
diff --git a/web-common/src/features/canvas/inspector/selectors.ts b/web-common/src/features/canvas/inspector/selectors.ts
new file mode 100644
index 00000000000..ea0705ed074
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/selectors.ts
@@ -0,0 +1,37 @@
+import { useMetricsViewValidSpec } from "@rilldata/web-common/features/dashboards/selectors";
+import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+import { MetricsViewSpecMeasureType } from "@rilldata/web-common/runtime-client";
+import { derived } from "svelte/store";
+import { parseDocument } from "yaml";
+
+export const useAllDimensionFromMetric = (
+  instanceId: string,
+  metricsViewName: string,
+) =>
+  useMetricsViewValidSpec(
+    instanceId,
+    metricsViewName,
+    (meta) => meta?.dimensions,
+  );
+
+export const useAllSimpleMeasureFromMetric = (
+  instanceId: string,
+  metricsViewName: string,
+) =>
+  useMetricsViewValidSpec(instanceId, metricsViewName, (meta) =>
+    meta?.measures?.filter(
+      (m) =>
+        !m.window &&
+        m.type !== MetricsViewSpecMeasureType.MEASURE_TYPE_TIME_COMPARISON,
+    ),
+  );
+
+export function getParsedDocument(fileArtifact: FileArtifact) {
+  const { editorContent, remoteContent } = fileArtifact;
+  return derived(
+    [editorContent, remoteContent],
+    ([$localContent, $remoteContent]) => {
+      return parseDocument($localContent ?? $remoteContent ?? "");
+    },
+  );
+}
diff --git a/web-common/src/features/canvas/inspector/types.ts b/web-common/src/features/canvas/inspector/types.ts
new file mode 100644
index 00000000000..4f206b32efa
--- /dev/null
+++ b/web-common/src/features/canvas/inspector/types.ts
@@ -0,0 +1,40 @@
+type NativeInputTypes = "text" | "number" | "boolean" | "textArea";
+type SemanticInputTypes =
+  | "metrics"
+  | "measure"
+  | "dimension"
+  | "multi_measures"
+  | "multi_dimensions";
+type ChartInputTypes = "positional" | "mark" | "tooltip";
+type CustomInputTypes = "rill_time";
+
+export type InputType =
+  | NativeInputTypes
+  | SemanticInputTypes
+  | ChartInputTypes
+  | CustomInputTypes;
+
+export type FilterInputTypes =
+  | "time_range"
+  | "comparison_range"
+  | "grain"
+  | "dimension_filters";
+
+export interface ComponentInputParam {
+  type: InputType;
+  label?: string;
+  showInUI?: boolean; // If not specified, can assume true
+  optional?: boolean;
+  description?: string; // Tooltip description for the input
+  meta?: Record<string, string>; // Any additional metadata
+}
+
+export interface FilterInputParam {
+  type: FilterInputTypes;
+  label: string;
+}
+
+export interface InputParams<T> {
+  component: Partial<Record<keyof T, ComponentInputParam>>;
+  filter: Partial<Record<FilterInputTypes, FilterInputParam>> | [];
+}
diff --git a/web-common/src/features/canvas/selector.ts b/web-common/src/features/canvas/selector.ts
new file mode 100644
index 00000000000..834f324cb34
--- /dev/null
+++ b/web-common/src/features/canvas/selector.ts
@@ -0,0 +1,72 @@
+import type { CreateQueryOptions } from "@rilldata/svelte-query";
+import {
+  ResourceKind,
+  useFilteredResources,
+} from "@rilldata/web-common/features/entity-management/resource-selectors";
+import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
+import {
+  createRuntimeServiceGetResource,
+  type RpcStatus,
+  type V1CanvasSpec,
+  type V1GetResourceResponse,
+} from "@rilldata/web-common/runtime-client";
+import type { ErrorType } from "@rilldata/web-common/runtime-client/http-client";
+
+export function useDefaultMetrics(instanceId: string) {
+  return useFilteredResources(instanceId, ResourceKind.MetricsView, (data) => {
+    const validMetricsViews = data?.resources?.filter(
+      (res) => !!res.metricsView?.state?.validSpec,
+    );
+
+    if (validMetricsViews && validMetricsViews?.length > 0) {
+      const firstMetricsView =
+        validMetricsViews[0].metricsView?.state?.validSpec;
+      const firstMetricName = validMetricsViews[0].meta?.name?.name as string;
+      const firstMeasure = firstMetricsView?.measures?.[0]?.name as string;
+      const firstDimension =
+        firstMetricsView?.dimensions?.[0]?.name ||
+        (firstMetricsView?.dimensions?.[0]?.column as string);
+
+      return {
+        metricsView: firstMetricName,
+        measure: firstMeasure,
+        dimension: firstDimension,
+      };
+    }
+
+    return null;
+  });
+}
+
+export function useCanvasValidSpec(
+  instanceId: string,
+  canvasName: string,
+  queryOptions?: CreateQueryOptions<
+    V1GetResourceResponse,
+    ErrorType<RpcStatus>,
+    V1CanvasSpec | undefined
+  >,
+) {
+  const defaultQueryOptions: CreateQueryOptions<
+    V1GetResourceResponse,
+    ErrorType<RpcStatus>,
+    V1CanvasSpec | undefined
+  > = {
+    select: (data) => data?.resource?.canvas?.state?.validSpec,
+    queryClient,
+    enabled: !!canvasName,
+  };
+  return createRuntimeServiceGetResource(
+    instanceId,
+    {
+      "name.kind": ResourceKind.Canvas,
+      "name.name": canvasName,
+    },
+    {
+      query: {
+        ...defaultQueryOptions,
+        ...queryOptions,
+      },
+    },
+  );
+}
diff --git a/web-common/src/features/canvas/state-managers/StateManagersProvider.svelte b/web-common/src/features/canvas/state-managers/StateManagersProvider.svelte
new file mode 100644
index 00000000000..df368c764c2
--- /dev/null
+++ b/web-common/src/features/canvas/state-managers/StateManagersProvider.svelte
@@ -0,0 +1,27 @@
+<script lang="ts">
+  import { createCanvasStateSync } from "@rilldata/web-common/features/canvas/stores/syncCanvasState";
+  import DelayedSpinner from "@rilldata/web-common/features/entity-management/DelayedSpinner.svelte";
+  import { useQueryClient } from "@tanstack/svelte-query";
+  import { setContext } from "svelte";
+  import { createStateManagers, DEFAULT_STORE_KEY } from "./state-managers";
+
+  export let canvasName: string;
+
+  const queryClient = useQueryClient();
+  const stateManagers = createStateManagers({
+    queryClient,
+    canvasName,
+  });
+
+  const canvasStoreReady = createCanvasStateSync(canvasName);
+
+  setContext(DEFAULT_STORE_KEY, stateManagers);
+</script>
+
+{#if canvasStoreReady.isFetching}
+  <div class="grid place-items-center size-full">
+    <DelayedSpinner isLoading={canvasStoreReady.isFetching} size="40px" />
+  </div>
+{:else}
+  <slot />
+{/if}
diff --git a/web-common/src/features/canvas/state-managers/state-managers.ts b/web-common/src/features/canvas/state-managers/state-managers.ts
new file mode 100644
index 00000000000..5c0421c0798
--- /dev/null
+++ b/web-common/src/features/canvas/state-managers/state-managers.ts
@@ -0,0 +1,56 @@
+import { useCanvasValidSpec } from "@rilldata/web-common/features/canvas/selector";
+import {
+  type RpcStatus,
+  type V1CanvasSpec,
+} from "@rilldata/web-common/runtime-client";
+import type { Runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+import type { QueryClient, QueryObserverResult } from "@tanstack/svelte-query";
+import { getContext } from "svelte";
+import { derived, writable, type Readable, type Writable } from "svelte/store";
+import { useCanvasEntity } from "../stores/canvas-entities";
+import type { CanvasEntity } from "../stores/canvas-entity";
+
+export type StateManagers = {
+  runtime: Writable<Runtime>;
+  canvasName: Writable<string>;
+  canvasEntity: CanvasEntity;
+  validSpecStore: Readable<
+    QueryObserverResult<V1CanvasSpec | undefined, RpcStatus>
+  >;
+  queryClient: QueryClient;
+};
+
+export const DEFAULT_STORE_KEY = Symbol("canvas-state-managers");
+
+export function getCanvasStateManagers(): StateManagers {
+  return getContext(DEFAULT_STORE_KEY);
+}
+
+export function createStateManagers({
+  queryClient,
+  canvasName,
+}: {
+  queryClient: QueryClient;
+  canvasName: string;
+}): StateManagers {
+  const canvasNameStore = writable(canvasName);
+
+  const canvasEntity = useCanvasEntity(canvasName);
+
+  const validSpecStore: Readable<
+    QueryObserverResult<V1CanvasSpec | undefined, RpcStatus>
+  > = derived([runtime, canvasNameStore], ([r, canvasName], set) =>
+    useCanvasValidSpec(r.instanceId, canvasName, { queryClient }).subscribe(
+      set,
+    ),
+  );
+
+  return {
+    runtime: runtime,
+    canvasName: canvasNameStore,
+    canvasEntity,
+    validSpecStore,
+    queryClient,
+  };
+}
diff --git a/web-common/src/features/canvas/stores/canvas-entities.ts b/web-common/src/features/canvas/stores/canvas-entities.ts
new file mode 100644
index 00000000000..324c32556e9
--- /dev/null
+++ b/web-common/src/features/canvas/stores/canvas-entities.ts
@@ -0,0 +1,36 @@
+import { CanvasEntity } from "./canvas-entity";
+
+export class CanvasEntities {
+  private entities: Map<string, CanvasEntity> = new Map();
+
+  addCanvas(name: string) {
+    if (!this.entities.has(name)) {
+      this.entities.set(name, new CanvasEntity(name));
+    }
+  }
+
+  removeCanvas(name: string) {
+    this.entities.delete(name);
+  }
+
+  hasCanvas(name: string) {
+    return this.entities.has(name);
+  }
+
+  getCanvas(name: string) {
+    let canvasEntity = this.entities.get(name);
+
+    if (!canvasEntity) {
+      canvasEntity = new CanvasEntity(name);
+      this.entities.set(name, canvasEntity);
+    }
+
+    return canvasEntity;
+  }
+}
+
+export const canvasEntities = new CanvasEntities();
+
+export function useCanvasEntity(name: string) {
+  return canvasEntities.getCanvas(name);
+}
diff --git a/web-common/src/features/canvas/stores/canvas-entity.ts b/web-common/src/features/canvas/stores/canvas-entity.ts
new file mode 100644
index 00000000000..063eeb4e390
--- /dev/null
+++ b/web-common/src/features/canvas/stores/canvas-entity.ts
@@ -0,0 +1,25 @@
+import { writable, type Writable } from "svelte/store";
+import { CanvasTimeControls } from "./canvas-time-control";
+
+export class CanvasEntity {
+  name: string;
+  /**
+   * Time controls for the canvas entity containing various
+   * time related writables
+   */
+  timeControls: CanvasTimeControls;
+  /**
+   * Index of the component higlighted or selected in the canvas
+   */
+  selectedComponentIndex: Writable<number | null>;
+
+  constructor(name: string) {
+    this.name = name;
+    this.timeControls = new CanvasTimeControls();
+    this.selectedComponentIndex = writable(null);
+  }
+
+  setSelectedComponentIndex(index: number | null) {
+    this.selectedComponentIndex.set(index);
+  }
+}
diff --git a/web-common/src/features/canvas/stores/canvas-time-control.ts b/web-common/src/features/canvas/stores/canvas-time-control.ts
new file mode 100644
index 00000000000..8b601a018c4
--- /dev/null
+++ b/web-common/src/features/canvas/stores/canvas-time-control.ts
@@ -0,0 +1,57 @@
+import {
+  TimeRangePreset,
+  type DashboardTimeControls,
+  type TimeRange,
+} from "@rilldata/web-common/lib/time/types";
+import { V1TimeGrain } from "@rilldata/web-common/runtime-client";
+import { writable, type Writable } from "svelte/store";
+
+export class CanvasTimeControls {
+  selectedTimeRange: Writable<DashboardTimeControls>;
+  selectedComparisonTimeRange: Writable<DashboardTimeControls | undefined>;
+  showTimeComparison: Writable<boolean>;
+  selectedTimezone: Writable<string>;
+
+  constructor() {
+    this.selectedTimeRange = writable({
+      name: TimeRangePreset.ALL_TIME,
+      start: new Date(0),
+      end: new Date(),
+      interval: V1TimeGrain.TIME_GRAIN_DAY,
+    });
+    this.selectedComparisonTimeRange = writable(undefined);
+    this.showTimeComparison = writable(false);
+    this.selectedTimezone = writable("UTC");
+  }
+
+  setTimeZone(timezone: string) {
+    this.selectedTimezone.set(timezone);
+  }
+
+  selectTimeRange(
+    timeRange: TimeRange,
+    timeGrain: V1TimeGrain,
+    comparisonTimeRange: DashboardTimeControls | undefined,
+  ) {
+    if (!timeRange.name) return;
+
+    if (timeRange.name === TimeRangePreset.ALL_TIME) {
+      this.showTimeComparison.set(false);
+    }
+
+    this.selectedTimeRange.set({
+      ...timeRange,
+      interval: timeGrain,
+    });
+
+    this.selectedComparisonTimeRange.set(comparisonTimeRange);
+  }
+
+  setSelectedComparisonRange(comparisonTimeRange: DashboardTimeControls) {
+    this.selectedComparisonTimeRange.set(comparisonTimeRange);
+  }
+
+  displayTimeComparison(showTimeComparison: boolean) {
+    this.showTimeComparison.set(showTimeComparison);
+  }
+}
diff --git a/web-common/src/features/canvas/stores/syncCanvasState.ts b/web-common/src/features/canvas/stores/syncCanvasState.ts
new file mode 100644
index 00000000000..28e47e17b5f
--- /dev/null
+++ b/web-common/src/features/canvas/stores/syncCanvasState.ts
@@ -0,0 +1,12 @@
+import { canvasEntities } from "@rilldata/web-common/features/canvas/stores/canvas-entities";
+
+export function createCanvasStateSync(canvasName: string) {
+  if (canvasEntities.hasCanvas(canvasName)) {
+    // TODO: Add sync method if required
+    return { isFetching: false, error: false };
+  } else {
+    // Running for the 1st time. Initialise the canvas store.
+    canvasEntities.addCanvas(canvasName);
+    return { isFetching: false, error: false };
+  }
+}
diff --git a/web-common/src/features/canvas/util.ts b/web-common/src/features/canvas/util.ts
index 2c67ad44fed..eefc9205fb0 100644
--- a/web-common/src/features/canvas/util.ts
+++ b/web-common/src/features/canvas/util.ts
@@ -17,3 +17,7 @@ export const vector = {
     return [vector[0] / divisor[0], vector[1] / divisor[1]];
   },
 };
+
+export function isString(value: unknown): value is string {
+  return typeof value === "string";
+}
diff --git a/web-common/src/features/dashboards/filters/FilterButton.svelte b/web-common/src/features/dashboards/filters/FilterButton.svelte
index b10cb959b6a..f72c0fe7088 100644
--- a/web-common/src/features/dashboards/filters/FilterButton.svelte
+++ b/web-common/src/features/dashboards/filters/FilterButton.svelte
@@ -1,13 +1,13 @@
 <script lang="ts">
+  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
   import Add from "@rilldata/web-common/components/icons/Add.svelte";
   import type { SearchableFilterSelectableGroup } from "@rilldata/web-common/components/searchable-filter-menu/SearchableFilterSelectableItem";
+  import SearchableMenuContent from "@rilldata/web-common/components/searchable-filter-menu/SearchableMenuContent.svelte";
   import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
   import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
   import { getDimensionDisplayName } from "@rilldata/web-common/features/dashboards/filters/getDisplayName";
   import { getStateManagers } from "../state-managers/state-managers";
   import { getMeasureDisplayName } from "./getDisplayName";
-  import SearchableMenuContent from "@rilldata/web-common/components/searchable-filter-menu/SearchableMenuContent.svelte";
-  import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
   const {
     selectors: {
       dimensions: { allDimensions },
diff --git a/web-common/src/features/dashboards/selectors.ts b/web-common/src/features/dashboards/selectors.ts
index 3444b1f69d8..0e9b3c62487 100644
--- a/web-common/src/features/dashboards/selectors.ts
+++ b/web-common/src/features/dashboards/selectors.ts
@@ -132,15 +132,6 @@ export function useMetricsViewTimeRange(
   );
 }
 
-export const useMetricsViewSpecMeasure = (
-  instanceId: string,
-  metricsViewName: string,
-  measureName: string,
-) =>
-  useMetricsViewValidSpec(instanceId, metricsViewName, (meta) =>
-    meta?.measures?.find((measure) => measure.name === measureName),
-  );
-
 export function getFiltersForOtherDimensions(
   whereFilter: V1Expression,
   dimName: string,
diff --git a/web-common/src/features/dashboards/state-managers/selectors/charts.ts b/web-common/src/features/dashboards/state-managers/selectors/charts.ts
index 7ea7910a05b..b93e15ad1de 100644
--- a/web-common/src/features/dashboards/state-managers/selectors/charts.ts
+++ b/web-common/src/features/dashboards/state-managers/selectors/charts.ts
@@ -4,7 +4,10 @@ import {
   getOffset,
   getTimeWidth,
 } from "@rilldata/web-common/lib/time/transforms";
-import { TimeOffsetType } from "@rilldata/web-common/lib/time/types";
+import {
+  TimeOffsetType,
+  type DashboardTimeControls,
+} from "@rilldata/web-common/lib/time/types";
 import type { DashboardDataSources } from "./types";
 
 export const chartSelectors = {
@@ -27,26 +30,30 @@ export const chartSelectors = {
   },
   getNewPanRange: (dashData: DashboardDataSources) => {
     const timeControls = timeControlsState(dashData);
+    const timeZone = dashData.dashboard?.selectedTimezone;
+    return getPanRangeForTimeRange(timeControls.selectedTimeRange, timeZone);
+  },
+};
 
-    return (direction: "left" | "right") => {
-      const selectedTimeRange = timeControls?.selectedTimeRange;
-      if (!selectedTimeRange) return;
-
-      const timeZone = dashData?.dashboard?.selectedTimezone || "UTC";
-      const { start, end } = selectedTimeRange;
+export function getPanRangeForTimeRange(
+  timeRange: DashboardTimeControls | undefined,
+  timeZone: string,
+) {
+  return (direction: "left" | "right") => {
+    if (!timeRange) return;
+    const { start, end } = timeRange;
 
-      if (!start || !end) return;
+    if (!start || !end) return;
 
-      const offsetType =
-        direction === "left" ? TimeOffsetType.SUBTRACT : TimeOffsetType.ADD;
+    const offsetType =
+      direction === "left" ? TimeOffsetType.SUBTRACT : TimeOffsetType.ADD;
 
-      const currentRangeWidth = getTimeWidth(start, end);
-      const panAmount = getDurationFromMS(currentRangeWidth);
+    const currentRangeWidth = getTimeWidth(start, end);
+    const panAmount = getDurationFromMS(currentRangeWidth);
 
-      const newStart = getOffset(start, panAmount, offsetType, timeZone);
-      const newEnd = getOffset(end, panAmount, offsetType, timeZone);
+    const newStart = getOffset(start, panAmount, offsetType, timeZone);
+    const newEnd = getOffset(end, panAmount, offsetType, timeZone);
 
-      return { start: newStart, end: newEnd };
-    };
-  },
-};
+    return { start: newStart, end: newEnd };
+  };
+}
diff --git a/web-common/src/features/dashboards/tab-bar/TabBar.svelte b/web-common/src/features/dashboards/tab-bar/TabBar.svelte
index 97dd959a045..cdaa6d575d8 100644
--- a/web-common/src/features/dashboards/tab-bar/TabBar.svelte
+++ b/web-common/src/features/dashboards/tab-bar/TabBar.svelte
@@ -9,8 +9,8 @@
     MetricsEventScreenName,
     MetricsEventSpace,
   } from "@rilldata/web-common/metrics/service/MetricsTypes";
-  import Tab from "./Tab.svelte";
   import type { ComponentType } from "svelte";
+  import Tab from "./Tab.svelte";
 
   type TabName = MetricsEventScreenName.Pivot | MetricsEventScreenName.Explore;
   type TabData = { label: string; Icon: ComponentType; beta?: true };
diff --git a/web-common/src/features/dashboards/time-dimension-details/charts/TDDAlternateChart.svelte b/web-common/src/features/dashboards/time-dimension-details/charts/TDDAlternateChart.svelte
index 151873bfeb7..f5e8aa13dbb 100644
--- a/web-common/src/features/dashboards/time-dimension-details/charts/TDDAlternateChart.svelte
+++ b/web-common/src/features/dashboards/time-dimension-details/charts/TDDAlternateChart.svelte
@@ -1,11 +1,11 @@
 <script lang="ts">
-  import VegaLiteRenderer from "@rilldata/web-common/features/canvas-components/render/VegaLiteRenderer.svelte";
-  import VegaRenderer from "@rilldata/web-common/features/canvas-components/render/VegaRenderer.svelte";
   import {
     resolveSignalField,
     resolveSignalIntervalField,
     resolveSignalTimeField,
-  } from "@rilldata/web-common/features/canvas-components/render/vega-signals";
+  } from "@rilldata/web-common/components/vega/vega-signals";
+  import VegaLiteRenderer from "@rilldata/web-common/components/vega/VegaLiteRenderer.svelte";
+  import VegaRenderer from "@rilldata/web-common/components/vega/VegaRenderer.svelte";
   import { getStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers";
   import { tableInteractionStore } from "@rilldata/web-common/features/dashboards/time-dimension-details/time-dimension-data-store";
   import type { DimensionDataItem } from "@rilldata/web-common/features/dashboards/time-series/multiple-dimension-queries";
diff --git a/web-common/src/features/dashboards/time-dimension-details/charts/utils.ts b/web-common/src/features/dashboards/time-dimension-details/charts/utils.ts
index 9e77f4bf7b1..0d2f37e08c4 100644
--- a/web-common/src/features/dashboards/time-dimension-details/charts/utils.ts
+++ b/web-common/src/features/dashboards/time-dimension-details/charts/utils.ts
@@ -1,4 +1,4 @@
-import { TDDChartMap } from "@rilldata/web-common/features/canvas-components/types";
+import { TDDChartMap } from "@rilldata/web-common/components/vega/types";
 import type { DimensionDataItem } from "@rilldata/web-common/features/dashboards/time-series/multiple-dimension-queries";
 import {
   type ChartField,
diff --git a/web-common/src/features/entity-management/AddAssetButton.svelte b/web-common/src/features/entity-management/AddAssetButton.svelte
index c7ecaa53dd0..36d1ba74c71 100644
--- a/web-common/src/features/entity-management/AddAssetButton.svelte
+++ b/web-common/src/features/entity-management/AddAssetButton.svelte
@@ -19,7 +19,6 @@
   } from "../../runtime-client";
   import { runtime } from "../../runtime-client/runtime-store";
   import { useIsModelingSupportedForDefaultOlapDriver } from "../connectors/olap/selectors";
-  import { featureFlags } from "../feature-flags";
   import { directoryState } from "../file-explorer/directory-store";
   import { createResourceFile } from "../file-explorer/new-files";
   import { addSourceModal } from "../sources/modal/add-source-visibility";
@@ -41,7 +40,6 @@
 
   const createFile = createRuntimeServicePutFile();
   const createFolder = createRuntimeServiceCreateDirectory();
-  const { customDashboards } = featureFlags;
 
   $: ({ instanceId } = $runtime);
   $: currentFile = $page.params.file;
@@ -229,6 +227,20 @@
         />
         Explore dashboard
       </DropdownMenu.Item>
+      <DropdownMenu.Item
+        class="flex gap-x-2"
+        on:click={async () => {
+          const newFilePath = await createResourceFile(ResourceKind.Canvas);
+          await wrapNavigation(newFilePath);
+        }}
+      >
+        <svelte:component
+          this={resourceIconMapping[ResourceKind.Canvas]}
+          color={resourceColorMapping[ResourceKind.Canvas]}
+          size="16px"
+        />
+        Canvas dashboard
+      </DropdownMenu.Item>
     {/if}
     <DropdownMenu.Separator />
     <DropdownMenu.Sub>
@@ -253,32 +265,7 @@
           API
           <DropdownMenu.Separator />
         </DropdownMenu.Item>
-        {#if $customDashboards}
-          <DropdownMenu.Separator />
-          <DropdownMenu.Item
-            class="flex gap-x-2"
-            on:click={() => handleAddResource(ResourceKind.Component)}
-          >
-            <svelte:component
-              this={resourceIconMapping[ResourceKind.Component]}
-              color={resourceColorMapping[ResourceKind.Component]}
-              size="16px"
-            />
-            Component
-          </DropdownMenu.Item>
-          <DropdownMenu.Item
-            class="flex gap-x-2"
-            on:click={() => handleAddResource(ResourceKind.Canvas)}
-          >
-            <svelte:component
-              this={resourceIconMapping[ResourceKind.Canvas]}
-              color={resourceColorMapping[ResourceKind.Canvas]}
-              size="16px"
-            />
-            Canvas dashboard
-          </DropdownMenu.Item>
-          <DropdownMenu.Separator />
-        {/if}
+        <DropdownMenu.Separator />
         <DropdownMenu.Item
           class="flex gap-x-2"
           on:click={() => handleAddResource(ResourceKind.Theme)}
diff --git a/web-common/src/features/entity-management/CreateExploreDialog.svelte b/web-common/src/features/entity-management/CreateExploreDialog.svelte
index 2d8bd9a120c..b59d5e48ace 100644
--- a/web-common/src/features/entity-management/CreateExploreDialog.svelte
+++ b/web-common/src/features/entity-management/CreateExploreDialog.svelte
@@ -1,10 +1,10 @@
 <script lang="ts">
   import * as AlertDialog from "@rilldata/web-common/components/alert-dialog";
-  import Select from "@rilldata/web-common/components/forms/Select.svelte";
-  import { ResourceKind } from "./resource-selectors";
   import Button from "@rilldata/web-common/components/button/Button.svelte";
-  import { createResourceFile } from "../file-explorer/new-files";
+  import Select from "@rilldata/web-common/components/forms/Select.svelte";
   import type { V1Resource } from "@rilldata/web-common/runtime-client";
+  import { createResourceFile } from "../file-explorer/new-files";
+  import { ResourceKind } from "./resource-selectors";
 
   export let open = false;
   export let metricsViews: V1Resource[];
diff --git a/web-common/src/features/explores/PreviewButton.svelte b/web-common/src/features/explores/PreviewButton.svelte
index 947e25059c5..bf223ccb7dc 100644
--- a/web-common/src/features/explores/PreviewButton.svelte
+++ b/web-common/src/features/explores/PreviewButton.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
-  import { Button } from "@rilldata/web-common/components/button";
   import { navigating } from "$app/stores";
+  import { Button } from "@rilldata/web-common/components/button";
   import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
   import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
   import { clearExploreSessionStore } from "@rilldata/web-common/features/dashboards/url-state/explore-web-view-store";
diff --git a/web-common/src/features/file-explorer/FileExplorer.svelte b/web-common/src/features/file-explorer/FileExplorer.svelte
index 944a749ecd1..44083dbb93d 100644
--- a/web-common/src/features/file-explorer/FileExplorer.svelte
+++ b/web-common/src/features/file-explorer/FileExplorer.svelte
@@ -1,7 +1,6 @@
 <script lang="ts">
   import { goto } from "$app/navigation";
   import { page } from "$app/stores";
-  import GenerateChartYAMLPrompt from "@rilldata/web-common/features/canvas-components/prompt/GenerateChartYAMLPrompt.svelte";
   import RenameAssetModal from "@rilldata/web-common/features/entity-management/RenameAssetModal.svelte";
   import {
     deleteFileArtifact,
@@ -113,26 +112,6 @@
     }
   }
 
-  let showGenerateChartModal = false;
-  let generateChartTable: string;
-  let generateChartConnector: string;
-  let generateChartMetricsView: string;
-
-  function onGenerateChart({
-    table,
-    connector,
-    metricsView,
-  }: {
-    table?: string;
-    connector?: string;
-    metricsView?: string;
-  }) {
-    showGenerateChartModal = true;
-    generateChartTable = table ?? "";
-    generateChartConnector = connector ?? "";
-    generateChartMetricsView = metricsView ?? "";
-  }
-
   const { dragData, position } = navEntryDragDropStore;
 
   async function handleDropSuccess(fromPath: string, toDir: string) {
@@ -188,7 +167,6 @@
       {onRename}
       {onDuplicate}
       {onDelete}
-      {onGenerateChart}
       onMouseDown={(e, dragData) =>
         navEntryDragDropStore.onMouseDown(e, dragData)}
     />
@@ -203,13 +181,6 @@
   />
 {/if}
 
-<GenerateChartYAMLPrompt
-  bind:open={showGenerateChartModal}
-  connector={generateChartConnector}
-  metricsView={generateChartMetricsView}
-  table={generateChartTable}
-/>
-
 {#if $dragData}
   <NavEntryPortal position={$position} dragData={$dragData} />
 {/if}
diff --git a/web-common/src/features/file-explorer/NavDirectory.svelte b/web-common/src/features/file-explorer/NavDirectory.svelte
index 53d9192a5de..f9bf6aac339 100644
--- a/web-common/src/features/file-explorer/NavDirectory.svelte
+++ b/web-common/src/features/file-explorer/NavDirectory.svelte
@@ -12,11 +12,6 @@
   export let onRename: (filePath: string, isDir: boolean) => void;
   export let onDuplicate: (filePath: string, isDir: boolean) => void;
   export let onDelete: (filePath: string, isDir: boolean) => void;
-  export let onGenerateChart: (data: {
-    table?: string;
-    connector?: string;
-    metricsView?: string;
-  }) => void;
   export let onMouseDown: (e: MouseEvent, dragData: NavDragData) => void;
 
   $: expanded = $directoryState[directory.path];
@@ -48,7 +43,6 @@
           {onRename}
           {onDuplicate}
           {onDelete}
-          {onGenerateChart}
           {onMouseDown}
         />
       {/each}
@@ -57,14 +51,7 @@
     {#each directory.files as file (file)}
       {@const filePath =
         directory.path === "/" ? `/${file}` : `${directory.path}/${file}`}
-      <NavFile
-        {filePath}
-        {onRename}
-        {onDuplicate}
-        {onDelete}
-        {onGenerateChart}
-        {onMouseDown}
-      />
+      <NavFile {filePath} {onRename} {onDuplicate} {onDelete} {onMouseDown} />
     {/each}
   {/if}
 </ul>
diff --git a/web-common/src/features/file-explorer/NavFile.svelte b/web-common/src/features/file-explorer/NavFile.svelte
index 30ef5409373..c5d3e37dc80 100644
--- a/web-common/src/features/file-explorer/NavFile.svelte
+++ b/web-common/src/features/file-explorer/NavFile.svelte
@@ -43,11 +43,6 @@
   export let onRename: (filePath: string, isDir: boolean) => void;
   export let onDuplicate: (filePath: string, isDir: boolean) => void;
   export let onDelete: (filePath: string, isDir: boolean) => void;
-  export let onGenerateChart: (data: {
-    table?: string;
-    connector?: string;
-    metricsView?: string;
-  }) => void;
   export let onMouseDown: (e: MouseEvent, dragData: NavDragData) => void;
 
   let contextMenuOpen = false;
@@ -159,22 +154,13 @@
       >
         {#if resourceKind}
           {#if resourceKind === ResourceKind.Source}
-            <SourceMenuItems
-              {filePath}
-              on:generate-chart={({ detail }) => onGenerateChart(detail)}
-            />
+            <SourceMenuItems {filePath} />
             <NavigationMenuSeparator />
           {:else if resourceKind === ResourceKind.Model}
-            <ModelMenuItems
-              {filePath}
-              on:generate-chart={({ detail }) => onGenerateChart(detail)}
-            />
+            <ModelMenuItems {filePath} />
             <NavigationMenuSeparator />
           {:else if resourceKind === ResourceKind.MetricsView}
-            <MetricsViewMenuItems
-              {filePath}
-              on:generate-chart={({ detail }) => onGenerateChart(detail)}
-            />
+            <MetricsViewMenuItems {filePath} />
             <NavigationMenuSeparator />
           {/if}
         {/if}
diff --git a/web-common/src/features/file-explorer/new-files.ts b/web-common/src/features/file-explorer/new-files.ts
index 5b025356a88..2fe5a79f9d3 100644
--- a/web-common/src/features/file-explorer/new-files.ts
+++ b/web-common/src/features/file-explorer/new-files.ts
@@ -247,16 +247,10 @@ vega_lite: |
     case ResourceKind.Canvas:
       return `type: canvas
 title: "Canvas Dashboard"
-columns: 24
-gap: 2
-
 items:
   - component:
       markdown:
         content: "First Component"
-        css:
-          font-size: "40px"
-          background-color: "#fff"
     width: 4
     height: 3
     x: 2
diff --git a/web-common/src/features/metrics-views/editor/MetricsEditor.svelte b/web-common/src/features/metrics-views/editor/MetricsEditor.svelte
index f36dbf811f8..7257b5a62a2 100644
--- a/web-common/src/features/metrics-views/editor/MetricsEditor.svelte
+++ b/web-common/src/features/metrics-views/editor/MetricsEditor.svelte
@@ -9,11 +9,11 @@
   import { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
   import { fileArtifacts } from "@rilldata/web-common/features/entity-management/file-artifacts";
   import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
   import { yamlSchema } from "codemirror-json-schema/yaml";
   import type { JSONSchema7 } from "json-schema";
   import { createPlaceholder } from "./create-placeholder";
   import metricsSchema from "./metrics-schema.json";
-  import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
 
   export let filePath: string;
   export let metricsViewName: string;
diff --git a/web-common/src/features/templates/TemplateRenderer.svelte b/web-common/src/features/templates/TemplateRenderer.svelte
deleted file mode 100644
index 7ae61d055c5..00000000000
--- a/web-common/src/features/templates/TemplateRenderer.svelte
+++ /dev/null
@@ -1,59 +0,0 @@
-<script lang="ts">
-  import Chart from "@rilldata/web-common/features/canvas/Chart.svelte";
-  import { useVariableInputParams } from "@rilldata/web-common/features/canvas/variables-store";
-  import Image from "@rilldata/web-common/features/templates/image/Image.svelte";
-  import KPITemplate from "@rilldata/web-common/features/templates/kpi/KPITemplate.svelte";
-  import Markdown from "@rilldata/web-common/features/templates/markdown/Markdown.svelte";
-  import Select from "@rilldata/web-common/features/templates/select/Select.svelte";
-  import Switch from "@rilldata/web-common/features/templates/switch/Switch.svelte";
-  import TableTemplate from "@rilldata/web-common/features/templates/table/TableTemplate.svelte";
-
-  import {
-    createQueryServiceResolveComponent,
-    type V1ComponentSpecRendererProperties,
-    type V1ComponentSpecResolverProperties,
-    type V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { getContext } from "svelte";
-
-  export let chartView: boolean;
-  export let renderer: string;
-  export let componentName: string;
-  export let input: V1ComponentVariable[] | undefined;
-  export let output: V1ComponentVariable | undefined;
-  export let resolverProperties: V1ComponentSpecResolverProperties | undefined;
-
-  const canvasName = getContext("rill::canvas:name") as string;
-
-  $: ({ instanceId } = $runtime);
-
-  $: inputVariableParams = useVariableInputParams(canvasName, input);
-  $: componentQuery = createQueryServiceResolveComponent(
-    instanceId,
-    componentName,
-    { args: $inputVariableParams },
-  );
-  $: componentData = $componentQuery?.data;
-  $: rendererProperties =
-    componentData?.rendererProperties as V1ComponentSpecRendererProperties;
-  $: data = componentData?.data;
-</script>
-
-{#if rendererProperties}
-  {#if renderer === "kpi"}
-    <KPITemplate {rendererProperties} />
-  {:else if renderer === "table"}
-    <TableTemplate {rendererProperties} />
-  {:else if renderer === "markdown"}
-    <Markdown {rendererProperties} />
-  {:else if renderer === "image"}
-    <Image {rendererProperties} />
-  {:else if renderer === "select"}
-    <Select {data} {componentName} {output} {rendererProperties} />
-  {:else if renderer === "switch"}
-    <Switch {output} {rendererProperties} />
-  {:else if resolverProperties}
-    <Chart {componentName} {chartView} {input} />
-  {/if}
-{/if}
diff --git a/web-common/src/features/templates/charts/build-template.ts b/web-common/src/features/templates/charts/build-template.ts
index 3124f8832f9..e9f6e8b71d1 100644
--- a/web-common/src/features/templates/charts/build-template.ts
+++ b/web-common/src/features/templates/charts/build-template.ts
@@ -1,4 +1,4 @@
-import { ChartType } from "@rilldata/web-common/features/canvas-components/types";
+import { ChartType } from "@rilldata/web-common/components/vega/types";
 import type { VisualizationSpec } from "svelte-vega";
 import { buildArea } from "./area";
 import { buildGroupedBar } from "./grouped-bar";
diff --git a/web-common/src/features/templates/charts/utils.ts b/web-common/src/features/templates/charts/utils.ts
index 49181b5d114..58a7c80886b 100644
--- a/web-common/src/features/templates/charts/utils.ts
+++ b/web-common/src/features/templates/charts/utils.ts
@@ -1,7 +1,5 @@
-import { ChartType } from "@rilldata/web-common/features/canvas-components/types";
-import type { ChartProperties } from "@rilldata/web-common/features/templates/types";
+import { ChartType } from "@rilldata/web-common/components/vega/types";
 import type { VisualizationSpec } from "svelte-vega";
-import { buildVegaLiteSpec } from "./build-template";
 
 export function singleLayerBaseSpec() {
   const baseSpec: VisualizationSpec = {
@@ -45,21 +43,3 @@ export const templateNameToChartEnumMap = {
   area_chart: ChartType.AREA,
   stacked_area_chart: ChartType.STACKED_AREA,
 };
-
-export function getSpecFromTemplateProperties(
-  renderer: string,
-  properties: ChartProperties,
-) {
-  if (!properties.x || !properties.y) {
-    return undefined;
-  }
-  const chartType = templateNameToChartEnumMap[renderer];
-
-  if (!chartType) return undefined;
-
-  const timeFields = [{ name: properties.x, label: properties.x }];
-  const quantitativeFields = [{ name: properties.y, label: properties.y }];
-
-  const spec = buildVegaLiteSpec(chartType, timeFields, quantitativeFields, []);
-  return spec;
-}
diff --git a/web-common/src/features/templates/kpi/KPITemplate.svelte b/web-common/src/features/templates/kpi/KPITemplate.svelte
deleted file mode 100644
index e784d6e5ba8..00000000000
--- a/web-common/src/features/templates/kpi/KPITemplate.svelte
+++ /dev/null
@@ -1,139 +0,0 @@
-<script lang="ts">
-  import { SimpleDataGraphic } from "@rilldata/web-common/components/data-graphic/elements";
-  import { ChunkedLine } from "@rilldata/web-common/components/data-graphic/marks";
-  import { extent } from "d3-array";
-  import MeasureBigNumber from "@rilldata/web-common/features/dashboards/big-number/MeasureBigNumber.svelte";
-  import { useMetricsViewSpecMeasure } from "@rilldata/web-common/features/dashboards/selectors";
-  import {
-    MainAreaColorGradientDark,
-    MainAreaColorGradientLight,
-    MainLineColor,
-  } from "@rilldata/web-common/features/dashboards/time-series/chart-colors";
-  import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
-  import {
-    useKPIComparisonTotal,
-    useKPISparkline,
-    useKPITotals,
-  } from "@rilldata/web-common/features/templates/kpi/selector";
-  import type { KPIProperties } from "@rilldata/web-common/features/templates/types";
-  import { humaniseISODuration } from "@rilldata/web-common/lib/time/ranges/iso-ranges";
-  import type { V1ComponentSpecRendererProperties } from "@rilldata/web-common/runtime-client";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
-
-  export let rendererProperties: V1ComponentSpecRendererProperties;
-
-  let containerWidth: number;
-
-  $: ({ instanceId } = $runtime);
-  $: kpiProperties = rendererProperties as KPIProperties;
-
-  $: ({
-    metrics_view: metricsViewName,
-    filter: whereSql,
-    measure: measureName,
-    time_range: timeRange,
-    comparison_range: comparisonTimeRange,
-  } = kpiProperties);
-
-  $: measure = useMetricsViewSpecMeasure(
-    instanceId,
-    metricsViewName,
-    measureName,
-  );
-
-  $: measureValue = useKPITotals(
-    instanceId,
-    metricsViewName,
-    measureName,
-    timeRange.toUpperCase(),
-    whereSql,
-  );
-
-  $: comparisonValue = useKPIComparisonTotal(
-    instanceId,
-    metricsViewName,
-    measureName,
-    comparisonTimeRange?.toUpperCase(),
-    timeRange.toUpperCase(),
-    whereSql,
-    queryClient,
-  );
-
-  $: sparkline = useKPISparkline(
-    instanceId,
-    metricsViewName,
-    measureName,
-    timeRange.toUpperCase(),
-    whereSql,
-    queryClient,
-  );
-
-  $: sparkData = $sparkline?.data || [];
-
-  const focusedAreaGradient: [string, string] = [
-    MainAreaColorGradientDark,
-    MainAreaColorGradientLight,
-  ];
-
-  $: [yMin, yMax] = extent(sparkData, (d) => d[measureName]);
-  $: [xMin, xMax] = extent(sparkData, (d) => d["ts"]);
-</script>
-
-<div
-  bind:clientWidth={containerWidth}
-  class="flex flex-row h-full w-full items-center bg-white"
->
-  {#if $measure.data && $measureValue.data}
-    <MeasureBigNumber
-      measure={$measure.data}
-      value={$measureValue.data}
-      withTimeseries={false}
-      showComparison
-      comparisonValue={$comparisonValue?.data}
-      status={$measureValue?.isFetching
-        ? EntityStatus.Running
-        : EntityStatus.Idle}
-      isMeasureExpanded={true}
-    />
-  {/if}
-
-  <div>
-    {#if sparkData.length}
-      <SimpleDataGraphic
-        height={comparisonTimeRange ? 70 : 65}
-        width={containerWidth - 160}
-        overflowHidden={false}
-        top={10}
-        bottom={0}
-        right={10}
-        left={0}
-        {xMin}
-        {xMax}
-        {yMin}
-        {yMax}
-      >
-        <ChunkedLine
-          lineColor={MainLineColor}
-          areaGradientColors={focusedAreaGradient}
-          data={sparkData}
-          xAccessor="ts"
-          yAccessor={measureName}
-        />
-      </SimpleDataGraphic>
-    {/if}
-
-    {#if comparisonTimeRange}
-      <div class="comparison-value">
-        vs last {humaniseISODuration(comparisonTimeRange.toUpperCase(), false)}
-      </div>
-    {/if}
-  </div>
-</div>
-
-<style lang="postcss">
-  .comparison-value {
-    font-size: 0.8rem;
-    @apply ui-copy-muted pl-1 pt-0.5;
-  }
-</style>
diff --git a/web-common/src/features/templates/select/Select.svelte b/web-common/src/features/templates/select/Select.svelte
deleted file mode 100644
index cfde9844a8f..00000000000
--- a/web-common/src/features/templates/select/Select.svelte
+++ /dev/null
@@ -1,53 +0,0 @@
-<script lang="ts">
-  import Select from "@rilldata/web-common/components/forms/Select.svelte";
-  import {
-    canvasVariablesStore,
-    useVariable,
-  } from "@rilldata/web-common/features/canvas/variables-store";
-  import type { SelectProperties } from "@rilldata/web-common/features/templates/types";
-  import type {
-    V1ComponentSpecRendererProperties,
-    V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
-  import { getContext } from "svelte";
-
-  const MAX_OPTIONS = 250;
-  const canvasName = getContext("rill::canvas:name") as string;
-
-  export let componentName: string;
-  export let data: any[] | undefined;
-  export let rendererProperties: V1ComponentSpecRendererProperties;
-  export let output: V1ComponentVariable | undefined;
-
-  $: outputVariableName = output?.name || "";
-  $: outputVariableValue = useVariable(canvasName, outputVariableName);
-  $: selectProperties = rendererProperties as SelectProperties;
-
-  $: value = (value || $outputVariableValue || output?.defaultValue) as string;
-
-  $: selectOptions = (data || [])
-    .map((v) => ({
-      value: String(v[selectProperties.valueField]),
-      label: String(
-        v[selectProperties?.labelField || selectProperties.valueField],
-      ),
-    }))
-    .slice(0, MAX_OPTIONS);
-</script>
-
-<div>
-  <Select
-    on:change={(e) =>
-      canvasVariablesStore.updateVariable(
-        canvasName,
-        outputVariableName,
-        e.detail,
-      )}
-    bind:value
-    id={componentName}
-    tooltip={selectProperties.tooltip || ""}
-    label={selectProperties.label || ""}
-    options={selectOptions}
-    placeholder={selectProperties.placeholder || ""}
-  />
-</div>
diff --git a/web-common/src/features/templates/switch/Switch.svelte b/web-common/src/features/templates/switch/Switch.svelte
deleted file mode 100644
index da910cdff66..00000000000
--- a/web-common/src/features/templates/switch/Switch.svelte
+++ /dev/null
@@ -1,52 +0,0 @@
-<script lang="ts">
-  import { Switch } from "@rilldata/web-common/components/button";
-  import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
-  import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
-  import {
-    canvasVariablesStore,
-    useVariable,
-  } from "@rilldata/web-common/features/canvas/variables-store";
-  import type { SwitchProperties } from "@rilldata/web-common/features/templates/types";
-  import type {
-    V1ComponentSpecRendererProperties,
-    V1ComponentVariable,
-  } from "@rilldata/web-common/runtime-client";
-  import { getContext } from "svelte";
-
-  export let rendererProperties: V1ComponentSpecRendererProperties;
-  export let output: V1ComponentVariable | undefined;
-
-  $: canvasName = getContext("rill::canvas:name") as string;
-  $: outputVariableName = output?.name || "";
-  $: outputVariableValue = useVariable(canvasName, outputVariableName);
-  $: switchProperties = rendererProperties as SwitchProperties;
-
-  $: value = (value || $outputVariableValue || output?.defaultValue) as boolean;
-</script>
-
-<Tooltip
-  distance={8}
-  location="bottom"
-  alignment="start"
-  suppress={!switchProperties?.tooltip}
->
-  <slot name="tooltip" />
-  <div class="m-1 p-1 flex items-center h-full">
-    <Switch
-      checked={value}
-      on:click={() => {
-        value = !value;
-        canvasVariablesStore.updateVariable(
-          canvasName,
-          outputVariableName,
-          value,
-        );
-      }}
-    >
-      {switchProperties.label}
-    </Switch>
-  </div>
-  <TooltipContent slot="tooltip-content">
-    {switchProperties?.tooltip}
-  </TooltipContent>
-</Tooltip>
diff --git a/web-common/src/features/templates/types.ts b/web-common/src/features/templates/types.ts
index a0cf2983f32..af9fd418797 100644
--- a/web-common/src/features/templates/types.ts
+++ b/web-common/src/features/templates/types.ts
@@ -3,35 +3,6 @@ interface DataProperties {
   filter?: string;
 }
 
-export interface ChartProperties {
-  x: string;
-  y: string;
-  xLabel?: string;
-  yLabel?: string;
-  color?: string;
-}
-
-interface LineChart {
-  line_chart: ChartProperties;
-}
-
-interface BarChart {
-  bar_chart: ChartProperties;
-}
-
-interface StackedBarChart {
-  stacked_bar_chart: ChartProperties;
-}
-
-export interface KPIProperties extends DataProperties {
-  measure: string;
-  time_range: string;
-  comparison_range?: string;
-}
-export interface KPITemplateT {
-  kpi: KPIProperties;
-}
-
 export interface TableProperties extends DataProperties {
   time_range: string;
   measures: string[];
@@ -83,11 +54,7 @@ export interface ImageTemplateT {
   image: ImageProperties;
 }
 
-type ChartTemplates = LineChart | BarChart | StackedBarChart;
-
 export type TemplateSpec =
-  | ChartTemplates
-  | KPITemplateT
   | TableTemplateT
   | MarkdownTemplateT
   | ImageTemplateT
diff --git a/web-common/src/features/visual-editing/SidebarWrapper.svelte b/web-common/src/features/visual-editing/SidebarWrapper.svelte
index a23e0d283cf..f8230ffb26c 100644
--- a/web-common/src/features/visual-editing/SidebarWrapper.svelte
+++ b/web-common/src/features/visual-editing/SidebarWrapper.svelte
@@ -1,14 +1,18 @@
 <script lang="ts">
   export let title: string;
+  export let type: "primary" | "secondary" = "primary";
+  export let disableHorizontalPadding = false;
 </script>
 
 <div
   class="size-full bg-background flex-none flex flex-col select-none rounded-[2px] w-full"
 >
-  <h1>{title}</h1>
+  <h1 class={type}>{title}</h1>
 
   <div
-    class="px-5 flex flex-col gap-y-3 w-full h-full overflow-y-auto overflow-x-visible"
+    class="{disableHorizontalPadding
+      ? ''
+      : 'px-5'} flex flex-col gap-y-3 w-full h-full overflow-y-auto overflow-x-visible"
   >
     <slot />
   </div>
@@ -17,12 +21,14 @@
 </div>
 
 <style lang="postcss">
-  h1 {
-    @apply text-lg font-semibold mb-2;
+  .primary {
+    @apply text-lg font-semibold;
     @apply pt-6 px-5 mb-2;
   }
 
-  /* h2 {
-    @apply text-sm font-medium;
-  } */
+  .secondary {
+    @apply text-sm font-semibold;
+    @apply bg-slate-50;
+    @apply px-5 py-2;
+  }
 </style>
diff --git a/web-common/src/features/visual-editing/ThemeInput.svelte b/web-common/src/features/visual-editing/ThemeInput.svelte
index f8617a3f6be..be2fa681dee 100644
--- a/web-common/src/features/visual-editing/ThemeInput.svelte
+++ b/web-common/src/features/visual-editing/ThemeInput.svelte
@@ -1,15 +1,15 @@
 <script lang="ts">
   import ColorInput from "@rilldata/web-common/components/color-picker/ColorInput.svelte";
+  import FieldSwitcher from "@rilldata/web-common/components/forms/FieldSwitcher.svelte";
   import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
   import Select from "@rilldata/web-common/components/forms/Select.svelte";
+  import type { V1ThemeSpec } from "@rilldata/web-common/runtime-client";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
   import {
     defaultPrimaryColors,
     defaultSecondaryColors,
   } from "../themes/color-config";
-  import type { V1ThemeSpec } from "@rilldata/web-common/runtime-client";
   import { useTheme } from "../themes/selectors";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import FieldSwitcher from "@rilldata/web-common/components/forms/FieldSwitcher.svelte";
 
   const defaultTheme: V1ThemeSpec = {
     primaryColorRaw: `hsl(${defaultPrimaryColors[500].split(" ").join(",")})`,
@@ -25,6 +25,7 @@
   export let theme: string | V1ThemeSpec | undefined;
   export let onThemeChange: (themeName: string | undefined) => void;
   export let onColorChange: (primary: string, secondary: string) => void;
+  export let small = false;
 
   let themeProxy: V1ThemeSpec =
     typeof theme === "string" || theme === undefined
@@ -46,14 +47,16 @@
   $: presetMode = theme === undefined || typeof theme === "string";
 </script>
 
-<div class="flex flex-col gap-y-1">
+<div class="flex flex-col {small ? 'gap-y-2' : 'gap-y-1'}">
   <InputLabel
     label="Theme"
+    {small}
     id="visual-explore-theme"
     hint="Colors may be adjusted for legibility"
   />
 
   <FieldSwitcher
+    {small}
     fields={["Presets", "Custom"]}
     selected={presetMode ? 0 : 1}
     onClick={(_, field) => {
@@ -71,7 +74,8 @@
   <div class="gap-y-2 flex flex-col">
     {#if typeof theme === "string" || theme === undefined}
       <Select
-        fontSize={14}
+        size={small ? "sm" : "lg"}
+        fontSize={small ? 12 : 14}
         sameWidth
         onChange={(value) => {
           if (value === "Default") {
@@ -92,6 +96,7 @@
     {/if}
 
     <ColorInput
+      {small}
       stringColor={currentTheme.primaryColorRaw}
       label="Primary"
       disabled={presetMode}
@@ -101,6 +106,7 @@
       }}
     />
     <ColorInput
+      {small}
       stringColor={currentTheme.secondaryColorRaw}
       label="Secondary"
       disabled={presetMode}
diff --git a/web-common/src/features/visual-editing/TimeRangeInput.svelte b/web-common/src/features/visual-editing/TimeRangeInput.svelte
new file mode 100644
index 00000000000..3d404857be5
--- /dev/null
+++ b/web-common/src/features/visual-editing/TimeRangeInput.svelte
@@ -0,0 +1,87 @@
+<script lang="ts">
+  import FieldSwitcher from "@rilldata/web-common/components/forms/FieldSwitcher.svelte";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+  import {
+    PERIOD_TO_DATE_RANGES,
+    LATEST_WINDOW_TIME_RANGES,
+    PREVIOUS_COMPLETE_DATE_RANGES,
+    DEFAULT_TIME_RANGES,
+  } from "@rilldata/web-common/lib/time/config";
+  import SelectionDropdown from "./SelectionDropdown.svelte";
+
+  const ranges = [
+    ...Object.keys(LATEST_WINDOW_TIME_RANGES),
+    ...Object.keys(PERIOD_TO_DATE_RANGES),
+    ...Object.keys(PREVIOUS_COMPLETE_DATE_RANGES),
+  ];
+
+  const defaultSet = new Set(ranges);
+
+  export let selectedItems: Set<string>;
+  export let keyNotSet: boolean;
+  export let onSelectCustomItem: (item: string) => void;
+  export let setTimeRanges: (timeRanges: string[]) => void;
+
+  let hasDefaultsSelected =
+    keyNotSet ||
+    (defaultSet.size === selectedItems.size &&
+      defaultSet.isSubsetOf(selectedItems));
+
+  let selected: 0 | 1 = hasDefaultsSelected ? 0 : 1;
+
+  let selectedProxy = new Set(selectedItems);
+
+  $: if (keyNotSet) {
+    selected = 0;
+  }
+</script>
+
+<div class="flex flex-col gap-y-1">
+  <InputLabel
+    capitalize={false}
+    label="Time ranges"
+    id="visual-explore-range"
+    hint="Time range shortcuts available via the dashboard filter bar"
+  />
+  <FieldSwitcher
+    fields={["default", "custom"]}
+    {selected}
+    onClick={(_, field) => {
+      if (field === "custom") {
+        selected = 1;
+        setTimeRanges(Array.from(selectedProxy));
+      } else if (field === "default") {
+        selected = 0;
+        setTimeRanges(ranges);
+      }
+    }}
+  />
+
+  {#if selected === 1}
+    <SelectionDropdown
+      allItems={defaultSet}
+      {selectedItems}
+      onSelect={(item) => {
+        const deleted = selectedProxy.delete(item);
+        if (!deleted) {
+          selectedProxy.add(item);
+        }
+
+        selectedProxy = selectedProxy;
+
+        onSelectCustomItem(item);
+      }}
+      setItems={(ranges) => {
+        selectedProxy = new Set(ranges);
+        setTimeRanges(ranges);
+      }}
+      let:item
+      type="time ranges"
+    >
+      {DEFAULT_TIME_RANGES[item]?.label ?? item}
+    </SelectionDropdown>
+  {/if}
+</div>
+
+<style lang="postcss">
+</style>
diff --git a/web-common/src/features/visual-editing/TimeZoneInput.svelte b/web-common/src/features/visual-editing/TimeZoneInput.svelte
new file mode 100644
index 00000000000..8cc722356dd
--- /dev/null
+++ b/web-common/src/features/visual-editing/TimeZoneInput.svelte
@@ -0,0 +1,75 @@
+<script lang="ts">
+  import FieldSwitcher from "@rilldata/web-common/components/forms/FieldSwitcher.svelte";
+  import InputLabel from "@rilldata/web-common/components/forms/InputLabel.svelte";
+  import { DEFAULT_TIMEZONES } from "@rilldata/web-common/lib/time/config";
+  import ZoneDisplay from "../dashboards/time-controls/super-pill/components/ZoneDisplay.svelte";
+  import SelectionDropdown from "./SelectionDropdown.svelte";
+
+  const defaultSet = new Set(DEFAULT_TIMEZONES);
+  const searchableItems = Intl.supportedValuesOf("timeZone");
+
+  export let selectedItems: Set<string>;
+  export let keyNotSet: boolean;
+  export let onSelectCustomItem: (item: string) => void;
+  export let setTimeZones: (timeZones: string[]) => void;
+
+  let hasDefaultsSelected =
+    keyNotSet ||
+    (defaultSet.size === selectedItems.size &&
+      defaultSet.isSubsetOf(selectedItems));
+
+  let selected: 0 | 1 = hasDefaultsSelected ? 0 : 1;
+
+  let selectedProxy = new Set(selectedItems);
+</script>
+
+<div class="flex flex-col gap-y-1">
+  <InputLabel
+    capitalize={false}
+    label="Time zones"
+    id="visual-explore-zone"
+    hint="Time zones selectable via the dashboard filter bar"
+  />
+  <FieldSwitcher
+    fields={["default", "custom"]}
+    {selected}
+    onClick={(_, field) => {
+      if (field === "custom") {
+        selected = 1;
+        setTimeZones(Array.from(selectedProxy));
+      } else if (field === "default") {
+        selected = 0;
+        setTimeZones(DEFAULT_TIMEZONES);
+      }
+    }}
+  />
+
+  {#if selected === 1}
+    <SelectionDropdown
+      {searchableItems}
+      allItems={defaultSet}
+      {selectedItems}
+      onSelect={(item) => {
+        const deleted = selectedProxy.delete(item);
+        if (!deleted) {
+          selectedProxy.add(item);
+        }
+
+        selectedProxy = selectedProxy;
+
+        onSelectCustomItem(item);
+      }}
+      setItems={(ranges) => {
+        selectedProxy = new Set(ranges);
+        setTimeZones(ranges);
+      }}
+      let:item
+      type="time zones"
+    >
+      <ZoneDisplay iana={item} />
+    </SelectionDropdown>
+  {/if}
+</div>
+
+<style lang="postcss">
+</style>
diff --git a/web-common/src/features/workspaces/CanvasDashboardWorkspace.svelte b/web-common/src/features/workspaces/CanvasDashboardWorkspace.svelte
deleted file mode 100644
index ec4311dc2ce..00000000000
--- a/web-common/src/features/workspaces/CanvasDashboardWorkspace.svelte
+++ /dev/null
@@ -1,336 +0,0 @@
-<script lang="ts">
-  import { goto } from "$app/navigation";
-  import type { EditorView } from "@codemirror/view";
-  import Label from "@rilldata/web-common/components/forms/Label.svelte";
-  import Switch from "@rilldata/web-common/components/forms/Switch.svelte";
-  import ComponentsEditor from "@rilldata/web-common/features/canvas-components/editor/ComponentsEditor.svelte";
-  import ComponentsEditorContainer from "@rilldata/web-common/features/canvas-components/editor/ComponentsEditorContainer.svelte";
-  import AddComponentMenu from "@rilldata/web-common/features/canvas/AddComponentMenu.svelte";
-  import CanvasDashboardPreview from "@rilldata/web-common/features/canvas/CanvasDashboardPreview.svelte";
-  import ViewSelector from "@rilldata/web-common/features/visual-editing/ViewSelector.svelte";
-  import type { Vector } from "@rilldata/web-common/features/canvas/types";
-  import Editor from "@rilldata/web-common/features/editor/Editor.svelte";
-  import { FileExtensionToEditorExtension } from "@rilldata/web-common/features/editor/getExtensionsForFile";
-  import { getNameFromFile } from "@rilldata/web-common/features/entity-management/entity-mappers";
-  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
-  import { fileArtifacts } from "@rilldata/web-common/features/entity-management/file-artifacts";
-  import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
-  import { handleEntityRename } from "@rilldata/web-common/features/entity-management/ui-actions";
-  import Resizer from "@rilldata/web-common/layout/Resizer.svelte";
-  import {
-    WorkspaceContainer,
-    WorkspaceHeader,
-  } from "@rilldata/web-common/layout/workspace";
-  import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
-  import type { V1CanvasSpec } from "@rilldata/web-common/runtime-client";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { setContext } from "svelte";
-  import Button from "web-common/src/components/button/Button.svelte";
-  import { parseDocument } from "yaml";
-  import {
-    resourceColorMapping,
-    resourceIconMapping,
-  } from "../entity-management/resource-icon-mapping";
-  import PreviewButton from "../explores/PreviewButton.svelte";
-
-  export let fileArtifact: FileArtifact;
-
-  let canvasDashboardName: string;
-  let selectedComponentFileArtifact: FileArtifact | undefined;
-  let selectedView: "split" | "code" | "viz";
-  let showGrid = true;
-  let showComponentEditor = false;
-  let containerWidth: number;
-  let containerHeight: number;
-  let editorPercentage = 0.5;
-  let editor: EditorView;
-  let selectedIndex: number | null = null;
-  let componentEditorPercentage = 0.4;
-  let selectedComponentName: string | null = null;
-  let spec: V1CanvasSpec = {
-    columns: 20,
-    gap: 4,
-    items: [],
-  };
-
-  $: canvasDashboardName = getNameFromFile(filePath);
-  $: setContext("rill::canvas:name", canvasDashboardName);
-
-  $: ({ instanceId } = $runtime);
-
-  $: errorsQuery = fileArtifact.getAllErrors(queryClient, instanceId);
-  $: errors = $errorsQuery;
-
-  $: ({
-    saveLocalContent: updateComponentFile,
-    autoSave,
-    path: filePath,
-    fileName,
-    updateEditorContent,
-    editorContent,
-    hasUnsavedChanges,
-  } = fileArtifact);
-
-  $: resourceQuery = fileArtifact.getResource(queryClient, instanceId);
-
-  $: spec = structuredClone($resourceQuery.data?.canvas?.spec ?? spec);
-
-  $: ({ items = [], columns = 20, gap = 4, variables = [] } = spec);
-  $: if (
-    items.filter(
-      (item) =>
-        !item.definedInCanvas && item.component === selectedComponentName,
-    ).length
-  ) {
-    selectedComponentFileArtifact = fileArtifacts.findFileArtifact(
-      ResourceKind.Component,
-      selectedComponentName ?? "",
-    );
-  } else {
-    selectedComponentName = null;
-    selectedComponentFileArtifact = undefined;
-    showComponentEditor = false;
-  }
-  $: selectedComponentFilePath = selectedComponentFileArtifact?.path;
-  $: editorWidth = editorPercentage * containerWidth;
-  $: componentEditorHeight = componentEditorPercentage * containerHeight;
-
-  async function onChangeCallback(newTitle: string) {
-    const newRoute = await handleEntityRename(
-      instanceId,
-      newTitle,
-      filePath,
-      fileName,
-    );
-    if (newRoute) await goto(newRoute);
-  }
-
-  async function handlePreviewUpdate(
-    e: CustomEvent<{
-      index: number;
-      position: Vector;
-      dimensions: Vector;
-    }>,
-  ) {
-    const parsedDocument = parseDocument($editorContent ?? "");
-    const items = parsedDocument.get("items") as any;
-
-    const node = items.get(e.detail.index);
-
-    node.set("width", e.detail.dimensions[0]);
-    node.set("height", e.detail.dimensions[1]);
-    node.set("x", e.detail.position[0]);
-    node.set("y", e.detail.position[1]);
-
-    updateEditorContent(parsedDocument.toString());
-
-    if ($autoSave) await updateComponentFile();
-  }
-
-  async function addComponent(componentName: string) {
-    const newComponent = {
-      component: componentName,
-      height: 4,
-      width: 4,
-      x: 0,
-      y: 0,
-    };
-    const parsedDocument = parseDocument($editorContent ?? "");
-
-    const items = parsedDocument.get("items") as any;
-
-    if (!items) {
-      parsedDocument.set("items", [newComponent]);
-    } else {
-      items.add(newComponent);
-    }
-
-    updateEditorContent(parsedDocument.toString(), true);
-
-    if ($autoSave) await updateComponentFile();
-  }
-
-  async function handleDeleteEvent(
-    e: CustomEvent<{
-      index: number;
-    }>,
-  ) {
-    if (!e.detail.index) return;
-    await deleteComponent(e.detail.index);
-  }
-
-  async function deleteComponent(index: number) {
-    const parsedDocument = parseDocument($editorContent ?? "");
-
-    const items = parsedDocument.get("items") as any;
-
-    if (!items) return;
-
-    items.delete(index);
-
-    updateEditorContent(parsedDocument.toString(), true);
-
-    if ($autoSave) await updateComponentFile();
-  }
-</script>
-
-<svelte:window
-  on:keydown={async (e) => {
-    if (e.target !== document.body || selectedIndex === null) return;
-    if (e.key === "Delete" || e.key === "Backspace") {
-      await deleteComponent(selectedIndex);
-    }
-  }}
-/>
-
-<WorkspaceContainer
-  bind:height={containerHeight}
-  bind:width={containerWidth}
-  inspector={false}
->
-  <WorkspaceHeader
-    slot="header"
-    {filePath}
-    resourceKind={ResourceKind.Canvas}
-    hasUnsavedChanges={$hasUnsavedChanges}
-    showInspectorToggle={false}
-    titleInput={fileName}
-    onTitleChange={onChangeCallback}
-  >
-    <div class="flex gap-x-2 items-center" slot="workspace-controls">
-      <PreviewButton
-        href="/custom/{canvasDashboardName}"
-        disabled={errors?.length > 0}
-      />
-
-      <AddComponentMenu {addComponent} />
-      <ViewSelector bind:selectedView />
-    </div>
-  </WorkspaceHeader>
-
-  <div class="flex w-full h-full flex-row overflow-hidden" slot="body">
-    {#if selectedView === "code" || selectedView === "split"}
-      <div
-        class="relative h-full flex-shrink-0 w-full"
-        class:!w-full={selectedView === "code"}
-        style:width="{editorPercentage * 100}%"
-      >
-        <div class="flex flex-col h-full overflow-hidden">
-          <section class="size-full flex flex-col flex-shrink overflow-hidden">
-            <ComponentsEditorContainer error={errors[0]}>
-              <Editor
-                bind:editor
-                {fileArtifact}
-                extensions={FileExtensionToEditorExtension[".yaml"]}
-                autoSave
-                showSaveBar={false}
-                onRevert={() => {
-                  spec = structuredClone(spec);
-                }}
-              />
-            </ComponentsEditorContainer>
-          </section>
-
-          {#if selectedComponentName || showComponentEditor}
-            <section
-              style:height="{componentEditorPercentage * 100}%"
-              class:!h-12={!showComponentEditor}
-              class="size-full flex flex-col flex-none flex-shrink-0 relative !min-h-12"
-            >
-              <Resizer
-                direction="NS"
-                dimension={componentEditorHeight}
-                min={80}
-                max={0.85 * containerHeight}
-                onUpdate={(height) =>
-                  (componentEditorPercentage = height / containerHeight)}
-              />
-              <header
-                class="flex justify-between items-center pr-2 bg-gray-100 flex-none py-2"
-              >
-                <h1
-                  class="font-semibold text-xl truncate flex items-center gap-x-2"
-                >
-                  {#if selectedComponentName}
-                    <svelte:component
-                      this={resourceIconMapping[ResourceKind.Component]}
-                      size="18px"
-                      color={resourceColorMapping[ResourceKind.Component]}
-                    />
-                    {selectedComponentName}.yaml
-                  {/if}
-                </h1>
-
-                <Button
-                  type="subtle"
-                  on:click={() => (showComponentEditor = !showComponentEditor)}
-                >
-                  {showComponentEditor ? "Close" : "Open"}
-                </Button>
-              </header>
-
-              {#if showComponentEditor}
-                <div class="size-full overflow-hidden">
-                  {#if selectedComponentFilePath}
-                    <ComponentsEditor filePath={selectedComponentFilePath} />
-                  {/if}
-                </div>
-              {/if}
-            </section>
-          {/if}
-        </div>
-      </div>
-    {/if}
-
-    {#if selectedView === "split"}
-      <Resizer
-        absolute={false}
-        direction="EW"
-        side="right"
-        dimension={editorWidth}
-        min={300}
-        max={0.65 * containerWidth}
-        onUpdate={(width) => (editorPercentage = width / containerWidth)}
-      />
-    {/if}
-
-    {#if selectedView === "viz" || selectedView === "split"}
-      <section
-        class="size-full flex flex-col relative overflow-hidden border border-gray-300 rounded-[2px]"
-      >
-        <CanvasDashboardPreview
-          {canvasDashboardName}
-          {gap}
-          {items}
-          {columns}
-          {showGrid}
-          {variables}
-          bind:selectedComponentName
-          bind:selectedIndex
-          on:update={handlePreviewUpdate}
-          on:delete={handleDeleteEvent}
-        />
-
-        <div class="floating-grid-wrapper">
-          <Switch small id="grid" bind:checked={showGrid} />
-          <Label for="grid" class="font-medium text-xs text-gray-600">
-            Grid
-          </Label>
-        </div>
-      </section>
-    {/if}
-  </div>
-</WorkspaceContainer>
-
-<style lang="postcss">
-  .floating-grid-wrapper {
-    @apply transition-all;
-    @apply opacity-50 shadow-lg border border-slate-200 bg-slate-100;
-    @apply flex gap-x-1 flex-none py-1 px-2 items-center h-fit rounded-full;
-    @apply absolute bottom-2 right-2;
-  }
-
-  .floating-grid-wrapper:hover {
-    @apply opacity-100;
-  }
-</style>
diff --git a/web-common/src/features/workspaces/CanvasWorkspace.svelte b/web-common/src/features/workspaces/CanvasWorkspace.svelte
new file mode 100644
index 00000000000..ccb80a45e28
--- /dev/null
+++ b/web-common/src/features/workspaces/CanvasWorkspace.svelte
@@ -0,0 +1,196 @@
+<script lang="ts">
+  import { goto } from "$app/navigation";
+  import ErrorPage from "@rilldata/web-common/components/ErrorPage.svelte";
+  import Canvas from "@rilldata/web-common/features/canvas/Canvas.svelte";
+  import CanvasEditor from "@rilldata/web-common/features/canvas/CanvasEditor.svelte";
+  import CanvasThemeProvider from "@rilldata/web-common/features/canvas/CanvasThemeProvider.svelte";
+  import AddComponentMenu from "@rilldata/web-common/features/canvas/components/AddComponentMenu.svelte";
+  import type { CanvasComponentType } from "@rilldata/web-common/features/canvas/components/types";
+  import { getComponentRegistry } from "@rilldata/web-common/features/canvas/components/util";
+  import VisualCanvasEditing from "@rilldata/web-common/features/canvas/inspector/VisualCanvasEditing.svelte";
+  import { useDefaultMetrics } from "@rilldata/web-common/features/canvas/selector";
+  import StateManagersProvider from "@rilldata/web-common/features/canvas/state-managers/StateManagersProvider.svelte";
+  import DelayedSpinner from "@rilldata/web-common/features/entity-management/DelayedSpinner.svelte";
+  import { getNameFromFile } from "@rilldata/web-common/features/entity-management/entity-mappers";
+  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
+  import {
+    resourceIsLoading,
+    ResourceKind,
+  } from "@rilldata/web-common/features/entity-management/resource-selectors";
+  import { handleEntityRename } from "@rilldata/web-common/features/entity-management/ui-actions";
+  import { mapParseErrorsToLines } from "@rilldata/web-common/features/metrics-views/errors";
+  import ViewSelector from "@rilldata/web-common/features/visual-editing/ViewSelector.svelte";
+  import {
+    WorkspaceContainer,
+    WorkspaceHeader,
+  } from "@rilldata/web-common/layout/workspace";
+  import { workspaces } from "@rilldata/web-common/layout/workspace/workspace-stores";
+  import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
+  import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
+  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { parseDocument } from "yaml";
+  import PreviewButton from "../explores/PreviewButton.svelte";
+
+  export let fileArtifact: FileArtifact;
+
+  let canvasName: string;
+  let selectedView: "split" | "code" | "viz";
+
+  const componentRegistry = getComponentRegistry(fileArtifact);
+
+  $: ({
+    saveLocalContent: updateComponentFile,
+    autoSave,
+    path: filePath,
+    fileName,
+    updateEditorContent,
+    editorContent,
+    getResource,
+    getAllErrors,
+    remoteContent,
+    hasUnsavedChanges,
+  } = fileArtifact);
+
+  $: resourceQuery = getResource(queryClient, instanceId);
+
+  $: ({ data } = $resourceQuery);
+
+  $: allErrorsQuery = getAllErrors(queryClient, instanceId);
+  $: allErrors = $allErrorsQuery;
+
+  $: resourceIsReconciling = resourceIsLoading(data);
+
+  $: workspace = workspaces.get(filePath);
+  $: selectedViewStore = workspace.view;
+  $: selectedView = $selectedViewStore ?? "code";
+
+  $: canvasResource = data?.canvas;
+  $: canvasName = getNameFromFile(filePath);
+
+  $: metricsViewQuery = useDefaultMetrics(instanceId);
+
+  $: ({ instanceId } = $runtime);
+
+  $: lineBasedRuntimeErrors = mapParseErrorsToLines(
+    allErrors,
+    $remoteContent ?? "",
+  );
+
+  $: mainError = lineBasedRuntimeErrors?.at(0);
+
+  async function onChangeCallback(newTitle: string) {
+    const newRoute = await handleEntityRename(
+      $runtime.instanceId,
+      newTitle,
+      filePath,
+      fileName,
+    );
+    if (newRoute) await goto(newRoute);
+  }
+
+  async function addComponent(componentName: CanvasComponentType) {
+    const defaultMetrics = $metricsViewQuery?.data;
+    if (!defaultMetrics) return;
+
+    const newSpec = componentRegistry[componentName].newComponentSpec(
+      defaultMetrics.metricsView,
+      defaultMetrics.measure,
+      defaultMetrics.dimension,
+    );
+
+    const { width, height } = componentRegistry[componentName].defaultSize;
+    const newComponent = {
+      component: { [componentName]: newSpec },
+      height,
+      width,
+      x: 0,
+      y: 0,
+    };
+    const parsedDocument = parseDocument(
+      $editorContent ?? $remoteContent ?? "",
+    );
+
+    const items = parsedDocument.get("items") as any;
+
+    if (!items) {
+      parsedDocument.set("items", [newComponent]);
+    } else {
+      items.add(newComponent);
+    }
+
+    updateEditorContent(parsedDocument.toString(), true);
+    await updateComponentFile();
+  }
+</script>
+
+{#if canvasResource && fileArtifact}
+  {#key canvasName}
+    <StateManagersProvider {canvasName}>
+      <CanvasThemeProvider>
+        <WorkspaceContainer>
+          <WorkspaceHeader
+            slot="header"
+            {filePath}
+            hasUnsavedChanges={$hasUnsavedChanges}
+            titleInput={fileName}
+            onTitleChange={onChangeCallback}
+            resourceKind={ResourceKind.Canvas}
+          >
+            <div class="flex gap-x-2" slot="cta">
+              <PreviewButton
+                href="/canvas/{canvasName}"
+                disabled={allErrors.length > 0 || resourceIsReconciling}
+                reconciling={resourceIsReconciling}
+              />
+
+              <AddComponentMenu {addComponent} />
+              <ViewSelector
+                allowSplit={false}
+                bind:selectedView={$selectedViewStore}
+              />
+            </div>
+          </WorkspaceHeader>
+
+          <WorkspaceEditorContainer
+            slot="body"
+            error={mainError}
+            showError={!!$remoteContent && selectedView === "code"}
+          >
+            {#if selectedView === "code"}
+              <CanvasEditor
+                bind:autoSave={$autoSave}
+                {canvasName}
+                {fileArtifact}
+                {lineBasedRuntimeErrors}
+              />
+            {:else if selectedView === "viz"}
+              {#if mainError}
+                <ErrorPage
+                  body={mainError.message}
+                  fatal
+                  header="Unable to load dashboard preview"
+                  statusCode={404}
+                />
+              {:else if canvasResource}
+                <Canvas {fileArtifact} />
+              {/if}
+            {/if}
+          </WorkspaceEditorContainer>
+
+          <VisualCanvasEditing {fileArtifact} slot="inspector" />
+        </WorkspaceContainer>
+      </CanvasThemeProvider>
+    </StateManagersProvider>
+  {/key}
+{:else if allErrors.length}
+  <ErrorPage
+    body="Please fix the errors in the code editor before previewing the dashboard."
+    header="Unable to load dashboard preview"
+    detail={allErrors.map((error) => error.message).join("\n")}
+    statusCode={404}
+  />
+{:else}
+  <div class="grid place-items-center size-full">
+    <DelayedSpinner isLoading={true} size="40px" />
+  </div>
+{/if}
diff --git a/web-common/src/features/workspaces/ComponentWorkspace.svelte b/web-common/src/features/workspaces/ComponentWorkspace.svelte
deleted file mode 100644
index f6c8a640957..00000000000
--- a/web-common/src/features/workspaces/ComponentWorkspace.svelte
+++ /dev/null
@@ -1,106 +0,0 @@
-<script lang="ts">
-  import ComponentDataDisplay from "@rilldata/web-common/features/canvas-components/ComponentDataDisplay.svelte";
-  import ComponentStatusDisplay from "@rilldata/web-common/features/canvas-components/ComponentStatusDisplay.svelte";
-  import ComponentsHeader from "@rilldata/web-common/features/canvas-components/ComponentsHeader.svelte";
-  import ComponentsEditor from "@rilldata/web-common/features/canvas-components/editor/ComponentsEditor.svelte";
-  import CanvasDashboardEmbed from "@rilldata/web-common/features/canvas/CanvasDashboardEmbed.svelte";
-  import { getNameFromFile } from "@rilldata/web-common/features/entity-management/entity-mappers";
-  import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
-  import {
-    ResourceKind,
-    useResource,
-  } from "@rilldata/web-common/features/entity-management/resource-selectors";
-  import Resizer from "@rilldata/web-common/layout/Resizer.svelte";
-  import { WorkspaceContainer } from "@rilldata/web-common/layout/workspace";
-  import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
-  import { getContext } from "svelte";
-
-  export let fileArtifact: FileArtifact;
-
-  const canvasName = getContext("rill::canvas:name") as string;
-
-  let containerWidth: number;
-  let containerHeight: number;
-  let editorPercentage = 0.55;
-  let tablePercentage = 0.45;
-
-  $: ({ instanceId } = $runtime);
-
-  $: ({ hasUnsavedChanges, path: filePath } = fileArtifact);
-  $: componentName = getNameFromFile(filePath);
-
-  $: editorWidth = editorPercentage * containerWidth;
-
-  $: resourceQuery = useResource(
-    instanceId,
-    componentName,
-    ResourceKind.Component,
-  );
-
-  $: ({ data: componentResource, isFetching } = $resourceQuery);
-
-  $: ({ resolverProperties, input } = componentResource?.component?.spec ?? {});
-
-  $: tableHeight = tablePercentage * containerHeight;
-</script>
-
-<WorkspaceContainer
-  inspector={false}
-  bind:width={containerWidth}
-  bind:height={containerHeight}
->
-  <ComponentsHeader
-    slot="header"
-    {filePath}
-    hasUnsavedChanges={$hasUnsavedChanges}
-  />
-  <div slot="body" class="flex size-full">
-    <section style:width="{editorPercentage * 100}%">
-      <ComponentsEditor {filePath} />
-    </section>
-
-    <Resizer
-      absolute={false}
-      direction="EW"
-      side="right"
-      dimension={editorWidth}
-      min={300}
-      max={0.65 * containerWidth}
-      onUpdate={(width) => (editorPercentage = width / containerWidth)}
-    />
-
-    <section class="size-full flex-col flex overflow-hidden">
-      <div
-        class="size-full overflow-hidden border border-gray-300 rounded-[2px]"
-      >
-        <ComponentStatusDisplay {isFetching} {componentName}>
-          <CanvasDashboardEmbed
-            {canvasName}
-            chartView
-            gap={8}
-            columns={10}
-            items={[
-              { width: 10, height: 10, x: 0, y: 0, component: componentName },
-            ]}
-          />
-        </ComponentStatusDisplay>
-      </div>
-
-      <Resizer
-        absolute={false}
-        direction="NS"
-        dimension={tableHeight}
-        min={100}
-        max={0.65 * containerHeight}
-        onUpdate={(height) => (tablePercentage = height / containerHeight)}
-      />
-
-      <ComponentDataDisplay
-        {componentName}
-        {tablePercentage}
-        {input}
-        {resolverProperties}
-      />
-    </section>
-  </div>
-</WorkspaceContainer>
diff --git a/web-common/src/features/workspaces/ExploreWorkspace.svelte b/web-common/src/features/workspaces/ExploreWorkspace.svelte
index f2e3ff93957..a97dc2709df 100644
--- a/web-common/src/features/workspaces/ExploreWorkspace.svelte
+++ b/web-common/src/features/workspaces/ExploreWorkspace.svelte
@@ -1,5 +1,6 @@
 <script lang="ts">
   import { goto } from "$app/navigation";
+  import ErrorPage from "@rilldata/web-common/components/ErrorPage.svelte";
   import { initLocalUserPreferenceStore } from "@rilldata/web-common/features/dashboards/user-preferences";
   import { getNameFromFile } from "@rilldata/web-common/features/entity-management/entity-mappers";
   import type { FileArtifact } from "@rilldata/web-common/features/entity-management/file-artifact";
@@ -9,20 +10,19 @@
   } from "@rilldata/web-common/features/entity-management/resource-selectors";
   import { handleEntityRename } from "@rilldata/web-common/features/entity-management/ui-actions";
   import ExploreEditor from "@rilldata/web-common/features/explores/ExploreEditor.svelte";
+  import ViewSelector from "@rilldata/web-common/features/visual-editing/ViewSelector.svelte";
+  import { workspaces } from "@rilldata/web-common/layout/workspace/workspace-stores";
   import WorkspaceContainer from "@rilldata/web-common/layout/workspace/WorkspaceContainer.svelte";
+  import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
   import WorkspaceHeader from "@rilldata/web-common/layout/workspace/WorkspaceHeader.svelte";
   import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
+  import { createRuntimeServiceGetExplore } from "@rilldata/web-common/runtime-client";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import DashboardWithProviders from "../dashboards/workspace/DashboardWithProviders.svelte";
+  import Spinner from "../entity-management/Spinner.svelte";
   import PreviewButton from "../explores/PreviewButton.svelte";
-  import { workspaces } from "@rilldata/web-common/layout/workspace/workspace-stores";
-  import ViewSelector from "@rilldata/web-common/features/visual-editing/ViewSelector.svelte";
-  import VisualExploreEditing from "./VisualExploreEditing.svelte";
   import { mapParseErrorsToLines } from "../metrics-views/errors";
-  import ErrorPage from "@rilldata/web-common/components/ErrorPage.svelte";
-  import { createRuntimeServiceGetExplore } from "@rilldata/web-common/runtime-client";
-  import Spinner from "../entity-management/Spinner.svelte";
-  import DashboardWithProviders from "../dashboards/workspace/DashboardWithProviders.svelte";
-  import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
+  import VisualExploreEditing from "./VisualExploreEditing.svelte";
 
   export let fileArtifact: FileArtifact;
 
diff --git a/web-common/src/layout/workspace/Inspector.svelte b/web-common/src/layout/workspace/Inspector.svelte
index 8c624b896ca..9e7350c0895 100644
--- a/web-common/src/layout/workspace/Inspector.svelte
+++ b/web-common/src/layout/workspace/Inspector.svelte
@@ -1,11 +1,12 @@
 <script lang="ts">
+  import { slide } from "svelte/transition";
   import Resizer from "../Resizer.svelte";
   import { workspaces } from "./workspace-stores";
-  import { slide } from "svelte/transition";
 
   export let filePath: string;
   export let resizable = true;
   export let fixedWidth: number | undefined = undefined;
+  export let minWidth = 320;
 
   let resizing = false;
 
@@ -28,7 +29,7 @@
       absolute={false}
       direction="EW"
       side="left"
-      min={fixedWidth ?? 320}
+      min={fixedWidth ?? minWidth}
       max={fixedWidth ?? 420}
       dimension={fixedWidth ?? width}
       onUpdate={(newWidth) => {
diff --git a/web-common/src/proto/gen/rill/runtime/v1/queries_pb.ts b/web-common/src/proto/gen/rill/runtime/v1/queries_pb.ts
index 09cf9f558d5..aacbb12fa73 100644
--- a/web-common/src/proto/gen/rill/runtime/v1/queries_pb.ts
+++ b/web-common/src/proto/gen/rill/runtime/v1/queries_pb.ts
@@ -3384,7 +3384,7 @@ export class ResolveComponentRequest extends Message<ResolveComponentRequest> {
   component = "";
 
   /**
-   * Optional args to pass to the data resolver and for resolving templating in the renderer properties
+   * Optional args for resolving templating in the renderer properties
    *
    * @generated from field: google.protobuf.Struct args = 3;
    */
@@ -3432,24 +3432,10 @@ export class ResolveComponentResponse extends Message<ResolveComponentResponse>
    */
   show = false;
 
-  /**
-   * Schema of the resolved component data
-   *
-   * @generated from field: rill.runtime.v1.StructType schema = 2;
-   */
-  schema?: StructType;
-
-  /**
-   * Resolved component data
-   *
-   * @generated from field: repeated google.protobuf.Struct data = 3;
-   */
-  data: Struct[] = [];
-
   /**
    * Renderer properties with templating resolved for the provided args
    *
-   * @generated from field: google.protobuf.Struct renderer_properties = 4;
+   * @generated from field: google.protobuf.Struct renderer_properties = 2;
    */
   rendererProperties?: Struct;
 
@@ -3462,9 +3448,7 @@ export class ResolveComponentResponse extends Message<ResolveComponentResponse>
   static readonly typeName = "rill.runtime.v1.ResolveComponentResponse";
   static readonly fields: FieldList = proto3.util.newFieldList(() => [
     { no: 1, name: "show", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
-    { no: 2, name: "schema", kind: "message", T: StructType },
-    { no: 3, name: "data", kind: "message", T: Struct, repeated: true },
-    { no: 4, name: "renderer_properties", kind: "message", T: Struct },
+    { no: 2, name: "renderer_properties", kind: "message", T: Struct },
   ]);
 
   static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ResolveComponentResponse {
diff --git a/web-common/src/proto/gen/rill/runtime/v1/resources_pb.ts b/web-common/src/proto/gen/rill/runtime/v1/resources_pb.ts
index 3a0cdb0cfd5..09df2c60d6a 100644
--- a/web-common/src/proto/gen/rill/runtime/v1/resources_pb.ts
+++ b/web-common/src/proto/gen/rill/runtime/v1/resources_pb.ts
@@ -4263,16 +4263,6 @@ export class ComponentSpec extends Message<ComponentSpec> {
    */
   description = "";
 
-  /**
-   * @generated from field: string resolver = 2;
-   */
-  resolver = "";
-
-  /**
-   * @generated from field: google.protobuf.Struct resolver_properties = 3;
-   */
-  resolverProperties?: Struct;
-
   /**
    * @generated from field: string renderer = 4;
    */
@@ -4315,8 +4305,6 @@ export class ComponentSpec extends Message<ComponentSpec> {
   static readonly fields: FieldList = proto3.util.newFieldList(() => [
     { no: 1, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
     { no: 7, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
-    { no: 2, name: "resolver", kind: "scalar", T: 9 /* ScalarType.STRING */ },
-    { no: 3, name: "resolver_properties", kind: "message", T: Struct },
     { no: 4, name: "renderer", kind: "scalar", T: 9 /* ScalarType.STRING */ },
     { no: 5, name: "renderer_properties", kind: "message", T: Struct },
     { no: 8, name: "input", kind: "message", T: ComponentVariable, repeated: true },
@@ -4481,14 +4469,19 @@ export class CanvasSpec extends Message<CanvasSpec> {
   displayName = "";
 
   /**
-   * @generated from field: uint32 columns = 2;
+   * @generated from field: uint32 max_width = 2;
+   */
+  maxWidth = 0;
+
+  /**
+   * @generated from field: string theme = 7;
    */
-  columns = 0;
+  theme = "";
 
   /**
-   * @generated from field: uint32 gap = 3;
+   * @generated from field: rill.runtime.v1.ThemeSpec embedded_theme = 8;
    */
-  gap = 0;
+  embeddedTheme?: ThemeSpec;
 
   /**
    * @generated from field: repeated rill.runtime.v1.ComponentVariable variables = 5;
@@ -4514,8 +4507,9 @@ export class CanvasSpec extends Message<CanvasSpec> {
   static readonly typeName = "rill.runtime.v1.CanvasSpec";
   static readonly fields: FieldList = proto3.util.newFieldList(() => [
     { no: 1, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
-    { no: 2, name: "columns", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
-    { no: 3, name: "gap", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
+    { no: 2, name: "max_width", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
+    { no: 7, name: "theme", kind: "scalar", T: 9 /* ScalarType.STRING */ },
+    { no: 8, name: "embedded_theme", kind: "message", T: ThemeSpec },
     { no: 5, name: "variables", kind: "message", T: ComponentVariable, repeated: true },
     { no: 4, name: "items", kind: "message", T: CanvasItem, repeated: true },
     { no: 6, name: "security_rules", kind: "message", T: SecurityRule, repeated: true },
diff --git a/web-common/src/runtime-client/gen/index.schemas.ts b/web-common/src/runtime-client/gen/index.schemas.ts
index 08999c4ba74..dd13b652268 100644
--- a/web-common/src/runtime-client/gen/index.schemas.ts
+++ b/web-common/src/runtime-client/gen/index.schemas.ts
@@ -582,6 +582,12 @@ export interface V1TimeSeriesValue {
   records?: V1TimeSeriesValueRecords;
 }
 
+export interface V1TimeSeriesTimeRange {
+  start?: string;
+  end?: string;
+  interval?: V1TimeGrain;
+}
+
 export interface V1TimeSeriesResponse {
   results?: V1TimeSeriesValue[];
   spark?: V1TimeSeriesValue[];
@@ -610,12 +616,6 @@ export const V1TimeGrain = {
   TIME_GRAIN_YEAR: "TIME_GRAIN_YEAR",
 } as const;
 
-export interface V1TimeSeriesTimeRange {
-  start?: string;
-  end?: string;
-  interval?: V1TimeGrain;
-}
-
 export interface V1TimeRange {
   start?: string;
   end?: string;
@@ -833,17 +833,20 @@ export type V1ResolveComponentResponseRendererProperties = {
   [key: string]: any;
 };
 
-export type V1ResolveComponentResponseDataItem = { [key: string]: any };
-
 export interface V1ResolveComponentResponse {
   /** Show property with templating resolved for the provided args.
 If it resolves to false, the other fields are not set. */
   show?: boolean;
-  schema?: V1StructType;
-  data?: V1ResolveComponentResponseDataItem[];
   rendererProperties?: V1ResolveComponentResponseRendererProperties;
 }
 
+export interface V1ReportState {
+  nextRunOn?: string;
+  currentExecution?: V1ReportExecution;
+  executionHistory?: V1ReportExecution[];
+  executionCount?: number;
+}
+
 export type V1ReportSpecAnnotations = { [key: string]: string };
 
 export interface V1ReportSpec {
@@ -872,13 +875,6 @@ export interface V1ReportExecution {
   finishedOn?: string;
 }
 
-export interface V1ReportState {
-  nextRunOn?: string;
-  currentExecution?: V1ReportExecution;
-  executionHistory?: V1ReportExecution[];
-  executionCount?: number;
-}
-
 export interface V1Report {
   spec?: V1ReportSpec;
   state?: V1ReportState;
@@ -1353,6 +1349,10 @@ export interface V1MetricsViewSort {
   ascending?: boolean;
 }
 
+export interface V1MetricsViewSearchResponse {
+  results?: MetricsViewSearchResponseSearchResult[];
+}
+
 export interface V1MetricsViewSchemaResponse {
   schema?: V1StructType;
 }
@@ -1833,6 +1833,11 @@ export const V1ExploreWebView = {
   EXPLORE_WEB_VIEW_CANVAS: "EXPLORE_WEB_VIEW_CANVAS",
 } as const;
 
+export interface V1ExploreTimeRange {
+  range?: string;
+  comparisonTimeRanges?: V1ExploreComparisonTimeRange[];
+}
+
 export interface V1ExploreSpec {
   displayName?: string;
   description?: string;
@@ -1885,11 +1890,6 @@ If not specified, it should fallback to the range of the base time range. */
   range?: string;
 }
 
-export interface V1ExploreTimeRange {
-  range?: string;
-  comparisonTimeRanges?: V1ExploreComparisonTimeRange[];
-}
-
 export type V1ExploreComparisonMode =
   (typeof V1ExploreComparisonMode)[keyof typeof V1ExploreComparisonMode];
 
@@ -2081,13 +2081,9 @@ export interface V1ComponentVariable {
 
 export type V1ComponentSpecRendererProperties = { [key: string]: any };
 
-export type V1ComponentSpecResolverProperties = { [key: string]: any };
-
 export interface V1ComponentSpec {
   displayName?: string;
   description?: string;
-  resolver?: string;
-  resolverProperties?: V1ComponentSpecResolverProperties;
   renderer?: string;
   rendererProperties?: V1ComponentSpecRendererProperties;
   input?: V1ComponentVariable[];
@@ -2283,8 +2279,9 @@ export interface V1CanvasItem {
 
 export interface V1CanvasSpec {
   displayName?: string;
-  columns?: number;
-  gap?: number;
+  maxWidth?: number;
+  theme?: string;
+  embeddedTheme?: V1ThemeSpec;
   variables?: V1ComponentVariable[];
   items?: V1CanvasItem[];
   securityRules?: V1SecurityRule[];
@@ -2675,10 +2672,6 @@ export interface MetricsViewSearchResponseSearchResult {
   value?: unknown;
 }
 
-export interface V1MetricsViewSearchResponse {
-  results?: MetricsViewSearchResponseSearchResult[];
-}
-
 export interface MetricsViewFilterCond {
   name?: string;
   in?: unknown[];
diff --git a/web-local/src/routes/(application)/(workspace)/files/[...file]/+page.svelte b/web-local/src/routes/(application)/(workspace)/files/[...file]/+page.svelte
index d92d414af35..68c6835234c 100644
--- a/web-local/src/routes/(application)/(workspace)/files/[...file]/+page.svelte
+++ b/web-local/src/routes/(application)/(workspace)/files/[...file]/+page.svelte
@@ -7,8 +7,8 @@
   import { getExtensionsForFile } from "@rilldata/web-common/features/editor/getExtensionsForFile";
   import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
   import { directoryState } from "@rilldata/web-common/features/file-explorer/directory-store";
-  import CanvasDashboardWorkspace from "@rilldata/web-common/features/workspaces/CanvasDashboardWorkspace.svelte";
-  import ComponentWorkspace from "@rilldata/web-common/features/workspaces/ComponentWorkspace.svelte";
+  import { mapParseErrorsToLines } from "@rilldata/web-common/features/metrics-views/errors";
+  import CanvasWorkspace from "@rilldata/web-common/features/workspaces/CanvasWorkspace.svelte";
   import ExploreWorkspace from "@rilldata/web-common/features/workspaces/ExploreWorkspace.svelte";
   import MetricsWorkspace from "@rilldata/web-common/features/workspaces/MetricsWorkspace.svelte";
   import ModelWorkspace from "@rilldata/web-common/features/workspaces/ModelWorkspace.svelte";
@@ -16,18 +16,16 @@
   import WorkspaceContainer from "@rilldata/web-common/layout/workspace/WorkspaceContainer.svelte";
   import WorkspaceEditorContainer from "@rilldata/web-common/layout/workspace/WorkspaceEditorContainer.svelte";
   import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient.js";
-  import { onMount } from "svelte";
   import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
+  import { onMount } from "svelte";
   import type { PageData } from "./$types";
-  import { mapParseErrorsToLines } from "@rilldata/web-common/features/metrics-views/errors";
 
   const workspaces = new Map([
     [ResourceKind.Source, SourceWorkspace],
     [ResourceKind.Model, ModelWorkspace],
     [ResourceKind.MetricsView, MetricsWorkspace],
     [ResourceKind.Explore, ExploreWorkspace],
-    [ResourceKind.Component, ComponentWorkspace],
-    [ResourceKind.Canvas, CanvasDashboardWorkspace],
+    [ResourceKind.Canvas, CanvasWorkspace],
     [null, null],
     [undefined, null],
   ]);
diff --git a/web-local/src/routes/(viz)/canvas/[name]/+page.svelte b/web-local/src/routes/(viz)/canvas/[name]/+page.svelte
new file mode 100644
index 00000000000..c02204b58ce
--- /dev/null
+++ b/web-local/src/routes/(viz)/canvas/[name]/+page.svelte
@@ -0,0 +1,22 @@
+<script lang="ts">
+  import CanvasDashboardEmbed from "@rilldata/web-common/features/canvas/CanvasDashboardEmbed.svelte";
+  import CanvasThemeProvider from "@rilldata/web-common/features/canvas/CanvasThemeProvider.svelte";
+  import StateManagersProvider from "@rilldata/web-common/features/canvas/state-managers/StateManagersProvider.svelte";
+  import type { PageData } from "./$types";
+
+  export let data: PageData;
+
+  let columns = 20;
+  let gap = 1;
+  $: canvasName = data.dashboardName;
+</script>
+
+<StateManagersProvider {canvasName}>
+  <CanvasThemeProvider>
+    <CanvasDashboardEmbed
+      items={data.dashboard.spec?.items || []}
+      {columns}
+      {gap}
+    />
+  </CanvasThemeProvider>
+</StateManagersProvider>
diff --git a/web-local/src/routes/(viz)/custom/[name]/+page.ts b/web-local/src/routes/(viz)/canvas/[name]/+page.ts
similarity index 96%
rename from web-local/src/routes/(viz)/custom/[name]/+page.ts
rename to web-local/src/routes/(viz)/canvas/[name]/+page.ts
index 58fc4407176..d88b2f7fa98 100644
--- a/web-local/src/routes/(viz)/custom/[name]/+page.ts
+++ b/web-local/src/routes/(viz)/canvas/[name]/+page.ts
@@ -44,9 +44,7 @@ export const load = async ({ params, depends }) => {
 
     return {
       dashboardName,
-      dashboard: {
-        ...dashboard.spec,
-      },
+      dashboard,
     };
   } catch (e) {
     console.error(e);
diff --git a/web-local/src/routes/(viz)/custom/[name]/+page.svelte b/web-local/src/routes/(viz)/custom/[name]/+page.svelte
deleted file mode 100644
index 4a4e85f1f6d..00000000000
--- a/web-local/src/routes/(viz)/custom/[name]/+page.svelte
+++ /dev/null
@@ -1,16 +0,0 @@
-<script lang="ts">
-  import CanvasDashboardEmbed from "@rilldata/web-common/features/canvas/CanvasDashboardEmbed.svelte";
-  import type { PageData } from "./$types";
-
-  export let data: PageData;
-
-  $: ({ items = [], columns, gap, variables } = data.dashboard);
-</script>
-
-<CanvasDashboardEmbed
-  canvasName={data.dashboardName}
-  {items}
-  {columns}
-  {gap}
-  {variables}
-/>