]> git.r.bdr.sh - rbdr/forum/commitdiff
Use routify and GraphQL server
authorRuben Beltran del Rio <redacted>
Sat, 13 Mar 2021 14:28:29 +0000 (15:28 +0100)
committerRuben Beltran del Rio <redacted>
Sat, 13 Mar 2021 14:28:29 +0000 (15:28 +0100)
34 files changed:
.eslintrc
.gitignore
index.html [moved from src/app.html with 90% similarity]
package-lock.json
package.json
src/components/forum/forum.svelte [new file with mode: 0644]
src/components/forum_list/forum_list.svelte
src/components/glyph/glyph.svelte
src/components/topic_index/topic_index.svelte [deleted file]
src/components/topic_summary/topic_summary.svelte [new file with mode: 0644]
src/config/apollo.js [new file with mode: 0644]
src/config/config.js
src/config/env.dist
src/data/queries.js [new file with mode: 0644]
src/forum.js [new file with mode: 0644]
src/forum.svelte
src/pages/_fallback.svelte [moved from src/routes/$error.svelte with 100% similarity]
src/pages/_layout.svelte [moved from src/routes/$layout.svelte with 87% similarity]
src/pages/a/[id].svelte [new file with mode: 0644]
src/pages/f/[id].svelte [new file with mode: 0644]
src/pages/g/[id].svelte [new file with mode: 0644]
src/pages/index.svelte [moved from src/routes/index.svelte with 100% similarity]
src/pages/p/[id].svelte [new file with mode: 0644]
src/pages/t/[id].svelte [new file with mode: 0644]
src/routes/a/[id].svelte [deleted file]
src/routes/f/[id].svelte [deleted file]
src/routes/g/[id].svelte [deleted file]
src/routes/p/[id].svelte [deleted file]
src/routes/t/[id].svelte [deleted file]
src/stores/forum.js [new file with mode: 0644]
src/stores/forums.js
src/utils/readable_time.js [new file with mode: 0644]
svelte.config.cjs [deleted file]
vite.config.js

index 8902297c7e2746bddb7258e178a0c52dd874769b..c9c017db82c2043686bf87cbf44a8fbebf4609c0 100644 (file)
--- a/.eslintrc
+++ b/.eslintrc
@@ -26,5 +26,8 @@
     ],
     "no-undef": 2,
     "require-yield": 0
+  },
+  "globals": {
+    "import"
   }
 }
index 5463788a8b3b546f56752abdf304b585f3f28ae5..25a11176ff7056e85a6df5c9da5f961a25259406 100644 (file)
@@ -5,3 +5,4 @@ dist
 .env
 
 .svelte
+.routify
similarity index 90%
rename from src/app.html
rename to index.html
index 26d754f54f40070772579daef8bea5faeea8d5a6..27e22c758f361716fdc322396f59acfaf957f522 100644 (file)
     <title>Forum.</title>
 
     <link rel="manifest" href="/manifest.webmanifest">
-
-               %svelte.head%
+    <script type="module" src="/src/forum.js"></script>
   </head>
   <body>
-               <div id="forum">%svelte.body%</div>
     <noscript>
       <h1>Javascript Required.</h1>
       <p>Please enable Javascript to use this forum.</p>
index 84403ff2b1a2c0b3a3b55fcce2c7f9b9b53aab57..0b2023417d2d7ac8f7026b9bfb13a5b7f4629c4b 100644 (file)
@@ -8,14 +8,16 @@
       "version": "1.0.0",
       "license": "Apache-2.0",
       "dependencies": {
+        "@apollo/client": "^3.3.11",
         "eventemitter3": "^4.0.4",
-        "language-name-map": "^0.3.0"
+        "language-name-map": "^0.3.0",
+        "svelte-apollo": "^0.4.0"
       },
       "devDependencies": {
         "@hapi/eslint-config-hapi": "^13.0.2",
         "@hapi/eslint-plugin-hapi": "^4.3.5",
-        "@sveltejs/adapter-node": "next",
-        "@sveltejs/kit": "next",
+        "@roxi/routify": "^2.14.0",
+        "@sveltejs/vite-plugin-svelte": "^1.0.0-next.2",
         "eslint": "^7.3.0",
         "eslint-plugin-svelte3": "^2.7.3",
         "htmlhint": "^0.14.0",
         "vite": "^2.0.4"
       }
     },
+    "node_modules/@apollo/client": {
+      "version": "3.3.11",
+      "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.11.tgz",
+      "integrity": "sha512-54+D5FB6RJlQ+g37f432gaexnyvDsG5X6L9VO5kqN54HJlbF8hCf/8CXtAQEHCWodAwZhy6kOLp2RM96829q3A==",
+      "dependencies": {
+        "@graphql-typed-document-node/core": "^3.0.0",
+        "@types/zen-observable": "^0.8.0",
+        "@wry/context": "^0.5.2",
+        "@wry/equality": "^0.3.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graphql-tag": "^2.12.0",
+        "hoist-non-react-statics": "^3.3.2",
+        "optimism": "^0.14.0",
+        "prop-types": "^15.7.2",
+        "symbol-observable": "^2.0.0",
+        "ts-invariant": "^0.6.0",
+        "tslib": "^1.10.0",
+        "zen-observable": "^0.8.14"
+      },
+      "peerDependencies": {
+        "graphql": "^14.0.0 || ^15.0.0",
+        "react": "^16.8.0 || ^17.0.0",
+        "subscriptions-transport-ws": "^0.9.0"
+      },
+      "peerDependenciesMeta": {
+        "react": {
+          "optional": true
+        },
+        "subscriptions-transport-ws": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@apollo/client/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.12.11",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
         "tslib": "^2.1.0"
       }
     },
+    "node_modules/@graphql-typed-document-node/core": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz",
+      "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==",
+      "peerDependencies": {
+        "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
+      }
+    },
     "node_modules/@hapi/eslint-config-hapi": {
       "version": "13.0.2",
       "resolved": "https://registry.npmjs.org/@hapi/eslint-config-hapi/-/eslint-config-hapi-13.0.2.tgz",
         "rollup": "^1.20.0||^2.0.0"
       }
     },
-    "node_modules/@sveltejs/adapter-node": {
-      "version": "1.0.0-next.5",
-      "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.5.tgz",
-      "integrity": "sha512-J8GTYQOHNtI3v/Kal4UUiPtHAn/2dqqNdDjo23I13NmefxnHWHYPIl+TbIIDu6FPFHcHw45CmtXth3uDt8sakQ==",
-      "dev": true
-    },
-    "node_modules/@sveltejs/kit": {
-      "version": "1.0.0-next.40",
-      "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.40.tgz",
-      "integrity": "sha512-tZNqT3o1/EgmAoVPRPTySO8iEIMpenRYgcaUu6aYt//wgtTQWfcMC+VNVtNZeFA5rLiu48hginCM+AOmKa65LA==",
+    "node_modules/@roxi/routify": {
+      "version": "2.14.0",
+      "resolved": "https://registry.npmjs.org/@roxi/routify/-/routify-2.14.0.tgz",
+      "integrity": "sha512-7hh/Nwp5uRgOGRee3/iMi40Nyc0oXxMYtpTTltfhFW/xISiXozEdRYJP7mav7IqjYgBZRJ4vIdeb1qN+aoL2bQ==",
       "dev": true,
       "dependencies": {
-        "@sveltejs/vite-plugin-svelte": "1.0.0-next.2",
-        "@svitejs/vite-plugin-svelte": "^0.10.0-0",
-        "cheap-watch": "^1.0.3",
-        "sade": "^1.7.4"
+        "@roxi/ssr": "^0.2.1",
+        "@types/node": ">=4.2.0 < 13",
+        "chalk": "^4.0.0",
+        "cheap-watch": "^1.0.2",
+        "commander": "^7.1.0",
+        "configent": "^2.1.4",
+        "esm": "^3.2.25",
+        "fs-extra": "^9.0.1",
+        "log-symbols": "^3.0.0",
+        "picomatch": "^2.2.2",
+        "rollup-pluginutils": "^2.8.2"
       },
       "bin": {
-        "svelte-kit": "svelte-kit.js"
-      },
-      "peerDependencies": {
-        "svelte": "^3.32.1",
-        "vite": "^2.0.4"
+        "routify": "plugins/cli.js"
+      }
+    },
+    "node_modules/@roxi/routify/node_modules/commander": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz",
+      "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@roxi/ssr": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/@roxi/ssr/-/ssr-0.2.1.tgz",
+      "integrity": "sha512-C86xWJOmtCGZr/U4MURqePM0oDKFkTlLeEyT07R+7jSKvREKZ2manJAeAebYudJLYEGITEPGqObhRan32bUUbg==",
+      "dev": true,
+      "dependencies": {
+        "bufferutil": "^4.0.1",
+        "jsdom": "^16.0.1",
+        "node-fetch": "^2.6.0",
+        "utf-8-validate": "^5.0.2"
       }
     },
     "node_modules/@sveltejs/vite-plugin-svelte": {
         "vite": "^2"
       }
     },
