diff --git a/assets/package-lock.json b/assets/package-lock.json
index 21e98c1a8cf49f45558462f96bba1e9b25fdff5e..6eb3c5f2219234c71b7105b7d9acd23273e25c73 100644
--- a/assets/package-lock.json
+++ b/assets/package-lock.json
@@ -28,8 +28,10 @@
         "luxon": "2.4.0",
         "raf-throttle": "2.0.5",
         "redux": "4.2.0",
+        "redux-connect-vue": "3.0.0-rc.4",
         "redux-thunk": "2.4.1",
         "reselect": "4.1.5",
+        "vue": "3.2.36",
         "wdfn-viz": "3.2.0"
       },
       "devDependencies": {
@@ -39,6 +41,7 @@
         "@rollup/plugin-json": "4.1.0",
         "@rollup/plugin-node-resolve": "13.3.0",
         "@rollup/plugin-replace": "4.0.0",
+        "@vitejs/plugin-vue": "2.3.3",
         "autoprefixer": "10.4.7",
         "buble": "0.20.0",
         "buble-jest": "1.0.1",
@@ -64,7 +67,8 @@
         "stylelint": "14.8.5",
         "stylelint-config-recommended-scss": "6.0.0",
         "stylelint-scss": "4.2.0",
-        "terser": "5.13.1"
+        "terser": "5.13.1",
+        "vite": "2.9.9"
       },
       "engines": {
         "node": "16.15.0"
@@ -433,10 +437,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.15.8",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz",
-      "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==",
-      "dev": true,
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.3.tgz",
+      "integrity": "sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==",
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -2304,6 +2307,137 @@
         "node": ">= 4"
       }
     },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.3.tgz",
+      "integrity": "sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^2.5.10",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.36.tgz",
+      "integrity": "sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-core/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.36.tgz",
+      "integrity": "sha512-tcOTAOiW4s24QLnq+ON6J+GRONXJ+A/mqKCORi0LSlIh8XQlNnlm24y8xIL8la+ZDgkdbjarQ9ZqYSvEja6gVA==",
+      "dependencies": {
+        "@vue/compiler-core": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.36.tgz",
+      "integrity": "sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.36",
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/compiler-ssr": "3.2.36",
+        "@vue/reactivity-transform": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7",
+        "postcss": "^8.1.10",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-sfc/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.36.tgz",
+      "integrity": "sha512-+KugInUFRvOxEdLkZwE+W43BqHyhBh0jpYXhmqw1xGq2dmE6J9eZ8UUSOKNhdHtQ/iNLWWeK/wPZkVLUf3YGaw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.36.tgz",
+      "integrity": "sha512-c2qvopo0crh9A4GXi2/2kfGYMxsJW4tVILrqRPydVGZHhq0fnzy6qmclWOhBFckEhmyxmpHpdJtIRYGeKcuhnA==",
+      "dependencies": {
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "node_modules/@vue/reactivity-transform": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.36.tgz",
+      "integrity": "sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.36.tgz",
+      "integrity": "sha512-PTWBD+Lub+1U3/KhbCExrfxyS14hstLX+cBboxVHaz+kXoiDLNDEYAovPtxeTutbqtClIXtft+wcGdC+FUQ9qQ==",
+      "dependencies": {
+        "@vue/reactivity": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.36.tgz",
+      "integrity": "sha512-gYPYblm7QXHVuBohqNRRT7Wez0f2Mx2D40rb4fleehrJU9CnkjG0phhcGEZFfGwCmHZRqBCRgbFWE98bPULqkg==",
+      "dependencies": {
+        "@vue/runtime-core": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "csstype": "^2.6.8"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.36.tgz",
+      "integrity": "sha512-uZE0+jfye6yYXWvAQYeHZv+f50sRryvy16uiqzk3jn8hEY8zTjI+rzlmZSGoE915k+W/Ol9XSw6vxOUD8dGkUg==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.2.36",
+        "@vue/shared": "3.2.36"
+      },
+      "peerDependencies": {
+        "vue": "3.2.36"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.36.tgz",
+      "integrity": "sha512-JtB41wXl7Au3+Nl3gD16Cfpj7k/6aCroZ6BbOiCMFCMvrOpkg/qQUXTso2XowaNqBbnkuGHurLAqkLBxNGc1hQ=="
+    },
     "node_modules/abab": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
@@ -4519,6 +4653,11 @@
       "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
       "dev": true
     },
+    "node_modules/csstype": {
+      "version": "2.6.20",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
+      "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
+    },
     "node_modules/d": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
@@ -5298,6 +5437,361 @@
         "es6-symbol": "^3.1.1"
       }
     },
