Repository: joinmarket-webui/joinmarket-webui
Pull request #176 (2022-03-15 13:09:20)

Add typescript support
This commit adds typescript support (`.ts`/`.tsx`).

- called `npm install --save-dev typescript @types/node @types/react @types/react-dom @types/jest`
- created `tsconfig.json` with `npx tsc --init`
- ~~added missing `include` option to `tsconfig.json`~~
- added `jsx: "react-jsx"` ~~and `noImplicitAny: false`~~ to `compilerOptions` in `tsconfig.json`

##### Examples
- ported `libs/JmWalletApi.js` to `libs/JmWalletApi.ts` and added exemplary types
- ported helper `session.js` to `session.ts`
- ported component `CurrentWalletAdvanced.jsx` to `CurrentWalletAdvanced.tsx`

This was just to easy... everything seems to work quite smoothly - I might be missing something (?)..

theborakompanioni: > Maybe remove the commented out stuff from the config file?

:heavy_check_mark: 

Still have some issues with destructing object params, but I guess nothing that cannot be fixed.
Will ping you once progress is made and the PR is ready.

theborakompanioni: 
> Awesome, sounds good!


This is now ready to the point where it has a couple of examples and a base that can be built upon. Is it okay for you if we implement this step by step? I did not want to start a full refactoring. It would be very helpful already in PR #175 .

Some shortcuts have been taken, as I just wanted to showcase at least porting one utils, one component and one test file.
e.g. `type` definitions of `Utxos` and `Alert` in `CurrentWalletAdvanced` are misplaced and must be adapted and move in the future.

Patch:
diff --git a/package-lock.json b/package-lock.json
index 76efac8..73de03c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,31 +13,36 @@
         "serve": "13.0.2"
       },
       "devDependencies": {
-        "@popperjs/core": "^2.11.2",
-        "@testing-library/jest-dom": "^5.16.1",
-        "@testing-library/react": "^12.1.2",
+        "@popperjs/core": "^2.11.4",
+        "@testing-library/jest-dom": "^5.16.2",
+        "@testing-library/react": "^12.1.4",
         "@testing-library/user-event": "^13.5.0",
+        "@types/jest": "^27.4.1",
+        "@types/node": "^17.0.21",
+        "@types/react": "^17.0.40",
+        "@types/react-dom": "^17.0.13",
         "bootstrap": "^5.1.3",
         "buffer": "^6.0.3",
         "conventional-changelog": "^3.1.25",
-        "http-proxy-middleware": "^2.0.1",
+        "http-proxy-middleware": "^2.0.4",
         "husky": "^7.0.4",
-        "i18next": "^21.6.12",
+        "i18next": "^21.6.14",
         "i18next-browser-languagedetector": "^6.1.3",
         "jest-watch-typeahead": "^0.6.5",
         "jest-websocket-mock": "^2.3.0",
-        "lint-staged": "^12.3.1",
+        "lint-staged": "^12.3.6",
         "moving-letters": "^1.0.1",
         "nth-check": ">=2.0.1",
-        "prettier": "^2.5.1",
+        "prettier": "^2.6.0",
         "qrcode": "^1.5.0",
         "react": "^17.0.2",
-        "react-bootstrap": "^2.1.1",
+        "react-bootstrap": "^2.2.1",
         "react-dom": "^17.0.2",
-        "react-i18next": "^11.15.5",
-        "react-router-bootstrap": "^0.26.0",
-        "react-router-dom": "^6.2.1",
+        "react-i18next": "^11.15.7",
+        "react-router-bootstrap": "^0.26.1",
+        "react-router-dom": "^6.2.2",
         "react-scripts": "^5.0.0",
+        "typescript": "^4.6.2",
         "web-vitals": "^2.1.4"
       },
       "engines": {
@@ -1964,9 +1969,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.16.5",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-      "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
+      "version": "7.17.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.7.tgz",
+      "integrity": "sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==",
       "dev": true,
       "dependencies": {
         "regenerator-runtime": "^0.13.4"
@@ -2624,21 +2629,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/@jest/types": {
-      "version": "26.6.2",
-      "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^15.0.0",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2675,9 +2665,9 @@
       }
     },
     "node_modules/@popperjs/core": {
-      "version": "2.11.2",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz",
-      "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==",
+      "version": "2.11.4",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz",
+      "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==",
       "dev": true,
       "funding": {
         "type": "opencollective",
@@ -2685,9 +2675,9 @@
       }
     },
     "node_modules/@react-aria/ssr": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.0.tgz",
-      "integrity": "sha512-RxqQKmE8sO7TGdrcSlHTcVzMP450hqowtBSd2bBS9oPlcokVkaGq28c3Rwa8ty5ctw4EBCjXqjP7xdcKMGDzug==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.2.tgz",
+      "integrity": "sha512-amXY11ImpokvkTMeKRHjsSsG7v1yzzs6yeqArCyBIk60J3Yhgxwx9Cah+Uu/804ATFwqzN22AXIo7SdtIaMP+g==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.6.2"
@@ -2709,9 +2699,9 @@
       }
     },
     "node_modules/@restart/ui": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-0.2.5.tgz",
-      "integrity": "sha512-3dP8pMFickPpvAG5MVQW53HnJl0c17h7MwvI4nNy9QF66sHSYVchudlqlI8eOSaqnmc5YVjGura63vMb9LTNbQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.0.2.tgz",
+      "integrity": "sha512-vKGe0UBJLnbvNAjr8ljlDvphf2HkpjBjXsblmgKPvKdZBDn/mtAz89wmznaomIaEJ9VNoSEY0vA5T5MDi2jIcQ==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.13.16",
@@ -3070,40 +3060,6 @@
         "node": ">=12"
       }
     },
-    "node_modules/@testing-library/dom/node_modules/@jest/types": {
-      "version": "27.2.5",
-      "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^16.0.0",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/@testing-library/dom/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-      "dev": true,
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/@testing-library/dom/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/@testing-library/dom/node_modules/aria-query": {
       "version": "5.0.0",
       "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==",
@@ -3117,29 +3073,10 @@
       "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==",
       "dev": true
     },
-    "node_modules/@testing-library/dom/node_modules/pretty-format": {
-      "version": "27.3.1",
-      "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.2.5",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/@testing-library/dom/node_modules/react-is": {
-      "version": "17.0.2",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/@testing-library/jest-dom": {
-      "version": "5.16.1",
-      "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz",
-      "integrity": "sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==",
+      "version": "5.16.2",
+      "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz",
+      "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.9.2",
@@ -3180,12 +3117,14 @@
       }
     },
     "node_modules/@testing-library/react": {
-      "version": "12.1.2",
-      "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==",
+      "version": "12.1.4",
+      "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz",
+      "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.12.5",
-        "@testing-library/dom": "^8.0.0"
+        "@testing-library/dom": "^8.0.0",
+        "@types/react-dom": "*"
       },
       "engines": {
         "node": ">=12"
@@ -3377,9 +3316,9 @@
       "dev": true
     },
     "node_modules/@types/http-proxy": {
-      "version": "1.17.7",
-      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
-      "integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==",
+      "version": "1.17.8",
+      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz",
+      "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
@@ -3412,12 +3351,13 @@
       }
     },
     "node_modules/@types/jest": {
-      "version": "26.0.24",
-      "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
+      "version": "27.4.1",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz",
+      "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==",
       "dev": true,
       "dependencies": {
-        "jest-diff": "^26.0.0",
-        "pretty-format": "^26.0.0"
+        "jest-matcher-utils": "^27.0.0",
+        "pretty-format": "^27.0.0"
       }
     },
     "node_modules/@types/json-schema": {
@@ -3445,8 +3385,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "16.4.10",
-      "integrity": "sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ==",
+      "version": "17.0.21",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
+      "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
       "dev": true
     },
     "node_modules/@types/normalize-package-data": {
@@ -3489,8 +3430,9 @@
       "dev": true
     },
     "node_modules/@types/react": {
-      "version": "17.0.19",
-      "integrity": "sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==",
+      "version": "17.0.40",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz",
+      "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==",
       "dev": true,
       "dependencies": {
         "@types/prop-types": "*",
@@ -3498,9 +3440,19 @@
         "csstype": "^3.0.2"
       }
     },
+    "node_modules/@types/react-dom": {
+      "version": "17.0.13",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz",
+      "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
     "node_modules/@types/react-transition-group": {
-      "version": "4.4.2",
-      "integrity": "sha512-KibDWL6nshuOJ0fu8ll7QnV/LVTo3PzQ9aCPnRUYPfX7eZohHwLIdNHj7pftanREzHNP4/nJa8oeM73uSiavMQ==",
+      "version": "4.4.4",
+      "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz",
+      "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==",
       "dev": true,
       "dependencies": {
         "@types/react": "*"
@@ -3589,14 +3541,6 @@
         "@types/node": "*"
       }
     },
-    "node_modules/@types/yargs": {
-      "version": "15.0.14",
-      "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
     "node_modules/@types/yargs-parser": {
       "version": "20.2.1",
       "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
@@ -4143,8 +4087,6 @@
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
       "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
       "dev": true,
-      "optional": true,
-      "peer": true,
       "dependencies": {
         "fast-deep-equal": "^3.1.1",
         "json-schema-traverse": "^1.0.0",
@@ -4160,9 +4102,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
       "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "optional": true,
-      "peer": true
+      "dev": true
     },
     "node_modules/ajv-keywords": {
       "version": "3.5.2",
@@ -6826,14 +6766,6 @@
       "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
       "dev": true
     },
-    "node_modules/diff-sequences": {
-      "version": "26.6.2",
-      "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
-      "dev": true,
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
     "node_modules/dijkstrajs": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.2.tgz",
@@ -9056,9 +8988,9 @@
       }
     },
     "node_modules/history": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
-      "integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
+      "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.7.6"
@@ -9278,12 +9210,12 @@
       }
     },
     "node_modules/http-proxy-middleware": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz",