-    "node_modules/@svitejs/vite-plugin-svelte": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/@svitejs/vite-plugin-svelte/-/vite-plugin-svelte-0.10.0.tgz",
-      "integrity": "sha512-gttcMIZvLwanYbkfkl77o8mkPKxnYGoqz0xOfz4ZPrzJdan+DzH9b2PEQbpWb53klFKANB7FPBDr7bCaixIT5Q==",
-      "dev": true,
+    "node_modules/@types/node": {
+      "version": "12.20.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.5.tgz",
+      "integrity": "sha512-5Oy7tYZnu3a4pnJ//d4yVvOImExl4Vtwf0D40iKUlU+XlUsyV9iyFWyCFlwy489b72FMAik/EFwRkNLjjOdSPg==",
+      "dev": true
+    },
+    "node_modules/@types/ungap__global-this": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz",
+      "integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g=="
+    },
+    "node_modules/@types/zen-observable": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz",
+      "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg=="
+    },
+    "node_modules/@ungap/global-this": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.4.tgz",
+      "integrity": "sha512-mHkm6FvepJECMNthFuIgpAEFmPOk71UyXuIxYfjytvFTnSDBIz7jmViO+LfHI/AjrazWije0PnSP3+/NlwzqtA=="
+    },
+    "node_modules/@wry/context": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.4.tgz",
+      "integrity": "sha512-/pktJKHUXDr4D6TJqWgudOPJW2Z+Nb+bqk40jufA3uTkLbnCRKdJPiYDIa/c7mfcPH8Hr6O8zjCERpg5Sq04Zg==",
       "dependencies": {
-        "@rollup/pluginutils": "^4.1.0",
-        "chalk": "^4.1.0",
-        "debug": "^4.3.1",
-        "hash-sum": "^2.0.0",
-        "require-relative": "^0.8.7",
-        "slash": "^3.0.0",
-        "source-map": "^0.7.3",
-        "svelte-hmr": "^0.13.0-2"
+        "tslib": "^1.14.1"
       },
       "engines": {
-        "node": ">=12.0.0"
+        "node": ">=8"
+      }
+    },
+    "node_modules/@wry/context/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/@wry/equality": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.3.4.tgz",
+      "integrity": "sha512-1gQQhCPenzxw/1HzLlvSIs/59eBHJf9ZDIussjjZhqNSqQuPKQIzN6SWt4kemvlBPDi7RqMuUa03pId7MAE93g==",
+      "dependencies": {
+        "tslib": "^1.14.1"
       },
-      "peerDependencies": {
-        "svelte": "^3.35.0",
-        "vite": "^2.0.5"
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/@svitejs/vite-plugin-svelte/node_modules/svelte-hmr": {
-      "version": "0.13.0-2",
-      "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.13.0-2.tgz",
-      "integrity": "sha512-3Sqxbs5hG212oweKhHzh2S7jVScylzbVXuEkydgdS9NpvcdnyCSufpaJSUNxUGc02wgjWugtqaJXs1DybAjRpw==",
-      "dev": true,
-      "peerDependencies": {
-        "svelte": ">=3.19.0"
+    "node_modules/@wry/equality/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/@wry/trie": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.2.2.tgz",
+      "integrity": "sha512-OxqBB39x6MfHaa2HpMiRMfhuUnQTddD32Ko020eBeJXq87ivX6xnSSnzKHVbA21p7iqBASz8n/07b6W5wW1BVQ==",
+      "dependencies": {
+        "tslib": "^1.14.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
+    "node_modules/@wry/trie/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/abab": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+      "dev": true
+    },
     "node_modules/acorn": {
       "version": "7.4.1",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
         "node": ">=0.4.0"
       }
     },
+    "node_modules/acorn-globals": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+      "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^7.1.1",
+        "acorn-walk": "^7.1.1"
+      }
+    },
     "node_modules/acorn-jsx": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
         "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
       }
     },
+    "node_modules/acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
       "dev": true
     },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/aws-sign2": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
         "concat-map": "0.0.1"
       }
     },
+    "node_modules/browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+      "dev": true
+    },
+    "node_modules/bufferutil": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
+      "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "^4.2.0"
+      }
+    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "node_modules/configent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/configent/-/configent-2.2.0.tgz",
+      "integrity": "sha512-yIN6zfOWk2nycNJ2JFNiWEai0oiqAhISIht8+pbEBP8bdcpwoQ74AhCZPbUv9aRVJwo7wh1MbCBDUV44UJa7Kw==",
+      "dev": true,
+      "dependencies": {
+        "dotenv": "^8.2.0"
+      }
+    },
     "node_modules/core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
         "node": ">= 8"
       }
     },
+    "node_modules/cssom": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+      "dev": true
+    },
+    "node_modules/cssstyle": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+      "dev": true,
+      "dependencies": {
+        "cssom": "~0.3.6"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cssstyle/node_modules/cssom": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+      "dev": true
+    },
     "node_modules/dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
         "node": ">=0.10"
       }
     },
+    "node_modules/data-urls": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+      "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+      "dev": true,
+      "dependencies": {
+        "abab": "^2.0.3",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/debug": {
       "version": "4.3.1",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
         }
       }
     },
+    "node_modules/decimal.js": {
+      "version": "10.2.1",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
+      "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+      "dev": true
+    },
     "node_modules/deep-is": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
         "node": ">=6.0.0"
       }
     },
+    "node_modules/domexception": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+      "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+      "dev": true,
+      "dependencies": {
+        "webidl-conversions": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/domexception/node_modules/webidl-conversions": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+      "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
         "node": ">=0.8.0"
       }
     },
+    "node_modules/escodegen": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+      "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+      "dev": true,
+      "dependencies": {
+        "esprima": "^4.0.1",
+        "estraverse": "^5.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      },
+      "bin": {
+        "escodegen": "bin/escodegen.js",
+        "esgenerate": "bin/esgenerate.js"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "optionalDependencies": {
+        "source-map": "~0.6.1"
+      }
+    },
+    "node_modules/escodegen/node_modules/estraverse": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+      "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/optionator": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
+      "dependencies": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.6",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "word-wrap": "~1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/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==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
     "node_modules/eslint": {
       "version": "7.21.0",
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
         "node": ">=10"
       }
     },
+    "node_modules/esm": {
+      "version": "3.2.25",
+      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/espree": {
       "version": "7.3.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
     "node_modules/fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
     },
     "node_modules/fast-levenshtein": {
       "version": "2.0.6",
         "node": ">= 0.12"
       }
     },
