diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 00000000..31354ec1
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 00000000..e76d78ff
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+yarn pre-commit
\ No newline at end of file
diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity
deleted file mode 100644
index 000c1a86..00000000
--- a/node_modules/.yarn-integrity
+++ /dev/null
@@ -1,142 +0,0 @@
-{
- "systemParams": "darwin-x64-93",
- "modulesFolders": [
- "node_modules"
- ],
- "flags": [],
- "linkedModules": [],
- "topLevelPatterns": [
- "gh-pages@^3.2.3",
- "react-markdown@^8.0.0",
- "react-router-dom@6"
- ],
- "lockfileEntries": {
- "@babel/runtime@^7.7.6": "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941",
- "@types/debug@^4.0.0": "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82",
- "@types/hast@^2.0.0": "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc",
- "@types/mdast@^3.0.0": "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af",
- "@types/mdurl@^1.0.0": "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9",
- "@types/ms@*": "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197",
- "@types/unist@*": "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d",
- "@types/unist@^2.0.0": "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d",
- "array-union@^1.0.1": "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39",
- "array-uniq@^1.0.1": "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6",
- "async@^2.6.1": "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff",
- "bail@^2.0.0": "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d",
- "balanced-match@^1.0.0": "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee",
- "brace-expansion@^1.1.7": "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd",
- "character-entities@^2.0.0": "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.1.tgz#98724833e1e27990dee0bd0f2b8a859c3476aac7",
- "comma-separated-tokens@^2.0.0": "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98",
- "commander@^2.18.0": "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33",
- "commondir@^1.0.1": "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b",
- "concat-map@0.0.1": "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b",
- "debug@^4.0.0": "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664",
- "decode-named-character-reference@^1.0.0": "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz#57b2bd9112659cacbc449d3577d7dadb8e1f3d1b",
- "dequal@^2.0.0": "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d",
- "diff@^5.0.0": "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b",
- "email-addresses@^3.0.1": "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.1.0.tgz#cabf7e085cbdb63008a70319a74e6136188812fb",
- "escape-string-regexp@^1.0.2": "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4",
- "extend@^3.0.0": "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa",
- "filename-reserved-regex@^2.0.0": "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229",
- "filenamify@^4.3.0": "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106",
- "find-cache-dir@^3.3.1": "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b",
- "find-up@^4.0.0": "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19",
- "fs-extra@^8.1.0": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0",
- "fs.realpath@^1.0.0": "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f",
- "gh-pages@^3.2.3": "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.2.3.tgz#897e5f15e111f42af57d21d430b83e5cdf29472c",
- "glob@^7.0.3": "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023",
- "globby@^6.1.0": "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c",
- "graceful-fs@^4.1.6": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96",
- "graceful-fs@^4.2.0": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96",
- "hast-util-whitespace@^2.0.0": "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz#4fc1086467cc1ef5ba20673cb6b03cec3a970f1c",
- "history@^5.2.0": "https://registry.yarnpkg.com/history/-/history-5.2.0.tgz#7cdd31cf9bac3c5d31f09c231c9928fad0007b7c",
- "inflight@^1.0.4": "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9",
- "inherits@2": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c",
- "inline-style-parser@0.1.1": "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1",
- "is-buffer@^2.0.0": "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191",
- "is-plain-obj@^4.0.0": "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.0.0.tgz#06c0999fd7574edf5a906ba5644ad0feb3a84d22",
- "js-tokens@^3.0.0 || ^4.0.0": "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499",
- "jsonfile@^4.0.0": "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb",
- "kleur@^4.0.3": "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d",
- "locate-path@^5.0.0": "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0",
- "lodash@^4.17.14": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c",
- "loose-envify@^1.4.0": "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf",
- "make-dir@^3.0.2": "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f",
- "mdast-util-definitions@^5.0.0": "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.0.tgz#b6d10ef00a3c4cf191e8d9a5fa58d7f4a366f817",
- "mdast-util-from-markdown@^1.0.0": "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz#84df2924ccc6c995dec1e2368b2b208ad0a76268",
- "mdast-util-to-hast@^12.1.0": "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.1.1.tgz#89a2bb405eaf3b05eb8bf45157678f35eef5dbca",
- "mdast-util-to-string@^3.1.0": "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9",
- "mdurl@^1.0.0": "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e",
- "micromark-core-commonmark@^1.0.1": "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad",
- "micromark-factory-destination@^1.0.0": "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e",
- "micromark-factory-label@^1.0.0": "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137",
- "micromark-factory-space@^1.0.0": "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633",
- "micromark-factory-title@^1.0.0": "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f",
- "micromark-factory-whitespace@^1.0.0": "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c",
- "micromark-util-character@^1.0.0": "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86",
- "micromark-util-chunked@^1.0.0": "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06",
- "micromark-util-classify-character@^1.0.0": "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20",
- "micromark-util-combine-extensions@^1.0.0": "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5",
- "micromark-util-decode-numeric-character-reference@^1.0.0": "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946",
- "micromark-util-decode-string@^1.0.0": "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02",
- "micromark-util-encode@^1.0.0": "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383",
- "micromark-util-html-tag-name@^1.0.0": "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz#75737e92fef50af0c6212bd309bc5cb8dbd489ed",
- "micromark-util-normalize-identifier@^1.0.0": "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828",
- "micromark-util-resolve-all@^1.0.0": "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88",
- "micromark-util-sanitize-uri@^1.0.0": "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz#27dc875397cd15102274c6c6da5585d34d4f12b2",
- "micromark-util-subtokenize@^1.0.0": "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105",
- "micromark-util-symbol@^1.0.0": "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e",
- "micromark-util-types@^1.0.0": "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20",
- "micromark-util-types@^1.0.1": "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20",
- "micromark@^3.0.0": "https://registry.yarnpkg.com/micromark/-/micromark-3.0.10.tgz#1eac156f0399d42736458a14b0ca2d86190b457c",
- "minimatch@^3.0.4": "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b",
- "mri@^1.1.0": "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b",
- "ms@2.1.2": "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009",
- "object-assign@^4.0.1": "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863",
- "object-assign@^4.1.1": "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863",
- "once@^1.3.0": "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1",
- "p-limit@^2.2.0": "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1",
- "p-locate@^4.1.0": "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07",
- "p-try@^2.0.0": "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6",
- "path-exists@^4.0.0": "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3",
- "path-is-absolute@^1.0.0": "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f",
- "pify@^2.0.0": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c",
- "pinkie-promise@^2.0.0": "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa",
- "pinkie@^2.0.0": "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870",
- "pkg-dir@^4.1.0": "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3",
- "prop-types@^15.0.0": "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5",
- "property-information@^6.0.0": "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22",
- "react-is@^16.13.1": "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4",
- "react-is@^17.0.0": "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0",
- "react-markdown@^8.0.0": "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.0.tgz#3243296a59ddb0f451d262cc2e11123674b416c2",
- "react-router-dom@6": "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec",
- "react-router@6.2.1": "https://registry.yarnpkg.com/react-router/-/react-router-6.2.1.tgz#be2a97a6006ce1d9123c28934e604faef51448a3",
- "regenerator-runtime@^0.13.4": "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52",
- "remark-parse@^10.0.0": "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775",
- "remark-rehype@^10.0.0": "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279",
- "sade@^1.7.3": "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701",
- "semver@^6.0.0": "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
- "space-separated-tokens@^2.0.0": "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b",
- "strip-outer@^1.0.1": "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631",
- "style-to-object@^0.3.0": "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46",
- "trim-repeated@^1.0.0": "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21",
- "trough@^2.0.0": "https://registry.yarnpkg.com/trough/-/trough-2.0.2.tgz#94a3aa9d5ce379fc561f6244905b3f36b7458d96",
- "unified@^10.0.0": "https://registry.yarnpkg.com/unified/-/unified-10.1.1.tgz#345e349e3ab353ab612878338eb9d57b4dea1d46",
- "unist-builder@^3.0.0": "https://registry.yarnpkg.com/unist-builder/-/unist-builder-3.0.0.tgz#728baca4767c0e784e1e64bb44b5a5a753021a04",
- "unist-util-generated@^2.0.0": "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113",
- "unist-util-is@^5.0.0": "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236",
- "unist-util-position@^4.0.0": "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.1.tgz#f8484b2da19a897a0180556d160c28633070dbb9",
- "unist-util-stringify-position@^3.0.0": "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz#d517d2883d74d0daa0b565adc3d10a02b4a8cde9",
- "unist-util-visit-parents@^4.0.0": "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz#e83559a4ad7e6048a46b1bdb22614f2f3f4724f2",
- "unist-util-visit-parents@^5.0.0": "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521",
- "unist-util-visit@^3.0.0": "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-3.1.0.tgz#9420d285e1aee938c7d9acbafc8e160186dbaf7b",
- "unist-util-visit@^4.0.0": "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5",
- "universalify@^0.1.0": "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66",
- "uvu@^0.5.0": "https://registry.yarnpkg.com/uvu/-/uvu-0.5.3.tgz#3d83c5bc1230f153451877bfc7f4aea2392219ae",
- "vfile-message@^3.0.0": "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.0.tgz#5437035aa43185ff4b9210d32fada6c640e59143",
- "vfile@^5.0.0": "https://registry.yarnpkg.com/vfile/-/vfile-5.3.0.tgz#4990c78cb3157005590ee8c930b71cd7fa6a006e",
- "wrappy@1": "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- },
- "files": [],
- "artifacts": {}
-}
\ No newline at end of file
diff --git a/package.json b/package.json
index a4fb29dc..5cb4dcca 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,13 @@
"react-markdown": "^8.0.0",
"react-router-dom": "6"
},
+ "devDependencies": {
+ "husky": "5.1.3"
+ },
"scripts": {
- "predeploy": "cd packages/app && npm run build",
- "deploy": "cd packages/app && gh-pages -d build"
+ "predeploy": "yarn --cwd packages/app yarn run build",
+ "deploy": "yarn --cwd packages/app yarn deploy",
+ "prepare": "husky install",
+ "pre-commit": "yarn --cwd packages/app pre-commit && yarn --cwd packages/subgraph pre-commit"
}
}
diff --git a/packages/app/package.json b/packages/app/package.json
index ce08a180..07538c32 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -19,12 +19,14 @@
"web-vitals": "^2.1.0"
},
"scripts": {
- "predeploy": "npm run build",
+ "predeploy": "yarn run build",
"deploy": "gh-pages -d build",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
- "eject": "react-scripts eject"
+ "eject": "react-scripts eject",
+ "fmt": "prettier '(test|src)/**/*.(ts|tsx)' -w",
+ "pre-commit": "yarn fmt"
},
"eslintConfig": {
"extends": [
@@ -43,5 +45,8 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "prettier": "^2.5.1"
}
}
diff --git a/packages/app/src/App.test.tsx b/packages/app/src/App.test.tsx
index 2a68616d..d76787ed 100644
--- a/packages/app/src/App.test.tsx
+++ b/packages/app/src/App.test.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import App from './App';
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import App from "./App";
-test('renders learn react link', () => {
+test("renders learn react link", () => {
render();
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
diff --git a/packages/app/src/reportWebVitals.ts b/packages/app/src/reportWebVitals.ts
index 49a2a16e..5fa3583b 100644
--- a/packages/app/src/reportWebVitals.ts
+++ b/packages/app/src/reportWebVitals.ts
@@ -1,8 +1,8 @@
-import { ReportHandler } from 'web-vitals';
+import { ReportHandler } from "web-vitals";
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
diff --git a/packages/app/src/setupTests.ts b/packages/app/src/setupTests.ts
index 8f2609b7..1dd407a6 100644
--- a/packages/app/src/setupTests.ts
+++ b/packages/app/src/setupTests.ts
@@ -2,4 +2,4 @@
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
+import "@testing-library/jest-dom";
diff --git a/packages/app/yarn.lock b/packages/app/yarn.lock
index 52d2bbff..cd351cbd 100644
--- a/packages/app/yarn.lock
+++ b/packages/app/yarn.lock
@@ -6957,6 +6957,11 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
+prettier@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
+ integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
+
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
version "5.6.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
diff --git a/packages/subgraph/.prettierrc b/packages/subgraph/.prettierrc
new file mode 100644
index 00000000..7866c46c
--- /dev/null
+++ b/packages/subgraph/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "printWidth": 120,
+ "trailingComma": "all",
+ "singleQuote": false,
+ "semi": false
+}
diff --git a/packages/subgraph/example.json b/packages/subgraph/example.json
index d5560760..c94a981c 100644
--- a/packages/subgraph/example.json
+++ b/packages/subgraph/example.json
@@ -1,4 +1,5 @@
{
+
"article": "QmeoVkGPKXQznziD53rYrV4v1MRoMTpxJkRqJjutCZrQ4t",
"authors": ["Auryn", "Sam"],
"tags": ["Lorem Ipsum"],
diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json
index ac117300..3a4db0e7 100644
--- a/packages/subgraph/package.json
+++ b/packages/subgraph/package.json
@@ -7,10 +7,16 @@
"deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ tabula",
"create-local": "graph create --node http://localhost:8020/ tabula",
"remove-local": "graph remove --node http://localhost:8020/ tabula",
- "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 tabula"
+ "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 tabula",
+ "fmt": "prettier '(test|src)/**/*.ts' -w",
+ "pre-commit": "yarn fmt"
},
"dependencies": {
"@graphprotocol/graph-cli": "0.27.0",
"@graphprotocol/graph-ts": "0.25.0"
+ },
+ "devDependencies": {
+ "matchstick-as": "^0.4.0",
+ "prettier": "^2.5.1"
}
}
diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql
index 912c508b..e2487853 100644
--- a/packages/subgraph/schema.graphql
+++ b/packages/subgraph/schema.graphql
@@ -8,5 +8,5 @@ type Post @entity {
tags: [String!]! # array of tags
title: String! # title of the post
description: String! # description of the post
- previewImage: String # IPFS hash of the preview image for the post
+ image: String # IPFS hash of the preview image for the post
}
diff --git a/packages/subgraph/src/mapping.ts b/packages/subgraph/src/mapping.ts
index 7226050c..d3991017 100644
--- a/packages/subgraph/src/mapping.ts
+++ b/packages/subgraph/src/mapping.ts
@@ -1,62 +1,58 @@
-import { BigInt, Bytes, crypto, ipfs } from "@graphprotocol/graph-ts";
-import { Poster, NewPost } from "../generated/Poster/Poster";
-import { Post } from "../generated/schema";
-import { json, JSONValueKind } from "@graphprotocol/graph-ts";
-import { jsonToString, jsonToArrayString } from "./utils";
+import { BigInt, Bytes, crypto, ipfs } from "@graphprotocol/graph-ts"
+import { Poster, NewPost } from "../generated/Poster/Poster"
+import { Post } from "../generated/schema"
+import { json, JSONValueKind } from "@graphprotocol/graph-ts"
+import { jsonToString, jsonToArrayString } from "./utils"
export function handleNewPost(event: NewPost): void {
// decode json content, fail gracefully.
- let contentData = json.try_fromString(event.params.content);
+ let contentData = json.try_fromString(event.params.content)
if (contentData.isError) {
- return;
+ return
}
- let content = contentData.value.toObject();
+ let content = contentData.value.toObject()
// Load post entity
- let post = Post.load(
- event.transaction.hash.toHex() + "-" + event.logIndex.toString()
- );
+ let post = Post.load(event.transaction.hash.toHex() + "-" + event.logIndex.toString())
// create new entity if it doesn't already exist
if (!post) {
- post = new Post(
- event.transaction.hash.toHex() + "-" + event.logIndex.toString()
- );
+ post = new Post(event.transaction.hash.toHex() + "-" + event.logIndex.toString())
}
// Set user
- post.publisher = event.params.user;
+ post.publisher = event.params.user
// Fetch article article from IPFS, fail gracefully.
- let article = ipfs.cat(jsonToString(content.get("article")));
+ let article = ipfs.cat(jsonToString(content.get("article")))
if (!article) {
- post.article = jsonToString(content.get("article"));
+ post.article = jsonToString(content.get("article"))
} else {
- post.article = article.toString();
+ post.article = article.toString()
}
// Set article
// post.article = jsonToString(content.get("article"));
// Set authors
- post.authors = jsonToArrayString(content.get("authors"));
+ post.authors = jsonToArrayString(content.get("authors"))
// Set postedOn timestamp
- post.postedOn = event.block.timestamp;
+ post.postedOn = event.block.timestamp
// Set lastUpdated timestamp
- post.lastUpdated = event.block.timestamp;
+ post.lastUpdated = event.block.timestamp
// Set tags
- post.tags = jsonToArrayString(content.get("tags"));
+ post.tags = jsonToArrayString(content.get("tags"))
// Set title
- post.title = jsonToString(content.get("title"));
+ post.title = jsonToString(content.get("title"))
// Set description
- post.description = jsonToString(content.get("description"));
+ post.description = jsonToString(content.get("description"))
// Set image
- post.image = jsonToString(content.get("image"));
+ post.image = jsonToString(content.get("image"))
// Safe updates to store
- post.save();
+ post.save()
}
diff --git a/packages/subgraph/src/utils.ts b/packages/subgraph/src/utils.ts
index 87b9e9f0..d6f4288a 100644
--- a/packages/subgraph/src/utils.ts
+++ b/packages/subgraph/src/utils.ts
@@ -1,4 +1,4 @@
-import { JSONValue, JSONValueKind } from "@graphprotocol/graph-ts";
+import { JSONValue, JSONValueKind } from "@graphprotocol/graph-ts"
/**
* Make sure the given JSONValue is a string and returns string it contains.
@@ -6,9 +6,9 @@ import { JSONValue, JSONValueKind } from "@graphprotocol/graph-ts";
*/
export function jsonToString(val: JSONValue | null): string {
if (val != null && val.kind === JSONValueKind.STRING) {
- return val.toString();
+ return val.toString()
}
- return "";
+ return ""
}
/**
@@ -18,13 +18,12 @@ export function jsonToString(val: JSONValue | null): string {
*/
export function jsonToArrayString(val: JSONValue | null): Array {
if (val != null && val.kind === JSONValueKind.ARRAY) {
- let valArray = val.toArray();
- let result: Array = new Array();
+ let valArray = val.toArray()
+ let result: Array = new Array()
for (let i = 0; i < valArray.length; i++) {
- if (valArray[i].kind === JSONValueKind.STRING)
- result.push(valArray[i].toString());
+ if (valArray[i].kind === JSONValueKind.STRING) result.push(valArray[i].toString())
}
- return result;
+ return result
}
- return [];
+ return []
}
diff --git a/packages/subgraph/yarn.lock b/packages/subgraph/yarn.lock
index d92a79a3..e0363655 100644
--- a/packages/subgraph/yarn.lock
+++ b/packages/subgraph/yarn.lock
@@ -244,6 +244,13 @@
dependencies:
assemblyscript "0.19.10"
+"@graphprotocol/graph-ts@^0.24.1":
+ version "0.24.1"
+ resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.24.1.tgz#50961b52b5383f9c5cf5e6e23fa039f24e729ddf"
+ integrity sha512-2vU4m5ZPQIqMlMce/z5vmOtGHRlRmcRhMfemS3NIwxCSxSBGVnX2zb7QBTzzdQKGwsAZdbz6V0okkOtvohELfQ==
+ dependencies:
+ assemblyscript "0.19.10"
+
"@types/bn.js@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68"
@@ -460,6 +467,15 @@ assemblyscript@0.19.10:
binaryen "101.0.0-nightly.20210723"
long "^4.0.0"
+assemblyscript@^0.19.20:
+ version "0.19.23"
+ resolved "https://registry.yarnpkg.com/assemblyscript/-/assemblyscript-0.19.23.tgz#16ece69f7f302161e2e736a0f6a474e6db72134c"
+ integrity sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==
+ dependencies:
+ binaryen "102.0.0-nightly.20211028"
+ long "^5.2.0"
+ source-map-support "^0.5.20"
+
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
@@ -547,6 +563,11 @@ binaryen@101.0.0-nightly.20210723:
resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz#b6bb7f3501341727681a03866c0856500eec3740"
integrity sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==
+binaryen@102.0.0-nightly.20211028:
+ version "102.0.0-nightly.20211028"
+ resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-102.0.0-nightly.20211028.tgz#8f1efb0920afd34509e342e37f84313ec936afb2"
+ integrity sha512-GCJBVB5exbxzzvyt8MGDv/MeUjs6gkXDvf4xOIItRBptYl0Tz5sm1o/uG95YK0L0VeG5ajDu3hRtkBP2kzqC5w==
+
bindings@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
@@ -1390,9 +1411,9 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
-"gluegun@git+https://github.com/edgeandnode/gluegun.git#v4.3.1-pin-colors-dep":
+"gluegun@https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep":
version "4.3.1"
- resolved "git+https://github.com/edgeandnode/gluegun.git#b34b9003d7bf556836da41b57ef36eb21570620a"
+ resolved "https://github.com/edgeandnode/gluegun#b34b9003d7bf556836da41b57ef36eb21570620a"
dependencies:
apisauce "^1.0.1"
app-module-path "^2.2.0"
@@ -2108,6 +2129,11 @@ long@^4.0.0:
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
+long@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61"
+ integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==
+
looper@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749"
@@ -2141,6 +2167,15 @@ mafmt@^7.0.0:
dependencies:
multiaddr "^7.3.0"
+matchstick-as@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/matchstick-as/-/matchstick-as-0.4.0.tgz#7456c2f20abee6d12366b65f4216385a9ef62a50"
+ integrity sha512-XkWoXQWUg1ms8DaDMkl2M95woGPB89f7aysjwDNst/x+G9FV48dxcAKSwilJ1BVGV3MqU7HfuKGHxegSsuxQxQ==
+ dependencies:
+ "@graphprotocol/graph-ts" "^0.24.1"
+ assemblyscript "^0.19.20"
+ wabt "1.0.24"
+
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -2602,6 +2637,11 @@ prettier@1.19.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
+prettier@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
+ integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -2948,6 +2988,19 @@ signed-varint@^2.0.1:
dependencies:
varint "~5.0.0"
+source-map-support@^0.5.20:
+ version "0.5.21"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map@^0.6.0:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
split-ca@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6"
@@ -3272,6 +3325,11 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+wabt@1.0.24:
+ version "1.0.24"
+ resolved "https://registry.yarnpkg.com/wabt/-/wabt-1.0.24.tgz#c02e0b5b4503b94feaf4a30a426ef01c1bea7c6c"
+ integrity sha512-8l7sIOd3i5GWfTWciPL0+ff/FK/deVK2Q6FN+MPz4vfUcD78i2M/49XJTwF6aml91uIiuXJEsLKWMB2cw/mtKg==
+
wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
diff --git a/yarn.lock b/yarn.lock
index ac80b0b6..7d9235e6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -244,6 +244,11 @@ history@^5.2.0:
dependencies:
"@babel/runtime" "^7.7.6"
+husky@5.1.3:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/husky/-/husky-5.1.3.tgz#1a0645a4fe3ffc006c4d0d8bd0bcb4c98787cc9d"
+ integrity sha512-fbNJ+Gz5wx2LIBtMweJNY1D7Uc8p1XERi5KNRMccwfQA+rXlxWNSdUxswo0gT8XqxywTIw7Ywm/F4v/O35RdMg==
+
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"