-      "integrity": "sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz",
+      "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==",
       "dev": true,
       "dependencies": {
-        "@types/http-proxy": "^1.17.5",
+        "@types/http-proxy": "^1.17.8",
         "http-proxy": "^1.18.1",
         "is-glob": "^4.0.1",
         "is-plain-obj": "^3.0.0",
@@ -9291,6 +9223,14 @@
       },
       "engines": {
         "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "@types/express": "^4.17.13"
+      },
+      "peerDependenciesMeta": {
+        "@types/express": {
+          "optional": true
+        }
       }
     },
     "node_modules/http-proxy-middleware/node_modules/is-plain-obj": {
@@ -9343,9 +9283,9 @@
       }
     },
     "node_modules/i18next": {
-      "version": "21.6.12",
-      "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.12.tgz",
-      "integrity": "sha512-xlGTPdu2g5PZEUIE6TA1mQ9EIAAv9nMFONzgwAIrKL/KTmYYWufQNGgOmp5Og1PvgUji+6i1whz0rMdsz1qaKw==",
+      "version": "21.6.14",
+      "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.14.tgz",
+      "integrity": "sha512-XL6WyD+xlwQwbieXRlXhKWoLb/rkch50/rA+vl6untHnJ+aYnkQ0YDZciTWE78PPhOpbi2gR0LTJCJpiAhA+uQ==",
       "dev": true,
       "funding": [
         {
@@ -9362,7 +9302,7 @@
         }
       ],
       "dependencies": {
-        "@babel/runtime": "^7.12.0"
+        "@babel/runtime": "^7.17.2"
       }
     },
     "node_modules/i18next-browser-languagedetector": {
@@ -10310,39 +10250,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-circus/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-circus/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-circus/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-cli": {
       "version": "27.4.5",
       "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz",
@@ -10468,18 +10375,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-config/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/jest-config/node_modules/jest-get-type": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
@@ -10489,41 +10384,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-config/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-config/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
-    "node_modules/jest-diff": {
-      "version": "26.6.2",
-      "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^4.0.0",
-        "diff-sequences": "^26.6.2",
-        "jest-get-type": "^26.3.0",
-        "pretty-format": "^26.6.2"
-      },
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
     "node_modules/jest-docblock": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz",
@@ -10577,18 +10437,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-each/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/jest-each/node_modules/jest-get-type": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
@@ -10598,27 +10446,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-each/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-each/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-environment-jsdom": {
       "version": "27.4.4",
       "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz",
@@ -10704,14 +10531,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-get-type": {
-      "version": "26.3.0",
-      "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
-      "dev": true,
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
     "node_modules/jest-haste-map": {
       "version": "27.4.5",
       "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz",
@@ -10817,45 +10636,36 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-jasmine2/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-jasmine2/node_modules/pretty-format": {
+    "node_modules/jest-leak-detector": {
       "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
+      "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz",
+      "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==",
       "dev": true,
       "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
+        "jest-get-type": "^27.4.0",
+        "pretty-format": "^27.4.2"
       },
       "engines": {
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-jasmine2/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
+    "node_modules/jest-leak-detector/node_modules/jest-get-type": {
+      "version": "27.4.0",
+      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
+      "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
+      "dev": true,
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
     },
-    "node_modules/jest-leak-detector": {
+    "node_modules/jest-matcher-utils": {
       "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz",
-      "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==",
+      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz",
+      "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==",
       "dev": true,
       "dependencies": {
+        "chalk": "^4.0.0",
+        "jest-diff": "^27.4.2",
         "jest-get-type": "^27.4.0",
         "pretty-format": "^27.4.2"
       },
@@ -10863,147 +10673,28 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-leak-detector/node_modules/@jest/types": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz",
-      "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==",
+    "node_modules/jest-matcher-utils/node_modules/diff-sequences": {
+      "version": "27.4.0",
+      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
+      "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==",
       "dev": true,
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^16.0.0",
-        "chalk": "^4.0.0"
-      },
       "engines": {
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-leak-detector/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+    "node_modules/jest-matcher-utils/node_modules/jest-diff": {
+      "version": "27.4.2",
+      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz",
+      "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==",
       "dev": true,
       "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-leak-detector/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-leak-detector/node_modules/jest-get-type": {
-      "version": "27.4.0",
-      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
-      "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
-      "dev": true,
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-leak-detector/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-leak-detector/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
-    "node_modules/jest-matcher-utils": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz",
-      "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^4.0.0",
-        "jest-diff": "^27.4.2",
-        "jest-get-type": "^27.4.0",
-        "pretty-format": "^27.4.2"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/@jest/types": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz",
-      "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==",
-      "dev": true,
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^16.0.0",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-      "dev": true,
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/diff-sequences": {
-      "version": "27.4.0",
-      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
-      "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==",
-      "dev": true,
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/jest-diff": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz",
-      "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^4.0.0",
-        "diff-sequences": "^27.4.0",
-        "jest-get-type": "^27.4.0",
-        "pretty-format": "^27.4.2"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "chalk": "^4.0.0",
+        "diff-sequences": "^27.4.0",
+        "jest-get-type": "^27.4.0",
+        "pretty-format": "^27.4.2"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
     "node_modules/jest-matcher-utils/node_modules/jest-get-type": {
@@ -11015,27 +10706,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-matcher-utils/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-matcher-utils/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-message-util": {
       "version": "27.4.2",
       "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz",
@@ -11081,39 +10751,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-message-util/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-mock": {
       "version": "27.4.2",
       "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz",
@@ -11523,18 +11160,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-snapshot/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/jest-snapshot/node_modules/diff-sequences": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
@@ -11568,27 +11193,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-snapshot/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-snapshot/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-util": {
       "version": "27.4.2",
       "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz",
@@ -11673,18 +11277,6 @@
         "@types/yargs-parser": "*"
       }
     },
-    "node_modules/jest-validate/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/jest-validate/node_modules/jest-get-type": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
@@ -11694,27 +11286,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-validate/node_modules/pretty-format": {
-      "version": "27.4.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-      "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-      "dev": true,
-      "dependencies": {
-        "@jest/types": "^27.4.2",
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-validate/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-watch-typeahead": {
       "version": "0.6.5",
       "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.6.5.tgz",
@@ -11789,18 +11360,6 @@
         "mock-socket": "^9.1.0"
       }
     },
-    "node_modules/jest-websocket-mock/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/jest-websocket-mock/node_modules/diff-sequences": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@@ -11834,26 +11393,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-websocket-mock/node_modules/pretty-format": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
-      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^5.0.1",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
-      }
-    },
-    "node_modules/jest-websocket-mock/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true
-    },
     "node_modules/jest-worker": {
       "version": "27.4.5",
       "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz",
@@ -12151,9 +11690,9 @@
       "dev": true
     },
     "node_modules/lint-staged": {
-      "version": "12.3.1",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.1.tgz",
-      "integrity": "sha512-Ocht/eT+4/siWOZDJpNUKcKX2UeWW/pDbohJ4gRsrafAjBi79JK8kiNVk2ciIVNKdw0Q4ABptl2nr6uQAlRImw==",
+      "version": "12.3.6",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.6.tgz",
+      "integrity": "sha512-tVNyl/HsAnplKh4oaoRNzyZLm0PE/6VaBUXvd/gA9zhYCC/+ivZwiwpoT6jOxcLzuIOjP19wW+mfOi7/Bw4c1A==",
       "dev": true,
       "dependencies": {
         "cli-truncate": "^3.1.0",
@@ -12166,6 +11705,7 @@
         "micromatch": "^4.0.4",
         "normalize-path": "^3.0.0",
         "object-inspect": "^1.12.0",
+        "pidtree": "^0.5.0",
         "string-argv": "^0.3.1",
         "supports-color": "^9.2.1",
         "yaml": "^1.10.2"
@@ -13554,6 +13094,18 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/pidtree": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz",
+      "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==",
+      "dev": true,
+      "bin": {
+        "pidtree": "bin/pidtree.js"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
     "node_modules/pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -14912,15 +14464,18 @@
       }
     },
     "node_modules/prettier": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
-      "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz",
+      "integrity": "sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==",
       "dev": true,
       "bin": {
         "prettier": "bin-prettier.js"
       },
       "engines": {
         "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
       }
     },
     "node_modules/pretty-bytes": {
@@ -14946,21 +14501,34 @@
       }
     },
     "node_modules/pretty-format": {
-      "version": "26.6.2",
-      "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
       "dev": true,
       "dependencies": {
-        "@jest/types": "^26.6.2",
-        "ansi-regex": "^5.0.0",
-        "ansi-styles": "^4.0.0",
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
         "react-is": "^17.0.1"
       },
       "engines": {
-        "node": ">= 10"
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/pretty-format/node_modules/react-is": {
       "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
       "dev": true
     },
@@ -15002,13 +14570,14 @@
       }
     },
     "node_modules/prop-types": {
-      "version": "15.7.2",
-      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
       "dev": true,
       "dependencies": {
         "loose-envify": "^1.4.0",
         "object-assign": "^4.1.1",
-        "react-is": "^16.8.1"
+        "react-is": "^16.13.1"
       }
     },
     "node_modules/prop-types-extra": {
@@ -15330,25 +14899,25 @@
       }
     },
     "node_modules/react-bootstrap": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.1.1.tgz",