+    "node_modules/fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
       "dev": true
     },
+    "node_modules/graceful-fs": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "dev": true
+    },
+    "node_modules/graphql": {
+      "version": "15.5.0",
+      "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz",
+      "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==",
+      "peer": true,
+      "engines": {
+        "node": ">= 10.x"
+      }
+    },
+    "node_modules/graphql-tag": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.1.tgz",
+      "integrity": "sha512-LPewEE1vzGkHnCO8zdOGogKsHHBdtpGyihow1UuMwp6RnZa0lAS7NcbvltLOuo4pi5diQCPASAXZkQq44ffixA==",
+      "dependencies": {
+        "tslib": "^1.14.1"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
+      }
+    },
+    "node_modules/graphql-tag/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
     "node_modules/har-schema": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
       "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
       "dev": true
     },
+    "node_modules/hoist-non-react-statics": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+      "dependencies": {
+        "react-is": "^16.7.0"
+      }
+    },
+    "node_modules/html-encoding-sniffer": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+      "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+      "dev": true,
+      "dependencies": {
+        "whatwg-encoding": "^1.0.5"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/htmlhint": {
       "version": "0.14.2",
       "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.14.2.tgz",
         "npm": ">=1.3.7"
       }
     },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/ignore": {
       "version": "4.0.6",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-potential-custom-element-name": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
+      "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
+      "dev": true
+    },
     "node_modules/is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
     },
     "node_modules/js-yaml": {
       "version": "3.14.1",
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "dev": true
     },
-    "node_modules/json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-      "dev": true
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
+    "node_modules/jsdom": {
+      "version": "16.5.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.0.tgz",
+      "integrity": "sha512-QxZH0nmDTnTTVI0YDm4RUlaUPl5dcyn62G5TMDNfMmTW+J1u1v9gCR8WR+WZ6UghAa7nKJjDOFaI00eMMWvJFQ==",
+      "dev": true,
+      "dependencies": {
+        "abab": "^2.0.5",
+        "acorn": "^8.0.5",
+        "acorn-globals": "^6.0.0",
+        "cssom": "^0.4.4",
+        "cssstyle": "^2.3.0",
+        "data-urls": "^2.0.0",
+        "decimal.js": "^10.2.1",
+        "domexception": "^2.0.1",
+        "escodegen": "^2.0.0",
+        "html-encoding-sniffer": "^2.0.1",
+        "is-potential-custom-element-name": "^1.0.0",
+        "nwsapi": "^2.2.0",
+        "parse5": "6.0.1",
+        "request": "^2.88.2",
+        "request-promise-native": "^1.0.9",
+        "saxes": "^5.0.1",
+        "symbol-tree": "^3.2.4",
+        "tough-cookie": "^4.0.0",
+        "w3c-hr-time": "^1.0.2",
+        "w3c-xmlserializer": "^2.0.0",
+        "webidl-conversions": "^6.1.0",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.0.0",
+        "ws": "^7.4.4",
+        "xml-name-validator": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "canvas": "^2.5.0"
+      },
+      "peerDependenciesMeta": {
+        "canvas": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/jsdom/node_modules/acorn": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.0.tgz",
+      "integrity": "sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/jsdom/node_modules/tough-cookie": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+      "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.33",
+        "punycode": "^2.1.1",
+        "universalify": "^0.1.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsdom/node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
     },
     "node_modules/json-stable-stringify-without-jsonify": {
       "version": "1.0.1",
       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
       "dev": true
     },
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
     "node_modules/jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
+    "node_modules/lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+      "dev": true
+    },
+    "node_modules/log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/log-symbols/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/log-symbols/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/log-symbols/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "node_modules/node-fetch": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+      "dev": true,
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      }
+    },
+    "node_modules/node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/nwsapi": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "dev": true
+    },
     "node_modules/oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
         "node": "*"
       }
     },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
         "wrappy": "1"
       }
     },
+    "node_modules/optimism": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.14.1.tgz",
+      "integrity": "sha512-7+1lSN+LJEtaj3uBLLFk8uFCFKy3txLvcvln5Dh1szXjF9yghEMeWclmnk0qdtYZ+lcMNyu48RmQQRw+LRYKSQ==",
+      "dependencies": {
+        "@wry/context": "^0.5.2",
+        "@wry/trie": "^0.2.1"
+      }
+    },
     "node_modules/optionator": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
         "node": ">=0.10.0"
       }
     },
+    "node_modules/parse5": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+      "dev": true
+    },
     "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
         "node": ">=0.4.0"
       }
     },
+    "node_modules/prop-types": {
+      "version": "15.7.2",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "dependencies": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.8.1"
+      }
+    },
     "node_modules/psl": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
         "node": ">=0.6"
       }
     },
+    "node_modules/react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+    },
     "node_modules/regexpp": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
         "node": ">= 6"
       }
     },
+    "node_modules/request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.19"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
+      }
+    },
+    "node_modules/request-promise-native": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+      "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
+      "dev": true,
+      "dependencies": {
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
+      }
+    },
     "node_modules/require-from-string": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
         "fsevents": "~2.3.1"
       }
     },
+    "node_modules/rollup-pluginutils": {
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+      "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+      "dev": true,
+      "dependencies": {
+        "estree-walker": "^0.6.1"
+      }
+    },
+    "node_modules/rollup-pluginutils/node_modules/estree-walker": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+      "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+      "dev": true
+    },
     "node_modules/sade": {
       "version": "1.7.4",
       "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
       "dev": true
     },
+    "node_modules/saxes": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+      "dev": true,
+      "dependencies": {
+        "xmlchars": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/semver": {
       "version": "7.3.4",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
         "node": ">=0.10.0"
       }
     },
+    "node_modules/stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/string-width": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
       "version": "3.35.0",
       "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.35.0.tgz",
       "integrity": "sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==",
-      "dev": true,
       "engines": {
         "node": ">= 8"
       }
     },
+    "node_modules/svelte-apollo": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/svelte-apollo/-/svelte-apollo-0.4.0.tgz",
+      "integrity": "sha512-VbianysptRx9wy6vQPd2lIRBVKV0XPtrSvqcMctihc5xGl1TVffNp8qsiSlqx2jnOlvOGUSK8xl4GW7C6bzSjw==",
+      "peerDependencies": {
+        "@apollo/client": "^3.2.0",
+        "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0",
+        "svelte": "^3.0.0"
+      }
+    },
     "node_modules/svelte-hmr": {
       "version": "0.12.9",
       "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.12.9.tgz",
         "svelte": "^3.25.1"
       }
     },
+    "node_modules/symbol-observable": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz",
+      "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/symbol-tree": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+      "dev": true
+    },
     "node_modules/table": {
       "version": "6.0.7",
       "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz",
         "node": ">=0.8"
       }
     },
+    "node_modules/tr46": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
+      "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ts-invariant": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.6.1.tgz",
+      "integrity": "sha512-QQgN33g8E8yrdDuH29HASveLtbzMnRRgWh0i/JNTW4+zcLsdIOnfsgEDi/NKx4UckQyuMFt9Ujm6TWLWQ58Kvg==",
+      "dependencies": {
+        "@types/ungap__global-this": "^0.3.1",
+        "@ungap/global-this": "^0.4.2",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ts-invariant/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
     "node_modules/tslib": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
         "node": ">=8"
       }
     },
+    "node_modules/universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
     "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/utf-8-validate": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
+      "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "^4.2.0"
+      }
+    },
     "node_modules/uuid": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
         "fsevents": "~2.3.1"
       }
     },