+    "node_modules/esbuild": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
+      "integrity": "sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "esbuild-android-64": "0.14.39",
+        "esbuild-android-arm64": "0.14.39",
+        "esbuild-darwin-64": "0.14.39",
+        "esbuild-darwin-arm64": "0.14.39",
+        "esbuild-freebsd-64": "0.14.39",
+        "esbuild-freebsd-arm64": "0.14.39",
+        "esbuild-linux-32": "0.14.39",
+        "esbuild-linux-64": "0.14.39",
+        "esbuild-linux-arm": "0.14.39",
+        "esbuild-linux-arm64": "0.14.39",
+        "esbuild-linux-mips64le": "0.14.39",
+        "esbuild-linux-ppc64le": "0.14.39",
+        "esbuild-linux-riscv64": "0.14.39",
+        "esbuild-linux-s390x": "0.14.39",
+        "esbuild-netbsd-64": "0.14.39",
+        "esbuild-openbsd-64": "0.14.39",
+        "esbuild-sunos-64": "0.14.39",
+        "esbuild-windows-32": "0.14.39",
+        "esbuild-windows-64": "0.14.39",
+        "esbuild-windows-arm64": "0.14.39"
+      }
+    },
+    "node_modules/esbuild-android-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.39.tgz",
+      "integrity": "sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-android-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.39.tgz",
+      "integrity": "sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz",
+      "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.39.tgz",
+      "integrity": "sha512-/fcQ5UhE05OiT+bW5v7/up1bDsnvaRZPJxXwzXsMRrr7rZqPa85vayrD723oWMT64dhrgWeA3FIneF8yER0XTw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.39.tgz",
+      "integrity": "sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.39.tgz",
+      "integrity": "sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-32": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.39.tgz",
+      "integrity": "sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.39.tgz",
+      "integrity": "sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.39.tgz",
+      "integrity": "sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.39.tgz",
+      "integrity": "sha512-23pc8MlD2D6Px1mV8GMglZlKgwgNKAO8gsgsLLcXWSs9lQsCYkIlMo/2Ycfo5JrDIbLdwgP8D2vpfH2KcBqrDQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-mips64le": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.39.tgz",
+      "integrity": "sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-ppc64le": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.39.tgz",
+      "integrity": "sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-riscv64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.39.tgz",
+      "integrity": "sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-s390x": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.39.tgz",
+      "integrity": "sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-netbsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.39.tgz",
+      "integrity": "sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-openbsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.39.tgz",
+      "integrity": "sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-sunos-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.39.tgz",
+      "integrity": "sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-32": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.39.tgz",
+      "integrity": "sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.39.tgz",
+      "integrity": "sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.39.tgz",
+      "integrity": "sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -5854,8 +6348,7 @@
     "node_modules/estree-walker": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
-      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
-      "dev": true
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
     },
     "node_modules/esutils": {
       "version": "2.0.2",
@@ -8290,9 +8783,9 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
-      "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
       "dependencies": {
         "has": "^1.0.3"
       },
@@ -11585,7 +12078,6 @@
       "version": "0.25.7",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
       "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
-      "dev": true,
       "dependencies": {
         "sourcemap-codec": "^1.4.4"
       }
@@ -12132,7 +12624,6 @@
       "version": "3.3.4",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
       "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
-      "dev": true,
       "bin": {
         "nanoid": "bin/nanoid.cjs"
       },
@@ -12951,9 +13442,9 @@
       }
     },
     "node_modules/path-parse": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
     },
     "node_modules/path-root": {
       "version": "0.1.1",
@@ -13008,8 +13499,7 @@
     "node_modules/picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-      "dev": true
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
     },
     "node_modules/picomatch": {
       "version": "2.3.1",
@@ -13136,7 +13626,6 @@
       "version": "8.4.14",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
       "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
-      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -13851,6 +14340,15 @@
         "@babel/runtime": "^7.9.2"
       }
     },