-      "integrity": "sha512-Igagk6LziNW/HgBlMVx+QiwPVt/oqrZ7tiBKgv31VYc/56kJEU0Y+BCJS6hrQP6QmmIpdVtX8TRaanv9xsmW5A==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.2.1.tgz",
+      "integrity": "sha512-x8lpVQflsbevphuWbTnTNCatcbKyPJNrP2WyQ1MJYmFEcVjbTbai1yZhdlXr0QUxLQLxA8g5hQWb5TwJtaZoCA==",
       "dev": true,
       "dependencies": {
-        "@babel/runtime": "^7.14.0",
+        "@babel/runtime": "^7.17.2",
         "@restart/hooks": "^0.4.5",
-        "@restart/ui": "^0.2.5",
-        "@types/invariant": "^2.2.33",
-        "@types/prop-types": "^15.7.3",
+        "@restart/ui": "^1.0.2",
+        "@types/invariant": "^2.2.35",
+        "@types/prop-types": "^15.7.4",
         "@types/react": ">=16.14.8",
-        "@types/react-transition-group": "^4.4.1",
+        "@types/react-transition-group": "^4.4.4",
         "@types/warning": "^3.0.0",
         "classnames": "^2.3.1",
         "dom-helpers": "^5.2.1",
         "invariant": "^2.2.4",
-        "prop-types": "^15.7.2",
+        "prop-types": "^15.8.1",
         "prop-types-extra": "^1.1.0",
-        "react-transition-group": "^4.4.1",
+        "react-transition-group": "^4.4.2",
         "uncontrollable": "^7.2.1",
         "warning": "^4.0.3"
       },
@@ -15494,9 +15063,9 @@
       "dev": true
     },
     "node_modules/react-i18next": {
-      "version": "11.15.5",
-      "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.5.tgz",
-      "integrity": "sha512-vBWuVEQgrhZrGKpyv8FmJ7Zs5jRQWl794Tte7yzJ0okZqqi3jd6j2pLYNg441WcREsbIOvWdiDXbY7W6E93p1A==",
+      "version": "11.15.7",
+      "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.7.tgz",
+      "integrity": "sha512-zSWZ+21LhaG4T155GcvLdepG1j/qJqD9hUGztVtD1MGBc4/l9ft/LMbUX7oKXdVVLyKWjUhUFoDNAwB2402BIQ==",
       "dev": true,
       "dependencies": {
         "@babel/runtime": "^7.14.5",
@@ -15537,9 +15106,9 @@
       }
     },
     "node_modules/react-router": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
-      "integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz",
+      "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==",
       "dev": true,
       "dependencies": {
         "history": "^5.2.0"
@@ -15549,9 +15118,9 @@
       }
     },
     "node_modules/react-router-bootstrap": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.0.tgz",
-      "integrity": "sha512-auVpsCOYgI+3CrmtpVjme8ucz76iiMvJhv2BrnWof2HtimrF9NtAHtFzdZrsku5hwp166EPbz7IuSyHJA8kkdA==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.1.tgz",
+      "integrity": "sha512-qgFDfnN2U5RBARTf4L/Xrk0xjNid4wRtBQFrzI2Z2Gu74nlfKT5qZreUxDiYvv4sI+NrWcYacRZEqS5yeLYH0A==",
       "dev": true,
       "dependencies": {
         "prop-types": "^15.7.2"
@@ -15562,13 +15131,13 @@
       }
     },
     "node_modules/react-router-dom": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
-      "integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz",
+      "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==",
       "dev": true,
       "dependencies": {
         "history": "^5.2.0",
-        "react-router": "6.2.1"
+        "react-router": "6.2.2"
       },
       "peerDependencies": {
         "react": ">=16.8",
@@ -18121,11 +17690,10 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
-      "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
       "dev": true,
-      "peer": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -20693,9 +20261,9 @@
       }
     },
     "@babel/runtime": {
-      "version": "7.16.5",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-      "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
+      "version": "7.17.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.7.tgz",
+      "integrity": "sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==",
       "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.4"
@@ -21249,18 +20817,6 @@
         }
       }
     },
-    "@jest/types": {
-      "version": "26.6.2",
-      "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
-      "dev": true,
-      "requires": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^15.0.0",
-        "chalk": "^4.0.0"
-      }
-    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -21288,15 +20844,15 @@
       }
     },
     "@popperjs/core": {
-      "version": "2.11.2",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz",
-      "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==",
+      "version": "2.11.4",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz",
+      "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==",
       "dev": true
     },
     "@react-aria/ssr": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.0.tgz",
-      "integrity": "sha512-RxqQKmE8sO7TGdrcSlHTcVzMP450hqowtBSd2bBS9oPlcokVkaGq28c3Rwa8ty5ctw4EBCjXqjP7xdcKMGDzug==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.2.tgz",
+      "integrity": "sha512-amXY11ImpokvkTMeKRHjsSsG7v1yzzs6yeqArCyBIk60J3Yhgxwx9Cah+Uu/804ATFwqzN22AXIo7SdtIaMP+g==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.6.2"
@@ -21312,9 +20868,9 @@
       }
     },
     "@restart/ui": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-0.2.5.tgz",
-      "integrity": "sha512-3dP8pMFickPpvAG5MVQW53HnJl0c17h7MwvI4nNy9QF66sHSYVchudlqlI8eOSaqnmc5YVjGura63vMb9LTNbQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.0.2.tgz",
+      "integrity": "sha512-vKGe0UBJLnbvNAjr8ljlDvphf2HkpjBjXsblmgKPvKdZBDn/mtAz89wmznaomIaEJ9VNoSEY0vA5T5MDi2jIcQ==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.13.16",
@@ -21542,31 +21098,6 @@
         "pretty-format": "^27.0.2"
       },
       "dependencies": {
-        "@jest/types": {
-          "version": "27.2.5",
-          "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
-          "dev": true,
-          "requires": {
-            "@types/istanbul-lib-coverage": "^2.0.0",
-            "@types/istanbul-reports": "^3.0.0",
-            "@types/node": "*",
-            "@types/yargs": "^16.0.0",
-            "chalk": "^4.0.0"
-          }
-        },
-        "@types/yargs": {
-          "version": "16.0.4",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-          "dev": true,
-          "requires": {
-            "@types/yargs-parser": "*"
-          }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "aria-query": {
           "version": "5.0.0",
           "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==",
@@ -21576,29 +21107,13 @@
           "version": "0.5.10",
           "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.3.1",
-          "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.2.5",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
     "@testing-library/jest-dom": {
-      "version": "5.16.1",
-      "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz",
-      "integrity": "sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==",
+      "version": "5.16.2",
+      "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz",
+      "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.9.2",
@@ -21630,12 +21145,14 @@
       }
     },
     "@testing-library/react": {
-      "version": "12.1.2",
-      "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==",
+      "version": "12.1.4",
+      "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz",
+      "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.12.5",
-        "@testing-library/dom": "^8.0.0"
+        "@testing-library/dom": "^8.0.0",
+        "@types/react-dom": "*"
       }
     },
     "@testing-library/user-event": {
@@ -21807,9 +21324,9 @@
       "dev": true
     },
     "@types/http-proxy": {
-      "version": "1.17.7",
-      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
-      "integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==",
+      "version": "1.17.8",
+      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz",
+      "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==",
       "dev": true,
       "requires": {
         "@types/node": "*"
@@ -21842,12 +21359,13 @@
       }
     },
     "@types/jest": {
-      "version": "26.0.24",
-      "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
+      "version": "27.4.1",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz",
+      "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==",
       "dev": true,
       "requires": {
-        "jest-diff": "^26.0.0",
-        "pretty-format": "^26.0.0"
+        "jest-matcher-utils": "^27.0.0",
+        "pretty-format": "^27.0.0"
       }
     },
     "@types/json-schema": {
@@ -21875,8 +21393,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "16.4.10",
-      "integrity": "sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ==",
+      "version": "17.0.21",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
+      "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
       "dev": true
     },
     "@types/normalize-package-data": {
@@ -21919,8 +21438,9 @@
       "dev": true
     },
     "@types/react": {
-      "version": "17.0.19",
-      "integrity": "sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==",
+      "version": "17.0.40",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz",
+      "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==",
       "dev": true,
       "requires": {
         "@types/prop-types": "*",
@@ -21928,9 +21448,19 @@
         "csstype": "^3.0.2"
       }
     },
+    "@types/react-dom": {
+      "version": "17.0.13",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz",
+      "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==",
+      "dev": true,
+      "requires": {
+        "@types/react": "*"
+      }
+    },
     "@types/react-transition-group": {
-      "version": "4.4.2",
-      "integrity": "sha512-KibDWL6nshuOJ0fu8ll7QnV/LVTo3PzQ9aCPnRUYPfX7eZohHwLIdNHj7pftanREzHNP4/nJa8oeM73uSiavMQ==",
+      "version": "4.4.4",
+      "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz",
+      "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==",
       "dev": true,
       "requires": {
         "@types/react": "*"
@@ -22019,14 +21549,6 @@
         "@types/node": "*"
       }
     },
-    "@types/yargs": {
-      "version": "15.0.14",
-      "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
-      "dev": true,
-      "requires": {
-        "@types/yargs-parser": "*"
-      }
-    },
     "@types/yargs-parser": {
       "version": "20.2.1",
       "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
@@ -22437,14 +21959,15 @@
       "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
       "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
       "dev": true,
-      "requires": {},
+      "requires": {
+        "ajv": "^8.0.0"
+      },
       "dependencies": {
         "ajv": {
-          "version": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
+          "version": "8.8.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
           "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
           "dev": true,
-          "optional": true,
-          "peer": true,
           "requires": {
             "fast-deep-equal": "^3.1.1",
             "json-schema-traverse": "^1.0.0",
@@ -22456,9 +21979,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
           "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true,
-          "optional": true,
-          "peer": true
+          "dev": true
         }
       }
     },
@@ -24464,12 +23985,7 @@
     "didyoumean": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
-      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
-      "dev": true
-    },
-    "diff-sequences": {
-      "version": "26.6.2",
-      "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
+      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
       "dev": true
     },
     "dijkstrajs": {
@@ -26173,9 +25689,9 @@
       "dev": true
     },
     "history": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
-      "integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
+      "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.7.6"
@@ -26358,12 +25874,12 @@
       }
     },
     "http-proxy-middleware": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz",