+    "node_modules/w3c-hr-time": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+      "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+      "dev": true,
+      "dependencies": {
+        "browser-process-hrtime": "^1.0.0"
+      }
+    },
+    "node_modules/w3c-xmlserializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+      "dev": true,
+      "dependencies": {
+        "xml-name-validator": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/webidl-conversions": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.4"
+      }
+    },
+    "node_modules/whatwg-encoding": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+      "dev": true,
+      "dependencies": {
+        "iconv-lite": "0.4.24"
+      }
+    },
+    "node_modules/whatwg-mimetype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+      "dev": true
+    },
+    "node_modules/whatwg-url": {
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz",
+      "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==",
+      "dev": true,
+      "dependencies": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^2.0.2",
+        "webidl-conversions": "^6.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
       "dev": true
     },
+    "node_modules/ws": {
+      "version": "7.4.4",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
+      "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/xml": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
       "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
       "dev": true
     },
+    "node_modules/xml-name-validator": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+      "dev": true
+    },
+    "node_modules/xmlchars": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+      "dev": true
+    },
     "node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
+    },
+    "node_modules/zen-observable": {
+      "version": "0.8.15",
+      "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
+      "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ=="
     }
   },
   "dependencies": {
+    "@apollo/client": {
+      "version": "3.3.11",
+      "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.11.tgz",
+      "integrity": "sha512-54+D5FB6RJlQ+g37f432gaexnyvDsG5X6L9VO5kqN54HJlbF8hCf/8CXtAQEHCWodAwZhy6kOLp2RM96829q3A==",
+      "requires": {
+        "@graphql-typed-document-node/core": "^3.0.0",
+        "@types/zen-observable": "^0.8.0",
+        "@wry/context": "^0.5.2",
+        "@wry/equality": "^0.3.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graphql-tag": "^2.12.0",
+        "hoist-non-react-statics": "^3.3.2",
+        "optimism": "^0.14.0",
+        "prop-types": "^15.7.2",
+        "symbol-observable": "^2.0.0",
+        "ts-invariant": "^0.6.0",
+        "tslib": "^1.10.0",
+        "zen-observable": "^0.8.14"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
     "@babel/code-frame": {
       "version": "7.12.11",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
         "tslib": "^2.1.0"
       }
     },
+    "@graphql-typed-document-node/core": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz",
+      "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==",
+      "requires": {}
+    },
     "@hapi/eslint-config-hapi": {
       "version": "13.0.2",
       "resolved": "https://registry.npmjs.org/@hapi/eslint-config-hapi/-/eslint-config-hapi-13.0.2.tgz",
         "picomatch": "^2.2.2"
       }
     },
-    "@sveltejs/adapter-node": {
-      "version": "1.0.0-next.5",
-      "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.5.tgz",
-      "integrity": "sha512-J8GTYQOHNtI3v/Kal4UUiPtHAn/2dqqNdDjo23I13NmefxnHWHYPIl+TbIIDu6FPFHcHw45CmtXth3uDt8sakQ==",
-      "dev": true
+    "@roxi/routify": {
+      "version": "2.14.0",
+      "resolved": "https://registry.npmjs.org/@roxi/routify/-/routify-2.14.0.tgz",
+      "integrity": "sha512-7hh/Nwp5uRgOGRee3/iMi40Nyc0oXxMYtpTTltfhFW/xISiXozEdRYJP7mav7IqjYgBZRJ4vIdeb1qN+aoL2bQ==",
+      "dev": true,
+      "requires": {
+        "@roxi/ssr": "^0.2.1",
+        "@types/node": ">=4.2.0 < 13",
+        "chalk": "^4.0.0",
+        "cheap-watch": "^1.0.2",
+        "commander": "^7.1.0",
+        "configent": "^2.1.4",
+        "esm": "^3.2.25",
+        "fs-extra": "^9.0.1",
+        "log-symbols": "^3.0.0",
+        "picomatch": "^2.2.2",
+        "rollup-pluginutils": "^2.8.2"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz",
+          "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==",
+          "dev": true
+        }
+      }
     },
-    "@sveltejs/kit": {
-      "version": "1.0.0-next.40",
-      "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.40.tgz",
-      "integrity": "sha512-tZNqT3o1/EgmAoVPRPTySO8iEIMpenRYgcaUu6aYt//wgtTQWfcMC+VNVtNZeFA5rLiu48hginCM+AOmKa65LA==",
+    "@roxi/ssr": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/@roxi/ssr/-/ssr-0.2.1.tgz",
+      "integrity": "sha512-C86xWJOmtCGZr/U4MURqePM0oDKFkTlLeEyT07R+7jSKvREKZ2manJAeAebYudJLYEGITEPGqObhRan32bUUbg==",
       "dev": true,
       "requires": {
-        "@sveltejs/vite-plugin-svelte": "1.0.0-next.2",
-        "@svitejs/vite-plugin-svelte": "^0.10.0-0",
-        "cheap-watch": "^1.0.3",
-        "sade": "^1.7.4"
+        "bufferutil": "^4.0.1",
+        "jsdom": "^16.0.1",
+        "node-fetch": "^2.6.0",
+        "utf-8-validate": "^5.0.2"
       }
     },
     "@sveltejs/vite-plugin-svelte": {
         "svelte-hmr": "^0.12.6"
       }
     },
-    "@svitejs/vite-plugin-svelte": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/@svitejs/vite-plugin-svelte/-/vite-plugin-svelte-0.10.0.tgz",
-      "integrity": "sha512-gttcMIZvLwanYbkfkl77o8mkPKxnYGoqz0xOfz4ZPrzJdan+DzH9b2PEQbpWb53klFKANB7FPBDr7bCaixIT5Q==",
-      "dev": true,
+    "@types/node": {
+      "version": "12.20.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.5.tgz",
+      "integrity": "sha512-5Oy7tYZnu3a4pnJ//d4yVvOImExl4Vtwf0D40iKUlU+XlUsyV9iyFWyCFlwy489b72FMAik/EFwRkNLjjOdSPg==",
+      "dev": true
+    },
+    "@types/ungap__global-this": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz",
+      "integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g=="
+    },
+    "@types/zen-observable": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz",
+      "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg=="
+    },
+    "@ungap/global-this": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.4.tgz",
+      "integrity": "sha512-mHkm6FvepJECMNthFuIgpAEFmPOk71UyXuIxYfjytvFTnSDBIz7jmViO+LfHI/AjrazWije0PnSP3+/NlwzqtA=="
+    },
+    "@wry/context": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.4.tgz",
+      "integrity": "sha512-/pktJKHUXDr4D6TJqWgudOPJW2Z+Nb+bqk40jufA3uTkLbnCRKdJPiYDIa/c7mfcPH8Hr6O8zjCERpg5Sq04Zg==",
       "requires": {
-        "@rollup/pluginutils": "^4.1.0",
-        "chalk": "^4.1.0",
-        "debug": "^4.3.1",
-        "hash-sum": "^2.0.0",
-        "require-relative": "^0.8.7",
-        "slash": "^3.0.0",
-        "source-map": "^0.7.3",
-        "svelte-hmr": "^0.13.0-2"
+        "tslib": "^1.14.1"
       },
       "dependencies": {
-        "svelte-hmr": {
-          "version": "0.13.0-2",
-          "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.13.0-2.tgz",
-          "integrity": "sha512-3Sqxbs5hG212oweKhHzh2S7jVScylzbVXuEkydgdS9NpvcdnyCSufpaJSUNxUGc02wgjWugtqaJXs1DybAjRpw==",
-          "dev": true,
-          "requires": {}
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@wry/equality": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.3.4.tgz",
+      "integrity": "sha512-1gQQhCPenzxw/1HzLlvSIs/59eBHJf9ZDIussjjZhqNSqQuPKQIzN6SWt4kemvlBPDi7RqMuUa03pId7MAE93g==",
+      "requires": {
+        "tslib": "^1.14.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
         }
       }
     },