+    "node_modules/redux-connect-vue": {
+      "version": "3.0.0-rc.4",
+      "resolved": "https://registry.npmjs.org/redux-connect-vue/-/redux-connect-vue-3.0.0-rc.4.tgz",
+      "integrity": "sha512-3uspuyx4Z5rI86O6g1iMRYrRdL+vD6GAWGkPjxVG4xYWu909JL7l/0caGAE0cYoEMSjGw9/Lk2lzgV9AkkR6Bg==",
+      "peerDependencies": {
+        "redux": "4.x",
+        "vue": "3.x"
+      }
+    },
     "node_modules/redux-thunk": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
@@ -14090,12 +14588,16 @@
       "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
     },
     "node_modules/resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
+      "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
       "dependencies": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.8.1",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -14723,7 +15225,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -14758,8 +15259,7 @@
     "node_modules/sourcemap-codec": {
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz",
-      "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==",
-      "dev": true
+      "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg=="
     },
     "node_modules/sparkles": {
       "version": "1.0.1",
@@ -15353,6 +15853,17 @@
         "node": ">=8"
       }
     },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/sver-compat": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
@@ -16355,6 +16866,69 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/vite": {
+      "version": "2.9.9",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz",
+      "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.14.27",
+        "postcss": "^8.4.13",
+        "resolve": "^1.22.0",
+        "rollup": "^2.59.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": ">=12.2.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "less": "*",
+        "sass": "*",
+        "stylus": "*"
+      },
+      "peerDependenciesMeta": {
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vite/node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/vue": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.36.tgz",
+      "integrity": "sha512-5yTXmrE6gW8IQgttzHW5bfBiFA6mx35ZXHjGLDmKYzW6MMmYvCwuKybANRepwkMYeXw2v1buGg3/lPICY5YlZw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/compiler-sfc": "3.2.36",
+        "@vue/runtime-dom": "3.2.36",
+        "@vue/server-renderer": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
     "node_modules/w3c-hr-time": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
@@ -16966,10 +17540,9 @@
       }
     },
     "@babel/parser": {
-      "version": "7.15.8",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz",
-      "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==",
-      "dev": true
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.3.tgz",
+      "integrity": "sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ=="
     },
     "@babel/plugin-syntax-async-generators": {
       "version": "7.8.4",
@@ -18411,6 +18984,126 @@
         "resolve-id-refs": "0.1.0"
       }
     },