-      "integrity": "sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz",
+      "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==",
       "dev": true,
       "requires": {
-        "@types/http-proxy": "^1.17.5",
+        "@types/http-proxy": "^1.17.8",
         "http-proxy": "^1.18.1",
         "is-glob": "^4.0.1",
         "is-plain-obj": "^3.0.0",
@@ -26401,12 +25917,12 @@
       "dev": true
     },
     "i18next": {
-      "version": "21.6.12",
-      "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.12.tgz",
-      "integrity": "sha512-xlGTPdu2g5PZEUIE6TA1mQ9EIAAv9nMFONzgwAIrKL/KTmYYWufQNGgOmp5Og1PvgUji+6i1whz0rMdsz1qaKw==",
+      "version": "21.6.14",
+      "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.14.tgz",
+      "integrity": "sha512-XL6WyD+xlwQwbieXRlXhKWoLb/rkch50/rA+vl6untHnJ+aYnkQ0YDZciTWE78PPhOpbi2gR0LTJCJpiAhA+uQ==",
       "dev": true,
       "requires": {
-        "@babel/runtime": "^7.12.0"
+        "@babel/runtime": "^7.17.2"
       }
     },
     "i18next-browser-languagedetector": {
@@ -27080,30 +26596,6 @@
           "requires": {
             "@types/yargs-parser": "*"
           }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -27203,49 +26695,14 @@
             "@types/yargs-parser": "*"
           }
         },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "jest-get-type": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
-    "jest-diff": {
-      "version": "26.6.2",
-      "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
-      "dev": true,
-      "requires": {
-        "chalk": "^4.0.0",
-        "diff-sequences": "^26.6.2",
-        "jest-get-type": "^26.3.0",
-        "pretty-format": "^26.6.2"
-      }
-    },
     "jest-docblock": {
       "version": "27.4.0",
       "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz",
@@ -27290,35 +26747,11 @@
             "@types/yargs-parser": "*"
           }
         },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "jest-get-type": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -27399,11 +26832,6 @@
         }
       }
     },
-    "jest-get-type": {
-      "version": "26.3.0",
-      "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
-      "dev": true
-    },
     "jest-haste-map": {
       "version": "27.4.5",
       "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz",
@@ -27496,30 +26924,6 @@
           "requires": {
             "@types/yargs-parser": "*"
           }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -27533,57 +26937,11 @@
         "pretty-format": "^27.4.2"
       },
       "dependencies": {
-        "@jest/types": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz",
-          "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==",
-          "dev": true,
-          "requires": {
-            "@types/istanbul-lib-coverage": "^2.0.0",
-            "@types/istanbul-reports": "^3.0.0",
-            "@types/node": "*",
-            "@types/yargs": "^16.0.0",
-            "chalk": "^4.0.0"
-          }
-        },
-        "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-          "dev": true,
-          "requires": {
-            "@types/yargs-parser": "*"
-          }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "jest-get-type": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -27599,34 +26957,6 @@
         "pretty-format": "^27.4.2"
       },
       "dependencies": {
-        "@jest/types": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz",
-          "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==",
-          "dev": true,
-          "requires": {
-            "@types/istanbul-lib-coverage": "^2.0.0",
-            "@types/istanbul-reports": "^3.0.0",
-            "@types/node": "*",
-            "@types/yargs": "^16.0.0",
-            "chalk": "^4.0.0"
-          }
-        },
-        "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-          "dev": true,
-          "requires": {
-            "@types/yargs-parser": "*"
-          }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "diff-sequences": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
@@ -27650,24 +26980,6 @@
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -27709,30 +27021,6 @@
           "requires": {
             "@types/yargs-parser": "*"
           }
-        },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -28079,12 +27367,6 @@
             "@types/yargs-parser": "*"
           }
         },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "diff-sequences": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
@@ -28108,24 +27390,6 @@
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -28203,35 +27467,11 @@
             "@types/yargs-parser": "*"
           }
         },
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "jest-get-type": {
           "version": "27.4.0",
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
           "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.4.2",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz",
-          "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==",
-          "dev": true,
-          "requires": {
-            "@jest/types": "^27.4.2",
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -28299,12 +27539,6 @@
         "mock-socket": "^9.1.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-          "dev": true
-        },
         "diff-sequences": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@@ -28328,23 +27562,6 @@
           "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
           "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
           "dev": true
-        },
-        "pretty-format": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
-          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^5.0.1",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
-          }
-        },
-        "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-          "dev": true
         }
       }
     },
@@ -28574,9 +27791,9 @@
       "dev": true
     },
     "lint-staged": {
-      "version": "12.3.1",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.1.tgz",
-      "integrity": "sha512-Ocht/eT+4/siWOZDJpNUKcKX2UeWW/pDbohJ4gRsrafAjBi79JK8kiNVk2ciIVNKdw0Q4ABptl2nr6uQAlRImw==",
+      "version": "12.3.6",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.6.tgz",
+      "integrity": "sha512-tVNyl/HsAnplKh4oaoRNzyZLm0PE/6VaBUXvd/gA9zhYCC/+ivZwiwpoT6jOxcLzuIOjP19wW+mfOi7/Bw4c1A==",
       "dev": true,
       "requires": {
         "cli-truncate": "^3.1.0",
@@ -28589,6 +27806,7 @@
         "micromatch": "^4.0.4",
         "normalize-path": "^3.0.0",
         "object-inspect": "^1.12.0",
+        "pidtree": "^0.5.0",
         "string-argv": "^0.3.1",
         "supports-color": "^9.2.1",
         "yaml": "^1.10.2"
@@ -29606,6 +28824,12 @@
       "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
       "dev": true
     },
+    "pidtree": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz",
+      "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==",
+      "dev": true
+    },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -30286,6 +29510,7 @@
         "css-has-pseudo": "^2.0.0",
         "css-prefers-color-scheme": "^5.0.0",
         "cssdb": "^5.0.0",
+        "postcss": "^8.3",
         "postcss-attribute-case-insensitive": "^5.0.0",
         "postcss-color-functional-notation": "^4.0.1",
         "postcss-color-hex-alpha": "^8.0.0",
@@ -30471,9 +29696,9 @@
       "dev": true
     },
     "prettier": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
-      "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz",
+      "integrity": "sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==",
       "dev": true
     },
     "pretty-bytes": {
@@ -30493,18 +29718,25 @@
       }
     },
     "pretty-format": {
-      "version": "26.6.2",
-      "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
       "dev": true,
       "requires": {
-        "@jest/types": "^26.6.2",
-        "ansi-regex": "^5.0.0",
-        "ansi-styles": "^4.0.0",
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
         "react-is": "^17.0.1"
       },
       "dependencies": {
+        "ansi-styles": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+          "dev": true
+        },
         "react-is": {
           "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
           "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
           "dev": true
         }
@@ -30542,13 +29774,14 @@
       }
     },
     "prop-types": {
-      "version": "15.7.2",
-      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
       "dev": true,
       "requires": {
         "loose-envify": "^1.4.0",
         "object-assign": "^4.1.1",
-        "react-is": "^16.8.1"
+        "react-is": "^16.13.1"
       }
     },
     "prop-types-extra": {
@@ -30797,25 +30030,25 @@
       }
     },
     "react-bootstrap": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.1.1.tgz",
-      "integrity": "sha512-Igagk6LziNW/HgBlMVx+QiwPVt/oqrZ7tiBKgv31VYc/56kJEU0Y+BCJS6hrQP6QmmIpdVtX8TRaanv9xsmW5A==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.2.1.tgz",
+      "integrity": "sha512-x8lpVQflsbevphuWbTnTNCatcbKyPJNrP2WyQ1MJYmFEcVjbTbai1yZhdlXr0QUxLQLxA8g5hQWb5TwJtaZoCA==",
       "dev": true,
       "requires": {
-        "@babel/runtime": "^7.14.0",
+        "@babel/runtime": "^7.17.2",
         "@restart/hooks": "^0.4.5",
-        "@restart/ui": "^0.2.5",
-        "@types/invariant": "^2.2.33",
-        "@types/prop-types": "^15.7.3",
+        "@restart/ui": "^1.0.2",
+        "@types/invariant": "^2.2.35",
+        "@types/prop-types": "^15.7.4",
         "@types/react": ">=16.14.8",
-        "@types/react-transition-group": "^4.4.1",
+        "@types/react-transition-group": "^4.4.4",
         "@types/warning": "^3.0.0",
         "classnames": "^2.3.1",
         "dom-helpers": "^5.2.1",
         "invariant": "^2.2.4",
-        "prop-types": "^15.7.2",
+        "prop-types": "^15.8.1",
         "prop-types-extra": "^1.1.0",
-        "react-transition-group": "^4.4.1",
+        "react-transition-group": "^4.4.2",
         "uncontrollable": "^7.2.1",
         "warning": "^4.0.3"
       }