+    "@wry/trie": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.2.2.tgz",
+      "integrity": "sha512-OxqBB39x6MfHaa2HpMiRMfhuUnQTddD32Ko020eBeJXq87ivX6xnSSnzKHVbA21p7iqBASz8n/07b6W5wW1BVQ==",
+      "requires": {
+        "tslib": "^1.14.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "abab": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+      "dev": true
+    },
     "acorn": {
       "version": "7.4.1",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
       "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
       "dev": true
     },
+    "acorn-globals": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+      "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-walk": "^7.1.1"
+      }
+    },
     "acorn-jsx": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
       "dev": true,
       "requires": {}
     },
+    "acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+      "dev": true
+    },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
       "dev": true
     },
+    "at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true
+    },
     "aws-sign2": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
         "concat-map": "0.0.1"
       }
     },
+    "browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+      "dev": true
+    },
+    "bufferutil": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
+      "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
+      "dev": true,
+      "requires": {
+        "node-gyp-build": "^4.2.0"
+      }
+    },
     "callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "configent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/configent/-/configent-2.2.0.tgz",
+      "integrity": "sha512-yIN6zfOWk2nycNJ2JFNiWEai0oiqAhISIht8+pbEBP8bdcpwoQ74AhCZPbUv9aRVJwo7wh1MbCBDUV44UJa7Kw==",
+      "dev": true,
+      "requires": {
+        "dotenv": "^8.2.0"
+      }
+    },
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
         "which": "^2.0.1"
       }
     },
+    "cssom": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+      "dev": true,
+      "requires": {
+        "cssom": "~0.3.6"
+      },
+      "dependencies": {
+        "cssom": {
+          "version": "0.3.8",
+          "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+          "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+          "dev": true
+        }
+      }
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
         "assert-plus": "^1.0.0"
       }
     },
+    "data-urls": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+      "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.3",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.0.0"
+      }
+    },
     "debug": {
       "version": "4.3.1",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
         "ms": "2.1.2"
       }
     },
+    "decimal.js": {
+      "version": "10.2.1",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
+      "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+      "dev": true
+    },
     "deep-is": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
         "esutils": "^2.0.2"
       }
     },
+    "domexception": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+      "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^5.0.0"
+      },
+      "dependencies": {
+        "webidl-conversions": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+          "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+          "dev": true
+        }
+      }
+    },
+    "dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true
+    },
     "ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
       "dev": true
     },
+    "escodegen": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+      "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+      "dev": true,
+      "requires": {
+        "esprima": "^4.0.1",
+        "estraverse": "^5.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+          "dev": true
+        },
+        "levn": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+          "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+          "dev": true,
+          "requires": {
+            "prelude-ls": "~1.1.2",
+            "type-check": "~0.3.2"
+          }
+        },
+        "optionator": {
+          "version": "0.8.3",
+          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+          "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+          "dev": true,
+          "requires": {
+            "deep-is": "~0.1.3",
+            "fast-levenshtein": "~2.0.6",
+            "levn": "~0.3.0",
+            "prelude-ls": "~1.1.2",
+            "type-check": "~0.3.2",
+            "word-wrap": "~1.2.3"
+          }
+        },
+        "prelude-ls": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+          "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        },
+        "type-check": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+          "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+          "dev": true,
+          "requires": {
+            "prelude-ls": "~1.1.2"
+          }
+        }
+      }
+    },
     "eslint": {
       "version": "7.21.0",
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
       "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
       "dev": true
     },
+    "esm": {
+      "version": "3.2.25",
+      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+      "dev": true
+    },
     "espree": {
       "version": "7.3.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
     "fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
     },
     "fast-levenshtein": {
       "version": "2.0.6",
         "mime-types": "^2.1.12"
       }
     },
+    "fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "dev": true,
+      "requires": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      }
+    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
       "dev": true
     },
+    "graceful-fs": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "dev": true
+    },
+    "graphql": {
+      "version": "15.5.0",
+      "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz",
+      "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==",
+      "peer": true
+    },
+    "graphql-tag": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.1.tgz",
+      "integrity": "sha512-LPewEE1vzGkHnCO8zdOGogKsHHBdtpGyihow1UuMwp6RnZa0lAS7NcbvltLOuo4pi5diQCPASAXZkQq44ffixA==",
+      "requires": {
+        "tslib": "^1.14.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
     "har-schema": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
       "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
       "dev": true
     },
+    "hoist-non-react-statics": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+      "requires": {
+        "react-is": "^16.7.0"
+      }
+    },
+    "html-encoding-sniffer": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+      "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.5"
+      }
+    },
     "htmlhint": {
       "version": "0.14.2",
       "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.14.2.tgz",
         "sshpk": "^1.7.0"
       }
     },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
     "ignore": {
       "version": "4.0.6",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
         "is-extglob": "^2.1.1"
       }
     },
+    "is-potential-custom-element-name": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
+      "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
+      "dev": true
+    },
     "is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
     },
     "js-yaml": {
       "version": "3.14.1",
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "dev": true
     },
+    "jsdom": {
+      "version": "16.5.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.0.tgz",
+      "integrity": "sha512-QxZH0nmDTnTTVI0YDm4RUlaUPl5dcyn62G5TMDNfMmTW+J1u1v9gCR8WR+WZ6UghAa7nKJjDOFaI00eMMWvJFQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.5",
+        "acorn": "^8.0.5",
+        "acorn-globals": "^6.0.0",
+        "cssom": "^0.4.4",
+        "cssstyle": "^2.3.0",
+        "data-urls": "^2.0.0",
+        "decimal.js": "^10.2.1",
+        "domexception": "^2.0.1",
+        "escodegen": "^2.0.0",
+        "html-encoding-sniffer": "^2.0.1",
+        "is-potential-custom-element-name": "^1.0.0",
+        "nwsapi": "^2.2.0",
+        "parse5": "6.0.1",
+        "request": "^2.88.2",
+        "request-promise-native": "^1.0.9",
+        "saxes": "^5.0.1",
+        "symbol-tree": "^3.2.4",
+        "tough-cookie": "^4.0.0",
+        "w3c-hr-time": "^1.0.2",
+        "w3c-xmlserializer": "^2.0.0",
+        "webidl-conversions": "^6.1.0",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.0.0",
+        "ws": "^7.4.4",
+        "xml-name-validator": "^3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.0.tgz",
+          "integrity": "sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==",
+          "dev": true
+        },
+        "tough-cookie": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+          "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
+          "dev": true,
+          "requires": {
+            "psl": "^1.1.33",
+            "punycode": "^2.1.1",
+            "universalify": "^0.1.2"
+          }
+        },
+        "universalify": {
+          "version": "0.1.2",
+          "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+          "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+          "dev": true
+        }
+      }
+    },
     "json-schema": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
       "dev": true
     },
+    "jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
+      }
+    },
     "jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+      "dev": true
+    },
+    "log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "color-convert": {
+          "version": "1.9.3",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+          "dev": true,
+          "requires": {
+            "color-name": "1.1.3"
+          }
+        },
+        "color-name": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
     "lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "node-fetch": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+      "dev": true
+    },
+    "node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true
+    },
+    "nwsapi": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "dev": true
+    },
     "oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
       "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
       "dev": true
     },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
         "wrappy": "1"
       }
     },
+    "optimism": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.14.1.tgz",
+      "integrity": "sha512-7+1lSN+LJEtaj3uBLLFk8uFCFKy3txLvcvln5Dh1szXjF9yghEMeWclmnk0qdtYZ+lcMNyu48RmQQRw+LRYKSQ==",
+      "requires": {
+        "@wry/context": "^0.5.2",
+        "@wry/trie": "^0.2.1"
+      }
+    },
     "optionator": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
         }
       }
     },