+    "@vitejs/plugin-vue": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.3.tgz",
+      "integrity": "sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==",
+      "dev": true,
+      "requires": {}
+    },
+    "@vue/compiler-core": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.36.tgz",
+      "integrity": "sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.36.tgz",
+      "integrity": "sha512-tcOTAOiW4s24QLnq+ON6J+GRONXJ+A/mqKCORi0LSlIh8XQlNnlm24y8xIL8la+ZDgkdbjarQ9ZqYSvEja6gVA==",
+      "requires": {
+        "@vue/compiler-core": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.36.tgz",
+      "integrity": "sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.36",
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/compiler-ssr": "3.2.36",
+        "@vue/reactivity-transform": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7",
+        "postcss": "^8.1.10",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.36.tgz",
+      "integrity": "sha512-+KugInUFRvOxEdLkZwE+W43BqHyhBh0jpYXhmqw1xGq2dmE6J9eZ8UUSOKNhdHtQ/iNLWWeK/wPZkVLUf3YGaw==",
+      "requires": {
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "@vue/reactivity": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.36.tgz",
+      "integrity": "sha512-c2qvopo0crh9A4GXi2/2kfGYMxsJW4tVILrqRPydVGZHhq0fnzy6qmclWOhBFckEhmyxmpHpdJtIRYGeKcuhnA==",
+      "requires": {
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "@vue/reactivity-transform": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.36.tgz",
+      "integrity": "sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.36.tgz",
+      "integrity": "sha512-PTWBD+Lub+1U3/KhbCExrfxyS14hstLX+cBboxVHaz+kXoiDLNDEYAovPtxeTutbqtClIXtft+wcGdC+FUQ9qQ==",
+      "requires": {
+        "@vue/reactivity": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.36.tgz",
+      "integrity": "sha512-gYPYblm7QXHVuBohqNRRT7Wez0f2Mx2D40rb4fleehrJU9CnkjG0phhcGEZFfGwCmHZRqBCRgbFWE98bPULqkg==",
+      "requires": {
+        "@vue/runtime-core": "3.2.36",
+        "@vue/shared": "3.2.36",
+        "csstype": "^2.6.8"
+      }
+    },
+    "@vue/server-renderer": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.36.tgz",
+      "integrity": "sha512-uZE0+jfye6yYXWvAQYeHZv+f50sRryvy16uiqzk3jn8hEY8zTjI+rzlmZSGoE915k+W/Ol9XSw6vxOUD8dGkUg==",
+      "requires": {
+        "@vue/compiler-ssr": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.36.tgz",
+      "integrity": "sha512-JtB41wXl7Au3+Nl3gD16Cfpj7k/6aCroZ6BbOiCMFCMvrOpkg/qQUXTso2XowaNqBbnkuGHurLAqkLBxNGc1hQ=="
+    },
     "abab": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
@@ -20161,6 +20854,11 @@
         }
       }
     },
+    "csstype": {
+      "version": "2.6.20",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
+      "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
+    },
     "d": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
@@ -20807,6 +21505,174 @@
         "es6-symbol": "^3.1.1"
       }
     },
+    "esbuild": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
+      "integrity": "sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==",
+      "dev": true,
+      "requires": {
+        "esbuild-android-64": "0.14.39",
+        "esbuild-android-arm64": "0.14.39",
+        "esbuild-darwin-64": "0.14.39",
+        "esbuild-darwin-arm64": "0.14.39",
+        "esbuild-freebsd-64": "0.14.39",
+        "esbuild-freebsd-arm64": "0.14.39",
+        "esbuild-linux-32": "0.14.39",
+        "esbuild-linux-64": "0.14.39",
+        "esbuild-linux-arm": "0.14.39",
+        "esbuild-linux-arm64": "0.14.39",
+        "esbuild-linux-mips64le": "0.14.39",
+        "esbuild-linux-ppc64le": "0.14.39",
+        "esbuild-linux-riscv64": "0.14.39",
+        "esbuild-linux-s390x": "0.14.39",
+        "esbuild-netbsd-64": "0.14.39",
+        "esbuild-openbsd-64": "0.14.39",
+        "esbuild-sunos-64": "0.14.39",
+        "esbuild-windows-32": "0.14.39",
+        "esbuild-windows-64": "0.14.39",
+        "esbuild-windows-arm64": "0.14.39"
+      }
+    },
+    "esbuild-android-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.39.tgz",
+      "integrity": "sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-android-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.39.tgz",
+      "integrity": "sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-darwin-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz",
+      "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-darwin-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.39.tgz",
+      "integrity": "sha512-/fcQ5UhE05OiT+bW5v7/up1bDsnvaRZPJxXwzXsMRrr7rZqPa85vayrD723oWMT64dhrgWeA3FIneF8yER0XTw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-freebsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.39.tgz",
+      "integrity": "sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-freebsd-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.39.tgz",
+      "integrity": "sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-32": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.39.tgz",
+      "integrity": "sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.39.tgz",
+      "integrity": "sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-arm": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.39.tgz",
+      "integrity": "sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.39.tgz",
+      "integrity": "sha512-23pc8MlD2D6Px1mV8GMglZlKgwgNKAO8gsgsLLcXWSs9lQsCYkIlMo/2Ycfo5JrDIbLdwgP8D2vpfH2KcBqrDQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-mips64le": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.39.tgz",
+      "integrity": "sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-ppc64le": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.39.tgz",
+      "integrity": "sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-riscv64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.39.tgz",
+      "integrity": "sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-s390x": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.39.tgz",
+      "integrity": "sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-netbsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.39.tgz",
+      "integrity": "sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-openbsd-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.39.tgz",
+      "integrity": "sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-sunos-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.39.tgz",
+      "integrity": "sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-32": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.39.tgz",
+      "integrity": "sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.39.tgz",
+      "integrity": "sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-arm64": {
+      "version": "0.14.39",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.39.tgz",
+      "integrity": "sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==",
+      "dev": true,
+      "optional": true
+    },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -21199,8 +22065,7 @@
     "estree-walker": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