@@ -30923,9 +30156,9 @@
       "dev": true
     },
     "react-i18next": {
-      "version": "11.15.5",
-      "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.5.tgz",
-      "integrity": "sha512-vBWuVEQgrhZrGKpyv8FmJ7Zs5jRQWl794Tte7yzJ0okZqqi3jd6j2pLYNg441WcREsbIOvWdiDXbY7W6E93p1A==",
+      "version": "11.15.7",
+      "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.7.tgz",
+      "integrity": "sha512-zSWZ+21LhaG4T155GcvLdepG1j/qJqD9hUGztVtD1MGBc4/l9ft/LMbUX7oKXdVVLyKWjUhUFoDNAwB2402BIQ==",
       "dev": true,
       "requires": {
         "@babel/runtime": "^7.14.5",
@@ -30951,31 +30184,31 @@
       "dev": true
     },
     "react-router": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
-      "integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz",
+      "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==",
       "dev": true,
       "requires": {
         "history": "^5.2.0"
       }
     },
     "react-router-bootstrap": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.0.tgz",
-      "integrity": "sha512-auVpsCOYgI+3CrmtpVjme8ucz76iiMvJhv2BrnWof2HtimrF9NtAHtFzdZrsku5hwp166EPbz7IuSyHJA8kkdA==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.1.tgz",
+      "integrity": "sha512-qgFDfnN2U5RBARTf4L/Xrk0xjNid4wRtBQFrzI2Z2Gu74nlfKT5qZreUxDiYvv4sI+NrWcYacRZEqS5yeLYH0A==",
       "dev": true,
       "requires": {
         "prop-types": "^15.7.2"
       }
     },
     "react-router-dom": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
-      "integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz",
+      "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==",
       "dev": true,
       "requires": {
         "history": "^5.2.0",
-        "react-router": "6.2.1"
+        "react-router": "6.2.2"
       }
     },
     "react-scripts": {
@@ -32880,11 +32113,10 @@
       }
     },
     "typescript": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