+    "parse5": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+      "dev": true
+    },
     "path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
       "dev": true
     },
+    "prop-types": {
+      "version": "15.7.2",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "requires": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.8.1"
+      }
+    },
     "psl": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
       "dev": true
     },
+    "react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+    },
     "regexpp": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
         "uuid": "^3.3.2"
       }
     },
+    "request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.19"
+      }
+    },
+    "request-promise-native": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+      "dev": true,
+      "requires": {
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      }
+    },
     "require-from-string": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
         "fsevents": "~2.3.1"
       }
     },
+    "rollup-pluginutils": {
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+      "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+      "dev": true,
+      "requires": {
+        "estree-walker": "^0.6.1"
+      },
+      "dependencies": {
+        "estree-walker": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+          "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+          "dev": true
+        }
+      }
+    },
     "sade": {
       "version": "1.7.4",
       "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
       "dev": true
     },
+    "saxes": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+      "dev": true,
+      "requires": {
+        "xmlchars": "^2.2.0"
+      }
+    },
     "semver": {
       "version": "7.3.4",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
         "tweetnacl": "~0.14.0"
       }
     },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true
+    },
     "string-width": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
     "svelte": {
       "version": "3.35.0",
       "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.35.0.tgz",
-      "integrity": "sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==",
-      "dev": true
+      "integrity": "sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g=="
+    },
+    "svelte-apollo": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/svelte-apollo/-/svelte-apollo-0.4.0.tgz",
+      "integrity": "sha512-VbianysptRx9wy6vQPd2lIRBVKV0XPtrSvqcMctihc5xGl1TVffNp8qsiSlqx2jnOlvOGUSK8xl4GW7C6bzSjw==",
+      "requires": {}
     },
     "svelte-hmr": {
       "version": "0.12.9",
         "tiny-glob": "^0.2.6"
       }
     },
+    "symbol-observable": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz",
+      "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA=="
+    },
+    "symbol-tree": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+      "dev": true
+    },
     "table": {
       "version": "6.0.7",
       "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz",
         "punycode": "^2.1.1"
       }
     },
+    "tr46": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
+      "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.1"
+      }
+    },
+    "ts-invariant": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.6.1.tgz",
+      "integrity": "sha512-QQgN33g8E8yrdDuH29HASveLtbzMnRRgWh0i/JNTW4+zcLsdIOnfsgEDi/NKx4UckQyuMFt9Ujm6TWLWQ58Kvg==",
+      "requires": {
+        "@types/ungap__global-this": "^0.3.1",
+        "@ungap/global-this": "^0.4.2",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
     "tslib": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
       "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
       "dev": true
     },
+    "universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "dev": true
+    },
     "uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
         "punycode": "^2.1.0"
       }
     },
+    "utf-8-validate": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
+      "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
+      "dev": true,
+      "requires": {
+        "node-gyp-build": "^4.2.0"
+      }
+    },
     "uuid": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
         "rollup": "^2.38.5"
       }
     },
+    "w3c-hr-time": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+      "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+      "dev": true,
+      "requires": {
+        "browser-process-hrtime": "^1.0.0"
+      }
+    },
+    "w3c-xmlserializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+      "dev": true,
+      "requires": {
+        "xml-name-validator": "^3.0.0"
+      }
+    },
+    "webidl-conversions": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+      "dev": true
+    },
+    "whatwg-encoding": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.24"
+      }
+    },
+    "whatwg-mimetype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+      "dev": true
+    },
+    "whatwg-url": {
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz",
+      "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==",
+      "dev": true,
+      "requires": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^2.0.2",
+        "webidl-conversions": "^6.1.0"
+      }
+    },
     "which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
       "dev": true
     },
+    "ws": {
+      "version": "7.4.4",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
+      "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+      "dev": true,
+      "requires": {}
+    },
     "xml": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
       "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
       "dev": true
     },
+    "xml-name-validator": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+      "dev": true
+    },
+    "xmlchars": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+      "dev": true
+    },
     "yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
+    },
+    "zen-observable": {
+      "version": "0.8.15",
+      "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
+      "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ=="
     }
   }
 }