-      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
-      "dev": true
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
     },
     "esutils": {
       "version": "2.0.2",
@@ -23112,9 +23977,9 @@
       "dev": true
     },
     "is-core-module": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
-      "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
       "requires": {
         "has": "^1.0.3"
       }
@@ -25601,7 +26466,6 @@
       "version": "0.25.7",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
       "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
-      "dev": true,
       "requires": {
         "sourcemap-codec": "^1.4.4"
       }
@@ -26023,8 +26887,7 @@
     "nanoid": {
       "version": "3.3.4",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
-      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
-      "dev": true
+      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
     },
     "nanomatch": {
       "version": "1.2.13",
@@ -26656,9 +27519,9 @@
       "dev": true
     },
     "path-parse": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
     },
     "path-root": {
       "version": "0.1.1",
@@ -26706,8 +27569,7 @@
     "picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-      "dev": true
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
     },
     "picomatch": {
       "version": "2.3.1",
@@ -26797,7 +27659,6 @@
       "version": "8.4.14",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
       "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
-      "dev": true,
       "requires": {
         "nanoid": "^3.3.4",
         "picocolors": "^1.0.0",
@@ -27319,6 +28180,12 @@
         "@babel/runtime": "^7.9.2"
       }
     },
+    "redux-connect-vue": {
+      "version": "3.0.0-rc.4",
+      "resolved": "https://registry.npmjs.org/redux-connect-vue/-/redux-connect-vue-3.0.0-rc.4.tgz",
+      "integrity": "sha512-3uspuyx4Z5rI86O6g1iMRYrRdL+vD6GAWGkPjxVG4xYWu909JL7l/0caGAE0cYoEMSjGw9/Lk2lzgV9AkkR6Bg==",
+      "requires": {}
+    },
     "redux-thunk": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
@@ -27504,12 +28371,13 @@
       "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
     },
     "resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
+      "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
       "requires": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.8.1",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
       }
     },
     "resolve-cwd": {
@@ -28009,8 +28877,7 @@
     "source-map-js": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "dev": true
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
     },
     "source-map-resolve": {
       "version": "0.5.2",
@@ -28042,8 +28909,7 @@
     "sourcemap-codec": {
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz",
-      "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==",
-      "dev": true
+      "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg=="
     },
     "sparkles": {
       "version": "1.0.1",
@@ -28514,6 +29380,11 @@
         }
       }
     },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+    },
     "sver-compat": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
@@ -29310,6 +30181,40 @@
         "vinyl": "^2.0.0"
       }
     },