-      "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
-      "dev": true,
-      "peer": true
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "dev": true
     },
     "uglify-js": {
       "version": "3.15.1",
diff --git a/package.json b/package.json
index ab7885c..c145b71 100644
--- a/package.json
+++ b/package.json
@@ -11,31 +11,36 @@
   },
   "homepage": ".",
   "devDependencies": {
-    "@popperjs/core": "^2.11.2",
-    "@testing-library/jest-dom": "^5.16.1",
-    "@testing-library/react": "^12.1.2",
+    "@popperjs/core": "^2.11.4",
+    "@testing-library/jest-dom": "^5.16.2",
+    "@testing-library/react": "^12.1.4",
     "@testing-library/user-event": "^13.5.0",
+    "@types/jest": "^27.4.1",
+    "@types/node": "^17.0.21",
+    "@types/react": "^17.0.40",
+    "@types/react-dom": "^17.0.13",
     "bootstrap": "^5.1.3",
     "buffer": "^6.0.3",
     "conventional-changelog": "^3.1.25",
-    "http-proxy-middleware": "^2.0.1",
+    "http-proxy-middleware": "^2.0.4",
     "husky": "^7.0.4",
-    "i18next": "^21.6.12",
+    "i18next": "^21.6.14",
     "i18next-browser-languagedetector": "^6.1.3",
     "jest-watch-typeahead": "^0.6.5",
     "jest-websocket-mock": "^2.3.0",
-    "lint-staged": "^12.3.1",
+    "lint-staged": "^12.3.6",
     "moving-letters": "^1.0.1",
     "nth-check": ">=2.0.1",
-    "prettier": "^2.5.1",
+    "prettier": "^2.6.0",
     "qrcode": "^1.5.0",
     "react": "^17.0.2",
-    "react-bootstrap": "^2.1.1",
+    "react-bootstrap": "^2.2.1",
     "react-dom": "^17.0.2",
-    "react-i18next": "^11.15.5",
-    "react-router-bootstrap": "^0.26.0",
-    "react-router-dom": "^6.2.1",
+    "react-i18next": "^11.15.7",
+    "react-router-bootstrap": "^0.26.1",
+    "react-router-dom": "^6.2.2",
     "react-scripts": "^5.0.0",
+    "typescript": "^4.6.2",
     "web-vitals": "^2.1.4"
   },
   "dependencies": {
@@ -47,8 +52,8 @@
     "test": "react-scripts test",
     "eject": "react-scripts eject",
     "postinstall": "husky install",
-    "lint": "prettier --check --no-error-on-unmatched-pattern src/**/*.{js,jsx,json,css,md}",
-    "format": "prettier --write --no-error-on-unmatched-pattern src/**/*.{js,jsx,json,css,md}",
+    "lint": "prettier --check --no-error-on-unmatched-pattern src/**/*.{js,jsx,ts,tsx,json,css,md}",
+    "format": "prettier --write --no-error-on-unmatched-pattern src/**/*.{js,jsx,ts,tsx,json,css,md}",
     "version": "node scripts/changelog.mjs && git checkout -b \"prepare-v${npm_package_version}-$(date +%s)\" && git add --all && git commit --message \"chore(release): prepare v${npm_package_version}\" && git push --set-upstream origin $(git branch --show-current)",
     "postversion": "which gh && gh pr create --title \"chore(release): prepare v${npm_package_version}\" --body \"Prepares the v${npm_package_version} release.\" --assignee @me --label release --repo joinmarket-webui/joinmarket-webui --draft",
     "regtest:rebuild": "npm run regtest:clear && docker-compose --file docker/regtest/docker-compose.yml build --pull --no-cache",
@@ -81,7 +86,7 @@
     ]
   },
   "lint-staged": {
-    "src/**/*.{js,jsx,json,css,md}": "prettier --no-error-on-unmatched-pattern --write"
+    "src/**/*.{js,jsx,ts,tsx,json,css,md}": "prettier --no-error-on-unmatched-pattern --write"
   },
   "jest": {
     "extraGlobals": [
diff --git a/src/components/App.jsx b/src/components/App.jsx
index 48b0302..025a03a 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -44,7 +44,7 @@ export default function App() {
 
   const startWallet = useCallback(
     (name, token) => {
-      setSession(name, token)
+      setSession({ name, token })
       setCurrentWallet({ name, token })
     },
     [setCurrentWallet]
diff --git a/src/components/CreateWallet.jsx b/src/components/CreateWallet.jsx
index dfaa216..535e129 100644
--- a/src/components/CreateWallet.jsx
+++ b/src/components/CreateWallet.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react'
+import React, { useState, useEffect } from 'react'
 import * as rb from 'react-bootstrap'
 import { Link, useNavigate } from 'react-router-dom'
 import { Trans, useTranslation } from 'react-i18next'
@@ -72,54 +72,170 @@ const WalletCreationForm = ({ createWallet, isCreating }) => {
   )
 }
 
-const WalletCreationConfirmation = ({ createdWallet, walletConfirmed }) => {
+const SeedWordInput = ({ number, targetWord, isValid, setIsValid }) => {
   const { t } = useTranslation()
-  const [userConfirmed, setUserConfirmed] = useState(false)
-  const [revealSensitiveInfo, setRevealSensitiveInfo] = useState(false)
-  const [sensitiveInfoWasRevealed, setSensitiveInfoWasRevealed] = useState(false)
+  const [enteredWord, setEnteredWord] = useState('')
+
+  useEffect(() => {
+    if (!isValid && enteredWord === targetWord) {
+      // Only use effect when value changes from false -> true to prevent an endless re-rendering loop.
+      setIsValid(true)
+    }
+  }, [enteredWord, targetWord, setIsValid, isValid])
+
+  return (
+    <rb.InputGroup>
+      <rb.InputGroup.Text className="seedword-index-backup">{number}.</rb.InputGroup.Text>
+      <rb.FormControl
+        type="text"
+        placeholder={`${t('create_wallet.placeholder_seed_word_input')} ${number}`}
+        value={enteredWord}
+        onChange={(e) => {
+          setEnteredWord(e.target.value)
+        }}
+        disabled={isValid}
+        isInvalid={!isValid && enteredWord.length > 0}
+        isValid={isValid}
+        required
+      />
+    </rb.InputGroup>
+  )
+}
+
+const BackupConfirmation = ({ createdWallet, walletConfirmed, parentStepSetter }) => {
+  const { t } = useTranslation()
+  const [seedBackup, setSeedBackup] = useState(false)
+  let seedphrase = createdWallet.seedphrase.split(' ')
+  const [seedWordConfirmations, setSeedWordConfirmations] = useState(new Array(seedphrase.length).fill(false))
+
+  useEffect(() => {
+    setSeedBackup(seedWordConfirmations.every((wordConfirmed) => wordConfirmed))
+  }, [seedWordConfirmations])
 
   return (
     <div>
-      <div className="mb-4">
-        <div>{t('create_wallet.confirmation_label_wallet_name')}</div>
-        <div className="fs-4">{walletDisplayName(createdWallet.name)}</div>
-      </div>
-      <div className="mb-4">
-        <Seedphrase seedphrase={createdWallet.seedphrase} isBlurred={!revealSensitiveInfo} />
-      </div>
-      <div className="mb-4">
-        <div>{t('create_wallet.confirmation_label_password')}</div>
-        <div className={`fs-4${revealSensitiveInfo ? '' : ' blurred-text'}`}>
-          {!revealSensitiveInfo ? 'randomrandom' : createdWallet.password}
+      <div className="fs-4">{t('create_wallet.confirm_backup_title')}</div>
+      <p className="text-secondary">{t('create_wallet.confirm_backup_subtitle')}</p>
+
+      <rb.Form noValidate>
+        <div className="container slashed-zeroes p-0">
+          {[...new Array(seedphrase.length)].map((_, outerIndex) => {
+            if (outerIndex % 2 !== 0) return null
+
+            const seedWords = seedphrase.slice(outerIndex, outerIndex + 2)
+
+            return (
+              <div className="row mb-4" key={outerIndex}>
+                {seedWords.map((seedWord, innerIndex) => {
+                  const wordIndex = outerIndex + innerIndex
+                  return (
+                    <div className="col" key={wordIndex}>
+                      <SeedWordInput
+                        number={wordIndex + 1}
+                        targetWord={seedWord}
+                        isValid={seedWordConfirmations[wordIndex]}
+                        setIsValid={(isValid) => {
+                          setSeedWordConfirmations(
+                            seedWordConfirmations.map((confirmation, index) =>
+                              index === wordIndex ? isValid : confirmation
+                            )
+                          )
+                        }}
+                      />
+                    </div>
+                  )
+                })}
+              </div>
+            )
+          })}
         </div>
-      </div>
-      <div className="mb-2">
-        <ToggleSwitch
-          label={t('create_wallet.confirmation_toggle_reveal_info')}
-          onToggle={(isToggled) => {
-            setRevealSensitiveInfo(isToggled)
-            setSensitiveInfoWasRevealed(true)
+      </rb.Form>
+      {seedBackup && <div className="text-center text-success">{t('create_wallet.feedback_seed_confirmed')}</div>}
+
+      <div className="d-flex mt-4 mb-4 gap-3">
+        <rb.Button
+          variant="dark"
+          disabled={seedBackup}
+          onClick={() => {
+            parentStepSetter()
           }}
-        />
-      </div>
-      <div className="mb-4">
-        <ToggleSwitch
-          label={t('create_wallet.confirmation_toggle_info_written_down')}
-          onToggle={(isToggled) => setUserConfirmed(isToggled)}
-        />
+        >
+          {t('create_wallet.back_button')}
+        </rb.Button>
+
+        <rb.Button variant="dark" onClick={() => walletConfirmed()} disabled={!seedBackup}>
+          {t('create_wallet.confirmation_button_fund_wallet')}
+        </rb.Button>
       </div>
-      <rb.Button
-        variant="dark"
-        type="submit"
-        disabled={!sensitiveInfoWasRevealed || !userConfirmed}
-        onClick={() => userConfirmed && walletConfirmed()}
-      >
-        {t('create_wallet.confirmation_button_fund_wallet')}
+
+      <rb.Button variant="outline-dark" onClick={() => walletConfirmed()} disabled={seedBackup}>
+        {t('create_wallet.skip_button')}
       </rb.Button>
     </div>
   )
 }
 
+const WalletCreationConfirmation = ({ createdWallet, walletConfirmed }) => {
+  const { t } = useTranslation()
+  const [userConfirmed, setUserConfirmed] = useState(false)
+  const [revealSensitiveInfo, setRevealSensitiveInfo] = useState(false)
+  const [sensitiveInfoWasRevealed, setSensitiveInfoWasRevealed] = useState(false)
+  const [step, setStep] = useState(0)
+
+  function childStepSetter() {
+    setRevealSensitiveInfo(false)
+    setSensitiveInfoWasRevealed(false)
+    setUserConfirmed(false)
+    setStep(0)
+  }
+
+  if (step === 0) {
+    return (
+      <div>
+        <div className="mb-4">
+          <div>{t('create_wallet.confirmation_label_wallet_name')}</div>
+          <div className="fs-4">{walletDisplayName(createdWallet.name)}</div>
+        </div>
+        <div className="mb-4">
+          <Seedphrase seedphrase={createdWallet.seedphrase} isBlurred={!revealSensitiveInfo} />
+        </div>
+        <div className="mb-4">
+          <div>{t('create_wallet.confirmation_label_password')}</div>
+          <div className={`fs-4${revealSensitiveInfo ? '' : ' blurred-text'}`}>
+            {!revealSensitiveInfo ? 'randomrandom' : createdWallet.password}
+          </div>
+        </div>
+        <div className="mb-2">
+          <ToggleSwitch
+            label={t('create_wallet.confirmation_toggle_reveal_info')}
+            onToggle={(isToggled) => {
+              setRevealSensitiveInfo(isToggled)
+              setSensitiveInfoWasRevealed(true)
+            }}
+          />
+        </div>
+        <div className="mb-4">
+          <ToggleSwitch
+            label={t('create_wallet.confirmation_toggle_info_written_down')}
+            onToggle={(isToggled) => setUserConfirmed(isToggled)}
+          />
+        </div>
+        <rb.Button variant="dark" disabled={!sensitiveInfoWasRevealed || !userConfirmed} onClick={() => setStep(1)}>
+          {t('create_wallet.next_button')}
+        </rb.Button>
+      </div>
+    )
+  } else {
+    return (
+      <BackupConfirmation
+        parentStepSetter={childStepSetter}
+        createdWallet={createdWallet}
+        walletConfirmed={walletConfirmed}
+      />
+    )
+  }
+}
+
 export default function CreateWallet({ startWallet }) {
   const { t } = useTranslation()
   const currentWallet = useCurrentWallet()
@@ -134,7 +250,7 @@ export default function CreateWallet({ startWallet }) {
     setIsCreating(true)
 
     try {
-      const res = await Api.postWalletCreate({ walletName, password })
+      const res = await Api.postWalletCreate({ walletname: walletName, password })
 
       if (res.ok) {
         const { seedphrase, token, walletname: createdWalletName } = await res.json()
diff --git a/src/components/CurrentWalletAdvanced.jsx b/src/components/CurrentWalletAdvanced.tsx
similarity index 74%
rename from src/components/CurrentWalletAdvanced.jsx
rename to src/components/CurrentWalletAdvanced.tsx
index 70975f4..0ad8772 100644
--- a/src/components/CurrentWalletAdvanced.jsx
+++ b/src/components/CurrentWalletAdvanced.tsx
@@ -1,28 +1,41 @@
 import React, { useState, useEffect } from 'react'
 import * as rb from 'react-bootstrap'
 import { useTranslation } from 'react-i18next'
+// @ts-ignore
 import DisplayAccounts from './DisplayAccounts'
+// @ts-ignore
 import DisplayAccountUTXOs from './DisplayAccountUTXOs'
+// @ts-ignore
 import DisplayUTXOs from './DisplayUTXOs'
+// @ts-ignore
 import { useCurrentWallet, useCurrentWalletInfo, useSetCurrentWalletInfo } from '../context/WalletContext'
 import * as Api from '../libs/JmWalletApi'
 
+type Utxos = any[]
+type Alert = { message: string; variant: string }
+
 export default function CurrentWalletAdvanced() {
   const { t } = useTranslation()
   const currentWallet = useCurrentWallet()
   const walletInfo = useCurrentWalletInfo()
   const setWalletInfo = useSetCurrentWalletInfo()
-  const [fidelityBonds, setFidelityBonds] = useState(null)
-  const [utxos, setUtxos] = useState(null)
+  const [fidelityBonds, setFidelityBonds] = useState<Utxos | null>(null)
+  const [utxos, setUtxos] = useState<Utxos | null>(null)
   const [showUTXO, setShowUTXO] = useState(false)
-  const [alert, setAlert] = useState(null)
+  const [alert, setAlert] = useState<Alert | null>(null)
   const [isLoading, setIsLoading] = useState(true)
 
   useEffect(() => {
+    if (!currentWallet) {
+      setAlert({ variant: 'danger', message: t('current_wallet.error_loading_failed') })
+      setIsLoading(false)
+      return
+    }
+
     const abortCtrl = new AbortController()
-    const { name, token } = currentWallet
+    const { name: walletName, token } = currentWallet
 
-    const setUtxoData = (utxos) => {
+    const setUtxoData = (utxos: Utxos) => {
       setUtxos(utxos)
       setFidelityBonds(utxos.filter((utxo) => utxo.locktime))
     }
@@ -30,20 +43,17 @@ export default function CurrentWalletAdvanced() {
     setAlert(null)
     setIsLoading(true)
 
-    const loadingWallet = Api.getWalletDisplay({ walletName: name, token, signal: abortCtrl.signal })
-      .then((res) =>
-        res.ok ? res.json() : Promise.reject(new Error(res.message || t('current_wallet.error_loading_failed')))
-      )
+    const loadingWallet = Api.getWalletDisplay({ walletName, token, signal: abortCtrl.signal })
+      .then((res) => (res.ok ? res.json() : Api.Helper.throwError(res, t('current_wallet.error_loading_failed'))))
       .then((data) => setWalletInfo(data.walletinfo))
       .catch((err) => {
         !abortCtrl.signal.aborted && setAlert({ variant: 'danger', message: err.message })
       })
 
-    const loadingUtxos = Api.getWalletUtxos({ walletName: name, token, signal: abortCtrl.signal })
-      .then((res) =>
-        res.ok
-          ? res.json()
-          : Promise.reject(new Error(res.message || t('current_wallet_advanced.error_loading_utxos_failed')))
+    const loadingUtxos = Api.getWalletUtxos({ walletName, token, signal: abortCtrl.signal })
+      .then(
+        (res): Promise<{ utxos: Utxos }> =>
+          res.ok ? res.json() : Api.Helper.throwError(res, t('current_wallet_advanced.error_loading_utxos_failed'))
       )
       .then((data) => setUtxoData(data.utxos))
       .catch((err) => {
diff --git a/src/components/Receive.jsx b/src/components/Receive.jsx
index ddb3424..bc5ad16 100644
--- a/src/components/Receive.jsx
+++ b/src/components/Receive.jsx
@@ -33,7 +33,7 @@ export default function Receive({ currentWallet }) {
 
       setAlert(null)
       setIsLoading(true)
-      Api.getAddressNew({ walletName, accountNr, token, signal: abortCtrl.signal })
+      Api.getAddressNew({ walletName, mixdepth: accountNr, token, signal: abortCtrl.signal })
         .then((res) =>
           res.ok ? res.json() : Promise.reject(new Error(res.message || t('receive.error_loading_address_failed')))
         )
diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json
index 49efd8e..5160f26 100644
--- a/src/i18n/locales/en/translation.json
+++ b/src/i18n/locales/en/translation.json
@@ -90,7 +90,14 @@
     "confirmation_label_password": "Password",
     "confirmation_toggle_reveal_info": "Reveal sensitive information",
     "confirmation_toggle_info_written_down": "I've written down the information above.",
-    "confirmation_button_fund_wallet": "Fund Wallet"
+    "confirmation_button_fund_wallet": "Fund Wallet",
+    "confirm_backup_title": "Confirm seed phrase backup",
+    "confirm_backup_subtitle": "Enter each word in sequential order.",
+    "feedback_seed_confirmed": "Seed phrase confirmed.",
+    "back_button": "Back",
+    "skip_button": "Skip",
+    "next_button": "Next",
+    "placeholder_seed_word_input": "Word"
   },
   "current_wallet": {
     "text_loading": "Loading",
diff --git a/src/index.css b/src/index.css
index 8bdaf53..0f7a5a5 100644
--- a/src/index.css
+++ b/src/index.css
@@ -372,6 +372,10 @@ main {
   width: 2ch;
 }
 
+.seedword-index-backup {
+  width: 5ch;
+}
+
 .blurred-text {
   color: transparent;
   text-shadow: 0 0 15px var(--bs-gray-600);
diff --git a/src/index.jsx b/src/index.tsx
similarity index 85%
rename from src/index.jsx
rename to src/index.tsx
index 64eb5be..abc9e24 100644
--- a/src/index.jsx
+++ b/src/index.tsx
@@ -1,15 +1,29 @@
 import React from 'react'
 import ReactDOM from 'react-dom'
 import { BrowserRouter } from 'react-router-dom'
+// @ts-ignore
 import App from './components/App'
+// @ts-ignore
 import { SettingsProvider } from './context/SettingsContext'
+// @ts-ignore
 import { WalletProvider } from './context/WalletContext'
+// @ts-ignore
 import { WebsocketProvider } from './context/WebsocketContext'
 import reportWebVitals from './reportWebVitals'
 import 'bootstrap/dist/css/bootstrap.min.css'
 import './index.css'
 import './i18n/config'
 
+declare global {
+  interface JamGlobal {
+    PUBLIC_PATH: string
+  }
+
+  interface Window {
+    JM: JamGlobal
+  }
+}
+
 ReactDOM.render(
   <BrowserRouter basename={window.JM.PUBLIC_PATH}>
     <SettingsProvider>
diff --git a/src/libs/JmWalletApi.js b/src/libs/JmWalletApi.js
deleted file mode 100644
index 0c00e86..0000000
--- a/src/libs/JmWalletApi.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Simple collection of api requests to jmwalletd.
- *
- * This is not aiming to be feature-complete.
- *
- * See OpenAPI spec: https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/api/wallet-rpc.yaml
- *
- * Because we forward all requests through a proxy, additional functionality
- * can be provided. One adaptation is to send the Authorization header as
- * 'x-jm-authorization' so that the reverse proxy can apply its own
- * authentication mechanism.
- */
-const BASE_PATH = `${window.JM.PUBLIC_PATH}/api`
-
-/**
- * Construct a bearer authorization header object for the given token.
- *
- * The 'x-jm-authorization' header is forwarded as 'Authorization' header in
- * requests to jmwalletd by the reverse proxy.
- *
- * @param {string} token the bearer token
- * @returns an object containing the authorization header
- */
-const Authorization = (token) => {
-  return { 'x-jm-authorization': `Bearer ${token}` }
-}
-
-const getSession = async ({ signal }) => {
-  return await fetch(`${BASE_PATH}/v1/session`, { signal })
-}
-
-const getAddressNew = async ({ walletName, token, accountNr, signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/address/new/${accountNr}`, {
-    headers: { ...Authorization(token) },
-    signal,
-  })
-}
-
-const getWalletAll = async ({ signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/all`, {
-    signal,
-  })
-}
-
-const postWalletCreate = async ({ walletName: name, password }) => {
-  const walletname = name.endsWith('.jmdat') ? name : `${name}.jmdat`
-
-  return await fetch(`${BASE_PATH}/v1/wallet/create`, {
-    method: 'POST',
-    body: JSON.stringify({
-      wallettype: 'sw-fb',
-      walletname,
-      password,
-    }),
-  })
-}
-
-const getWalletDisplay = async ({ walletName, token, signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/display`, {
-    headers: { ...Authorization(token) },
-    signal,
-  })
-}
-
-const getWalletSeed = async ({ walletName, token, signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/getseed`, {
-    headers: { ...Authorization(token) },
-    signal,
-  })
-}
-
-/**
- * Block access to a currently decrypted wallet.
- * After this (authenticated) action, the wallet will not be readable or writeable.
- *
- * Note: Performs a non-idempotent GET request.
- */
-const getWalletLock = async ({ walletName, token }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/lock`, {
-    headers: { ...Authorization(token) },
-  })
-}
-
-const postWalletUnlock = async ({ walletName }, { password }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/unlock`, {
-    method: 'POST',
-    body: JSON.stringify({ password }),
-  })
-}
-
-const getWalletUtxos = async ({ walletName, token, signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/utxos`, {
-    headers: { ...Authorization(token) },
-    signal,
-  })
-}
-
-const postMakerStart = async ({ walletName, token, signal }, { cjfee_a, cjfee_r, ordertype, minsize }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/maker/start`, {
-    method: 'POST',
-    headers: { ...Authorization(token) },
-    signal,
-    body: JSON.stringify({
-      txfee: 0,
-      cjfee_a,
-      cjfee_r,
-      ordertype,
-      minsize,
-    }),
-  })
-}
-
-/**
- * Stop the yield generator service.
- *
- * Note: Performs a non-idempotent GET request.
- */
-const getMakerStop = async ({ walletName, token }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/maker/stop`, {
-    headers: { ...Authorization(token) },
-  })
-}
-
-const postDirectSend = async ({ walletName, token }, { account, destination, amount_sats }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/taker/direct-send`, {
-    method: 'POST',
-    headers: { ...Authorization(token) },
-    body: JSON.stringify({
-      mixdepth: String(account),
-      destination,
-      amount_sats,
-    }),
-  })
-}
-
-const postCoinjoin = async ({ walletName, token }, { account, destination, amount_sats, counterparties }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/taker/coinjoin`, {
-    method: 'POST',
-    headers: { ...Authorization(token) },
-    body: JSON.stringify({
-      mixdepth: String(account),
-      destination,
-      amount_sats,
-      counterparties,
-    }),
-  })
-}
-
-const getYieldgenReport = async ({ signal }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/yieldgen/report`, {
-    signal,
-  })
-}
-
-const postFreeze = async ({ walletName, token }, { utxo, freeze = true }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/freeze`, {
-    method: 'POST',
-    headers: { ...Authorization(token) },
-    body: JSON.stringify({
-      'utxo-string': utxo,
-      freeze,
-    }),
-  })
-}
-
-/**
- * Get the value of a specific config setting. Note that values are always returned as string.
- *
- * @returns an object with property `configvalue` as string
- */
-const postConfigGet = async ({ walletName, token, signal }, { section, field }) => {
-  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/configget`, {
-    method: 'POST',
-    headers: { ...Authorization(token) },
-    signal,
-    body: JSON.stringify({
-      section,
-      field,
-    }),
-  })
-}
-
-export {
-  postMakerStart,
-  getMakerStop,
-  getSession,
-  postDirectSend,
-  postCoinjoin,
-  getAddressNew,
-  getWalletAll,
-  postWalletCreate,
-  getWalletDisplay,
-  getWalletLock,
-  postWalletUnlock,
-  getWalletUtxos,
-  getYieldgenReport,
-  postFreeze,
-  postConfigGet,
-  getWalletSeed,
-}
diff --git a/src/libs/JmWalletApi.ts b/src/libs/JmWalletApi.ts
new file mode 100644
index 0000000..629b777
--- /dev/null
+++ b/src/libs/JmWalletApi.ts
@@ -0,0 +1,295 @@
+/**
+ * Simple collection of api requests to jmwalletd.
+ *
+ * This is not aiming to be feature-complete.
+ *
+ * See OpenAPI spec: https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/api/wallet-rpc.yaml
+ *
+ * Because we forward all requests through a proxy, additional functionality
+ * can be provided. One adaptation is to send the Authorization header as
+ * 'x-jm-authorization' so that the reverse proxy can apply its own
+ * authentication mechanism.
+ */
+const BASE_PATH = `${window.JM.PUBLIC_PATH}/api`
+
+type ApiToken = string
+type WalletName = string
+
+type Mixdepth = number
+type AmountSats = BigInt
+type BitcoinAddress = string
+
+type WithWalletName = {
+  walletName: WalletName
+}
+type WithMixdepth = {
+  mixdepth: Mixdepth
+}
+
+interface ApiRequestContext {
+  signal?: AbortSignal
+}
+
+interface AuthApiRequestContext extends ApiRequestContext {
+  token: ApiToken
+}
+
+type WalletRequestContext = AuthApiRequestContext & WithWalletName
+
+interface ApiError {
+  message: string
+}
+
+type WalletType = 'sw-fb'
+
+interface CreateWalletRequest {
+  wallettype: WalletType
+  walletname: WalletName
+  password: string
+}
+
+interface WalletUnlockRequest {
+  password: string
+}
+
+type OrderType = 'sw0reloffer' | 'sw0absoffer'
+
+interface StartMakerRequest {
+  cjfee_a: AmountSats
+  cjfee_r: number
+  ordertype: OrderType
+  minsize: AmountSats
+}
+
+interface DirectSendRequest {
+  mixdepth: Mixdepth
+  destination: BitcoinAddress
+  amount_sats: AmountSats
+}
+
+interface DoCoinjoinRequest {
+  mixdepth: Mixdepth
+  destination: BitcoinAddress
+  amount_sats: AmountSats
+  counterparties: number
+}
+
+interface FreezeRequest {
+  utxo: string
+  freeze: boolean
+}
+
+interface ConfigSetRequest {
+  section: string
+  field: string
+}
+
+/**
+ * Construct a bearer authorization header object for the given token.
+ *
+ * The 'x-jm-authorization' header is forwarded as 'Authorization' header in
+ * requests to jmwalletd by the reverse proxy.
+ *
+ * @param {ApiToken} token the bearer token
+ * @returns an object containing the authorization header
+ */
+const Authorization = (token: ApiToken) => {
+  return { 'x-jm-authorization': `Bearer ${token}` }
+}
+
+const getSession = async ({ signal }: ApiRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/session`, { signal })
+}
+
+const getAddressNew = async ({ token, signal, walletName, mixdepth }: WalletRequestContext & WithMixdepth) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/address/new/${mixdepth}`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+const getWalletAll = async ({ signal }: ApiRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/all`, {
+    signal,
+  })
+}
+
+const postWalletCreate = async (req: CreateWalletRequest) => {
+  const walletname = req.walletname.endsWith('.jmdat') ? req.walletname : `${req.walletname}.jmdat`
+
+  return await fetch(`${BASE_PATH}/v1/wallet/create`, {
+    method: 'POST',
+    body: JSON.stringify({ ...req, walletname, wallettype: 'sw-fb' }),
+  })
+}
+
+const getWalletDisplay = async ({ token, signal, walletName }: WalletRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/display`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+const getWalletSeed = async ({ token, signal, walletName }: WalletRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/getseed`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+/**
+ * Block access to a currently decrypted wallet.
+ * After this (authenticated) action, the wallet will not be readable or writeable.
+ *
+ * Note: Performs a non-idempotent GET request.
+ */
+const getWalletLock = async ({ token, signal, walletName }: WalletRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/lock`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+const postWalletUnlock = async (
+  { signal, walletName }: ApiRequestContext & WithWalletName,
+  { password }: WalletUnlockRequest
+) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/unlock`, {
+    method: 'POST',
+    body: JSON.stringify({ password }),
+    signal,
+  })
+}
+
+const getWalletUtxos = async ({ token, signal, walletName }: WalletRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/utxos`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+const postMakerStart = async ({ token, signal, walletName }: WalletRequestContext, req: StartMakerRequest) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/maker/start`, {
+    method: 'POST',
+    headers: { ...Authorization(token) },
+    body: JSON.stringify({ ...req, txfee: '0' }),
+    signal,
+  })
+}
+
+/**
+ * Stop the yield generator service.
+ *
+ * Note: Performs a non-idempotent GET request.
+ */
+const getMakerStop = async ({ token, signal, walletName }: WalletRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/maker/stop`, {
+    headers: { ...Authorization(token) },
+    signal,
+  })
+}
+
+const postDirectSend = async ({ token, signal, walletName }: WalletRequestContext, req: DirectSendRequest) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/taker/direct-send`, {
+    method: 'POST',
+    headers: { ...Authorization(token) },
+    // docs say "integer", but "midxdepth" must serialize as string!
+    body: JSON.stringify({ ...req, mixdepth: String(req.mixdepth) }),
+    signal,
+  })
+}
+
+const postCoinjoin = async ({ token, signal, walletName }: WalletRequestContext, req: DoCoinjoinRequest) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/taker/coinjoin`, {
+    method: 'POST',
+    headers: { ...Authorization(token) },
+    // docs say "integer", but "midxdepth" must serialize as string!
+    body: JSON.stringify({ ...req, mixdepth: String(req.mixdepth) }),
+    signal,
+  })
+}
+
+const getYieldgenReport = async ({ signal }: ApiRequestContext) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/yieldgen/report`, {
+    signal,
+  })
+}
+
+const postFreeze = async (
+  { token, signal, walletName }: WalletRequestContext,
+  { utxo, freeze = true }: FreezeRequest
+) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/freeze`, {
+    method: 'POST',
+    headers: { ...Authorization(token) },
+    body: JSON.stringify({
+      'utxo-string': utxo,
+      freeze,
+    }),
+    signal,
+  })
+}
+
+/**
+ * Get the value of a specific config setting. Note that values are always returned as string.
+ *
+ * @returns an object with property `configvalue` as string
+ */
+const postConfigGet = async ({ token, signal, walletName }: WalletRequestContext, req: ConfigSetRequest) => {
+  return await fetch(`${BASE_PATH}/v1/wallet/${walletName}/configget`, {
+    method: 'POST',
+    headers: { ...Authorization(token) },
+    body: JSON.stringify(req),
+    signal,
+  })
+}
+
+const Helper = (() => {
+  const extractErrorMessage = async (response: Response, fallbackReason: string): Promise<string> => {
+    // The server will answer with a html response instead of json on certain errors.
+    // The situation is mitigated by parsing the returned html.
+    const isHtmlErrorMessage = response.headers.get('content-type') === 'text/html'
+
+    if (isHtmlErrorMessage) {
+      return await response
+        .text()
+        .then((html) => {
+          var parser = new DOMParser()
+          var doc = parser.parseFromString(html, 'text/html')
+          return doc.title || fallbackReason
+        })
+        .then((reason) => `The server reported a problem: ${reason}`)
+    }
+
+    const { message }: ApiError = await response.json()
+    return message || fallbackReason
+  }
+
+  const throwError = async (response: Response, fallbackReason: string): Promise<void> => {
+    throw new Error(await extractErrorMessage(response, fallbackReason))
+  }
+
+  return {
+    throwError,
+  }
+})()
+
+export {
+  postMakerStart,
+  getMakerStop,
+  getSession,
+  postDirectSend,
+  postCoinjoin,
+  getAddressNew,
+  getWalletAll,
+  postWalletCreate,
+  getWalletDisplay,
+  getWalletLock,
+  postWalletUnlock,
+  getWalletUtxos,
+  getYieldgenReport,
+  postFreeze,
+  postConfigGet,
+  getWalletSeed,
+  Helper,
+}
diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js
deleted file mode 100644
index dc6ff07..0000000
--- a/src/reportWebVitals.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const reportWebVitals = (onPerfEntry) => {
-  if (onPerfEntry && onPerfEntry instanceof Function) {
-    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
-      getCLS(onPerfEntry)
-      getFID(onPerfEntry)
-      getFCP(onPerfEntry)
-      getLCP(onPerfEntry)
-      getTTFB(onPerfEntry)
-    })
-  }
-}
-
-export default reportWebVitals
diff --git a/src/reportWebVitals.ts b/src/reportWebVitals.ts
new file mode 100644
index 0000000..c03c4f6
--- /dev/null
+++ b/src/reportWebVitals.ts
@@ -0,0 +1,13 @@
+const reportWebVitals = (onPerfEntry?: Function) => {
+  if (onPerfEntry) {
+    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+      getCLS(onPerfEntry as any)
+      getFID(onPerfEntry as any)
+      getFCP(onPerfEntry as any)
+      getLCP(onPerfEntry as any)
+      getTTFB(onPerfEntry as any)
+    })
+  }
+}
+
+export default reportWebVitals
diff --git a/src/session.js b/src/session.js
deleted file mode 100644
index 7094b24..0000000
--- a/src/session.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const SESSION_KEY = 'joinmarket'
-
-export const setSession = (name, token) => sessionStorage.setItem(SESSION_KEY, JSON.stringify({ name, token }))
-
-export const getSession = () => {
-  const { name, token } = JSON.parse(sessionStorage.getItem(SESSION_KEY)) || {}
-  if (name && token) {
-    return { name, token }
-  } else {
-    clearSession()
-  }
-}
-
-export const clearSession = () => sessionStorage.removeItem(SESSION_KEY)
diff --git a/src/session.ts b/src/session.ts
new file mode 100644
index 0000000..966ff13
--- /dev/null
+++ b/src/session.ts
@@ -0,0 +1,21 @@
+const SESSION_KEY = 'joinmarket'
+
+export interface SessionItem {
+  name: string
+  token: string
+}
+
+export const setSession = (session: SessionItem) => sessionStorage.setItem(SESSION_KEY, JSON.stringify(session))
+
+export const getSession = (): SessionItem | null => {
+  const json = sessionStorage.getItem(SESSION_KEY)
+  const { name, token }: any = (json && JSON.parse(json)) || {}
+  if (name && token) {
+    return { name, token }
+  } else {
+    clearSession()
+    return null
+  }
+}
+
+export const clearSession = () => sessionStorage.removeItem(SESSION_KEY)
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..77efca0
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+  "compilerOptions": {
+    "target": "es2016",
+    "module": "commonjs",
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+    "strict": true,
+    "jsx": "react-jsx",
+    "skipLibCheck": true
+  }
+}


Test patch:
diff --git a/src/components/CurrentWalletAdvanced.test.tsx b/src/components/CurrentWalletAdvanced.test.tsx
new file mode 100644
index 0000000..f8db360
--- /dev/null
+++ b/src/components/CurrentWalletAdvanced.test.tsx
@@ -0,0 +1,18 @@
+import React from 'react'
+// @ts-ignore
+import { render, screen } from '../testUtils'
+import { act } from 'react-dom/test-utils'
+
+import CurrentWalletAdvanced from './CurrentWalletAdvanced'
+
+describe('<CurrentWalletAdvanced />', () => {
+  const setup = () => {
+    render(<CurrentWalletAdvanced />)
+  }
+
+  it('should display error if component is rendered without active wallet', () => {
+    act(setup)
+
+    expect(screen.getByText('current_wallet.error_loading_failed')).toBeInTheDocument()
+  })
+})