index 2fd94ef4d2ced68da28f03f33614bc40391c0da2..7b652635e6610cbfede8c71d13cdb14305234615 100644 (file)
   },
   "version": "1.0.0",
   "scripts": {
-    "dev": "svelte-kit dev",
-    "build": "svelte-kit build",
-    "start": "svelte-kit start",
+    "dev": "routify -c dev-vite",
+    "dev-vite": "vite",
+    "build": "routify -b && vite build",
     "lint": "eslint --ext .svelte --ext .js .",
     "linthtml": "htmlhint",
     "setup-hooks": "ln -s ../../scripts/git-hooks/pre-commit .git/hooks/pre-commit",
     "test": "echo sorry"
   },
   "dependencies": {
+    "@apollo/client": "^3.3.11",
     "eventemitter3": "^4.0.4",
-    "language-name-map": "^0.3.0"
+    "language-name-map": "^0.3.0",
+    "svelte-apollo": "^0.4.0"
   },
   "devDependencies": {
     "@hapi/eslint-config-hapi": "^13.0.2",
     "@hapi/eslint-plugin-hapi": "^4.3.5",
-    "@sveltejs/adapter-node": "next",
-    "@sveltejs/kit": "next",
+    "@roxi/routify": "^2.14.0",
+    "@sveltejs/vite-plugin-svelte": "^1.0.0-next.2",
     "eslint": "^7.3.0",
     "eslint-plugin-svelte3": "^2.7.3",
     "htmlhint": "^0.14.0",
diff --git a/src/components/forum/forum.svelte b/src/components/forum/forum.svelte
new file mode 100644 (file)
index 0000000..7008e66
--- /dev/null
@@ -0,0 +1,27 @@
+<script>
+  export let id;
+
+  import { _ } from 'svelte-i18n';
+  import { getForum } from '$stores/forum';
+  import ErrorBlock from '../error_block/error_block.svelte';
+
+  import TopicSummary from '$components/topic_summary/topic_summary.svelte';
+
+  $: store = getForum(id);
+  $: forum = $store.data;
+</script>
+
+{#if $store.loading}
+  <p>Loading...</p>
+{/if}
+{#if $store.error}
+  <ErrorBlock message={$_('forum_list.error.unavailable')} />
+{/if}
+{#if forum}
+  <h1>{forum.glyph} {$_(forum.label)}</h1>
+  <ul>
+    {#each forum.topics as topic}
+      <TopicSummary topic={topic} />
+    {/each}
+  </ul>
+{/if}
index 174ae2556dc95c0a77a732ab66592eba4a6dfa04..46f60f08a4f05e3f955bb3420855cb17f8bbcb33 100644 (file)
@@ -1,15 +1,18 @@
 <script>
   import { _ } from 'svelte-i18n';
-  import { forums } from '../../stores/forums.js';
+  import { forums } from '$stores/forums';
   import ErrorBlock from '../error_block/error_block.svelte';
 </script>
 
 <nav title="{$_('forum_list.title')}">
-  {#if !$forums.length}
+  {#if $forums.loading}
+    <p>Loading...</p>
+  {/if}
+  {#if $forums.error}
     <ErrorBlock message={$_('forum_list.error.unavailable')} />
   {/if}
   <ul>
-    {#each $forums as forum}
+    {#each $forums.data as forum}
       <li>
         <a href="/f/{forum.id}">
           <span aria-hidden="true" class="navigation-glyph {forum.glyph}">{forum.glyph}</span>
index e4b9166c773ca3f98c9e454218f489b0b826ba26..98d1c6e5d96b456b1147c2d6a21af24426e3e478 100644 (file)
@@ -21,6 +21,8 @@
     height: 48px;
     margin-top: 5px;
     width: 48px;
+    background-color: white;
+    padding: 2px;
   }
 
   span {
diff --git a/src/components/topic_index/topic_index.svelte b/src/components/topic_index/topic_index.svelte
deleted file mode 100644 (file)
index 3de83bb..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<script>
-  export let params;
-  import ErrorBlock from '../error_block/error_block.svelte';
-</script>
-
-<ErrorBlock />
-<h1>Topic Index.</h1>
-<p>This component lists topics for category or tag with id: {params.id}</p>
diff --git a/src/components/topic_summary/topic_summary.svelte b/src/components/topic_summary/topic_summary.svelte
new file mode 100644 (file)
index 0000000..deef3e2
--- /dev/null
@@ -0,0 +1,17 @@
+<script>
+  export let topic;
+
+  import { _ } from 'svelte-i18n';
+  import { readableTime } from '../../utils/readable_time.js';
+
+  $: remainingTime = (topic.updated_at + topic.ttl) - Date.now();
+  $: remaining = readableTime(remainingTime);
+</script>
+
+<li class="h-entry" title="{$_('topic.title')}">
+  <span class="p-name"><a class="u-url u-uid" title="{$_('topic.permalink_title')}" href="/t/{topic.id}">{topic.title}</a></span>
+  <span class="topic-ttl">({$_('topic.remaining_time', { values: { remaining: $_(remaining.label, { values: { count: remaining.count } }) } })})</span>
+</li>
+
+<style>
+</style>
diff --git a/src/config/apollo.js b/src/config/apollo.js
new file mode 100644 (file)
index 0000000..4cfca79
--- /dev/null
@@ -0,0 +1,9 @@
+import { ApolloClient, InMemoryCache } from '@apollo/client/core';
+import { apollo as apolloConfig } from './config';
+
+const cache = new InMemoryCache();
+
+export const client = new ApolloClient({
+  cache,
+  ...apolloConfig
+});
index 6d819a36d7ed24a884192103da0aa5864b87c859..0570e1cd312e85a22022daea96fc023a1a2ce694 100644 (file)
@@ -1,4 +1,4 @@
-import { version as packageVersion } from '../../package.json';
+import { name, version as packageVersion } from '../../package.json';
 
 /*
  * The main configuration object for the Forum frontend. These values
@@ -6,6 +6,12 @@ import { version as packageVersion } from '../../package.json';
  * file, otherwise it won't work.
  */
 
+export const apollo = {
+  uri: import.meta.env.VITE_APOLLO_SERVER,
+  name,
+  version: packageVersion
+};
+
 export const socketServer = import.meta.env.FORUM_SOCKET_SERVER;
 
 export const version = packageVersion;
index 0bcd782f2ae2b9b6056f22ee1330fc88814c0f73..1f3ff0cdf290d3bbeddb63ed0cf3d49341ac8e09 100644 (file)
@@ -1 +1 @@
-FORUM_SOCKET_SERVER=ws://location_of_socket_server
+VITE_APOLLO_SERVER=http://location_of_apollo_server
diff --git a/src/data/queries.js b/src/data/queries.js
new file mode 100644 (file)
index 0000000..de223cb
--- /dev/null
@@ -0,0 +1,29 @@
+import { gql } from '@apollo/client/core';
+
+export const GET_FORUMS = gql`
+  query GetForums {
+    forums {
+      id
+      glyph
+      label
+      position
+    }
+  }
+`;
+
+export const GET_FORUM = gql`
+  query GetForum($id: ID!) {
+    forum(id: $id) {
+      id
+      glyph
+      label
+      position
+      topics {
+        id
+        title,
+        updated_at,
+        ttl
+      }
+    }
+  }
+`;
diff --git a/src/forum.js b/src/forum.js
new file mode 100644 (file)
index 0000000..1e8ec25
--- /dev/null
@@ -0,0 +1,6 @@
+import HMR from '@roxi/routify/hmr';
+import Forum from './Forum.svelte';
+
+const app = HMR(Forum, { target: document.body }, 'forum');
+
+export default app;
index d2a6e1bc07dd7bb06b6eb46eb43f57fece1cf81c..0eb4b90182bff50450cdcbdad09b2e765e303c4e 100644 (file)
@@ -1,63 +1,6 @@
 <script>
-  import LightRouter from 'lightrouter';
-
-  // Initialize localization
-
-  import './config/i18n';
-
-  // Global components
-
-  import ForumList from './components/forum_list/forum_list.svelte';
-  import Header from './components/header/header.svelte';
-  import Footer from './components/footer/footer.svelte';
-
-  // Routed Components
-  import Author from './components/author/author.svelte';
-  import Home from './components/home/home.svelte';
-  import InvalidRoute from './components/invalid_route/invalid_route.svelte';
-  import Post from './components/post/post.svelte';
-  import Topic from './components/topic/topic.svelte';
-  import TopicIndex from './components/topic_index/topic_index.svelte';
-
-  let page;
-  let params;
-
-  // sets the route params and current page.
-
-  const setRoute = function setRoute(targetPage) {
-
-    return function (routerParams) {
-
-      params = routerParams;
-      page = targetPage;
-    };
-  };
-
-  const router = new LightRouter({
-    routes: {
-      '': () => (page = Home) && true,
-      'f/{id}': setRoute(TopicIndex),
-      'g/{id}': setRoute(TopicIndex),
-      'a/{id}': setRoute(Author),
-      't/{id}': setRoute(Topic),
-      'p/{id}': setRoute(Post),
-      '.*': setRoute(InvalidRoute)
-    }
-  });
-
-  router.run();
-
+  import { Router } from '@roxi/routify';
+  import { routes } from '../.routify/routes';
 </script>
 
-<Header />
-<main>
-  <svelte:component this={ page } params={ params } />
-</main>
-<ForumList />
-<Footer />
-
-<style>
-  main {
-    grid-column: col-start 2 / span 11;
-  }
-</style>
+<Router {routes} />
similarity index 87%
rename from src/routes/$layout.svelte
rename to src/pages/_layout.svelte
index a848a59fce3f79ffc03508c3973bfc695fe1ae7b..80cc29e61159466f06e402593a91a91740bfb246 100644 (file)
@@ -1,12 +1,6 @@
 <script>
   import '$config/i18n';
-  import { isLoading, waitLocale } from 'svelte-i18n';
-
-  export const load = function load() {
-
-    return waitLocale;
-  };
-
+  import { isLoading } from 'svelte-i18n';
   import ForumList from '$components/forum_list/forum_list.svelte';
   import Header from '$components/header/header.svelte';
   import Footer from '$components/footer/footer.svelte';
@@ -36,4 +30,8 @@
     grid-gap: 20px;
     grid-auto-rows: minmax(24px, auto);
   }
+
+  :global(body) {
+    background-color: whitesmoke;
+  }
 </style>
diff --git a/src/pages/a/[id].svelte b/src/pages/a/[id].svelte
new file mode 100644 (file)
index 0000000..9e6f184
--- /dev/null
@@ -0,0 +1,5 @@
+<script>
+  import Author from '$components/author/author.svelte';
+</script>
+
+<Author/>
diff --git a/src/pages/f/[id].svelte b/src/pages/f/[id].svelte
new file mode 100644 (file)
index 0000000..0251694
--- /dev/null
@@ -0,0 +1,6 @@
+<script>
+  import Forum from '$components/forum/forum.svelte';
+  export let id;
+</script>
+
+<Forum id={id}/>
diff --git a/src/pages/g/[id].svelte b/src/pages/g/[id].svelte
new file mode 100644 (file)
index 0000000..04fda92
--- /dev/null
@@ -0,0 +1,6 @@
+<script>
+  export let id;
+</script>
+
+<h1>Tag Index.</h1>
+<p>This component lists topics for tag with id: {id}</p>
diff --git a/src/pages/p/[id].svelte b/src/pages/p/[id].svelte
new file mode 100644 (file)
index 0000000..9caab6f
--- /dev/null
@@ -0,0 +1,5 @@
+<script>
+  import Post from '$components/post/post.svelte';
+</script>
+
+<Post/>
diff --git a/src/pages/t/[id].svelte b/src/pages/t/[id].svelte
new file mode 100644 (file)
index 0000000..3fd9560
--- /dev/null
@@ -0,0 +1,5 @@
+<script>
+  import Topic from '$components/topic/topic.svelte';
+</script>
+
+<Topic/>
diff --git a/src/routes/a/[id].svelte b/src/routes/a/[id].svelte
deleted file mode 100644 (file)
index 1b6c705..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<script>
-  export async function load(ctx) {
-    let id = ctx.page.params.id
-    return { props: { id }}
-  }
-
-  import Author from '$components/author/author.svelte';
-</script>
-
-<Author/>
diff --git a/src/routes/f/[id].svelte b/src/routes/f/[id].svelte
deleted file mode 100644 (file)
index d1fae4c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<script>
-  export async function load(ctx) {
-    let id = ctx.page.params.id
-    return { props: { id }}
-  }
-</script>
-
-<h1>Forum Index.</h1>
-<p>This component lists topics for forum with id: {id}</p>
diff --git a/src/routes/g/[id].svelte b/src/routes/g/[id].svelte
deleted file mode 100644 (file)
index d036c36..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<script>
-  export async function load(ctx) {
-    let id = ctx.page.params.id
-    return { props: { id }}
-  }
-</script>
-
-<h1>Tag Index.</h1>
-<p>This component lists topics for tag with id: {id}</p>
diff --git a/src/routes/p/[id].svelte b/src/routes/p/[id].svelte
deleted file mode 100644 (file)
index b8a8165..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<script>
-  export const load = function load(ctx) {
-
-    const id = ctx.page.params.id;
-    return { props: { id } };
-  };
-
-  import Post from '$components/post/post.svelte';
-</script>
-
-<Post/>
diff --git a/src/routes/t/[id].svelte b/src/routes/t/[id].svelte
deleted file mode 100644 (file)
index 8775cec..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<script>
-  export async function load(ctx) {
-    let id = ctx.page.params.id
-    return { props: { id }}
-  }
-
-  import Topic from '$components/topic/topic.svelte';
-</script>
-
-<Topic/>
diff --git a/src/stores/forum.js b/src/stores/forum.js
new file mode 100644 (file)
index 0000000..e7d335e
--- /dev/null
@@ -0,0 +1,39 @@
+import { ApolloError } from '@apollo/client/core';
+import { readable } from 'svelte/store';
+import { client } from '$config/apollo';
+import { GET_FORUM } from '$data/queries';
+
+const internals = {
+
+  // The exported data structure
+
+  initialValue: {
+    loading: true,
+    data: null,
+    error: undefined
+  }
+};
+
+export const getForum = function forum(id) {
+
+  return readable(internals.initialValue, (set) => {
+
+    client.watchQuery({ query: GET_FORUM, variables: { id } }).subscribe((result) => {
+
+      if (result.errors) {
+        const error = new ApolloError({ graphQLErrors: result.errors });
+        return set({
+          loading: false,
+          data: null,
+          error
+        });
+      }
+
+      set({
+        loading: false,
+        data: result.data.forum,
+        error: undefined
+      });
+    });
+  });
+};
index e7acb606cf536db7f227018da308eff532a3136f..ade01a7110e76ed0fa2c14d30e19ca7ba22d16e1 100644 (file)
@@ -1,36 +1,36 @@
+import { ApolloError } from '@apollo/client/core';
 import { readable } from 'svelte/store';
+import { client } from '$config/apollo';
+import { GET_FORUMS } from '$data/queries';
 
 const internals = {
 
-  // Constants
-
-  kChangeFeedEventName: 'changefeed:forums',
-
   // The exported data structure
 
-  forums: [],
-
-  // Handles messages from the event
-
-  handleChangeFeed(data) {
-
-    // No old value == add
-    if (!data.old_val) {
-      return internals.forums.push(data.new_val);
-    }
+  initialValue: {
+    loading: true,
+    data: [],
+    error: undefined
+  }
+};
 
-    // We have an old value, let's find it.
-    const index = internals.forums.findIndex((element) => element.id === data.old_val.id);
+export const forums = readable(internals.initialValue, (set) => {
 
-    if (index > -1) {
-      if (data.new_val) {
-        return internals.forums.splice(index, 1, data.new_val || undefined);
-      }
+  client.watchQuery({ query: GET_FORUMS }).subscribe((result) => {
 
-      return internals.forums.splice(index, 1);
+    if (result.errors) {
+      const error = new ApolloError({ graphQLErrors: result.errors });
+      return set({
+        loading: false,
+        data: [],
+        error
+      });
     }
-  }
-};
 
-export const forums = readable(internals.forums, (set) => {
+    set({
+      loading: false,
+      data: result.data.forums,
+      error: undefined
+    });
+  });
 });
diff --git a/src/utils/readable_time.js b/src/utils/readable_time.js
new file mode 100644 (file)
index 0000000..4476952
--- /dev/null
@@ -0,0 +1,38 @@
+const internals = {
+  magnitudes: {
+    day: 86400000,
+    hour: 3600000,
+    minute: 60000,
+    second: 1000
+  },
+  labels: {
+    day: 'time.days',
+    hour: 'time.hours',
+    minute: 'time.minutes',
+    second: 'time.seconds'
+  },
+
+  makeTimeReadable(time, magnitude) {
+
+    return {
+      count: Math.floor(time / internals.magnitudes[magnitude]),
+      label: internals.labels[magnitude]
+    };
+  }
+};
+
+export const readableTime = function readableTime(time) {
+
+  switch (true) {
+  case time >= internals.magnitudes.day:
+    return internals.makeTimeReadable(time, 'day');
+  case time >= internals.magnitudes.hour:
+    return internals.makeTimeReadable(time, 'hour');
+  case time >= internals.magnitudes.minute:
+    return internals.makeTimeReadable(time, 'minute');
+  case time < 0:
+    return internals.makeTimeReadable(0, 'second');
+  default:
+    return internals.makeTimeReadable(time, 'second');
+  }
+};
diff --git a/svelte.config.cjs b/svelte.config.cjs
deleted file mode 100644 (file)
index cf7a842..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = {
-       kit: {
-               // By default, `npm run build` will create a standard Node app.
-               // You can create optimized builds for different platforms by
-               // specifying a different adapter
-               adapter: '@sveltejs/adapter-node',
-
-               // hydrate the <div id="forum"> element in src/app.html
-               target: '#forum'
-       }
-};
index e4b56a21767205a6a22885ee31fbc826ab676086..f73988179f1aa8b728b0c8a6fd45c8c5d1609abf 100644 (file)
@@ -1,11 +1,22 @@
 // Consult https://vitejs.dev/config/ to learn about these options
 import { resolve } from 'path';
+import Svelte from '@sveltejs/vite-plugin-svelte';
 
 export default {
+  optimizeDeps: {
+    exclude: ['@roxi/routify']
+  },
+  plugins: [
+    Svelte({
+      emitCss: true
+    })
+  ],
   resolve: {
     alias: {
       $components: resolve('src/components'),
-      $config: resolve('src/config')
+      $config: resolve('src/config'),
+      $data: resolve('src/data'),
+      $stores: resolve('src/stores')
     }
   }
 };