+    "vite": {
+      "version": "2.9.9",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz",
+      "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==",
+      "dev": true,
+      "requires": {
+        "esbuild": "^0.14.27",
+        "fsevents": "~2.3.2",
+        "postcss": "^8.4.13",
+        "resolve": "^1.22.0",
+        "rollup": "^2.59.0"
+      },
+      "dependencies": {
+        "fsevents": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+          "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "vue": {
+      "version": "3.2.36",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.36.tgz",
+      "integrity": "sha512-5yTXmrE6gW8IQgttzHW5bfBiFA6mx35ZXHjGLDmKYzW6MMmYvCwuKybANRepwkMYeXw2v1buGg3/lPICY5YlZw==",
+      "requires": {
+        "@vue/compiler-dom": "3.2.36",
+        "@vue/compiler-sfc": "3.2.36",
+        "@vue/runtime-dom": "3.2.36",
+        "@vue/server-renderer": "3.2.36",
+        "@vue/shared": "3.2.36"
+      }
+    },
     "w3c-hr-time": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
diff --git a/assets/package.json b/assets/package.json
index a6c68e70bce7b36498e140bf2001b1f10454a026..c0d2eddee1a91332e974091f2bac2e51779048ef 100644
--- a/assets/package.json
+++ b/assets/package.json
@@ -29,7 +29,8 @@
     "watch:css": "nodemon -w src/styles -e scss -x \"npm run build:css\"",
     "watch:fonts": "nodemon -w node_modules/uswds/src/fonts -x \"npm run build:fonts\"",
     "watch:images": "nodemon -w src/img -x \"npm run build:images\"",
-    "watch:js": "mkdir -p dist/scripts && npm run build:wdfnviz && npm run build:uswdsjs && rollup -c --watch"
+    "watch:js": "mkdir -p dist/scripts && npm run build:wdfnviz && npm run build:uswdsjs && rollup -c --watch",
+    "buildvite": "vite build --mode development"
   },
   "engines": {
     "node": "16.15.0"
@@ -51,6 +52,7 @@
     "@rollup/plugin-json": "4.1.0",
     "@rollup/plugin-node-resolve": "13.3.0",
     "@rollup/plugin-replace": "4.0.0",
+    "@vitejs/plugin-vue": "2.3.3",
     "autoprefixer": "10.4.7",
     "buble": "0.20.0",
     "buble-jest": "1.0.1",
@@ -76,7 +78,8 @@
     "stylelint": "14.8.5",
     "stylelint-config-recommended-scss": "6.0.0",
     "stylelint-scss": "4.2.0",
-    "terser": "5.13.1"
+    "terser": "5.13.1",
+    "vite": "2.9.9"
   },
   "dependencies": {
     "autotrack": "2.4.1",
@@ -98,8 +101,10 @@
     "luxon": "2.4.0",
     "raf-throttle": "2.0.5",
     "redux": "4.2.0",
+    "redux-connect-vue": "3.0.0-rc.4",
     "redux-thunk": "2.4.1",
     "reselect": "4.1.5",
+    "vue": "3.2.36",
     "wdfn-viz": "3.2.0"
   }
 }
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/GraphControlsApp.vue b/assets/src/scripts/monitoring-location/components/hydrograph/GraphControlsApp.vue
new file mode 100644
index 0000000000000000000000000000000000000000..82e69819fb1ea0acdea895e6f74eb5d455618d8f
--- /dev/null
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/GraphControlsApp.vue
@@ -0,0 +1,19 @@
+<template>
+  <div>My Test GraphControls</div>
+  <GraphControls/>
+</template>
+
+<script>
+import GraphControls from './components/graph-controls.vue';
+
+export default {
+  name: "GraphControlsApp",
+  components: {
+    GraphControls
+  }
+}
+</script>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/components/graph-controls.vue b/assets/src/scripts/monitoring-location/components/hydrograph/components/graph-controls.vue
new file mode 100644
index 0000000000000000000000000000000000000000..a8dd2076b3823682d6072d51886dc3017727ce19
--- /dev/null
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/components/graph-controls.vue
@@ -0,0 +1,91 @@
+<template>
+  <div class="usa-checkbox">
+    <input
+      class="usa-checkbox__input"
+      id="vue-compare-timeseries"
+      type="checkbox"
+      name="graphControls"
+      value="compare"
+      :checked="compareChecked"
+      @change="selectCompare"
+    />
+    <label
+      class="usa-checkbox__label"
+      for="vue-compare-timeseries"
+    >
+      Vue compare
+    </label>
+  </div>
+  <div class="usa-checkbox">
+    <input
+      class="usa-checkbox__input"
+      id="vue-median-timeseries"
+      type="checkbox"
+      name="graphControls"
+      value="median"
+    />
+    <label
+      class="usa-checkbox__label"
+      for="vue-median-timeseries"
+    >
+      Vue median
+    </label>
+  </div>
+</template>
+
+<script>
+import {useActions, useState} from 'redux-connect-vue';
+import {createStructuredSelector, createSelector} from 'reselect';
+import {inject} from 'vue';
+
+import {getSelectedParameterCode, getSelectedTimeSpan} from 'ml/selectors/hydrograph-state-selector';
+import {getTimeRange} from 'ml/selectors/hydrograph-data-selector';
+import {retrieveMedianStatistics, retrievePriorYearIVData} from 'ml/store/hydrograph-data';
+import {setCompareDataVisibility} from 'ml/store/hydrograph-state';
+
+import {isVisible} from '../selectors/time-series-data';
+import {showDataIndicators} from '../data-indicator';
+
+export default {
+  name: "GraphControls",
+  setup() {
+    const state =  useState({
+      compareChecked: isVisible('compare')
+    });
+
+    const actions = useActions({
+      setCompareDataVisibility,
+      retrievePriorYearIVData
+    });
+
+    const reduxStore = inject('store')
+    const siteno = inject('siteno')
+
+    function selectCompare(ev) {
+      const reduxState = reduxStore.getState();
+      const currentTimeRange = getTimeRange('current')(reduxState);
+      actions.setCompareDataVisibility(ev.target.checked);
+      if (ev.target.checked) {
+        showDataIndicators(true, reduxStore);
+        actions.retrievePriorYearIVData(siteno, {
+            parameterCode: getSelectedParameterCode(reduxState),
+            startTime: currentTimeRange.start,
+            endTime: currentTimeRange.end
+        }).then(() => {
+          showDataIndicators(false, reduxStore);
+        });
+      } else {
+        showDataIndicators(false, reduxStore);
+      }
+    }
+    return {
+      ...state,
+      selectCompare
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.js
index 7711362f102afbcf084a1f49082b5cbce96d7302..3280cea89465ba427e2c81d4b1b23e5b6bc447e3 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/index.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.js
@@ -2,6 +2,10 @@
  * Hydrograph charting module.
  */
 import {select} from 'd3-selection';
+import {bindActionCreators} from 'redux';
+import ReduxConnectVue from 'redux-connect-vue';
+import {createStructuredSelector} from 'reselect';
+import {createApp} from 'vue';
 
 import config from 'ui/config.js';
 
@@ -33,6 +37,8 @@ import {drawTimeSpanShortcutButtons} from './time-span-shortcuts';
 import {initializeTimeSeriesGraph, drawTimeSeriesGraphData} from './time-series-graph';
 import {initializeTooltipCursorSlider, drawTooltipCursorSlider} from './tooltip';
 
+import GraphControlsApp from './GraphControlsApp.vue';
+
 /*
  * Renders the hydrograph on the node element using the Redux store for state information. The siteno, latitude, and
  * longitude are required parameters. All others are optional and are used to set the initial state of the hydrograph.
@@ -112,6 +118,15 @@ export const attachToNode = function(store,
     if (!showOnlyGraph) {
         nodeElem.select('.short-cut-time-span-container').call(drawTimeSpanShortcutButtons, store, siteno, agencyCd);
         select(node).select('.select-actions-container').call(drawSelectActions, store, siteno, agencyCd);
+        const app = createApp(GraphControlsApp, {});
+        app.use(ReduxConnectVue, {
+            store,
+            mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
+            mapStateToPropsFactory: createStructuredSelector
+        });
+        app.provide('store', store);
+        app.provide('siteno', siteno);
+        app.mount('#vue-graph-controls');
     }
 
     const graphContainer = nodeElem.select('.graph-container');
diff --git a/assets/src/scripts/monitoring-location/index.js b/assets/src/scripts/monitoring-location/index.js
index 55fc86ded32fff6ce22c27a9dd5bbd917254a696..9cf515554249b6db77d3732cb1bde366eab9aecd 100644
--- a/assets/src/scripts/monitoring-location/index.js
+++ b/assets/src/scripts/monitoring-location/index.js
@@ -1,4 +1,5 @@
 import wdfnviz from 'wdfn-viz';
+import 'vite/modulepreload-polyfill';
 
 import {getParamString} from 'ml/url-params';
 
diff --git a/assets/vite.config.js b/assets/vite.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..13dbd8d746fe94a67a4d3d4b92f8cb727f7e86c6
--- /dev/null
+++ b/assets/vite.config.js
@@ -0,0 +1,66 @@
+const path = require('path');
+
+const alias = require('@rollup/plugin-alias');
+const replace = require('@rollup/plugin-replace');
+const resolve = require('@rollup/plugin-node-resolve');
+const vue = require('@vitejs/plugin-vue');
+const {defineConfig} = require('vite');
+
+const entries = [
+    {find: 'uswds-components', replacement: path.resolve(__dirname, 'node_modules/@uswds/uswds/packages')},
+    {find: 'ui', replacement: path.resolve(__dirname, 'src/scripts/')},
+    {find: 'ml', replacement: path.resolve(__dirname, 'src/scripts/monitoring-location')},
+    {find: 'd3render', replacement: path.resolve(__dirname, 'src/scripts/d3-rendering')},
+    {find: 'map', replacement: path.resolve(__dirname, 'src/scripts/monitoring-location/components/map')},
+    {
+        find: 'dvhydrograph',
+        replacement: path.resolve(__dirname, 'src/scripts/monitoring-location/components/daily-value-hydrograph')
+    },
+    {
+        find: 'ivhydrograph',
+        replacement: path.resolve(__dirname, 'src/scripts/monitoring-location/components/hydrograph')
+    },
+    {find: 'network', replacement: path.resolve(__dirname, 'src/scripts/network')}
+];
+
+export default defineConfig(({command, mode}) => {
+    return {
+        base: '/static/',
+        plugins: [
+            vue({
+                isProduction: true,
+                template: {
+                    compilerOptions: {}
+                }
+            })
+        ],
+        build: {
+            outDir: 'dist',
+            assetsDir: '',
+            manifest: 'manifest.json',
+            emptyOutDir: false,
+            sourcemap: mode === 'development',
+            rollupOptions: {
+                input: {
+                    monitoringLocation: 'src/scripts/monitoring-location/index.js',
+                },
+                plugins: [
+                    alias({
+                        entries: entries,
+                        customResolver: resolve.nodeResolve({
+                            extensions: ['.js', '.json']
+                        })
+                    }),
+                    replace({
+                        preventAssignment: true,
+                        'process.env.NODE_ENV': JSON.stringify(mode)
+                    })
+                ],
+                output: {
+                    dir: 'dist',
+                    entryFileNames: '[name].js'
+                }
+            }
+        }
+    };
+});
\ No newline at end of file
diff --git a/wdfn-server/waterdata/templates/macros/components.html b/wdfn-server/waterdata/templates/macros/components.html
index 13798128f79a6fa18faae5934fa2c220081a8118..89d060367e23fd31a2f799a174e82ccd95ea6d34 100644
--- a/wdfn-server/waterdata/templates/macros/components.html
+++ b/wdfn-server/waterdata/templates/macros/components.html
@@ -8,6 +8,7 @@
             {% endif %}
             <div class="select-actions-container"></div>
         </div>
+        <div id="vue-graph-controls"></div>
         <div id="hydrograph-wrapper">
             <div class="graph-container"></div>
             <div id="hydrograph-loading-indicator-container" class="loading-indicator-container"></div>
diff --git a/wdfn-server/waterdata/templates/monitoring_location.html b/wdfn-server/waterdata/templates/monitoring_location.html
index 618a479cd3a6a5e189e5fd1b6c3ad4fc5faf661e..59cdf0405d0859965911a5c537dfd7e3f37279a7 100644
--- a/wdfn-server/waterdata/templates/monitoring_location.html
+++ b/wdfn-server/waterdata/templates/monitoring_location.html
@@ -378,6 +378,6 @@
             });
         </script>
     {% else %}
-        <script src="{{ 'monitoring_location.js' | asset_url }}"></script>
+        <script type="module" crossorigin="" src="{{ 'monitoringLocation.js' | asset_url }}"></script>
     {% endif %}
 {% endblock %}