]> Untitled Git - lemmy-ui.git/commitdiff
Merge branch 'LemmyNet:main' into multiple-images-upload
authorsam365724 <111515092+sam365724@users.noreply.github.com>
Fri, 30 Sep 2022 20:36:55 +0000 (22:36 +0200)
committerGitHub <noreply@github.com>
Fri, 30 Sep 2022 20:36:55 +0000 (22:36 +0200)
64 files changed:
.eslintrc.json
lemmy-translations
package.json
src/assets/css/themes/darkly-red.css
src/assets/css/themes/darkly.css
src/shared/components/app/app.tsx
src/shared/components/app/footer.tsx
src/shared/components/app/navbar.tsx
src/shared/components/app/no-match.tsx
src/shared/components/comment/comment-form.tsx
src/shared/components/comment/comment-node.tsx
src/shared/components/comment/comment-nodes.tsx
src/shared/components/comment/comment-report.tsx
src/shared/components/common/banner-icon-header.tsx
src/shared/components/common/comment-sort-select.tsx
src/shared/components/common/data-type-select.tsx
src/shared/components/common/html-tags.tsx
src/shared/components/common/icon.tsx
src/shared/components/common/image-upload-form.tsx
src/shared/components/common/language-select.tsx [new file with mode: 0644]
src/shared/components/common/listing-type-select.tsx
src/shared/components/common/markdown-textarea.tsx
src/shared/components/common/paginator.tsx
src/shared/components/common/registration-application.tsx
src/shared/components/common/sort-select.tsx
src/shared/components/common/symbols.tsx
src/shared/components/community/communities.tsx
src/shared/components/community/community-form.tsx
src/shared/components/community/community-link.tsx
src/shared/components/community/community.tsx
src/shared/components/community/create-community.tsx
src/shared/components/community/sidebar.tsx
src/shared/components/home/admin-settings.tsx
src/shared/components/home/home.tsx
src/shared/components/home/instances.tsx
src/shared/components/home/legal.tsx
src/shared/components/home/login.tsx
src/shared/components/home/setup.tsx
src/shared/components/home/signup.tsx
src/shared/components/home/site-form.tsx
src/shared/components/home/site-sidebar.tsx
src/shared/components/modlog.tsx
src/shared/components/person/inbox.tsx
src/shared/components/person/password-change.tsx
src/shared/components/person/person-details.tsx
src/shared/components/person/profile.tsx
src/shared/components/person/registration-applications.tsx
src/shared/components/person/reports.tsx
src/shared/components/person/settings.tsx
src/shared/components/person/verify-email.tsx
src/shared/components/post/create-post.tsx
src/shared/components/post/metadata-card.tsx
src/shared/components/post/post-form.tsx
src/shared/components/post/post-listing.tsx
src/shared/components/post/post-listings.tsx
src/shared/components/post/post-report.tsx
src/shared/components/post/post.tsx
src/shared/components/private_message/create-private-message.tsx
src/shared/components/private_message/private-message-form.tsx
src/shared/components/private_message/private-message-report.tsx [new file with mode: 0644]
src/shared/components/private_message/private-message.tsx
src/shared/components/search.tsx
src/shared/utils.ts
yarn.lock

index 4e05f0c5a73bf41a8da67062d94fe3953d2648cd..0c9a5f46f8beaa3b9298e456c0207b2a88228d1e 100644 (file)
@@ -8,7 +8,8 @@
   ],
   "extends": [
     "eslint:recommended",
-    "plugin:@typescript-eslint/recommended"
+    "plugin:@typescript-eslint/recommended",
+    "plugin:inferno/recommended"
   ],
   "parser": "@typescript-eslint/parser",
   "parserOptions": {
index 7ac48ae98271b3b573e28c90b87f9704492e0b62..ae3132fef13542ab7fc337361bf484183d12d786 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7ac48ae98271b3b573e28c90b87f9704492e0b62
+Subproject commit ae3132fef13542ab7fc337361bf484183d12d786
index a430314b31de4333fac7cd64c44dd2f6ffdf5fc5..e7c0b50945f9de8608b38ac51842ddf9823d4cf0 100644 (file)
     "emoji-short-name": "^2.0.0",
     "express": "~4.18.1",
     "i18next": "^21.8.14",
-    "inferno": "^7.4.11",
-    "inferno-create-element": "^7.4.11",
+    "inferno": "^8.0.3",
+    "inferno-create-element": "^8.0.3",
     "inferno-helmet": "^5.2.1",
-    "inferno-hydrate": "^7.4.11",
-    "inferno-i18next-dess": "^0.0.1",
-    "inferno-router": "^7.4.11",
-    "inferno-server": "^7.4.11",
+    "inferno-hydrate": "^8.0.3",
+    "inferno-i18next-dess": "0.0.2",
+    "inferno-router": "^8.0.3",
+    "inferno-server": "^8.0.3",
     "isomorphic-cookie": "^1.2.4",
     "jwt-decode": "^3.1.2",
     "markdown-it": "^13.0.1",
@@ -55,7 +55,7 @@
     "@babel/plugin-proposal-decorators": "^7.18.9",
     "@babel/plugin-transform-runtime": "^7.18.9",
     "@babel/plugin-transform-typescript": "^7.18.8",
-    "@babel/preset-env": "7.18.9",
+    "@babel/preset-env": "7.19.3",
     "@babel/preset-typescript": "^7.18.6",
     "@babel/runtime": "^7.18.9",
     "@sniptt/monads": "^0.5.10",
     "copy-webpack-plugin": "^11.0.0",
     "css-loader": "^6.7.1",
     "eslint": "^8.20.0",
+    "eslint-plugin-inferno": "^7.31.8",
     "eslint-plugin-prettier": "^4.2.1",
     "husky": "^8.0.1",
     "import-sort-style-module": "^6.0.0",
-    "lemmy-js-client": "0.17.0-rc.43",
+    "lemmy-js-client": "0.17.0-rc.46",
     "lint-staged": "^13.0.3",
     "mini-css-extract-plugin": "^2.6.1",
     "node-fetch": "^2.6.1",
     "sortpack": "^2.3.0",
     "style-loader": "^3.3.1",
     "terser": "^5.14.2",
-    "typescript": "^4.7.4",
+    "typescript": "^4.8.4",
     "webpack": "5.74.0",
     "webpack-cli": "^4.10.0",
-    "webpack-dev-server": "4.9.3",
+    "webpack-dev-server": "4.11.1",
     "webpack-node-externals": "^3.0.0"
   },
   "engines": {
index c68a889494a79a4de4101c7ebeff3cdf1d39f04e..bb594f0f7c0a8ff9eaf4e4c760563564b5310827 100644 (file)
@@ -53,7 +53,7 @@ section {
 }
 body {
  margin:0;
- font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
+ font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Cantarell,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
  font-size:.9375rem;
  font-weight:400;
  line-height:1.5;
index de1f69849ca6f3e37bef9a48617a50636398cee8..bb4e35589315ee3e2f2e732f70f734e05af1caeb 100644 (file)
@@ -1 +1 @@
-:root{--blue:#375a7f;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#e74c3c;--orange:#fd7e14;--yellow:#f39c12;--green:#00bc8c;--teal:#20c997;--cyan:#3498db;--white:#fff;--gray:#888;--gray-dark:#303030;--primary:#375a7f;--secondary:#444;--success:#00bc8c;--info:#3498db;--warning:#f39c12;--danger:#e74c3c;--light:#303030;--dark:#dee2e6;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:"Lato",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:.9375rem;font-weight:400;line-height:1.5;color:#dee2e6;text-align:left;background-color:#222}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#00bc8c;text-decoration:none;background-color:transparent}a:hover{color:#007053;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#888;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:3rem}.h2,h2{font-size:2.5rem}.h3,h3{font-size:2rem}.h4,h4{font-size:1.40625rem}.h5,h5{font-size:1.17188rem}.h6,h6{font-size:.9375rem}.lead{font-size:1.17188rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#333}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.17188rem}.blockquote-footer{display:block;font-size:80%;color:#888}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#888}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#222;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#dee2e6}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #444}.table thead th{vertical-align:bottom;border-bottom:2px solid #444}.table tbody+tbody{border-top:2px solid #444}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #444}.table-bordered td,.table-bordered th{border:1px solid #444}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:#303030}.table-hover tbody tr:hover{color:#dee2e6;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#c7d1db}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#97a9bc}.table-hover .table-primary:hover{background-color:#b7c4d1}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b7c4d1}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#cbcbcb}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#9e9e9e}.table-hover .table-secondary:hover{background-color:#bebebe}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#bebebe}.table-success,.table-success>td,.table-success>th{background-color:#b8ecdf}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#7adcc3}.table-hover .table-success:hover{background-color:#a4e7d6}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a4e7d6}.table-info,.table-info>td,.table-info>th{background-color:#c6e2f5}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#95c9ec}.table-hover .table-info:hover{background-color:#b0d7f1}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#b0d7f1}.table-warning,.table-warning>td,.table-warning>th{background-color:#fce3bd}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#f9cc84}.table-hover .table-warning:hover{background-color:#fbd9a5}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#fbd9a5}.table-danger,.table-danger>td,.table-danger>th{background-color:#f8cdc8}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#f3a29a}.table-hover .table-danger:hover{background-color:#f5b8b1}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f5b8b1}.table-light,.table-light>td,.table-light>th{background-color:#c5c5c5}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#939393}.table-hover .table-light:hover{background-color:#b8b8b8}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#b8b8b8}.table-dark,.table-dark>td,.table-dark>th{background-color:#f6f7f8}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#eef0f2}.table-hover .table-dark:hover{background-color:#e8eaed}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#e8eaed}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#303030;border-color:#434343}.table .thead-light th{color:#444;background-color:#ebebeb;border-color:#444}.table-dark{color:#fff;background-color:#303030}.table-dark td,.table-dark th,.table-dark thead th{border-color:#434343}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#fff;background-color:#444;background-clip:padding-box;border:1px solid #222;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #fff}.form-control:focus{color:#fff;background-color:#444;border-color:#739ac2;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#2b2b2b;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{appearance:none}select.form-control:focus::-ms-value{color:#fff;background-color:#444}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.17188rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.82031rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:.9375rem;line-height:1.5;color:#dee2e6;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#888}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#00bc8c;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #444 no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#00bc8c}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#00bc8c}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#00efb2;background-color:#00efb2}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#00bc8c}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#00bc8c}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#e74c3c;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e") #444 no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#e74c3c}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#e74c3c}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#ed7669;background-color:#ed7669}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#e74c3c}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#e74c3c}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#dee2e6;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:.9375rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#dee2e6;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-primary:hover{color:#fff;background-color:#2b4764;border-color:#28415b}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#2b4764;border-color:#28415b;box-shadow:0 0 0 .2rem rgba(85,115,146,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#28415b;border-color:#243a53}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(85,115,146,.5)}.btn-secondary{color:#fff;background-color:#444;border-color:#444}.btn-secondary:hover{color:#fff;background-color:#313131;border-color:#2b2b2b}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#313131;border-color:#2b2b2b;box-shadow:0 0 0 .2rem rgba(96,96,96,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#444;border-color:#444}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#2b2b2b;border-color:#242424}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(96,96,96,.5)}.btn-success{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-success:hover{color:#fff;background-color:#009670;border-color:#008966}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#009670;border-color:#008966;box-shadow:0 0 0 .2rem rgba(38,198,157,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#008966;border-color:#007c5d}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,198,157,.5)}.btn-info{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:hover{color:#fff;background-color:#2384c6;border-color:#217dbb}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#2384c6;border-color:#217dbb;box-shadow:0 0 0 .2rem rgba(82,167,224,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#217dbb;border-color:#1f76b0}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,167,224,.5)}.btn-warning{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:hover{color:#fff;background-color:#d4860b;border-color:#c87f0a}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#d4860b;border-color:#c87f0a;box-shadow:0 0 0 .2rem rgba(245,171,54,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#c87f0a;border-color:#bc770a}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(245,171,54,.5)}.btn-danger{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:hover{color:#fff;background-color:#e12e1c;border-color:#d62c1a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#e12e1c;border-color:#d62c1a;box-shadow:0 0 0 .2rem rgba(235,103,89,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#d62c1a;border-color:#ca2a19}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(235,103,89,.5)}.btn-light{color:#fff;background-color:#303030;border-color:#303030}.btn-light:hover{color:#fff;background-color:#1d1d1d;border-color:#171717}.btn-light.focus,.btn-light:focus{color:#fff;background-color:#1d1d1d;border-color:#171717;box-shadow:0 0 0 .2rem rgba(79,79,79,.5)}.btn-light.disabled,.btn-light:disabled{color:#fff;background-color:#303030;border-color:#303030}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#171717;border-color:#101010}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(79,79,79,.5)}.btn-dark{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-dark:hover{color:#222;background-color:#c8cfd6;border-color:#c1c9d0}.btn-dark.focus,.btn-dark:focus{color:#222;background-color:#c8cfd6;border-color:#c1c9d0;box-shadow:0 0 0 .2rem rgba(194,197,201,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#222;background-color:#c1c9d0;border-color:#bac2cb}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(194,197,201,.5)}.btn-outline-primary{color:#375a7f;border-color:#375a7f}.btn-outline-primary:hover{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#375a7f;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.btn-outline-secondary{color:#444;border-color:#444}.btn-outline-secondary:hover{color:#fff;background-color:#444;border-color:#444}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#444;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#444;border-color:#444}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.btn-outline-success{color:#00bc8c;border-color:#00bc8c}.btn-outline-success:hover{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#00bc8c;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.btn-outline-info{color:#3498db;border-color:#3498db}.btn-outline-info:hover{color:#fff;background-color:#3498db;border-color:#3498db}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#3498db;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#3498db;border-color:#3498db}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.btn-outline-warning{color:#f39c12;border-color:#f39c12}.btn-outline-warning:hover{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#f39c12;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.btn-outline-danger{color:#e74c3c;border-color:#e74c3c}.btn-outline-danger:hover{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#e74c3c;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.btn-outline-light{color:#303030;border-color:#303030}.btn-outline-light:hover{color:#fff;background-color:#303030;border-color:#303030}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#303030;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#fff;background-color:#303030;border-color:#303030}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.btn-outline-dark{color:#dee2e6;border-color:#dee2e6}.btn-outline-dark:hover{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#dee2e6;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.btn-link{font-weight:400;color:#00bc8c;text-decoration:none}.btn-link:hover{color:#007053;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#888;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:.9375rem;color:#dee2e6;text-align:left;list-style:none;background-color:#222;background-clip:padding-box;border:1px solid #444;border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #444}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#fff;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#fff;text-decoration:none;background-color:#375a7f}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#375a7f}.dropdown-item.disabled,.dropdown-item:disabled{color:#888;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.82031rem;color:#888;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:.9375rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.40625rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.20312rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#375a7f;background-color:#375a7f}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#739ac2}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#97b3d2;border-color:#97b3d2}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#888}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#2b2b2b}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#444;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#375a7f;background-color:#375a7f}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.20312rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#444;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#fff;vertical-align:middle;background:#444 url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #222;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#739ac2;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-select:focus::-ms-value{color:#fff;background-color:#444}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#888;background-color:#ebebeb}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #fff}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.82031rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.17188rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#739ac2;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#2b2b2b}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#adb5bd;background-color:#444;border:1px solid #222;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#adb5bd;content:"Browse";background-color:#444;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#97b3d2}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#97b3d2}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#97b3d2}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 2rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#adb5bd;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #444}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#444 #444 transparent}.nav-tabs .nav-link.disabled{color:#adb5bd;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#fff;background-color:#222;border-color:#444 #444 transparent}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#375a7f}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:1rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.32422rem;padding-bottom:.32422rem;margin-right:1rem;font-size:1.17188rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.17188rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:#fff}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:#fff}.navbar-light .navbar-nav .nav-link{color:rgba(255,255,255,.6)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:#fff}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:#fff}.navbar-light .navbar-toggler{color:rgba(255,255,255,.6);border-color:rgba(34,34,34,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(255,255,255,.6)}.navbar-light .navbar-text a{color:#fff}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:#fff}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.6)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:#fff}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.6);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.6)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#303030;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#444;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:#444;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#444;border-radius:.25rem}.breadcrumb-item{display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#888;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#888}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:0;line-height:1.25;color:#fff;background-color:#00bc8c;border:0 solid transparent}.page-link:hover{z-index:2;color:#fff;text-decoration:none;background-color:#00efb2;border-color:transparent}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#00efb2;border-color:transparent}.page-item.disabled .page-link{color:#fff;pointer-events:none;cursor:auto;background-color:#007053;border-color:transparent}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.17188rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#375a7f}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#28415b}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.badge-secondary{color:#fff;background-color:#444}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#2b2b2b}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.badge-success{color:#fff;background-color:#00bc8c}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#008966}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.badge-info{color:#fff;background-color:#3498db}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#217dbb}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.badge-warning{color:#fff;background-color:#f39c12}a.badge-warning:focus,a.badge-warning:hover{color:#fff;background-color:#c87f0a}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.badge-danger{color:#fff;background-color:#e74c3c}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#d62c1a}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.badge-light{color:#fff;background-color:#303030}a.badge-light:focus,a.badge-light:hover{color:#fff;background-color:#171717}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.badge-dark{color:#222;background-color:#dee2e6}a.badge-dark:focus,a.badge-dark:hover{color:#222;background-color:#c1c9d0}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#303030;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3.90625rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#1d2f42;background-color:#d7dee5;border-color:#c7d1db}.alert-primary hr{border-top-color:#b7c4d1}.alert-primary .alert-link{color:#0d161f}.alert-secondary{color:#232323;background-color:#dadada;border-color:#cbcbcb}.alert-secondary hr{border-top-color:#bebebe}.alert-secondary .alert-link{color:#0a0a0a}.alert-success{color:#006249;background-color:#ccf2e8;border-color:#b8ecdf}.alert-success hr{border-top-color:#a4e7d6}.alert-success .alert-link{color:#002f23}.alert-info{color:#1b4f72;background-color:#d6eaf8;border-color:#c6e2f5}.alert-info hr{border-top-color:#b0d7f1}.alert-info .alert-link{color:#113249}.alert-warning{color:#7e5109;background-color:#fdebd0;border-color:#fce3bd}.alert-warning hr{border-top-color:#fbd9a5}.alert-warning .alert-link{color:#4e3206}.alert-danger{color:#78281f;background-color:#fadbd8;border-color:#f8cdc8}.alert-danger hr{border-top-color:#f5b8b1}.alert-danger .alert-link{color:#4f1a15}.alert-light{color:#191919;background-color:#d6d6d6;border-color:#c5c5c5}.alert-light hr{border-top-color:#b8b8b8}.alert-light .alert-link{color:#000}.alert-dark{color:#737678;background-color:#f8f9fa;border-color:#f6f7f8}.alert-dark hr{border-top-color:#e8eaed}.alert-dark .alert-link{color:#5a5c5e}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.70312rem;background-color:#444;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#375a7f;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#444;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#444;text-decoration:none;background-color:#444}.list-group-item-action:active{color:#dee2e6;background-color:#ebebeb}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#303030;border:1px solid #444}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#888;pointer-events:none;background-color:#303030}.list-group-item.active{z-index:2;color:#fff;background-color:#375a7f;border-color:#375a7f}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#1d2f42;background-color:#c7d1db}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#1d2f42;background-color:#b7c4d1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#1d2f42;border-color:#1d2f42}.list-group-item-secondary{color:#232323;background-color:#cbcbcb}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#232323;background-color:#bebebe}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#232323;border-color:#232323}.list-group-item-success{color:#006249;background-color:#b8ecdf}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#006249;background-color:#a4e7d6}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#006249;border-color:#006249}.list-group-item-info{color:#1b4f72;background-color:#c6e2f5}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1b4f72;background-color:#b0d7f1}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1b4f72;border-color:#1b4f72}.list-group-item-warning{color:#7e5109;background-color:#fce3bd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#7e5109;background-color:#fbd9a5}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#7e5109;border-color:#7e5109}.list-group-item-danger{color:#78281f;background-color:#f8cdc8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#78281f;background-color:#f5b8b1}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#78281f;border-color:#78281f}.list-group-item-light{color:#191919;background-color:#c5c5c5}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#191919;background-color:#b8b8b8}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#191919;border-color:#191919}.list-group-item-dark{color:#737678;background-color:#f6f7f8}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#737678;background-color:#e8eaed}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#737678;border-color:#737678}.close{float:right;font-size:1.40625rem;font-weight:700;line-height:1;color:#fff;text-shadow:none;opacity:.5}.close:hover{color:#fff;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:#444;background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#888;background-color:#303030;background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#303030;background-clip:padding-box;border:1px solid #444;border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #444;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #444;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;background-color:#303030;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#303030}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#303030}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#303030}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #444}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#303030}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:.9375rem;background-color:#444;border-bottom:1px solid #373737;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#dee2e6}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#375a7f!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#28415b!important}.bg-secondary{background-color:#444!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#2b2b2b!important}.bg-success{background-color:#00bc8c!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#008966!important}.bg-info{background-color:#3498db!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#217dbb!important}.bg-warning{background-color:#f39c12!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#c87f0a!important}.bg-danger{background-color:#e74c3c!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#d62c1a!important}.bg-light{background-color:#303030!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#171717!important}.bg-dark{background-color:#dee2e6!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#c1c9d0!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#375a7f!important}.border-secondary{border-color:#444!important}.border-success{border-color:#00bc8c!important}.border-info{border-color:#3498db!important}.border-warning{border-color:#f39c12!important}.border-danger{border-color:#e74c3c!important}.border-light{border-color:#303030!important}.border-dark{border-color:#dee2e6!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#375a7f!important}a.text-primary:focus,a.text-primary:hover{color:#20344a!important}.text-secondary{color:#444!important}a.text-secondary:focus,a.text-secondary:hover{color:#1e1e1e!important}.text-success{color:#00bc8c!important}a.text-success:focus,a.text-success:hover{color:#007053!important}.text-info{color:#3498db!important}a.text-info:focus,a.text-info:hover{color:#1d6fa5!important}.text-warning{color:#f39c12!important}a.text-warning:focus,a.text-warning:hover{color:#b06f09!important}.text-danger{color:#e74c3c!important}a.text-danger:focus,a.text-danger:hover{color:#bf2718!important}.text-light{color:#303030!important}a.text-light:focus,a.text-light:hover{color:#0a0a0a!important}.text-dark{color:#dee2e6!important}a.text-dark:focus,a.text-dark:hover{color:#b2bcc5!important}.text-body{color:#dee2e6!important}.text-muted{color:#888!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#444}.table .thead-dark th{color:inherit;border-color:#444}}
+:root{--blue:#375a7f;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#e74c3c;--orange:#fd7e14;--yellow:#f39c12;--green:#00bc8c;--teal:#20c997;--cyan:#3498db;--white:#fff;--gray:#888;--gray-dark:#303030;--primary:#375a7f;--secondary:#444;--success:#00bc8c;--info:#3498db;--warning:#f39c12;--danger:#e74c3c;--light:#303030;--dark:#dee2e6;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:"Lato",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Cantarell,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:.9375rem;font-weight:400;line-height:1.5;color:#dee2e6;text-align:left;background-color:#222}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#00bc8c;text-decoration:none;background-color:transparent}a:hover{color:#007053;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#888;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:3rem}.h2,h2{font-size:2.5rem}.h3,h3{font-size:2rem}.h4,h4{font-size:1.40625rem}.h5,h5{font-size:1.17188rem}.h6,h6{font-size:.9375rem}.lead{font-size:1.17188rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#333}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.17188rem}.blockquote-footer{display:block;font-size:80%;color:#888}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#888}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#222;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#dee2e6}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #444}.table thead th{vertical-align:bottom;border-bottom:2px solid #444}.table tbody+tbody{border-top:2px solid #444}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #444}.table-bordered td,.table-bordered th{border:1px solid #444}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:#303030}.table-hover tbody tr:hover{color:#dee2e6;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#c7d1db}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#97a9bc}.table-hover .table-primary:hover{background-color:#b7c4d1}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b7c4d1}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#cbcbcb}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#9e9e9e}.table-hover .table-secondary:hover{background-color:#bebebe}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#bebebe}.table-success,.table-success>td,.table-success>th{background-color:#b8ecdf}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#7adcc3}.table-hover .table-success:hover{background-color:#a4e7d6}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a4e7d6}.table-info,.table-info>td,.table-info>th{background-color:#c6e2f5}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#95c9ec}.table-hover .table-info:hover{background-color:#b0d7f1}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#b0d7f1}.table-warning,.table-warning>td,.table-warning>th{background-color:#fce3bd}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#f9cc84}.table-hover .table-warning:hover{background-color:#fbd9a5}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#fbd9a5}.table-danger,.table-danger>td,.table-danger>th{background-color:#f8cdc8}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#f3a29a}.table-hover .table-danger:hover{background-color:#f5b8b1}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f5b8b1}.table-light,.table-light>td,.table-light>th{background-color:#c5c5c5}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#939393}.table-hover .table-light:hover{background-color:#b8b8b8}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#b8b8b8}.table-dark,.table-dark>td,.table-dark>th{background-color:#f6f7f8}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#eef0f2}.table-hover .table-dark:hover{background-color:#e8eaed}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#e8eaed}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#303030;border-color:#434343}.table .thead-light th{color:#444;background-color:#ebebeb;border-color:#444}.table-dark{color:#fff;background-color:#303030}.table-dark td,.table-dark th,.table-dark thead th{border-color:#434343}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#fff;background-color:#444;background-clip:padding-box;border:1px solid #222;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #fff}.form-control:focus{color:#fff;background-color:#444;border-color:#739ac2;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#2b2b2b;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{appearance:none}select.form-control:focus::-ms-value{color:#fff;background-color:#444}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.17188rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.82031rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:.9375rem;line-height:1.5;color:#dee2e6;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#888}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#00bc8c;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #444 no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#00bc8c}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#00bc8c}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#00efb2;background-color:#00efb2}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#00bc8c}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#00bc8c}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#00bc8c;box-shadow:0 0 0 .2rem rgba(0,188,140,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#e74c3c;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e") #444 no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#e74c3c}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#e74c3c}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#ed7669;background-color:#ed7669}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#e74c3c}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#e74c3c}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#e74c3c;box-shadow:0 0 0 .2rem rgba(231,76,60,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#dee2e6;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:.9375rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#dee2e6;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-primary:hover{color:#fff;background-color:#2b4764;border-color:#28415b}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#2b4764;border-color:#28415b;box-shadow:0 0 0 .2rem rgba(85,115,146,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#28415b;border-color:#243a53}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(85,115,146,.5)}.btn-secondary{color:#fff;background-color:#444;border-color:#444}.btn-secondary:hover{color:#fff;background-color:#313131;border-color:#2b2b2b}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#313131;border-color:#2b2b2b;box-shadow:0 0 0 .2rem rgba(96,96,96,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#444;border-color:#444}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#2b2b2b;border-color:#242424}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(96,96,96,.5)}.btn-success{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-success:hover{color:#fff;background-color:#009670;border-color:#008966}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#009670;border-color:#008966;box-shadow:0 0 0 .2rem rgba(38,198,157,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#008966;border-color:#007c5d}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,198,157,.5)}.btn-info{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:hover{color:#fff;background-color:#2384c6;border-color:#217dbb}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#2384c6;border-color:#217dbb;box-shadow:0 0 0 .2rem rgba(82,167,224,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#217dbb;border-color:#1f76b0}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,167,224,.5)}.btn-warning{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:hover{color:#fff;background-color:#d4860b;border-color:#c87f0a}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#d4860b;border-color:#c87f0a;box-shadow:0 0 0 .2rem rgba(245,171,54,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#c87f0a;border-color:#bc770a}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(245,171,54,.5)}.btn-danger{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:hover{color:#fff;background-color:#e12e1c;border-color:#d62c1a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#e12e1c;border-color:#d62c1a;box-shadow:0 0 0 .2rem rgba(235,103,89,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#d62c1a;border-color:#ca2a19}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(235,103,89,.5)}.btn-light{color:#fff;background-color:#303030;border-color:#303030}.btn-light:hover{color:#fff;background-color:#1d1d1d;border-color:#171717}.btn-light.focus,.btn-light:focus{color:#fff;background-color:#1d1d1d;border-color:#171717;box-shadow:0 0 0 .2rem rgba(79,79,79,.5)}.btn-light.disabled,.btn-light:disabled{color:#fff;background-color:#303030;border-color:#303030}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#171717;border-color:#101010}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(79,79,79,.5)}.btn-dark{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-dark:hover{color:#222;background-color:#c8cfd6;border-color:#c1c9d0}.btn-dark.focus,.btn-dark:focus{color:#222;background-color:#c8cfd6;border-color:#c1c9d0;box-shadow:0 0 0 .2rem rgba(194,197,201,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#222;background-color:#c1c9d0;border-color:#bac2cb}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(194,197,201,.5)}.btn-outline-primary{color:#375a7f;border-color:#375a7f}.btn-outline-primary:hover{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#375a7f;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#375a7f;border-color:#375a7f}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.btn-outline-secondary{color:#444;border-color:#444}.btn-outline-secondary:hover{color:#fff;background-color:#444;border-color:#444}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#444;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#444;border-color:#444}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.btn-outline-success{color:#00bc8c;border-color:#00bc8c}.btn-outline-success:hover{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#00bc8c;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#00bc8c;border-color:#00bc8c}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.btn-outline-info{color:#3498db;border-color:#3498db}.btn-outline-info:hover{color:#fff;background-color:#3498db;border-color:#3498db}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#3498db;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#3498db;border-color:#3498db}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.btn-outline-warning{color:#f39c12;border-color:#f39c12}.btn-outline-warning:hover{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#f39c12;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.btn-outline-danger{color:#e74c3c;border-color:#e74c3c}.btn-outline-danger:hover{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#e74c3c;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.btn-outline-light{color:#303030;border-color:#303030}.btn-outline-light:hover{color:#fff;background-color:#303030;border-color:#303030}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#303030;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#fff;background-color:#303030;border-color:#303030}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.btn-outline-dark{color:#dee2e6;border-color:#dee2e6}.btn-outline-dark:hover{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#dee2e6;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#222;background-color:#dee2e6;border-color:#dee2e6}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.btn-link{font-weight:400;color:#00bc8c;text-decoration:none}.btn-link:hover{color:#007053;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#888;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:.9375rem;color:#dee2e6;text-align:left;list-style:none;background-color:#222;background-clip:padding-box;border:1px solid #444;border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #444}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#fff;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#fff;text-decoration:none;background-color:#375a7f}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#375a7f}.dropdown-item.disabled,.dropdown-item:disabled{color:#888;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.82031rem;color:#888;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:.9375rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.40625rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.20312rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#375a7f;background-color:#375a7f}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#739ac2}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#97b3d2;border-color:#97b3d2}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#888}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#2b2b2b}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#444;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#375a7f;background-color:#375a7f}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.20312rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#444;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(55,90,127,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#fff;vertical-align:middle;background:#444 url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23303030' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #222;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#739ac2;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-select:focus::-ms-value{color:#fff;background-color:#444}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#888;background-color:#ebebeb}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #fff}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.82031rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.17188rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#739ac2;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#2b2b2b}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#adb5bd;background-color:#444;border:1px solid #222;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#adb5bd;content:"Browse";background-color:#444;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #222,0 0 0 .2rem rgba(55,90,127,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#97b3d2}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#97b3d2}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#375a7f;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#97b3d2}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 2rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#adb5bd;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #444}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#444 #444 transparent}.nav-tabs .nav-link.disabled{color:#adb5bd;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#fff;background-color:#222;border-color:#444 #444 transparent}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#375a7f}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:1rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.32422rem;padding-bottom:.32422rem;margin-right:1rem;font-size:1.17188rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.17188rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:#fff}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:#fff}.navbar-light .navbar-nav .nav-link{color:rgba(255,255,255,.6)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:#fff}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:#fff}.navbar-light .navbar-toggler{color:rgba(255,255,255,.6);border-color:rgba(34,34,34,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(255,255,255,.6)}.navbar-light .navbar-text a{color:#fff}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:#fff}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.6)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:#fff}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.6);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.6)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#303030;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#444;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:#444;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#444;border-radius:.25rem}.breadcrumb-item{display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#888;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#888}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:0;line-height:1.25;color:#fff;background-color:#00bc8c;border:0 solid transparent}.page-link:hover{z-index:2;color:#fff;text-decoration:none;background-color:#00efb2;border-color:transparent}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#00efb2;border-color:transparent}.page-item.disabled .page-link{color:#fff;pointer-events:none;cursor:auto;background-color:#007053;border-color:transparent}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.17188rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#375a7f}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#28415b}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(55,90,127,.5)}.badge-secondary{color:#fff;background-color:#444}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#2b2b2b}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(68,68,68,.5)}.badge-success{color:#fff;background-color:#00bc8c}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#008966}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,188,140,.5)}.badge-info{color:#fff;background-color:#3498db}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#217dbb}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,152,219,.5)}.badge-warning{color:#fff;background-color:#f39c12}a.badge-warning:focus,a.badge-warning:hover{color:#fff;background-color:#c87f0a}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(243,156,18,.5)}.badge-danger{color:#fff;background-color:#e74c3c}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#d62c1a}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(231,76,60,.5)}.badge-light{color:#fff;background-color:#303030}a.badge-light:focus,a.badge-light:hover{color:#fff;background-color:#171717}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(48,48,48,.5)}.badge-dark{color:#222;background-color:#dee2e6}a.badge-dark:focus,a.badge-dark:hover{color:#222;background-color:#c1c9d0}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(222,226,230,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#303030;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3.90625rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#1d2f42;background-color:#d7dee5;border-color:#c7d1db}.alert-primary hr{border-top-color:#b7c4d1}.alert-primary .alert-link{color:#0d161f}.alert-secondary{color:#232323;background-color:#dadada;border-color:#cbcbcb}.alert-secondary hr{border-top-color:#bebebe}.alert-secondary .alert-link{color:#0a0a0a}.alert-success{color:#006249;background-color:#ccf2e8;border-color:#b8ecdf}.alert-success hr{border-top-color:#a4e7d6}.alert-success .alert-link{color:#002f23}.alert-info{color:#1b4f72;background-color:#d6eaf8;border-color:#c6e2f5}.alert-info hr{border-top-color:#b0d7f1}.alert-info .alert-link{color:#113249}.alert-warning{color:#7e5109;background-color:#fdebd0;border-color:#fce3bd}.alert-warning hr{border-top-color:#fbd9a5}.alert-warning .alert-link{color:#4e3206}.alert-danger{color:#78281f;background-color:#fadbd8;border-color:#f8cdc8}.alert-danger hr{border-top-color:#f5b8b1}.alert-danger .alert-link{color:#4f1a15}.alert-light{color:#191919;background-color:#d6d6d6;border-color:#c5c5c5}.alert-light hr{border-top-color:#b8b8b8}.alert-light .alert-link{color:#000}.alert-dark{color:#737678;background-color:#f8f9fa;border-color:#f6f7f8}.alert-dark hr{border-top-color:#e8eaed}.alert-dark .alert-link{color:#5a5c5e}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.70312rem;background-color:#444;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#375a7f;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#444;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#444;text-decoration:none;background-color:#444}.list-group-item-action:active{color:#dee2e6;background-color:#ebebeb}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#303030;border:1px solid #444}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#888;pointer-events:none;background-color:#303030}.list-group-item.active{z-index:2;color:#fff;background-color:#375a7f;border-color:#375a7f}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#1d2f42;background-color:#c7d1db}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#1d2f42;background-color:#b7c4d1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#1d2f42;border-color:#1d2f42}.list-group-item-secondary{color:#232323;background-color:#cbcbcb}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#232323;background-color:#bebebe}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#232323;border-color:#232323}.list-group-item-success{color:#006249;background-color:#b8ecdf}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#006249;background-color:#a4e7d6}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#006249;border-color:#006249}.list-group-item-info{color:#1b4f72;background-color:#c6e2f5}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1b4f72;background-color:#b0d7f1}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1b4f72;border-color:#1b4f72}.list-group-item-warning{color:#7e5109;background-color:#fce3bd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#7e5109;background-color:#fbd9a5}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#7e5109;border-color:#7e5109}.list-group-item-danger{color:#78281f;background-color:#f8cdc8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#78281f;background-color:#f5b8b1}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#78281f;border-color:#78281f}.list-group-item-light{color:#191919;background-color:#c5c5c5}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#191919;background-color:#b8b8b8}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#191919;border-color:#191919}.list-group-item-dark{color:#737678;background-color:#f6f7f8}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#737678;background-color:#e8eaed}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#737678;border-color:#737678}.close{float:right;font-size:1.40625rem;font-weight:700;line-height:1;color:#fff;text-shadow:none;opacity:.5}.close:hover{color:#fff;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:#444;background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#888;background-color:#303030;background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#303030;background-clip:padding-box;border:1px solid #444;border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #444;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #444;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;background-color:#303030;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#303030}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#303030}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#303030}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #444}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#303030}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:.9375rem;background-color:#444;border-bottom:1px solid #373737;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#dee2e6}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#375a7f!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#28415b!important}.bg-secondary{background-color:#444!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#2b2b2b!important}.bg-success{background-color:#00bc8c!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#008966!important}.bg-info{background-color:#3498db!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#217dbb!important}.bg-warning{background-color:#f39c12!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#c87f0a!important}.bg-danger{background-color:#e74c3c!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#d62c1a!important}.bg-light{background-color:#303030!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#171717!important}.bg-dark{background-color:#dee2e6!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#c1c9d0!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#375a7f!important}.border-secondary{border-color:#444!important}.border-success{border-color:#00bc8c!important}.border-info{border-color:#3498db!important}.border-warning{border-color:#f39c12!important}.border-danger{border-color:#e74c3c!important}.border-light{border-color:#303030!important}.border-dark{border-color:#dee2e6!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#375a7f!important}a.text-primary:focus,a.text-primary:hover{color:#20344a!important}.text-secondary{color:#444!important}a.text-secondary:focus,a.text-secondary:hover{color:#1e1e1e!important}.text-success{color:#00bc8c!important}a.text-success:focus,a.text-success:hover{color:#007053!important}.text-info{color:#3498db!important}a.text-info:focus,a.text-info:hover{color:#1d6fa5!important}.text-warning{color:#f39c12!important}a.text-warning:focus,a.text-warning:hover{color:#b06f09!important}.text-danger{color:#e74c3c!important}a.text-danger:focus,a.text-danger:hover{color:#bf2718!important}.text-light{color:#303030!important}a.text-light:focus,a.text-light:hover{color:#0a0a0a!important}.text-dark{color:#dee2e6!important}a.text-dark:focus,a.text-dark:hover{color:#b2bcc5!important}.text-body{color:#dee2e6!important}.text-muted{color:#888!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#444}.table .thead-dark th{color:inherit;border-color:#444}}
index 72119a8d601cc9d7f6f21aa98b7e6f933d09e487..960f6badda7b4e50c8ca3058e7c612716c02daa2 100644 (file)
@@ -42,7 +42,7 @@ export class App extends Component<any, any> {
                 none: <></>,
               })}
             <Navbar siteRes={siteRes} />
-            <div class="mt-4 p-0 fl-1">
+            <div className="mt-4 p-0 fl-1">
               <Switch>
                 {routes.map(({ path, exact, component: C, ...rest }) => (
                   <Route
index e5e1db5a5b0a59eb08ecd08ac818506cd9b42885..f2a5e83c916ccb9734a32c2b3d7222551b3c9c00 100644 (file)
@@ -16,16 +16,16 @@ export class Footer extends Component<FooterProps, any> {
 
   render() {
     return (
-      <nav class="container navbar navbar-expand-md navbar-light navbar-bg p-3">
+      <nav className="container navbar navbar-expand-md navbar-light navbar-bg p-3">
         <div className="navbar-collapse">
-          <ul class="navbar-nav ml-auto">
+          <ul className="navbar-nav ml-auto">
             {this.props.site.version !== VERSION && (
-              <li class="nav-item">
-                <span class="nav-link">UI: {VERSION}</span>
+              <li className="nav-item">
+                <span className="nav-link">UI: {VERSION}</span>
               </li>
             )}
-            <li class="nav-item">
-              <span class="nav-link">BE: {this.props.site.version}</span>
+            <li className="nav-item">
+              <span className="nav-link">BE: {this.props.site.version}</span>
             </li>
             <li className="nav-item">
               <NavLink className="nav-link" to="/modlog">
@@ -42,23 +42,23 @@ export class Footer extends Component<FooterProps, any> {
               </li>
             )}
             {this.props.site.federated_instances && (
-              <li class="nav-item">
+              <li className="nav-item">
                 <NavLink className="nav-link" to="/instances">
                   {i18n.t("instances")}
                 </NavLink>
               </li>
             )}
-            <li class="nav-item">
+            <li className="nav-item">
               <a className="nav-link" href={docsUrl}>
                 {i18n.t("docs")}
               </a>
             </li>
-            <li class="nav-item">
+            <li className="nav-item">
               <a className="nav-link" href={repoUrl}>
                 {i18n.t("code")}
               </a>
             </li>
-            <li class="nav-item">
+            <li className="nav-item">
               <a className="nav-link" href={joinLemmyUrl}>
                 {i18n.t("join_lemmy")}
               </a>
index 2408a76b84306fa76476d4e4a023090831bcafeb..d6bc7727db2ccee4b036fd170209160cb766011c 100644 (file)
@@ -1,4 +1,4 @@
-import { None, Some } from "@sniptt/monads";
+import { None } from "@sniptt/monads";
 import { Component, createRef, linkEvent, RefObject } from "inferno";
 import { NavLink } from "inferno-router";
 import {
@@ -21,6 +21,7 @@ import { UserService, WebSocketService } from "../../services";
 import {
   amAdmin,
   auth,
+  canCreateCommunity,
   donateLemmyUrl,
   isBrowser,
   notifyComment,
@@ -144,8 +145,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
   // TODO class active corresponding to current page
   navbar() {
     return (
-      <nav class="navbar navbar-expand-md navbar-light shadow-sm p-0 px-3">
-        <div class="container">
+      <nav className="navbar navbar-expand-md navbar-light shadow-sm p-0 px-3">
+        <div className="container">
           {this.props.siteRes.site_view.match({
             some: siteView => (
               <NavLink
@@ -166,7 +167,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
           })}
           {UserService.Instance.myUserInfo.isSome() && (
             <>
-              <ul class="navbar-nav ml-auto">
+              <ul className="navbar-nav ml-auto">
                 <li className="nav-item">
                   <NavLink
                     to="/inbox"
@@ -179,7 +180,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   >
                     <Icon icon="bell" />
                     {this.state.unreadInboxCount > 0 && (
-                      <span class="mx-1 badge badge-light">
+                      <span className="mx-1 badge badge-light">
                         {numToSI(this.state.unreadInboxCount)}
                       </span>
                     )}
@@ -187,7 +188,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                 </li>
               </ul>
               {this.moderatesSomething && (
-                <ul class="navbar-nav ml-1">
+                <ul className="navbar-nav ml-1">
                   <li className="nav-item">
                     <NavLink
                       to="/reports"
@@ -200,7 +201,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                     >
                       <Icon icon="shield" />
                       {this.state.unreadReportCount > 0 && (
-                        <span class="mx-1 badge badge-light">
+                        <span className="mx-1 badge badge-light">
                           {numToSI(this.state.unreadReportCount)}
                         </span>
                       )}
@@ -208,8 +209,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   </li>
                 </ul>
               )}
-              {this.amAdmin && (
-                <ul class="navbar-nav ml-1">
+              {amAdmin() && (
+                <ul className="navbar-nav ml-1">
                   <li className="nav-item">
                     <NavLink
                       to="/registration_applications"
@@ -224,7 +225,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                     >
                       <Icon icon="clipboard" />
                       {this.state.unreadApplicationCount > 0 && (
-                        <span class="mx-1 badge badge-light">
+                        <span className="mx-1 badge badge-light">
                           {numToSI(this.state.unreadApplicationCount)}
                         </span>
                       )}
@@ -235,7 +236,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
             </>
           )}
           <button
-            class="navbar-toggler border-0 p-1"
+            className="navbar-toggler border-0 p-1"
             type="button"
             aria-label="menu"
             onClick={linkEvent(this, this.handleToggleExpandNavbar)}
@@ -246,8 +247,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
           <div
             className={`${!this.state.expanded && "collapse"} navbar-collapse`}
           >
-            <ul class="navbar-nav my-2 mr-auto">
-              <li class="nav-item">
+            <ul className="navbar-nav my-2 mr-auto">
+              <li className="nav-item">
                 <NavLink
                   to="/communities"
                   className="nav-link"
@@ -257,11 +258,15 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   {i18n.t("communities")}
                 </NavLink>
               </li>
-              <li class="nav-item">
+              <li className="nav-item">
+                {/* TODO make sure this works: https://github.com/infernojs/inferno/issues/1608 */}
                 <NavLink
                   to={{
                     pathname: "/create_post",
-                    prevPath: this.currentLocation,
+                    search: "",
+                    hash: "",
+                    key: "",
+                    state: { prevPath: this.currentLocation },
                   }}
                   className="nav-link"
                   onMouseUp={linkEvent(this, this.handleHideExpandNavbar)}
@@ -270,8 +275,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   {i18n.t("create_post")}
                 </NavLink>
               </li>
-              {this.canCreateCommunity && (
-                <li class="nav-item">
+              {canCreateCommunity(this.props.siteRes) && (
+                <li className="nav-item">
                   <NavLink
                     to="/create_community"
                     className="nav-link"
@@ -282,7 +287,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   </NavLink>
                 </li>
               )}
-              <li class="nav-item">
+              <li className="nav-item">
                 <a
                   className="nav-link"
                   title={i18n.t("support_lemmy")}
@@ -292,8 +297,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                 </a>
               </li>
             </ul>
-            <ul class="navbar-nav my-2">
-              {this.amAdmin && (
+            <ul className="navbar-nav my-2">
+              {amAdmin() && (
                 <li className="nav-item">
                   <NavLink
                     to="/admin"
@@ -310,12 +315,12 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
               /^\/search/
             ) && (
               <form
-                class="form-inline mr-2"
+                className="form-inline mr-2"
                 onSubmit={linkEvent(this, this.handleSearchSubmit)}
               >
                 <input
                   id="search-input"
-                  class={`form-control mr-0 search-input ${
+                  className={`form-control mr-0 search-input ${
                     this.state.toggleSearch ? "show-input" : "hide-input"
                   }`}
                   onInput={linkEvent(this, this.handleSearchParam)}
@@ -325,13 +330,13 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   placeholder={i18n.t("search")}
                   onBlur={linkEvent(this, this.handleSearchBlur)}
                 ></input>
-                <label class="sr-only" htmlFor="search-input">
+                <label className="sr-only" htmlFor="search-input">
                   {i18n.t("search")}
                 </label>
                 <button
                   name="search-btn"
                   onClick={linkEvent(this, this.handleSearchBtn)}
-                  class="px-1 btn btn-link"
+                  className="px-1 btn btn-link"
                   style="color: var(--gray)"
                   aria-label={i18n.t("search")}
                 >
@@ -341,7 +346,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
             )}
             {UserService.Instance.myUserInfo.isSome() ? (
               <>
-                <ul class="navbar-nav my-2">
+                <ul className="navbar-nav my-2">
                   <li className="nav-item">
                     <NavLink
                       className="nav-link"
@@ -354,7 +359,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                     >
                       <Icon icon="bell" />
                       {this.state.unreadInboxCount > 0 && (
-                        <span class="ml-1 badge badge-light">
+                        <span className="ml-1 badge badge-light">
                           {numToSI(this.state.unreadInboxCount)}
                         </span>
                       )}
@@ -362,7 +367,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   </li>
                 </ul>
                 {this.moderatesSomething && (
-                  <ul class="navbar-nav my-2">
+                  <ul className="navbar-nav my-2">
                     <li className="nav-item">
                       <NavLink
                         className="nav-link"
@@ -375,7 +380,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                       >
                         <Icon icon="shield" />
                         {this.state.unreadReportCount > 0 && (
-                          <span class="ml-1 badge badge-light">
+                          <span className="ml-1 badge badge-light">
                             {numToSI(this.state.unreadReportCount)}
                           </span>
                         )}
@@ -383,8 +388,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                     </li>
                   </ul>
                 )}
-                {this.amAdmin && (
-                  <ul class="navbar-nav my-2">
+                {amAdmin() && (
+                  <ul className="navbar-nav my-2">
                     <li className="nav-item">
                       <NavLink
                         to="/registration_applications"
@@ -399,7 +404,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                       >
                         <Icon icon="clipboard" />
                         {this.state.unreadApplicationCount > 0 && (
-                          <span class="mx-1 badge badge-light">
+                          <span className="mx-1 badge badge-light">
                             {numToSI(this.state.unreadApplicationCount)}
                           </span>
                         )}
@@ -411,10 +416,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   .map(m => m.local_user_view.person)
                   .match({
                     some: person => (
-                      <ul class="navbar-nav">
-                        <li class="nav-item dropdown">
+                      <ul className="navbar-nav">
+                        <li className="nav-item dropdown">
                           <button
-                            class="nav-link btn btn-link dropdown-toggle"
+                            className="nav-link btn btn-link dropdown-toggle"
                             onClick={linkEvent(this, this.handleToggleDropdown)}
                             id="navbarDropdown"
                             role="button"
@@ -433,7 +438,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                           </button>
                           {this.state.showDropdown && (
                             <div
-                              class="dropdown-content"
+                              className="dropdown-content"
                               onMouseLeave={linkEvent(
                                 this,
                                 this.handleToggleDropdown
@@ -460,7 +465,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                                 </NavLink>
                               </li>
                               <li>
-                                <hr class="dropdown-divider" />
+                                <hr className="dropdown-divider" />
                               </li>
                               <li className="nav-item">
                                 <button
@@ -484,7 +489,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   })}
               </>
             ) : (
-              <ul class="navbar-nav my-2">
+              <ul className="navbar-nav my-2">
                 <li className="nav-item">
                   <NavLink
                     to="/login"
@@ -520,20 +525,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     );
   }
 
-  get amAdmin(): boolean {
-    return amAdmin(Some(this.props.siteRes.admins));
-  }
-
-  get canCreateCommunity(): boolean {
-    let adminOnly = this.props.siteRes.site_view
-      .map(s => s.site.community_creation_admin_only)
-      .unwrapOr(false);
-    return !adminOnly || this.amAdmin;
-  }
-
   handleToggleExpandNavbar(i: Navbar) {
-    i.state.expanded = !i.state.expanded;
-    i.setState(i.state);
+    i.setState({ expanded: !i.state.expanded });
   }
 
   handleHideExpandNavbar(i: Navbar) {
@@ -541,8 +534,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
   }
 
   handleSearchParam(i: Navbar, event: any) {
-    i.state.searchParam = event.target.value;
-    i.setState(i.state);
+    i.setState({ searchParam: event.target.value });
   }
 
   handleSearchSubmit(i: Navbar, event: any) {
@@ -563,8 +555,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
 
   handleSearchBlur(i: Navbar, event: any) {
     if (!(event.relatedTarget && event.relatedTarget.name !== "search-btn")) {
-      i.state.toggleSearch = false;
-      i.setState(i.state);
+      i.setState({ toggleSearch: false });
     }
   }
 
@@ -574,8 +565,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
   }
 
   handleToggleDropdown(i: Navbar) {
-    i.state.showDropdown = !i.state.showDropdown;
-    i.setState(i.state);
+    i.setState({ showDropdown: !i.state.showDropdown });
   }
 
   parseMessage(msg: any) {
@@ -601,25 +591,28 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
         msg,
         GetUnreadCountResponse
       );
-      this.state.unreadInboxCount =
-        data.replies + data.mentions + data.private_messages;
-      this.setState(this.state);
+      this.setState({
+        unreadInboxCount: data.replies + data.mentions + data.private_messages,
+      });
       this.sendUnreadCount();
     } else if (op == UserOperation.GetReportCount) {
       let data = wsJsonToRes<GetReportCountResponse>(
         msg,
         GetReportCountResponse
       );
-      this.state.unreadReportCount = data.post_reports + data.comment_reports;
-      this.setState(this.state);
+      this.setState({
+        unreadReportCount:
+          data.post_reports +
+          data.comment_reports +
+          data.private_message_reports.unwrapOr(0),
+      });
       this.sendReportUnread();
     } else if (op == UserOperation.GetUnreadRegistrationApplicationCount) {
       let data = wsJsonToRes<GetUnreadRegistrationApplicationCountResponse>(
         msg,
         GetUnreadRegistrationApplicationCountResponse
       );
-      this.state.unreadApplicationCount = data.registration_applications;
-      this.setState(this.state);
+      this.setState({ unreadApplicationCount: data.registration_applications });
       this.sendApplicationUnread();
     } else if (op == UserOperation.CreateComment) {
       let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
@@ -627,8 +620,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
       UserService.Instance.myUserInfo.match({
         some: mui => {
           if (data.recipient_ids.includes(mui.local_user_view.local_user.id)) {
-            this.state.unreadInboxCount++;
-            this.setState(this.state);
+            this.setState({
+              unreadInboxCount: this.state.unreadInboxCount + 1,
+            });
             this.sendUnreadCount();
             notifyComment(data.comment_view, this.context.router);
           }
@@ -647,8 +641,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
             data.private_message_view.recipient.id ==
             mui.local_user_view.person.id
           ) {
-            this.state.unreadInboxCount++;
-            this.setState(this.state);
+            this.setState({
+              unreadInboxCount: this.state.unreadInboxCount + 1,
+            });
             this.sendUnreadCount();
             notifyPrivateMessage(
               data.private_message_view,
@@ -677,7 +672,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     });
     WebSocketService.Instance.send(wsClient.getReportCount(reportCountForm));
 
-    if (this.amAdmin) {
+    if (amAdmin()) {
       console.log("Fetching applications...");
 
       let applicationCountForm = new GetUnreadRegistrationApplicationCount({
index ca3fe64f0bcf889e828f2a3dc8625646136b97e5..45ba65e99879177436cac141660b585d5406a86d 100644 (file)
@@ -13,7 +13,7 @@ export class NoMatch extends Component<any, any> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <h1>404</h1>
         {this.errCode && (
           <h3>
index 6778b68fc16fb562a0c3eabedb6d90262c8fb5d5..d9630fda0759ebd88eee6111cd36104d760dca63 100644 (file)
@@ -7,6 +7,7 @@ import {
   CommentResponse,
   CreateComment,
   EditComment,
+  Language,
   UserOperation,
   wsJsonToRes,
   wsUserOp,
@@ -17,6 +18,7 @@ import { UserService, WebSocketService } from "../../services";
 import {
   auth,
   capitalizeFirstLetter,
+  myFirstDiscussionLanguageId,
   wsClient,
   wsSubscribe,
 } from "../../utils";
@@ -32,6 +34,7 @@ interface CommentFormProps {
   disabled?: boolean;
   focus?: boolean;
   onReplyCancel?(): any;
+  allLanguages: Language[];
 }
 
 interface CommentFormState {
@@ -74,11 +77,19 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
         this.props.edit ? Some(node.comment_view.comment.content) : None,
       right: () => None,
     });
+
+    let selectedLang = this.props.node
+      .left()
+      .map(n => n.comment_view.comment.language_id)
+      .or(myFirstDiscussionLanguageId(UserService.Instance.myUserInfo));
+
     return (
-      <div class="mb-3">
+      <div className="mb-3">
         {UserService.Instance.myUserInfo.isSome() ? (
           <MarkdownTextArea
             initialContent={initialContent}
+            initialLanguageId={selectedLang}
+            showLanguage
             buttonTitle={Some(this.state.buttonTitle)}
             maxLength={None}
             finished={this.state.finished}
@@ -88,9 +99,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
             onSubmit={this.handleCommentSubmit}
             onReplyCancel={this.handleReplyCancel}
             placeholder={Some(i18n.t("comment_here"))}
+            allLanguages={this.props.allLanguages}
           />
         ) : (
-          <div class="alert alert-warning" role="alert">
+          <div className="alert alert-warning" role="alert">
             <Icon icon="alert-triangle" classes="icon-inline mr-2" />
             <T i18nKey="must_login" class="d-inline">
               #
@@ -104,27 +116,34 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
     );
   }
 
-  handleCommentSubmit(msg: { val: string; formId: string }) {
+  handleCommentSubmit(msg: {
+    val: Option<string>;
+    formId: string;
+    languageId: Option<number>;
+  }) {
     let content = msg.val;
-    this.state.formId = Some(msg.formId);
+    let language_id = msg.languageId;
+    this.setState({ formId: Some(msg.formId) });
 
     this.props.node.match({
       left: node => {
         if (this.props.edit) {
           let form = new EditComment({
-            content: Some(content),
+            content,
             distinguished: None,
             form_id: this.state.formId,
             comment_id: node.comment_view.comment.id,
+            language_id,
             auth: auth().unwrap(),
           });
           WebSocketService.Instance.send(wsClient.editComment(form));
         } else {
           let form = new CreateComment({
-            content,
+            content: content.unwrap(),
             form_id: this.state.formId,
             post_id: node.comment_view.post.id,
             parent_id: Some(node.comment_view.comment.id),
+            language_id,
             auth: auth().unwrap(),
           });
           WebSocketService.Instance.send(wsClient.createComment(form));
@@ -132,10 +151,11 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
       },
       right: postId => {
         let form = new CreateComment({
-          content,
+          content: content.unwrap(),
           form_id: this.state.formId,
           post_id: postId,
           parent_id: None,
+          language_id,
           auth: auth().unwrap(),
         });
         WebSocketService.Instance.send(wsClient.createComment(form));
index f654b65a2a35aef80a3f12356caa93a539c9d776..6d1621c18ed9de241efd2468706614b0c02813c6 100644 (file)
@@ -17,6 +17,7 @@ import {
   DeleteComment,
   EditComment,
   GetComments,
+  Language,
   ListingType,
   MarkCommentReplyAsRead,
   MarkPersonMentionAsRead,
@@ -101,6 +102,7 @@ interface CommentNodeProps {
   showCommunity?: boolean;
   enableDownvotes: boolean;
   viewType: CommentViewType;
+  allLanguages: Language[];
 }
 
 export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
@@ -147,13 +149,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
   // TODO see if there's a better way to do this, and all willReceiveProps
   componentWillReceiveProps(nextProps: CommentNodeProps) {
     let cv = nextProps.node.comment_view;
-    this.state.my_vote = cv.my_vote;
-    this.state.upvotes = cv.counts.upvotes;
-    this.state.downvotes = cv.counts.downvotes;
-    this.state.score = cv.counts.score;
-    this.state.readLoading = false;
-    this.state.saveLoading = false;
-    this.setState(this.state);
+    this.setState({
+      my_vote: cv.my_vote,
+      upvotes: cv.counts.upvotes,
+      downvotes: cv.counts.downvotes,
+      score: cv.counts.score,
+      readLoading: false,
+      saveLoading: false,
+    });
   }
 
   render() {
@@ -227,10 +230,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
           }
         >
           <div
-            class={`${!this.props.noIndent && this.props.node.depth && "ml-2"}`}
+            className={`${
+              !this.props.noIndent && this.props.node.depth && "ml-2"
+            }`}
           >
-            <div class="d-flex flex-wrap align-items-center text-muted small">
-              <span class="mr-2">
+            <div className="d-flex flex-wrap align-items-center text-muted small">
+              <span className="mr-2">
                 <PersonListing person={cv.creator} />
               </span>
               {cv.comment.distinguished && (
@@ -263,16 +268,16 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
               )}
               {this.props.showCommunity && (
                 <>
-                  <span class="mx-1">{i18n.t("to")}</span>
+                  <span className="mx-1">{i18n.t("to")}</span>
                   <CommunityLink community={cv.community} />
-                  <span class="mx-2">•</span>
+                  <span className="mx-2">•</span>
                   <Link className="mr-2" to={`/post/${cv.post.id}`}>
                     {cv.post.name}
                   </Link>
                 </>
               )}
               <button
-                class="btn btn-sm text-muted"
+                className="btn btn-sm text-muted"
                 onClick={linkEvent(this, this.handleCommentCollapse)}
                 aria-label={this.expandText}
                 data-tippy-content={this.expandText}
@@ -294,7 +299,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                     data-tippy-content={this.pointsTippy}
                   >
                     <span
-                      class="mr-1 font-weight-bold"
+                      className="mr-1 font-weight-bold"
                       aria-label={i18n.t("number_of_points", {
                         count: this.state.score,
                         formattedCount: this.state.score,
@@ -321,6 +326,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                 onReplyCancel={this.handleReplyCancel}
                 disabled={this.props.locked}
                 focus
+                allLanguages={this.props.allLanguages}
               />
             )}
             {!this.state.showEdit && !this.state.collapsed && (
@@ -335,11 +341,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                     )}
                   />
                 )}
-                <div class="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold">
+                <div className="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold">
                   {this.props.showContext && this.linkBtn()}
                   {this.props.markable && (
                     <button
-                      class="btn btn-link btn-animate text-muted"
+                      className="btn btn-link btn-animate text-muted"
                       onClick={linkEvent(this, this.handleMarkRead)}
                       data-tippy-content={
                         this.commentReplyOrMentionRead
@@ -380,7 +386,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                           <Icon icon="arrow-up1" classes="icon-inline" />
                           {showScores() &&
                             this.state.upvotes !== this.state.score && (
-                              <span class="ml-1">
+                              <span className="ml-1">
                                 {numToSI(this.state.upvotes)}
                               </span>
                             )}
@@ -399,14 +405,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                             <Icon icon="arrow-down1" classes="icon-inline" />
                             {showScores() &&
                               this.state.upvotes !== this.state.score && (
-                                <span class="ml-1">
+                                <span className="ml-1">
                                   {numToSI(this.state.downvotes)}
                                 </span>
                               )}
                           </button>
                         )}
                         <button
-                          class="btn btn-link btn-animate text-muted"
+                          className="btn btn-link btn-animate text-muted"
                           onClick={linkEvent(this, this.handleReplyClick)}
                           data-tippy-content={i18n.t("reply")}
                           aria-label={i18n.t("reply")}
@@ -426,7 +432,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                           <>
                             {!this.myComment && (
                               <>
-                                <button class="btn btn-link btn-animate">
+                                <button className="btn btn-link btn-animate">
                                   <Link
                                     className="text-muted"
                                     to={`/create_private_message/recipient/${cv.creator.id}`}
@@ -436,7 +442,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   </Link>
                                 </button>
                                 <button
-                                  class="btn btn-link btn-animate text-muted"
+                                  className="btn btn-link btn-animate text-muted"
                                   onClick={linkEvent(
                                     this,
                                     this.handleShowReportDialog
@@ -449,7 +455,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   <Icon icon="flag" />
                                 </button>
                                 <button
-                                  class="btn btn-link btn-animate text-muted"
+                                  className="btn btn-link btn-animate text-muted"
                                   onClick={linkEvent(
                                     this,
                                     this.handleBlockUserClick
@@ -462,7 +468,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                               </>
                             )}
                             <button
-                              class="btn btn-link btn-animate text-muted"
+                              className="btn btn-link btn-animate text-muted"
                               onClick={linkEvent(
                                 this,
                                 this.handleSaveCommentClick
@@ -501,7 +507,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                             {this.myComment && (
                               <>
                                 <button
-                                  class="btn btn-link btn-animate text-muted"
+                                  className="btn btn-link btn-animate text-muted"
                                   onClick={linkEvent(
                                     this,
                                     this.handleEditClick
@@ -512,7 +518,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   <Icon icon="edit" classes="icon-inline" />
                                 </button>
                                 <button
-                                  class="btn btn-link btn-animate text-muted"
+                                  className="btn btn-link btn-animate text-muted"
                                   onClick={linkEvent(
                                     this,
                                     this.handleDeleteClick
@@ -538,7 +544,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
 
                                 {(canModOnSelf || canAdminOnSelf) && (
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     onClick={linkEvent(
                                       this,
                                       this.handleDistinguishClick
@@ -570,7 +576,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                               <>
                                 {!cv.comment.removed ? (
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     onClick={linkEvent(
                                       this,
                                       this.handleModRemoveShow
@@ -581,7 +587,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   </button>
                                 ) : (
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     onClick={linkEvent(
                                       this,
                                       this.handleModRemoveSubmit
@@ -599,7 +605,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                 {!isMod_ &&
                                   (!cv.creator_banned_from_community ? (
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handleModBanFromCommunityShow
@@ -610,7 +616,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                     </button>
                                   ) : (
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handleModBanFromCommunitySubmit
@@ -623,7 +629,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                 {!cv.creator_banned_from_community &&
                                   (!this.state.showConfirmAppointAsMod ? (
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handleShowConfirmAppointAsMod
@@ -641,13 +647,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   ) : (
                                     <>
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         aria-label={i18n.t("are_you_sure")}
                                       >
                                         {i18n.t("are_you_sure")}
                                       </button>
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleAddModToCommunity
@@ -657,7 +663,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                         {i18n.t("yes")}
                                       </button>
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleCancelConfirmAppointAsMod
@@ -676,7 +682,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                               cv.creator.local &&
                               (!this.state.showConfirmTransferCommunity ? (
                                 <button
-                                  class="btn btn-link btn-animate text-muted"
+                                  className="btn btn-link btn-animate text-muted"
                                   onClick={linkEvent(
                                     this,
                                     this.handleShowConfirmTransferCommunity
@@ -688,13 +694,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                               ) : (
                                 <>
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     aria-label={i18n.t("are_you_sure")}
                                   >
                                     {i18n.t("are_you_sure")}
                                   </button>
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     onClick={linkEvent(
                                       this,
                                       this.handleTransferCommunity
@@ -704,7 +710,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                     {i18n.t("yes")}
                                   </button>
                                   <button
-                                    class="btn btn-link btn-animate text-muted"
+                                    className="btn btn-link btn-animate text-muted"
                                     onClick={linkEvent(
                                       this,
                                       this
@@ -722,7 +728,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                 {!isAdmin_ && (
                                   <>
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handlePurgePersonShow
@@ -732,7 +738,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                       {i18n.t("purge_user")}
                                     </button>
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handlePurgeCommentShow
@@ -744,7 +750,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
 
                                     {!isBanned(cv.creator) ? (
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleModBanShow
@@ -755,7 +761,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                       </button>
                                     ) : (
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleModBanSubmit
@@ -771,7 +777,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                   cv.creator.local &&
                                   (!this.state.showConfirmAppointAsAdmin ? (
                                     <button
-                                      class="btn btn-link btn-animate text-muted"
+                                      className="btn btn-link btn-animate text-muted"
                                       onClick={linkEvent(
                                         this,
                                         this.handleShowConfirmAppointAsAdmin
@@ -788,11 +794,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                     </button>
                                   ) : (
                                     <>
-                                      <button class="btn btn-link btn-animate text-muted">
+                                      <button className="btn btn-link btn-animate text-muted">
                                         {i18n.t("are_you_sure")}
                                       </button>
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleAddAdmin
@@ -802,7 +808,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                                         {i18n.t("yes")}
                                       </button>
                                       <button
-                                        class="btn btn-link btn-animate text-muted"
+                                        className="btn btn-link btn-animate text-muted"
                                         onClick={linkEvent(
                                           this,
                                           this.handleCancelConfirmAppointAsAdmin
@@ -833,7 +839,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
             style={`border-left: 2px ${moreRepliesBorderColor} solid !important`}
           >
             <button
-              class="btn btn-link text-muted"
+              className="btn btn-link text-muted"
               onClick={linkEvent(this, this.handleFetchChildren)}
             >
               {i18n.t("x_more_replies", {
@@ -847,11 +853,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
         {/* end of details */}
         {this.state.showRemoveDialog && (
           <form
-            class="form-inline"
+            className="form-inline"
             onSubmit={linkEvent(this, this.handleModRemoveSubmit)}
           >
             <label
-              class="sr-only"
+              className="sr-only"
               htmlFor={`mod-remove-reason-${cv.comment.id}`}
             >
               {i18n.t("reason")}
@@ -859,14 +865,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
             <input
               type="text"
               id={`mod-remove-reason-${cv.comment.id}`}
-              class="form-control mr-2"
+              className="form-control mr-2"
               placeholder={i18n.t("reason")}
               value={toUndefined(this.state.removeReason)}
               onInput={linkEvent(this, this.handleModRemoveReasonChange)}
             />
             <button
               type="submit"
-              class="btn btn-secondary"
+              className="btn btn-secondary"
               aria-label={i18n.t("remove_comment")}
             >
               {i18n.t("remove_comment")}
@@ -875,24 +881,27 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
         )}
         {this.state.showReportDialog && (
           <form
-            class="form-inline"
+            className="form-inline"
             onSubmit={linkEvent(this, this.handleReportSubmit)}
           >
-            <label class="sr-only" htmlFor={`report-reason-${cv.comment.id}`}>
+            <label
+              className="sr-only"
+              htmlFor={`report-reason-${cv.comment.id}`}
+            >
               {i18n.t("reason")}
             </label>
             <input
               type="text"
               required
               id={`report-reason-${cv.comment.id}`}
-              class="form-control mr-2"
+              className="form-control mr-2"
               placeholder={i18n.t("reason")}
               value={this.state.reportReason}
               onInput={linkEvent(this, this.handleReportReasonChange)}
             />
             <button
               type="submit"
-              class="btn btn-secondary"
+              className="btn btn-secondary"
               aria-label={i18n.t("create_report")}
             >
               {i18n.t("create_report")}
@@ -901,9 +910,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
         )}
         {this.state.showBanDialog && (
           <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
-            <div class="form-group row col-12">
+            <div className="form-group row col-12">
               <label
-                class="col-form-label"
+                className="col-form-label"
                 htmlFor={`mod-ban-reason-${cv.comment.id}`}
               >
                 {i18n.t("reason")}
@@ -911,13 +920,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
               <input
                 type="text"
                 id={`mod-ban-reason-${cv.comment.id}`}
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("reason")}
                 value={toUndefined(this.state.banReason)}
                 onInput={linkEvent(this, this.handleModBanReasonChange)}
               />
               <label
-                class="col-form-label"
+                className="col-form-label"
                 htmlFor={`mod-ban-expires-${cv.comment.id}`}
               >
                 {i18n.t("expires")}
@@ -925,22 +934,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
               <input
                 type="number"
                 id={`mod-ban-expires-${cv.comment.id}`}
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("number_of_days")}
                 value={toUndefined(this.state.banExpireDays)}
                 onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
               />
-              <div class="form-group">
-                <div class="form-check">
+              <div className="form-group">
+                <div className="form-check">
                   <input
-                    class="form-check-input"
+                    className="form-check-input"
                     id="mod-ban-remove-data"
                     type="checkbox"
                     checked={this.state.removeData}
                     onChange={linkEvent(this, this.handleModRemoveDataChange)}
                   />
                   <label
-                    class="form-check-label"
+                    className="form-check-label"
                     htmlFor="mod-ban-remove-data"
                     title={i18n.t("remove_content_more")}
                   >
@@ -954,10 +963,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
             {/*   <label class="col-form-label">Expires</label> */}
             {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
             {/* </div> */}
-            <div class="form-group row">
+            <div className="form-group row">
               <button
                 type="submit"
-                class="btn btn-secondary"
+                className="btn btn-secondary"
                 aria-label={i18n.t("ban")}
               >
                 {i18n.t("ban")} {cv.creator.name}
@@ -969,24 +978,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
         {this.state.showPurgeDialog && (
           <form onSubmit={linkEvent(this, this.handlePurgeSubmit)}>
             <PurgeWarning />
-            <label class="sr-only" htmlFor="purge-reason">
+            <label className="sr-only" htmlFor="purge-reason">
               {i18n.t("reason")}
             </label>
             <input
               type="text"
               id="purge-reason"
-              class="form-control my-3"
+              className="form-control my-3"
               placeholder={i18n.t("reason")}
               value={toUndefined(this.state.purgeReason)}
               onInput={linkEvent(this, this.handlePurgeReasonChange)}
             />
-            <div class="form-group row col-12">
+            <div className="form-group row col-12">
               {this.state.purgeLoading ? (
                 <Spinner />
               ) : (
                 <button
                   type="submit"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   aria-label={purgeTypeText}
                 >
                   {purgeTypeText}
@@ -1001,6 +1010,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
             onReplyCancel={this.handleReplyCancel}
             disabled={this.props.locked}
             focus
+            allLanguages={this.props.allLanguages}
           />
         )}
         {!this.state.collapsed && node.children.length > 0 && (
@@ -1012,10 +1022,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
             maxCommentsShown={None}
             enableDownvotes={this.props.enableDownvotes}
             viewType={this.props.viewType}
+            allLanguages={this.props.allLanguages}
           />
         )}
         {/* A collapsed clearfix */}
-        {this.state.collapsed && <div class="row col-12"></div>}
+        {this.state.collapsed && <div className="row col-12"></div>}
       </div>
     );
   }
@@ -1090,13 +1101,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
   }
 
   handleReplyClick(i: CommentNode) {
-    i.state.showReply = true;
-    i.setState(i.state);
+    i.setState({ showReply: true });
   }
 
   handleEditClick(i: CommentNode) {
-    i.state.showEdit = true;
-    i.setState(i.state);
+    i.setState({ showEdit: true });
   }
 
   handleBlockUserClick(i: CommentNode) {
@@ -1129,14 +1138,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
 
     WebSocketService.Instance.send(wsClient.saveComment(form));
 
-    i.state.saveLoading = true;
-    i.setState(this.state);
+    i.setState({ saveLoading: true });
   }
 
   handleReplyCancel() {
-    this.state.showReply = false;
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showReply: false, showEdit: false });
   }
 
   handleCommentUpvote(event: any) {
@@ -1145,18 +1151,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
     let newVote = myVote == 1 ? 0 : 1;
 
     if (myVote == 1) {
-      this.state.score--;
-      this.state.upvotes--;
+      this.setState({
+        score: this.state.score - 1,
+        upvotes: this.state.upvotes - 1,
+      });
     } else if (myVote == -1) {
-      this.state.downvotes--;
-      this.state.upvotes++;
-      this.state.score += 2;
+      this.setState({
+        downvotes: this.state.downvotes - 1,
+        upvotes: this.state.upvotes + 1,
+        score: this.state.score + 2,
+      });
     } else {
-      this.state.upvotes++;
-      this.state.score++;
+      this.setState({
+        score: this.state.score + 1,
+        upvotes: this.state.upvotes + 1,
+      });
     }
 
-    this.state.my_vote = Some(newVote);
+    this.setState({ my_vote: Some(newVote) });
 
     let form = new CreateCommentLike({
       comment_id: this.props.node.comment_view.comment.id,
@@ -1164,7 +1176,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.likeComment(form));
-    this.setState(this.state);
     setupTippy();
   }
 
@@ -1174,18 +1185,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
     let newVote = myVote == -1 ? 0 : -1;
 
     if (myVote == 1) {
-      this.state.score -= 2;
-      this.state.upvotes--;
-      this.state.downvotes++;
+      this.setState({
+        downvotes: this.state.downvotes + 1,
+        upvotes: this.state.upvotes - 1,
+        score: this.state.score - 2,
+      });
     } else if (myVote == -1) {
-      this.state.downvotes--;
-      this.state.score++;
+      this.setState({
+        downvotes: this.state.downvotes - 1,
+        score: this.state.score + 1,
+      });
     } else {
-      this.state.downvotes++;
-      this.state.score--;
+      this.setState({
+        downvotes: this.state.downvotes + 1,
+        score: this.state.score - 1,
+      });
     }
 
-    this.state.my_vote = Some(newVote);
+    this.setState({ my_vote: Some(newVote) });
 
     let form = new CreateCommentLike({
       comment_id: this.props.node.comment_view.comment.id,
@@ -1194,18 +1211,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
     });
 
     WebSocketService.Instance.send(wsClient.likeComment(form));
-    this.setState(this.state);
     setupTippy();
   }
 
   handleShowReportDialog(i: CommentNode) {
-    i.state.showReportDialog = !i.state.showReportDialog;
-    i.setState(i.state);
+    i.setState({ showReportDialog: !i.state.showReportDialog });
   }
 
   handleReportReasonChange(i: CommentNode, event: any) {
-    i.state.reportReason = event.target.value;
-    i.setState(i.state);
+    i.setState({ reportReason: event.target.value });
   }
 
   handleReportSubmit(i: CommentNode) {
@@ -1217,24 +1231,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
     });
     WebSocketService.Instance.send(wsClient.createCommentReport(form));
 
-    i.state.showReportDialog = false;
-    i.setState(i.state);
+    i.setState({ showReportDialog: false });
   }
 
   handleModRemoveShow(i: CommentNode) {
-    i.state.showRemoveDialog = !i.state.showRemoveDialog;
-    i.state.showBanDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showRemoveDialog: !i.state.showRemoveDialog,
+      showBanDialog: false,
+    });
   }
 
   handleModRemoveReasonChange(i: CommentNode, event: any) {
-    i.state.removeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ removeReason: Some(event.target.value) });
   }
 
   handleModRemoveDataChange(i: CommentNode, event: any) {
-    i.state.removeData = event.target.checked;
-    i.setState(i.state);
+    i.setState({ removeData: event.target.checked });
   }
 
   handleModRemoveSubmit(i: CommentNode) {
@@ -1247,8 +1259,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
     });
     WebSocketService.Instance.send(wsClient.removeComment(form));
 
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({ showRemoveDialog: false });
   }
 
   handleDistinguishClick(i: CommentNode) {
@@ -1258,6 +1269,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       form_id: None, // TODO not sure about this
       content: None,
       distinguished: Some(!comment.distinguished),
+      language_id: Some(comment.language_id),
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.editComment(form));
@@ -1293,43 +1305,40 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       WebSocketService.Instance.send(wsClient.markCommentReplyAsRead(form));
     }
 
-    i.state.readLoading = true;
-    i.setState(this.state);
+    i.setState({ readLoading: true });
   }
 
   handleModBanFromCommunityShow(i: CommentNode) {
-    i.state.showBanDialog = true;
-    i.state.banType = BanType.Community;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showBanDialog: true,
+      banType: BanType.Community,
+      showRemoveDialog: false,
+    });
   }
 
   handleModBanShow(i: CommentNode) {
-    i.state.showBanDialog = true;
-    i.state.banType = BanType.Site;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showBanDialog: true,
+      banType: BanType.Site,
+      showRemoveDialog: false,
+    });
   }
 
   handleModBanReasonChange(i: CommentNode, event: any) {
-    i.state.banReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ banReason: Some(event.target.value) });
   }
 
   handleModBanExpireDaysChange(i: CommentNode, event: any) {
-    i.state.banExpireDays = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ banExpireDays: Some(event.target.value) });
   }
 
   handleModBanFromCommunitySubmit(i: CommentNode) {
-    i.state.banType = BanType.Community;
-    i.setState(i.state);
+    i.setState({ banType: BanType.Community });
     i.handleModBanBothSubmit(i);
   }
 
   handleModBanSubmit(i: CommentNode) {
-    i.state.banType = BanType.Site;
-    i.setState(i.state);
+    i.setState({ banType: BanType.Site });
     i.handleModBanBothSubmit(i);
   }
 
@@ -1340,7 +1349,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       // If its an unban, restore all their data
       let ban = !cv.creator_banned_from_community;
       if (ban == false) {
-        i.state.removeData = false;
+        i.setState({ removeData: false });
       }
       let form = new BanFromCommunity({
         person_id: cv.creator.id,
@@ -1356,7 +1365,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       // If its an unban, restore all their data
       let ban = !cv.creator.banned;
       if (ban == false) {
-        i.state.removeData = false;
+        i.setState({ removeData: false });
       }
       let form = new BanPerson({
         person_id: cv.creator.id,
@@ -1369,27 +1378,27 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       WebSocketService.Instance.send(wsClient.banPerson(form));
     }
 
-    i.state.showBanDialog = false;
-    i.setState(i.state);
+    i.setState({ showBanDialog: false });
   }
 
   handlePurgePersonShow(i: CommentNode) {
-    i.state.showPurgeDialog = true;
-    i.state.purgeType = PurgeType.Person;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showPurgeDialog: true,
+      purgeType: PurgeType.Person,
+      showRemoveDialog: false,
+    });
   }
 
   handlePurgeCommentShow(i: CommentNode) {
-    i.state.showPurgeDialog = true;
-    i.state.purgeType = PurgeType.Comment;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showPurgeDialog: true,
+      purgeType: PurgeType.Comment,
+      showRemoveDialog: false,
+    });
   }
 
   handlePurgeReasonChange(i: CommentNode, event: any) {
-    i.state.purgeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ purgeReason: Some(event.target.value) });
   }
 
   handlePurgeSubmit(i: CommentNode, event: any) {
@@ -1411,18 +1420,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       WebSocketService.Instance.send(wsClient.purgeComment(form));
     }
 
-    i.state.purgeLoading = true;
-    i.setState(i.state);
+    i.setState({ purgeLoading: true });
   }
 
   handleShowConfirmAppointAsMod(i: CommentNode) {
-    i.state.showConfirmAppointAsMod = true;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsMod: true });
   }
 
   handleCancelConfirmAppointAsMod(i: CommentNode) {
-    i.state.showConfirmAppointAsMod = false;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsMod: false });
   }
 
   handleAddModToCommunity(i: CommentNode) {
@@ -1434,18 +1440,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.addModToCommunity(form));
-    i.state.showConfirmAppointAsMod = false;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsMod: false });
   }
 
   handleShowConfirmAppointAsAdmin(i: CommentNode) {
-    i.state.showConfirmAppointAsAdmin = true;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsAdmin: true });
   }
 
   handleCancelConfirmAppointAsAdmin(i: CommentNode) {
-    i.state.showConfirmAppointAsAdmin = false;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsAdmin: false });
   }
 
   handleAddAdmin(i: CommentNode) {
@@ -1456,18 +1459,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.addAdmin(form));
-    i.state.showConfirmAppointAsAdmin = false;
-    i.setState(i.state);
+    i.setState({ showConfirmAppointAsAdmin: false });
   }
 
   handleShowConfirmTransferCommunity(i: CommentNode) {
-    i.state.showConfirmTransferCommunity = true;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: true });
   }
 
   handleCancelShowConfirmTransferCommunity(i: CommentNode) {
-    i.state.showConfirmTransferCommunity = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: false });
   }
 
   handleTransferCommunity(i: CommentNode) {
@@ -1478,18 +1478,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.transferCommunity(form));
-    i.state.showConfirmTransferCommunity = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: false });
   }
 
   handleShowConfirmTransferSite(i: CommentNode) {
-    i.state.showConfirmTransferSite = true;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferSite: true });
   }
 
   handleCancelShowConfirmTransferSite(i: CommentNode) {
-    i.state.showConfirmTransferSite = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferSite: false });
   }
 
   get isCommentNew(): boolean {
@@ -1499,19 +1496,16 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
   }
 
   handleCommentCollapse(i: CommentNode) {
-    i.state.collapsed = !i.state.collapsed;
-    i.setState(i.state);
+    i.setState({ collapsed: !i.state.collapsed });
     setupTippy();
   }
 
   handleViewSource(i: CommentNode) {
-    i.state.viewSource = !i.state.viewSource;
-    i.setState(i.state);
+    i.setState({ viewSource: !i.state.viewSource });
   }
 
   handleShowAdvanced(i: CommentNode) {
-    i.state.showAdvanced = !i.state.showAdvanced;
-    i.setState(i.state);
+    i.setState({ showAdvanced: !i.state.showAdvanced });
     setupTippy();
   }
 
index f9484c2d4497e15a1d8d18a9beaf8ee1435702de..708105895a76f7e7add80835b35bac7cfa7a07f9 100644 (file)
@@ -3,6 +3,7 @@ import { Component } from "inferno";
 import {
   CommentNode as CommentNodeI,
   CommunityModeratorView,
+  Language,
   PersonViewSafe,
 } from "lemmy-js-client";
 import { CommentViewType } from "../../interfaces";
@@ -22,6 +23,7 @@ interface CommentNodesProps {
   showCommunity?: boolean;
   enableDownvotes?: boolean;
   viewType: CommentViewType;
+  allLanguages: Language[];
 }
 
 export class CommentNodes extends Component<CommentNodesProps, any> {
@@ -51,6 +53,7 @@ export class CommentNodes extends Component<CommentNodesProps, any> {
             showCommunity={this.props.showCommunity}
             enableDownvotes={this.props.enableDownvotes}
             viewType={this.props.viewType}
+            allLanguages={this.props.allLanguages}
           />
         ))}
       </div>
index a2d2b10c19008a70299f9f1f09d8ea8efe6444f0..f72f8a6a09c7c734122d83a3954524d908fc445f 100644 (file)
@@ -64,6 +64,7 @@ export class CommentReport extends Component<CommentReportProps, any> {
           enableDownvotes={true}
           viewOnly={true}
           showCommunity={true}
+          allLanguages={[]}
         />
         <div>
           {i18n.t("reporter")}: <PersonListing person={r.creator} />
index d3383b5f6f83cf5bc399d4e67be5153f3c85bb1d..a72400a3dc824cd075ea39607d1bbb663a6350da 100644 (file)
@@ -14,7 +14,7 @@ export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
 
   render() {
     return (
-      <div class="position-relative mb-2">
+      <div className="position-relative mb-2">
         {this.props.banner.match({
           some: banner => <PictrsImage src={banner} banner alt="" />,
           none: <></>,
index b87f26664c4a8859855f7bfccd7be5a954303ac4..0e49d561ed9f0c631ff0c3bfdc2f8af6a5a418f2 100644 (file)
@@ -41,7 +41,7 @@ export class CommentSortSelect extends Component<
           name={this.id}
           value={this.state.sort}
           onChange={linkEvent(this, this.handleSortChange)}
-          class="custom-select w-auto mr-2 mb-2"
+          className="custom-select w-auto mr-2 mb-2"
           aria-label={i18n.t("sort_type")}
         >
           <option disabled aria-hidden="true">
index b9b6a6f580c07a04cac295e7f93c9203c39e9162..8a5613e85863553de3830bcc076c92060566fc5b 100644 (file)
@@ -32,7 +32,7 @@ export class DataTypeSelect extends Component<
 
   render() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`pointer btn btn-outline-secondary 
             ${this.state.type_ == DataType.Post && "active"}
index 1997b4f8cee16e62e191f15558d0444c262d4761..56cf3238ed0abf23407c449efd27bdda03655eae 100644 (file)
@@ -19,10 +19,10 @@ export class HtmlTags extends Component<HtmlTagsProps, any> {
     return (
       <Helmet title={this.props.title}>
         {["title", "og:title", "twitter:title"].map(t => (
-          <meta property={t} content={this.props.title} />
+          <meta key={t} property={t} content={this.props.title} />
         ))}
         {["og:url", "twitter:url"].map(u => (
-          <meta property={u} content={url} />
+          <meta key={u} property={u} content={url} />
         ))}
 
         {/* Open Graph / Facebook */}
@@ -35,6 +35,7 @@ export class HtmlTags extends Component<HtmlTagsProps, any> {
         {this.props.description.isSome() &&
           ["description", "og:description", "twitter:description"].map(n => (
             <meta
+              key={n}
               name={n}
               content={md.renderInline(this.props.description.unwrap())}
             />
@@ -42,7 +43,7 @@ export class HtmlTags extends Component<HtmlTagsProps, any> {
 
         {this.props.image.isSome() &&
           ["og:image", "twitter:image"].map(p => (
-            <meta property={p} content={this.props.image.unwrap()} />
+            <meta key={p} property={p} content={this.props.image.unwrap()} />
           ))}
       </Helmet>
     );
index 91271cfe539e45b889f38768ad5223c516851eae..f922e175e88cd4051b1e6625ee12d1da7d5bfdac 100644 (file)
@@ -17,13 +17,13 @@ export class Icon extends Component<IconProps, any> {
   render() {
     return (
       <svg
-        class={classNames("icon", this.props.classes, {
+        className={classNames("icon", this.props.classes, {
           "icon-inline": this.props.inline,
           small: this.props.small,
         })}
       >
         <use xlinkHref={`#icon-${this.props.icon}`}></use>
-        <div class="sr-only">
+        <div className="sr-only">
           <title>{this.props.icon}</title>
         </div>
       </svg>
@@ -57,7 +57,7 @@ export class PurgeWarning extends Component<any, any> {
 
   render() {
     return (
-      <div class="mt-2 alert alert-danger" role="alert">
+      <div className="mt-2 alert alert-danger" role="alert">
         <Icon icon="alert-triangle" classes="icon-inline mr-2" />
         {i18n.t("purge_warning")}
       </div>
index 5f7a8168f437518a01c78dfaa354ccb4d7547c29..432521efa26fac5f849e444ab6985b876d172ab2 100644 (file)
@@ -34,14 +34,14 @@ export class ImageUploadForm extends Component<
 
   render() {
     return (
-      <form class="d-inline">
+      <form className="d-inline">
         <label
           htmlFor={this.id}
-          class="pointer text-muted small font-weight-bold"
+          className="pointer text-muted small font-weight-bold"
         >
           {this.props.imageSrc.match({
             some: imageSrc => (
-              <span class="d-inline-block position-relative">
+              <span className="d-inline-block position-relative">
                 <img
                   src={imageSrc}
                   height={this.props.rounded ? 60 : ""}
@@ -59,7 +59,9 @@ export class ImageUploadForm extends Component<
               </span>
             ),
             none: (
-              <span class="btn btn-secondary">{this.props.uploadTitle}</span>
+              <span className="btn btn-secondary">
+                {this.props.uploadTitle}
+              </span>
             ),
           })}
         </label>
@@ -68,7 +70,7 @@ export class ImageUploadForm extends Component<
           type="file"
           accept="image/*,video/*"
           name={this.id}
-          class="d-none"
+          className="d-none"
           disabled={UserService.Instance.myUserInfo.isNone()}
           onChange={linkEvent(this, this.handleImageUpload)}
         />
@@ -82,8 +84,7 @@ export class ImageUploadForm extends Component<
     const formData = new FormData();
     formData.append("images[]", file);
 
-    i.state.loading = true;
-    i.setState(i.state);
+    i.setState({ loading: true });
 
     fetch(pictrsUri, {
       method: "POST",
@@ -96,18 +97,15 @@ export class ImageUploadForm extends Component<
         if (res.msg == "ok") {
           let hash = res.files[0].file;
           let url = `${pictrsUri}/${hash}`;
-          i.state.loading = false;
-          i.setState(i.state);
+          i.setState({ loading: false });
           i.props.onUpload(url);
         } else {
-          i.state.loading = false;
-          i.setState(i.state);
+          i.setState({ loading: false });
           toast(JSON.stringify(res), "danger");
         }
       })
       .catch(error => {
-        i.state.loading = false;
-        i.setState(i.state);
+        i.setState({ loading: false });
         console.error(error);
         toast(error, "danger");
       });
@@ -115,8 +113,7 @@ export class ImageUploadForm extends Component<
 
   handleRemoveImage(i: ImageUploadForm, event: any) {
     event.preventDefault();
-    i.state.loading = true;
-    i.setState(i.state);
+    i.setState({ loading: true });
     i.props.onRemove();
   }
 }
diff --git a/src/shared/components/common/language-select.tsx b/src/shared/components/common/language-select.tsx
new file mode 100644 (file)
index 0000000..746fea4
--- /dev/null
@@ -0,0 +1,109 @@
+import { Option } from "@sniptt/monads";
+import classNames from "classnames";
+import { Component, linkEvent } from "inferno";
+import { Language } from "lemmy-js-client";
+import { i18n } from "../../i18next";
+import { randomStr } from "../../utils";
+import { Icon } from "./icon";
+
+interface LanguageSelectProps {
+  allLanguages: Language[];
+  selectedLanguageIds: Option<number[]>;
+  multiple: boolean;
+  onChange(val: number[]): any;
+}
+
+export class LanguageSelect extends Component<LanguageSelectProps, any> {
+  private id = `language-select-${randomStr()}`;
+
+  constructor(props: any, context: any) {
+    super(props, context);
+  }
+
+  componentDidMount() {
+    this.setSelectedValues();
+  }
+
+  // Necessary because there is no HTML way to set selected for multiple in value=
+  setSelectedValues() {
+    this.props.selectedLanguageIds.map(toString).match({
+      some: ids => {
+        var select = (document.getElementById(this.id) as HTMLSelectElement)
+          .options;
+        for (let i = 0; i < select.length; i++) {
+          let o = select[i];
+          if (ids.includes(o.value)) {
+            o.selected = true;
+          }
+        }
+      },
+      none: void 0,
+    });
+  }
+
+  render() {
+    let selectedLangs = this.props.selectedLanguageIds;
+
+    return (
+      <div className="form-group row">
+        <label
+          className={classNames("col-form-label", {
+            "col-sm-3": this.props.multiple,
+            "col-sm-2": !this.props.multiple,
+          })}
+          htmlFor={this.id}
+        >
+          {i18n.t(this.props.multiple ? "language_plural" : "language")}
+        </label>
+        <div
+          className={classNames("input-group", {
+            "col-sm-9": this.props.multiple,
+            "col-sm-10": !this.props.multiple,
+          })}
+        >
+          <select
+            className="form-control custom-select"
+            id={this.id}
+            onChange={linkEvent(this, this.handleLanguageChange)}
+            aria-label="action"
+            multiple={this.props.multiple}
+          >
+            {this.props.allLanguages.map(l => (
+              <option
+                key={l.id}
+                value={l.id}
+                selected={selectedLangs.unwrapOr([]).includes(l.id)}
+              >
+                {l.name}
+              </option>
+            ))}
+          </select>
+          {this.props.multiple && (
+            <div className="input-group-append">
+              <button
+                className="input-group-text"
+                onClick={linkEvent(this, this.handleDeselectAll)}
+              >
+                <Icon icon="x" />
+              </button>
+            </div>
+          )}
+        </div>
+      </div>
+    );
+  }
+
+  handleLanguageChange(i: LanguageSelect, event: any) {
+    let options: HTMLOptionElement[] = Array.from(event.target.options);
+    let selected: number[] = options
+      .filter(o => o.selected)
+      .map(o => Number(o.value));
+
+    i.props.onChange(selected);
+  }
+
+  handleDeselectAll(i: LanguageSelect, event: any) {
+    event.preventDefault();
+    i.props.onChange([]);
+  }
+}
index 0ddd0e9abfca57ce1f2301ac092958be9c55c38d..38e6acddc639ee6f79b97d3e995cc330d5c5ad16 100644 (file)
@@ -40,7 +40,7 @@ export class ListingTypeSelect extends Component<
 
   render() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         {this.props.showSubscribed && (
           <label
             title={i18n.t("subscribed_description")}
index b453acc3ce2383f6d635545b19a16d5d3e9d5927..498c262579a569eb22cb79e841c1fe6b4c0072b7 100644 (file)
@@ -2,7 +2,7 @@ import { None, Option, Some } from "@sniptt/monads";
 import autosize from "autosize";
 import { Component, linkEvent } from "inferno";
 import { Prompt } from "inferno-router";
-import { toUndefined } from "lemmy-js-client";
+import { Language, toUndefined } from "lemmy-js-client";
 import { pictrsUri } from "../../env";
 import { i18n } from "../../i18next";
 import { UserService } from "../../services";
@@ -18,9 +18,11 @@ import {
   toast,
 } from "../../utils";
 import { Icon, Spinner } from "./icon";
+import { LanguageSelect } from "./language-select";
 
 interface MarkdownTextAreaProps {
   initialContent: Option<string>;
+  initialLanguageId: Option<number>;
   placeholder: Option<string>;
   buttonTitle: Option<string>;
   maxLength: Option<number>;
@@ -28,14 +30,21 @@ interface MarkdownTextAreaProps {
   focus?: boolean;
   disabled?: boolean;
   finished?: boolean;
+  showLanguage?: boolean;
   hideNavigationWarnings?: boolean;
   onContentChange?(val: string): any;
   onReplyCancel?(): any;
-  onSubmit?(msg: { val: string; formId: string }): any;
+  onSubmit?(msg: {
+    val: Option<string>;
+    formId: string;
+    languageId: Option<number>;
+  }): any;
+  allLanguages: Language[];
 }
 
 interface MarkdownTextAreaState {
   content: Option<string>;
+  languageId: Option<number>;
   previewMode: boolean;
   loading: boolean;
   imageLoading: boolean;
@@ -50,6 +59,7 @@ export class MarkdownTextArea extends Component<
   private tribute: any;
   private emptyState: MarkdownTextAreaState = {
     content: this.props.initialContent,
+    languageId: this.props.initialLanguageId,
     previewMode: false,
     loading: false,
     imageLoading: false,
@@ -58,6 +68,8 @@ export class MarkdownTextArea extends Component<
   constructor(props: any, context: any) {
     super(props, context);
 
+    this.handleLanguageChange = this.handleLanguageChange.bind(this);
+
     if (isBrowser()) {
       this.tribute = setupTribute();
     }
@@ -70,8 +82,7 @@ export class MarkdownTextArea extends Component<
       autosize(textarea);
       this.tribute.attach(textarea);
       textarea.addEventListener("tribute-replaced", () => {
-        this.state.content = Some(textarea.value);
-        this.setState(this.state);
+        this.setState({ content: Some(textarea.value) });
         autosize.update(textarea);
       });
 
@@ -96,10 +107,7 @@ export class MarkdownTextArea extends Component<
 
   componentWillReceiveProps(nextProps: MarkdownTextAreaProps) {
     if (nextProps.finished) {
-      this.state.previewMode = false;
-      this.state.loading = false;
-      this.state.content = None;
-      this.setState(this.state);
+      this.setState({ previewMode: false, loading: false, content: None });
       if (this.props.replyType) {
         this.props.onReplyCancel();
       }
@@ -108,7 +116,6 @@ export class MarkdownTextArea extends Component<
       let form: any = document.getElementById(this.formId);
       form.reset();
       setTimeout(() => autosize.update(textarea), 10);
-      this.setState(this.state);
     }
   }
 
@@ -125,7 +132,7 @@ export class MarkdownTextArea extends Component<
           }
           message={i18n.t("block_leaving")}
         />
-        <div class="form-group row">
+        <div className="form-group row">
           <div className={`col-sm-12`}>
             <textarea
               id={this.id}
@@ -150,17 +157,29 @@ export class MarkdownTextArea extends Component<
                 none: <></>,
               })}
           </div>
-          <label class="sr-only" htmlFor={this.id}>
+          <label className="sr-only" htmlFor={this.id}>
             {i18n.t("body")}
           </label>
         </div>
-        <div class="row">
-          <div class="col-sm-12 d-flex flex-wrap">
+        {this.props.showLanguage && (
+          <div className="row justify-content-end">
+            <div className="col-sm-8">
+              <LanguageSelect
+                allLanguages={this.props.allLanguages}
+                selectedLanguageIds={this.state.languageId.map(Array.of)}
+                multiple={false}
+                onChange={this.handleLanguageChange}
+              />
+            </div>
+          </div>
+        )}
+        <div className="row">
+          <div className="col-sm-12 d-flex flex-wrap">
             {this.props.buttonTitle.match({
               some: buttonTitle => (
                 <button
                   type="submit"
-                  class="btn btn-sm btn-secondary mr-2"
+                  className="btn btn-sm btn-secondary mr-2"
                   disabled={this.props.disabled || this.state.loading}
                 >
                   {this.state.loading ? (
@@ -175,7 +194,7 @@ export class MarkdownTextArea extends Component<
             {this.props.replyType && (
               <button
                 type="button"
-                class="btn btn-sm btn-secondary mr-2"
+                className="btn btn-sm btn-secondary mr-2"
                 onClick={linkEvent(this, this.handleReplyCancel)}
               >
                 {i18n.t("cancel")}
@@ -192,9 +211,9 @@ export class MarkdownTextArea extends Component<
               </button>
             )}
             {/* A flex expander */}
-            <div class="flex-grow-1"></div>
+            <div className="flex-grow-1"></div>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("bold")}
               aria-label={i18n.t("bold")}
               onClick={linkEvent(this, this.handleInsertBold)}
@@ -202,7 +221,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="bold" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("italic")}
               aria-label={i18n.t("italic")}
               onClick={linkEvent(this, this.handleInsertItalic)}
@@ -210,14 +229,14 @@ export class MarkdownTextArea extends Component<
               <Icon icon="italic" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("link")}
               aria-label={i18n.t("link")}
               onClick={linkEvent(this, this.handleInsertLink)}
             >
               <Icon icon="link" classes="icon-inline" />
             </button>
-            <form class="btn btn-sm text-muted font-weight-bold">
+            <form className="btn btn-sm text-muted font-weight-bold">
               <label
                 htmlFor={`file-upload-${this.id}`}
                 className={`mb-0 ${
@@ -236,13 +255,13 @@ export class MarkdownTextArea extends Component<
                 type="file"
                 accept="image/*,video/*"
                 name="file"
-                class="d-none"
+                className="d-none"
                 disabled={UserService.Instance.myUserInfo.isNone()}
                 onChange={linkEvent(this, this.handleImageUpload)}
               />
             </form>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("header")}
               aria-label={i18n.t("header")}
               onClick={linkEvent(this, this.handleInsertHeader)}
@@ -250,7 +269,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="header" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("strikethrough")}
               aria-label={i18n.t("strikethrough")}
               onClick={linkEvent(this, this.handleInsertStrikethrough)}
@@ -258,7 +277,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="strikethrough" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("quote")}
               aria-label={i18n.t("quote")}
               onClick={linkEvent(this, this.handleInsertQuote)}
@@ -266,7 +285,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="format_quote" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("list")}
               aria-label={i18n.t("list")}
               onClick={linkEvent(this, this.handleInsertList)}
@@ -274,7 +293,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="list" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("code")}
               aria-label={i18n.t("code")}
               onClick={linkEvent(this, this.handleInsertCode)}
@@ -282,7 +301,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="code" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("subscript")}
               aria-label={i18n.t("subscript")}
               onClick={linkEvent(this, this.handleInsertSubscript)}
@@ -290,7 +309,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="subscript" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("superscript")}
               aria-label={i18n.t("superscript")}
               onClick={linkEvent(this, this.handleInsertSuperscript)}
@@ -298,7 +317,7 @@ export class MarkdownTextArea extends Component<
               <Icon icon="superscript" classes="icon-inline" />
             </button>
             <button
-              class="btn btn-sm text-muted"
+              className="btn btn-sm text-muted"
               data-tippy-content={i18n.t("spoiler")}
               aria-label={i18n.t("spoiler")}
               onClick={linkEvent(this, this.handleInsertSpoiler)}
@@ -307,7 +326,7 @@ export class MarkdownTextArea extends Component<
             </button>
             <a
               href={markdownHelpUrl}
-              class="btn btn-sm text-muted font-weight-bold"
+              className="btn btn-sm text-muted font-weight-bold"
               title={i18n.t("formatting_help")}
               rel={relTags}
             >
@@ -338,8 +357,7 @@ export class MarkdownTextArea extends Component<
     const formData = new FormData();
     formData.append("images[]", file);
 
-    i.state.imageLoading = true;
-    i.setState(i.state);
+    i.setState({ imageLoading: true });
 
     fetch(pictrsUri, {
       method: "POST",
@@ -355,15 +373,16 @@ export class MarkdownTextArea extends Component<
           let deleteToken = res.files[0].delete_token;
           let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`;
           let imageMarkdown = `![](${url})`;
-          i.state.content = Some(
-            i.state.content.match({
-              some: content => `${content}\n${imageMarkdown}`,
-              none: imageMarkdown,
-            })
-          );
-          i.state.imageLoading = false;
+          i.setState({
+            content: Some(
+              i.state.content.match({
+                some: content => `${content}\n${imageMarkdown}`,
+                none: imageMarkdown,
+              })
+            ),
+            imageLoading: false,
+          });
           i.contentChange();
-          i.setState(i.state);
           let textarea: any = document.getElementById(i.id);
           autosize.update(textarea);
           pictrsDeleteToast(
@@ -373,14 +392,12 @@ export class MarkdownTextArea extends Component<
             deleteUrl
           );
         } else {
-          i.state.imageLoading = false;
-          i.setState(i.state);
+          i.setState({ imageLoading: false });
           toast(JSON.stringify(res), "danger");
         }
       })
       .catch(error => {
-        i.state.imageLoading = false;
-        i.setState(i.state);
+        i.setState({ imageLoading: false });
         console.error(error);
         toast(error, "danger");
       });
@@ -393,22 +410,27 @@ export class MarkdownTextArea extends Component<
   }
 
   handleContentChange(i: MarkdownTextArea, event: any) {
-    i.state.content = Some(event.target.value);
+    i.setState({ content: Some(event.target.value) });
     i.contentChange();
-    i.setState(i.state);
   }
 
   handlePreviewToggle(i: MarkdownTextArea, event: any) {
     event.preventDefault();
-    i.state.previewMode = !i.state.previewMode;
-    i.setState(i.state);
+    i.setState({ previewMode: !i.state.previewMode });
+  }
+
+  handleLanguageChange(val: number[]) {
+    this.setState({ languageId: Some(val[0]) });
   }
 
   handleSubmit(i: MarkdownTextArea, event: any) {
     event.preventDefault();
-    i.state.loading = true;
-    i.setState(i.state);
-    let msg = { val: toUndefined(i.state.content), formId: i.formId };
+    i.setState({ loading: true });
+    let msg = {
+      val: i.state.content,
+      formId: i.formId,
+      languageId: i.state.languageId,
+    };
     i.props.onSubmit(msg);
   }
 
@@ -424,27 +446,28 @@ export class MarkdownTextArea extends Component<
     let end: number = textarea.selectionEnd;
 
     if (i.state.content.isNone()) {
-      i.state.content = Some("");
+      i.setState({ content: Some("") });
     }
 
     let content = i.state.content.unwrap();
 
     if (start !== end) {
       let selectedText = content.substring(start, end);
-      i.state.content = Some(
-        `${content.substring(0, start)}[${selectedText}]()${content.substring(
-          end
-        )}`
-      );
+      i.setState({
+        content: Some(
+          `${content.substring(0, start)}[${selectedText}]()${content.substring(
+            end
+          )}`
+        ),
+      });
       textarea.focus();
       setTimeout(() => (textarea.selectionEnd = end + 3), 10);
     } else {
-      i.state.content = Some(`${content} []()`);
+      i.setState({ content: Some(`${content} []()`) });
       textarea.focus();
       setTimeout(() => (textarea.selectionEnd -= 1), 10);
     }
     i.contentChange();
-    i.setState(i.state);
   }
 
   simpleSurround(chars: string) {
@@ -461,7 +484,7 @@ export class MarkdownTextArea extends Component<
     emptyChars = "___"
   ) {
     if (this.state.content.isNone()) {
-      this.state.content = Some("");
+      this.setState({ content: Some("") });
     }
     let textarea: any = document.getElementById(this.id);
     let start: number = textarea.selectionStart;
@@ -471,19 +494,20 @@ export class MarkdownTextArea extends Component<
 
     if (start !== end) {
       let selectedText = content.substring(start, end);
-      this.state.content = Some(
-        `${content.substring(
-          0,
-          start
-        )}${beforeChars}${selectedText}${afterChars}${content.substring(end)}`
-      );
+      this.setState({
+        content: Some(
+          `${content.substring(
+            0,
+            start
+          )}${beforeChars}${selectedText}${afterChars}${content.substring(end)}`
+        ),
+      });
     } else {
-      this.state.content = Some(
-        `${content}${beforeChars}${emptyChars}${afterChars}`
-      );
+      this.setState({
+        content: Some(`${content}${beforeChars}${emptyChars}${afterChars}`),
+      });
     }
     this.contentChange();
-    this.setState(this.state);
 
     textarea.focus();
 
@@ -555,9 +579,11 @@ export class MarkdownTextArea extends Component<
 
   simpleInsert(chars: string) {
     if (this.state.content.isNone()) {
-      this.state.content = Some(`${chars} `);
+      this.setState({ content: Some(`${chars} `) });
     } else {
-      this.state.content = Some(`${this.state.content.unwrap()}\n${chars} `);
+      this.setState({
+        content: Some(`${this.state.content.unwrap()}\n${chars} `),
+      });
     }
 
     let textarea: any = document.getElementById(this.id);
@@ -566,7 +592,6 @@ export class MarkdownTextArea extends Component<
       autosize.update(textarea);
     }, 10);
     this.contentChange();
-    this.setState(this.state);
   }
 
   handleInsertSpoiler(i: MarkdownTextArea, event: any) {
@@ -586,13 +611,14 @@ export class MarkdownTextArea extends Component<
           .map(t => `> ${t}`)
           .join("\n") + "\n\n";
       if (this.state.content.isNone()) {
-        this.state.content = Some("");
+        this.setState({ content: Some("") });
       } else {
-        this.state.content = Some(`${this.state.content.unwrap()}\n`);
+        this.setState({ content: Some(`${this.state.content.unwrap()}\n`) });
       }
-      this.state.content = Some(`${this.state.content.unwrap()}${quotedText}`);
+      this.setState({
+        content: Some(`${this.state.content.unwrap()}${quotedText}`),
+      });
       this.contentChange();
-      this.setState(this.state);
       // Not sure why this needs a delay
       setTimeout(() => autosize.update(textarea), 10);
     }
index 50094de48b839293667686106ad9f4ac32731fbd..75acde3e105ce59cc5a3510ee1f432392e269d6c 100644 (file)
@@ -12,16 +12,16 @@ export class Paginator extends Component<PaginatorProps, any> {
   }
   render() {
     return (
-      <div class="my-2">
+      <div className="my-2">
         <button
-          class="btn btn-secondary mr-2"
+          className="btn btn-secondary mr-2"
           disabled={this.props.page == 1}
           onClick={linkEvent(this, this.handlePrev)}
         >
           {i18n.t("prev")}
         </button>
         <button
-          class="btn btn-secondary"
+          className="btn btn-secondary"
           onClick={linkEvent(this, this.handleNext)}
         >
           {i18n.t("next")}
index f3c2cf523ddc142b414c6e2a05e8eb26ab49c478..07fbf203926ebbd8aac31e112d5ac4b531a6afde 100644 (file)
@@ -88,18 +88,20 @@ export class RegistrationApplication extends Component<
         })}
 
         {this.state.denyExpanded && (
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label">
               {i18n.t("deny_reason")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <MarkdownTextArea
                 initialContent={this.state.denyReason}
+                initialLanguageId={None}
                 onContentChange={this.handleDenyReasonChange}
                 placeholder={None}
                 buttonTitle={None}
                 maxLength={None}
                 hideNavigationWarnings
+                allLanguages={[]}
               />
             </div>
           </div>
@@ -157,7 +159,6 @@ export class RegistrationApplication extends Component<
   }
 
   handleDenyReasonChange(val: string) {
-    this.state.denyReason = Some(val);
-    this.setState(this.state);
+    this.setState({ denyReason: Some(val) });
   }
 }
index 3f815f5b0eb6e728ff9fea9ad01544fd59fd4505..facc16f47bebf79d1be04e3653ebaf1613be65c8 100644 (file)
@@ -40,23 +40,27 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
           name={this.id}
           value={this.state.sort}
           onChange={linkEvent(this, this.handleSortChange)}
-          class="custom-select w-auto mr-2 mb-2"
+          className="custom-select w-auto mr-2 mb-2"
           aria-label={i18n.t("sort_type")}
         >
           <option disabled aria-hidden="true">
             {i18n.t("sort_type")}
           </option>
           {!this.props.hideHot && [
-            <option value={SortType.Hot}>{i18n.t("hot")}</option>,
-            <option value={SortType.Active}>{i18n.t("active")}</option>,
+            <option key={SortType.Hot} value={SortType.Hot}>
+              {i18n.t("hot")}
+            </option>,
+            <option key={SortType.Active} value={SortType.Active}>
+              {i18n.t("active")}
+            </option>,
           ]}
           <option value={SortType.New}>{i18n.t("new")}</option>
           <option value={SortType.Old}>{i18n.t("old")}</option>
           {!this.props.hideMostComments && [
-            <option value={SortType.MostComments}>
+            <option key={SortType.MostComments} value={SortType.MostComments}>
               {i18n.t("most_comments")}
             </option>,
-            <option value={SortType.NewComments}>
+            <option key={SortType.NewComments} value={SortType.NewComments}>
               {i18n.t("new_comments")}
             </option>,
           ]}
index 03791d1bec58cc9977f1e49890236f37a1b65f65..cb066cc2e3d4cf48f46bba1a4d40ceece156b2fa 100644 (file)
@@ -17,7 +17,7 @@ export const SYMBOLS = (
         viewBox="0 0 196.52 196.52"
         xmlns="http://www.w3.org/2000/svg"
       >
-        <g color="#000" font-weight="400" font-family="sans-serif">
+        <g color="#000" fontWeight="400" fontFamily="sans-serif">
           <path
             d="M47.924 72.797a18.228 18.228 0 0 1-7.796 7.76l42.799 42.965 10.318-5.23zm56.453 56.67l-10.319 5.23 21.686 21.77a18.228 18.228 0 0 1 7.798-7.76z"
             overflow="visible"
@@ -69,7 +69,7 @@ export const SYMBOLS = (
             fill="#dbb210"
           />
         </g>
-        <g transform="rotate(3.118 600.365 106.46)" fill-opacity=".996">
+        <g transform="rotate(3.118 600.365 106.46)" fillOpacity=".996">
           <circle cx="106.266" cy="51.536" r="16.571" fill="#ffca00" />
           <circle cx="171.428" cy="110.193" r="16.571" fill="#64ff00" />
           <circle cx="135.764" cy="190.277" r="16.571" fill="#00a3ff" />
index db17084a3e56ebd0e74f8cb41055d234124e358a..95e593efb7d5aac44462b2f42ce8c518b0870df3 100644 (file)
@@ -75,8 +75,11 @@ export class Communities extends Component<any, CommunitiesState> {
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
       let listRes = Some(this.isoData.routeData[0] as ListCommunitiesResponse);
-      this.state.listCommunitiesResponse = listRes;
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        listCommunitiesResponse: listRes,
+        loading: false,
+      };
     } else {
       this.refetch();
     }
@@ -114,7 +117,7 @@ export class Communities extends Component<any, CommunitiesState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -127,10 +130,10 @@ export class Communities extends Component<any, CommunitiesState> {
           </h5>
         ) : (
           <div>
-            <div class="row">
-              <div class="col-md-6">
+            <div className="row">
+              <div className="col-md-6">
                 <h4>{i18n.t("list_of_communities")}</h4>
-                <span class="mb-2">
+                <span className="mb-2">
                   <ListingTypeSelect
                     type_={this.state.listingType}
                     showLocal={showLocal(this.isoData)}
@@ -139,24 +142,27 @@ export class Communities extends Component<any, CommunitiesState> {
                   />
                 </span>
               </div>
-              <div class="col-md-6">
-                <div class="float-md-right">{this.searchForm()}</div>
+              <div className="col-md-6">
+                <div className="float-md-right">{this.searchForm()}</div>
               </div>
             </div>
 
-            <div class="table-responsive">
-              <table id="community_table" class="table table-sm table-hover">
-                <thead class="pointer">
+            <div className="table-responsive">
+              <table
+                id="community_table"
+                className="table table-sm table-hover"
+              >
+                <thead className="pointer">
                   <tr>
                     <th>{i18n.t("name")}</th>
-                    <th class="text-right">{i18n.t("subscribers")}</th>
-                    <th class="text-right">
+                    <th className="text-right">{i18n.t("subscribers")}</th>
+                    <th className="text-right">
                       {i18n.t("users")} / {i18n.t("month")}
                     </th>
-                    <th class="text-right d-none d-lg-table-cell">
+                    <th className="text-right d-none d-lg-table-cell">
                       {i18n.t("posts")}
                     </th>
-                    <th class="text-right d-none d-lg-table-cell">
+                    <th className="text-right d-none d-lg-table-cell">
                       {i18n.t("comments")}
                     </th>
                     <th></th>
@@ -167,26 +173,26 @@ export class Communities extends Component<any, CommunitiesState> {
                     .map(l => l.communities)
                     .unwrapOr([])
                     .map(cv => (
-                      <tr>
+                      <tr key={cv.community.id}>
                         <td>
                           <CommunityLink community={cv.community} />
                         </td>
-                        <td class="text-right">
+                        <td className="text-right">
                           {numToSI(cv.counts.subscribers)}
                         </td>
-                        <td class="text-right">
+                        <td className="text-right">
                           {numToSI(cv.counts.users_active_month)}
                         </td>
-                        <td class="text-right d-none d-lg-table-cell">
+                        <td className="text-right d-none d-lg-table-cell">
                           {numToSI(cv.counts.posts)}
                         </td>
-                        <td class="text-right d-none d-lg-table-cell">
+                        <td className="text-right d-none d-lg-table-cell">
                           {numToSI(cv.counts.comments)}
                         </td>
-                        <td class="text-right">
+                        <td className="text-right">
                           {cv.subscribed == SubscribedType.Subscribed && (
                             <button
-                              class="btn btn-link d-inline-block"
+                              className="btn btn-link d-inline-block"
                               onClick={linkEvent(
                                 cv.community.id,
                                 this.handleUnsubscribe
@@ -197,7 +203,7 @@ export class Communities extends Component<any, CommunitiesState> {
                           )}
                           {cv.subscribed == SubscribedType.NotSubscribed && (
                             <button
-                              class="btn btn-link d-inline-block"
+                              className="btn btn-link d-inline-block"
                               onClick={linkEvent(
                                 cv.community.id,
                                 this.handleSubscribe
@@ -207,7 +213,7 @@ export class Communities extends Component<any, CommunitiesState> {
                             </button>
                           )}
                           {cv.subscribed == SubscribedType.Pending && (
-                            <div class="text-warning d-inline-block">
+                            <div className="text-warning d-inline-block">
                               {i18n.t("subscribe_pending")}
                             </div>
                           )}
@@ -230,23 +236,23 @@ export class Communities extends Component<any, CommunitiesState> {
   searchForm() {
     return (
       <form
-        class="form-inline"
+        className="form-inline"
         onSubmit={linkEvent(this, this.handleSearchSubmit)}
       >
         <input
           type="text"
           id="communities-search"
-          class="form-control mr-2 mb-2"
+          className="form-control mr-2 mb-2"
           value={this.state.searchText}
           placeholder={`${i18n.t("search")}...`}
           onInput={linkEvent(this, this.handleSearchChange)}
           required
           minLength={3}
         />
-        <label class="sr-only" htmlFor="communities-search">
+        <label className="sr-only" htmlFor="communities-search">
           {i18n.t("search")}
         </label>
-        <button type="submit" class="btn btn-secondary mr-2 mb-2">
+        <button type="submit" className="btn btn-secondary mr-2 mb-2">
           <span>{i18n.t("search")}</span>
         </button>
       </form>
@@ -343,10 +349,8 @@ export class Communities extends Component<any, CommunitiesState> {
         msg,
         ListCommunitiesResponse
       );
-      this.state.listCommunitiesResponse = Some(data);
-      this.state.loading = false;
+      this.setState({ listCommunitiesResponse: Some(data), loading: false });
       window.scrollTo(0, 0);
-      this.setState(this.state);
     } else if (op == UserOperation.FollowCommunity) {
       let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse);
       this.state.listCommunitiesResponse.match({
index cce144bf07b2de1b2f264cfe73c90af626d19a73..db7cff08a508e3644fd1a04aad75b50c8813bb6f 100644 (file)
@@ -73,9 +73,14 @@ export class CommunityForm extends Component<
     this.handleBannerUpload = this.handleBannerUpload.bind(this);
     this.handleBannerRemove = this.handleBannerRemove.bind(this);
 
-    this.props.community_view.match({
-      some: cv => {
-        this.state.communityForm = new CreateCommunity({
+    this.parseMessage = this.parseMessage.bind(this);
+    this.subscription = wsSubscribe(this.parseMessage);
+
+    if (this.props.community_view.isSome()) {
+      let cv = this.props.community_view.unwrap();
+      this.state = {
+        ...this.state,
+        communityForm: new CreateCommunity({
           name: cv.community.name,
           title: cv.community.title,
           description: cv.community.description,
@@ -86,13 +91,9 @@ export class CommunityForm extends Component<
             cv.community.posting_restricted_to_mods
           ),
           auth: undefined,
-        });
-      },
-      none: void 0,
-    });
-
-    this.parseMessage = this.parseMessage.bind(this);
-    this.subscription = wsSubscribe(this.parseMessage);
+        }),
+      };
+    }
   }
 
   componentDidUpdate() {
@@ -127,24 +128,24 @@ export class CommunityForm extends Component<
         />
         <form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
           {this.props.community_view.isNone() && (
-            <div class="form-group row">
+            <div className="form-group row">
               <label
-                class="col-12 col-sm-2 col-form-label"
+                className="col-12 col-sm-2 col-form-label"
                 htmlFor="community-name"
               >
                 {i18n.t("name")}
                 <span
-                  class="position-absolute pointer unselectable ml-2 text-muted"
+                  className="position-absolute pointer unselectable ml-2 text-muted"
                   data-tippy-content={i18n.t("name_explain")}
                 >
                   <Icon icon="help-circle" classes="icon-inline" />
                 </span>
               </label>
-              <div class="col-12 col-sm-10">
+              <div className="col-12 col-sm-10">
                 <input
                   type="text"
                   id="community-name"
-                  class="form-control"
+                  className="form-control"
                   value={this.state.communityForm.name}
                   onInput={linkEvent(this, this.handleCommunityNameChange)}
                   required
@@ -155,35 +156,35 @@ export class CommunityForm extends Component<
               </div>
             </div>
           )}
-          <div class="form-group row">
+          <div className="form-group row">
             <label
-              class="col-12 col-sm-2 col-form-label"
+              className="col-12 col-sm-2 col-form-label"
               htmlFor="community-title"
             >
               {i18n.t("display_name")}
               <span
-                class="position-absolute pointer unselectable ml-2 text-muted"
+                className="position-absolute pointer unselectable ml-2 text-muted"
                 data-tippy-content={i18n.t("display_name_explain")}
               >
                 <Icon icon="help-circle" classes="icon-inline" />
               </span>
             </label>
-            <div class="col-12 col-sm-10">
+            <div className="col-12 col-sm-10">
               <input
                 type="text"
                 id="community-title"
                 value={this.state.communityForm.title}
                 onInput={linkEvent(this, this.handleCommunityTitleChange)}
-                class="form-control"
+                className="form-control"
                 required
                 minLength={3}
                 maxLength={100}
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-sm-2">{i18n.t("icon")}</label>
-            <div class="col-12 col-sm-10">
+          <div className="form-group row">
+            <label className="col-12 col-sm-2">{i18n.t("icon")}</label>
+            <div className="col-12 col-sm-10">
               <ImageUploadForm
                 uploadTitle={i18n.t("upload_icon")}
                 imageSrc={this.state.communityForm.icon}
@@ -193,9 +194,9 @@ export class CommunityForm extends Component<
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-sm-2">{i18n.t("banner")}</label>
-            <div class="col-12 col-sm-10">
+          <div className="form-group row">
+            <label className="col-12 col-sm-2">{i18n.t("banner")}</label>
+            <div className="col-12 col-sm-10">
               <ImageUploadForm
                 uploadTitle={i18n.t("upload_banner")}
                 imageSrc={this.state.communityForm.banner}
@@ -204,30 +205,32 @@ export class CommunityForm extends Component<
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-sm-2 col-form-label" htmlFor={this.id}>
+          <div className="form-group row">
+            <label className="col-12 col-sm-2 col-form-label" htmlFor={this.id}>
               {i18n.t("sidebar")}
             </label>
-            <div class="col-12 col-sm-10">
+            <div className="col-12 col-sm-10">
               <MarkdownTextArea
                 initialContent={this.state.communityForm.description}
+                initialLanguageId={None}
                 placeholder={Some("description")}
                 buttonTitle={None}
                 maxLength={None}
                 onContentChange={this.handleCommunityDescriptionChange}
+                allLanguages={[]}
               />
             </div>
           </div>
 
           {this.props.enableNsfw && (
-            <div class="form-group row">
-              <legend class="col-form-label col-sm-2 pt-0">
+            <div className="form-group row">
+              <legend className="col-form-label col-sm-2 pt-0">
                 {i18n.t("nsfw")}
               </legend>
-              <div class="col-10">
-                <div class="form-check">
+              <div className="col-10">
+                <div className="form-check">
                   <input
-                    class="form-check-input position-static"
+                    className="form-check-input position-static"
                     id="community-nsfw"
                     type="checkbox"
                     checked={toUndefined(this.state.communityForm.nsfw)}
@@ -237,14 +240,14 @@ export class CommunityForm extends Component<
               </div>
             </div>
           )}
-          <div class="form-group row">
-            <legend class="col-form-label col-6 pt-0">
+          <div className="form-group row">
+            <legend className="col-form-label col-6 pt-0">
               {i18n.t("only_mods_can_post_in_community")}
             </legend>
-            <div class="col-6">
-              <div class="form-check">
+            <div className="col-6">
+              <div className="form-check">
                 <input
-                  class="form-check-input position-static"
+                  className="form-check-input position-static"
                   id="community-only-mods-can-post"
                   type="checkbox"
                   checked={toUndefined(
@@ -258,11 +261,11 @@ export class CommunityForm extends Component<
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
+          <div className="form-group row">
+            <div className="col-12">
               <button
                 type="submit"
-                class="btn btn-secondary mr-2"
+                className="btn btn-secondary mr-2"
                 disabled={this.state.loading}
               >
                 {this.state.loading ? (
@@ -276,7 +279,7 @@ export class CommunityForm extends Component<
               {this.props.community_view.isSome() && (
                 <button
                   type="button"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(this, this.handleCancel)}
                 >
                   {i18n.t("cancel")}
@@ -291,7 +294,7 @@ export class CommunityForm extends Component<
 
   handleCreateCommunitySubmit(i: CommunityForm, event: any) {
     event.preventDefault();
-    i.state.loading = true;
+    i.setState({ loading: true });
     let cForm = i.state.communityForm;
     cForm.auth = auth().unwrap();
 
@@ -330,17 +333,18 @@ export class CommunityForm extends Component<
   }
 
   handleCommunityDescriptionChange(val: string) {
-    this.state.communityForm.description = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.communityForm.description = Some(val)), s));
   }
 
   handleCommunityNsfwChange(i: CommunityForm, event: any) {
-    i.state.communityForm.nsfw = event.target.checked;
+    i.state.communityForm.nsfw = Some(event.target.checked);
     i.setState(i.state);
   }
 
   handleCommunityPostingRestrictedToMods(i: CommunityForm, event: any) {
-    i.state.communityForm.posting_restricted_to_mods = event.target.checked;
+    i.state.communityForm.posting_restricted_to_mods = Some(
+      event.target.checked
+    );
     i.setState(i.state);
   }
 
@@ -349,23 +353,19 @@ export class CommunityForm extends Component<
   }
 
   handleIconUpload(url: string) {
-    this.state.communityForm.icon = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.communityForm.icon = Some(url)), s));
   }
 
   handleIconRemove() {
-    this.state.communityForm.icon = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.communityForm.icon = Some("")), s));
   }
 
   handleBannerUpload(url: string) {
-    this.state.communityForm.banner = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.communityForm.banner = Some(url)), s));
   }
 
   handleBannerRemove() {
-    this.state.communityForm.banner = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.communityForm.banner = Some("")), s));
   }
 
   parseMessage(msg: any) {
@@ -374,12 +374,10 @@ export class CommunityForm extends Component<
     if (msg.error) {
       // Errors handled by top level pages
       // toast(i18n.t(msg.error), "danger");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (op == UserOperation.CreateCommunity) {
       let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse);
-      this.state.loading = false;
       this.props.onCreate(data.community_view);
 
       // Update myUserInfo
@@ -401,7 +399,7 @@ export class CommunityForm extends Component<
       });
     } else if (op == UserOperation.EditCommunity) {
       let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse);
-      this.state.loading = false;
+      this.setState({ loading: false });
       this.props.onEdit(data.community_view);
       let community = data.community_view.community;
 
index cc987053246c4a7ed2db183209ea80b5f5492ff3..b051ed8aac36d85e72eafa7a9b981c30301362e3 100644 (file)
@@ -64,7 +64,7 @@ export class CommunityLink extends Component<CommunityLinkProps, any> {
             some: icon => <PictrsImage src={icon} icon />,
             none: <></>,
           })}
-        <span class="overflow-wrap-anywhere">{displayName}</span>
+        <span className="overflow-wrap-anywhere">{displayName}</span>
       </>
     );
   }
index 4e8d949c4ca1b99f6119eff73d61dc1e97303445..82049100f60205ce772114e72685ce6ea91030f3 100644 (file)
@@ -49,7 +49,9 @@ import {
   getDataTypeFromProps,
   getPageFromProps,
   getSortTypeFromProps,
+  isPostBlocked,
   notifyPost,
+  nsfwCheck,
   postToCommentSortType,
   relTags,
   restoreScrollPosition,
@@ -139,24 +141,27 @@ export class Community extends Component<any, State> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.communityRes = Some(
-        this.isoData.routeData[0] as GetCommunityResponse
-      );
+      this.state = {
+        ...this.state,
+        communityRes: Some(this.isoData.routeData[0] as GetCommunityResponse),
+      };
       let postsRes = Some(this.isoData.routeData[1] as GetPostsResponse);
       let commentsRes = Some(this.isoData.routeData[2] as GetCommentsResponse);
 
-      postsRes.match({
-        some: pvs => (this.state.posts = pvs.posts),
-        none: void 0,
-      });
-      commentsRes.match({
-        some: cvs => (this.state.comments = cvs.comments),
-        none: void 0,
-      });
+      if (postsRes.isSome()) {
+        this.state = { ...this.state, posts: postsRes.unwrap().posts };
+      }
+
+      if (commentsRes.isSome()) {
+        this.state = { ...this.state, comments: commentsRes.unwrap().comments };
+      }
 
-      this.state.communityLoading = false;
-      this.state.postsLoading = false;
-      this.state.commentsLoading = false;
+      this.state = {
+        ...this.state,
+        communityLoading: false,
+        postsLoading: false,
+        commentsLoading: false,
+      };
     } else {
       this.fetchCommunity();
       this.fetchData();
@@ -278,7 +283,7 @@ export class Community extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.communityLoading ? (
           <h5>
             <Spinner large />
@@ -294,12 +299,12 @@ export class Community extends Component<any, State> {
                   image={res.community_view.community.icon}
                 />
 
-                <div class="row">
-                  <div class="col-12 col-md-8">
+                <div className="row">
+                  <div className="col-12 col-md-8">
                     {this.communityInfo()}
-                    <div class="d-block d-md-none">
+                    <div className="d-block d-md-none">
                       <button
-                        class="btn btn-secondary d-inline-block mb-2 mr-3"
+                        className="btn btn-secondary d-inline-block mb-2 mr-3"
                         onClick={linkEvent(this, this.handleShowSidebarMobile)}
                       >
                         {i18n.t("sidebar")}{" "}
@@ -344,7 +349,7 @@ export class Community extends Component<any, State> {
                       onChange={this.handlePageChange}
                     />
                   </div>
-                  <div class="d-none d-md-block col-md-4">
+                  <div className="d-none d-md-block col-md-4">
                     <Sidebar
                       community_view={res.community_view}
                       moderators={res.moderators}
@@ -388,6 +393,7 @@ export class Community extends Component<any, State> {
           removeDuplicates
           enableDownvotes={enableDownvotes(this.state.siteRes)}
           enableNsfw={enableNsfw(this.state.siteRes)}
+          allLanguages={this.state.siteRes.all_languages}
         />
       )
     ) : this.state.commentsLoading ? (
@@ -404,6 +410,7 @@ export class Community extends Component<any, State> {
         moderators={this.state.communityRes.map(r => r.moderators)}
         admins={Some(this.state.siteRes.admins)}
         maxCommentsShown={None}
+        allLanguages={this.state.siteRes.all_languages}
       />
     );
   }
@@ -413,9 +420,9 @@ export class Community extends Component<any, State> {
       .map(r => r.community_view.community)
       .match({
         some: community => (
-          <div class="mb-2">
+          <div className="mb-2">
             <BannerIconHeader banner={community.banner} icon={community.icon} />
-            <h5 class="mb-0 overflow-wrap-anywhere">{community.title}</h5>
+            <h5 className="mb-0 overflow-wrap-anywhere">{community.title}</h5>
             <CommunityLink
               community={community}
               realLink
@@ -434,14 +441,14 @@ export class Community extends Component<any, State> {
       communityRSSUrl(r.community_view.community.actor_id, this.state.sort)
     );
     return (
-      <div class="mb-3">
-        <span class="mr-3">
+      <div className="mb-3">
+        <span className="mr-3">
           <DataTypeSelect
             type_={this.state.dataType}
             onChange={this.handleDataTypeChange}
           />
         </span>
-        <span class="mr-2">
+        <span className="mr-2">
           <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
         </span>
         {communityRss.match({
@@ -475,8 +482,7 @@ export class Community extends Component<any, State> {
   }
 
   handleShowSidebarMobile(i: Community) {
-    i.state.showSidebarMobile = !i.state.showSidebarMobile;
-    i.setState(i.state);
+    i.setState({ showSidebarMobile: !i.state.showSidebarMobile });
   }
 
   updateUrl(paramUpdates: UrlParams) {
@@ -543,9 +549,7 @@ export class Community extends Component<any, State> {
       this.fetchData();
     } else if (op == UserOperation.GetCommunity) {
       let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse);
-      this.state.communityRes = Some(data);
-      this.state.communityLoading = false;
-      this.setState(this.state);
+      this.setState({ communityRes: Some(data), communityLoading: false });
       // TODO why is there no auth in this form?
       WebSocketService.Instance.send(
         wsClient.communityJoin({
@@ -576,9 +580,7 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.GetPosts) {
       let data = wsJsonToRes<GetPostsResponse>(msg, GetPostsResponse);
-      this.state.posts = data.posts;
-      this.state.postsLoading = false;
-      this.setState(this.state);
+      this.setState({ posts: data.posts, postsLoading: false });
       restoreScrollPosition(this.context);
       setupTippy();
     } else if (
@@ -594,15 +596,24 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.CreatePost) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
-      this.state.posts.unshift(data.post_view);
+
+      let showPostNotifs = UserService.Instance.myUserInfo
+        .map(m => m.local_user_view.local_user.show_new_post_notifs)
+        .unwrapOr(false);
+
+      // Only push these if you're on the first page, you pass the nsfw check, and it isn't blocked
+      //
       if (
-        UserService.Instance.myUserInfo
-          .map(m => m.local_user_view.local_user.show_new_post_notifs)
-          .unwrapOr(false)
+        this.state.page == 1 &&
+        nsfwCheck(data.post_view) &&
+        !isPostBlocked(data.post_view)
       ) {
-        notifyPost(data.post_view, this.context.router);
+        this.state.posts.unshift(data.post_view);
+        if (showPostNotifs) {
+          notifyPost(data.post_view, this.context.router);
+        }
+        this.setState(this.state);
       }
-      this.setState(this.state);
     } else if (op == UserOperation.CreatePostLike) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
       createPostLikeFindRes(data.post_view, this.state.posts);
@@ -631,9 +642,7 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.GetComments) {
       let data = wsJsonToRes<GetCommentsResponse>(msg, GetCommentsResponse);
-      this.state.comments = data.comments;
-      this.state.commentsLoading = false;
-      this.setState(this.state);
+      this.setState({ comments: data.comments, commentsLoading: false });
     } else if (
       op == UserOperation.EditComment ||
       op == UserOperation.DeleteComment ||
index 9a36678433b964492b394e4ea34223f88a2aa15a..8aed56b12eb61ef3dc8c6fe91d4e6bb78328ceea 100644 (file)
@@ -56,7 +56,7 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -68,8 +68,8 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
             <Spinner large />
           </h5>
         ) : (
-          <div class="row">
-            <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+          <div className="row">
+            <div className="col-12 col-lg-6 offset-lg-3 mb-4">
               <h5>{i18n.t("create_community")}</h5>
               <CommunityForm
                 community_view={None}
index 775fd636edae18a6fb795b9c2e3061f8eff7f835..43e863c87c09172edee88aa640c51a0066c10d74 100644 (file)
@@ -91,16 +91,17 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   sidebar() {
     return (
       <div>
-        <div class="card border-secondary mb-3">
-          <div class="card-body">
+        <div className="card border-secondary mb-3">
+          <div className="card-body">
             {this.communityTitle()}
             {this.adminButtons()}
             {this.subscribe()}
             {this.canPost && this.createPost()}
+            {this.blockCommunity()}
           </div>
         </div>
-        <div class="card border-secondary mb-3">
-          <div class="card-body">
+        <div className="card border-secondary mb-3">
+          <div className="card-body">
             {this.description()}
             {this.badges()}
             {this.mods()}
@@ -119,10 +120,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           {this.props.showIcon && (
             <BannerIconHeader icon={community.icon} banner={community.banner} />
           )}
-          <span class="mr-2">{community.title}</span>
+          <span className="mr-2">{community.title}</span>
           {subscribed == SubscribedType.Subscribed && (
             <button
-              class="btn btn-secondary btn-sm mr-2"
+              className="btn btn-secondary btn-sm mr-2"
               onClick={linkEvent(this, this.handleUnsubscribe)}
             >
               <Icon icon="check" classes="icon-inline text-success mr-1" />
@@ -131,7 +132,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           )}
           {subscribed == SubscribedType.Pending && (
             <button
-              class="btn btn-warning mr-2"
+              className="btn btn-warning mr-2"
               onClick={linkEvent(this, this.handleUnsubscribe)}
             >
               {i18n.t("subscribe_pending")}
@@ -168,7 +169,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     let community_view = this.props.community_view;
     let counts = community_view.counts;
     return (
-      <ul class="my-1 list-inline">
+      <ul className="my-1 list-inline">
         <li className="list-inline-item badge badge-secondary">
           {i18n.t("number_online", {
             count: this.props.online,
@@ -259,10 +260,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
 
   mods() {
     return (
-      <ul class="list-inline small">
-        <li class="list-inline-item">{i18n.t("mods")}: </li>
+      <ul className="list-inline small">
+        <li className="list-inline-item">{i18n.t("mods")}: </li>
         {this.props.moderators.map(mod => (
-          <li class="list-inline-item">
+          <li key={mod.moderator.id} className="list-inline-item">
             <PersonListing person={mod.moderator} />
           </li>
         ))}
@@ -273,49 +274,55 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   createPost() {
     let cv = this.props.community_view;
     return (
-      cv.subscribed == SubscribedType.Subscribed && (
-        <Link
-          className={`btn btn-secondary btn-block mb-2 ${
-            cv.community.deleted || cv.community.removed ? "no-click" : ""
-          }`}
-          to={`/create_post?community_id=${cv.community.id}`}
-        >
-          {i18n.t("create_a_post")}
-        </Link>
-      )
+      <Link
+        className={`btn btn-secondary btn-block mb-2 ${
+          cv.community.deleted || cv.community.removed ? "no-click" : ""
+        }`}
+        to={`/create_post?community_id=${cv.community.id}`}
+      >
+        {i18n.t("create_a_post")}
+      </Link>
     );
   }
 
   subscribe() {
     let community_view = this.props.community_view;
-    let blocked = this.props.community_view.blocked;
     return (
-      <div class="mb-2">
+      <div className="mb-2">
         {community_view.subscribed == SubscribedType.NotSubscribed && (
-          <>
+          <button
+            className="btn btn-secondary btn-block"
+            onClick={linkEvent(this, this.handleSubscribe)}
+          >
+            {i18n.t("subscribe")}
+          </button>
+        )}
+      </div>
+    );
+  }
+
+  blockCommunity() {
+    let community_view = this.props.community_view;
+    let blocked = this.props.community_view.blocked;
+
+    return (
+      <div className="mb-2">
+        {community_view.subscribed == SubscribedType.NotSubscribed &&
+          (blocked ? (
             <button
-              class="btn btn-secondary btn-block"
-              onClick={linkEvent(this, this.handleSubscribe)}
+              className="btn btn-danger btn-block"
+              onClick={linkEvent(this, this.handleUnblock)}
             >
-              {i18n.t("subscribe")}
+              {i18n.t("unblock_community")}
             </button>
-            {blocked ? (
-              <button
-                class="btn btn-danger btn-block"
-                onClick={linkEvent(this, this.handleUnblock)}
-              >
-                {i18n.t("unblock_community")}
-              </button>
-            ) : (
-              <button
-                class="btn btn-danger btn-block"
-                onClick={linkEvent(this, this.handleBlock)}
-              >
-                {i18n.t("block_community")}
-              </button>
-            )}
-          </>
-        )}
+          ) : (
+            <button
+              className="btn btn-danger btn-block"
+              onClick={linkEvent(this, this.handleBlock)}
+            >
+              {i18n.t("block_community")}
+            </button>
+          ))}
       </div>
     );
   }
@@ -334,12 +341,12 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     let community_view = this.props.community_view;
     return (
       <>
-        <ul class="list-inline mb-1 text-muted font-weight-bold">
+        <ul className="list-inline mb-1 text-muted font-weight-bold">
           {amMod(Some(this.props.moderators)) && (
             <>
               <li className="list-inline-item-action">
                 <button
-                  class="btn btn-link text-muted d-inline-block"
+                  className="btn btn-link text-muted d-inline-block"
                   onClick={linkEvent(this, this.handleEditClick)}
                   data-tippy-content={i18n.t("edit")}
                   aria-label={i18n.t("edit")}
@@ -351,7 +358,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                 (!this.state.showConfirmLeaveModTeam ? (
                   <li className="list-inline-item-action">
                     <button
-                      class="btn btn-link text-muted d-inline-block"
+                      className="btn btn-link text-muted d-inline-block"
                       onClick={linkEvent(
                         this,
                         this.handleShowConfirmLeaveModTeamClick
@@ -367,7 +374,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                     </li>
                     <li className="list-inline-item-action">
                       <button
-                        class="btn btn-link text-muted d-inline-block"
+                        className="btn btn-link text-muted d-inline-block"
                         onClick={linkEvent(this, this.handleLeaveModTeamClick)}
                       >
                         {i18n.t("yes")}
@@ -375,7 +382,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                     </li>
                     <li className="list-inline-item-action">
                       <button
-                        class="btn btn-link text-muted d-inline-block"
+                        className="btn btn-link text-muted d-inline-block"
                         onClick={linkEvent(
                           this,
                           this.handleCancelLeaveModTeamClick
@@ -389,7 +396,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
               {amTopMod(Some(this.props.moderators)) && (
                 <li className="list-inline-item-action">
                   <button
-                    class="btn btn-link text-muted d-inline-block"
+                    className="btn btn-link text-muted d-inline-block"
                     onClick={linkEvent(this, this.handleDeleteClick)}
                     data-tippy-content={
                       !community_view.community.deleted
@@ -413,25 +420,25 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
               )}
             </>
           )}
-          {amAdmin(Some(this.props.admins)) && (
+          {amAdmin() && (
             <li className="list-inline-item">
               {!this.props.community_view.community.removed ? (
                 <button
-                  class="btn btn-link text-muted d-inline-block"
+                  className="btn btn-link text-muted d-inline-block"
                   onClick={linkEvent(this, this.handleModRemoveShow)}
                 >
                   {i18n.t("remove")}
                 </button>
               ) : (
                 <button
-                  class="btn btn-link text-muted d-inline-block"
+                  className="btn btn-link text-muted d-inline-block"
                   onClick={linkEvent(this, this.handleModRemoveSubmit)}
                 >
                   {i18n.t("restore")}
                 </button>
               )}
               <button
-                class="btn btn-link text-muted d-inline-block"
+                className="btn btn-link text-muted d-inline-block"
                 onClick={linkEvent(this, this.handlePurgeCommunityShow)}
                 aria-label={i18n.t("purge_community")}
               >
@@ -442,14 +449,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
         </ul>
         {this.state.showRemoveDialog && (
           <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
-            <div class="form-group">
-              <label class="col-form-label" htmlFor="remove-reason">
+            <div className="form-group">
+              <label className="col-form-label" htmlFor="remove-reason">
                 {i18n.t("reason")}
               </label>
               <input
                 type="text"
                 id="remove-reason"
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("optional")}
                 value={toUndefined(this.state.removeReason)}
                 onInput={linkEvent(this, this.handleModRemoveReasonChange)}
@@ -460,8 +467,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
             {/*   <label class="col-form-label">Expires</label> */}
             {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
             {/* </div> */}
-            <div class="form-group">
-              <button type="submit" class="btn btn-secondary">
+            <div className="form-group">
+              <button type="submit" className="btn btn-secondary">
                 {i18n.t("remove_community")}
               </button>
             </div>
@@ -469,29 +476,29 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
         )}
         {this.state.showPurgeDialog && (
           <form onSubmit={linkEvent(this, this.handlePurgeSubmit)}>
-            <div class="form-group">
+            <div className="form-group">
               <PurgeWarning />
             </div>
-            <div class="form-group">
-              <label class="sr-only" htmlFor="purge-reason">
+            <div className="form-group">
+              <label className="sr-only" htmlFor="purge-reason">
                 {i18n.t("reason")}
               </label>
               <input
                 type="text"
                 id="purge-reason"
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("reason")}
                 value={toUndefined(this.state.purgeReason)}
                 onInput={linkEvent(this, this.handlePurgeReasonChange)}
               />
             </div>
-            <div class="form-group">
+            <div className="form-group">
               {this.state.purgeLoading ? (
                 <Spinner />
               ) : (
                 <button
                   type="submit"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   aria-label={i18n.t("purge_community")}
                 >
                   {i18n.t("purge_community")}
@@ -505,18 +512,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   handleEditClick(i: Sidebar) {
-    i.state.showEdit = true;
-    i.setState(i.state);
+    i.setState({ showEdit: true });
   }
 
   handleEditCommunity() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   handleEditCancel() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   handleDeleteClick(i: Sidebar, event: any) {
@@ -530,8 +534,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   handleShowConfirmLeaveModTeamClick(i: Sidebar) {
-    i.state.showConfirmLeaveModTeam = true;
-    i.setState(i.state);
+    i.setState({ showConfirmLeaveModTeam: true });
   }
 
   handleLeaveModTeamClick(i: Sidebar) {
@@ -544,16 +547,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           auth: auth().unwrap(),
         });
         WebSocketService.Instance.send(wsClient.addModToCommunity(form));
-        i.state.showConfirmLeaveModTeam = false;
-        i.setState(i.state);
+        i.setState({ showConfirmLeaveModTeam: false });
       },
       none: void 0,
     });
   }
 
   handleCancelLeaveModTeamClick(i: Sidebar) {
-    i.state.showConfirmLeaveModTeam = false;
-    i.setState(i.state);
+    i.setState({ showConfirmLeaveModTeam: false });
   }
 
   handleUnsubscribe(i: Sidebar, event: any) {
@@ -599,23 +600,20 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     return (
       !this.props.community_view.community.posting_restricted_to_mods ||
       amMod(Some(this.props.moderators)) ||
-      amAdmin(Some(this.props.admins))
+      amAdmin()
     );
   }
 
   handleModRemoveShow(i: Sidebar) {
-    i.state.showRemoveDialog = true;
-    i.setState(i.state);
+    i.setState({ showRemoveDialog: true });
   }
 
   handleModRemoveReasonChange(i: Sidebar, event: any) {
-    i.state.removeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ removeReason: Some(event.target.value) });
   }
 
   handleModRemoveExpiresChange(i: Sidebar, event: any) {
-    i.state.removeExpires = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ removeExpires: Some(event.target.value) });
   }
 
   handleModRemoveSubmit(i: Sidebar, event: any) {
@@ -629,19 +627,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     });
     WebSocketService.Instance.send(wsClient.removeCommunity(removeForm));
 
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({ showRemoveDialog: false });
   }
 
   handlePurgeCommunityShow(i: Sidebar) {
-    i.state.showPurgeDialog = true;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({ showPurgeDialog: true, showRemoveDialog: false });
   }
 
   handlePurgeReasonChange(i: Sidebar, event: any) {
-    i.state.purgeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ purgeReason: Some(event.target.value) });
   }
 
   handlePurgeSubmit(i: Sidebar, event: any) {
@@ -654,8 +648,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     });
     WebSocketService.Instance.send(wsClient.purgeCommunity(form));
 
-    i.state.purgeLoading = true;
-    i.setState(i.state);
+    i.setState({ purgeLoading: true });
   }
 
   handleBlock(i: Sidebar, event: any) {
index e01a09d7ac612a04ac274d987fd0b4d6b257f785..011a5767ac9e164465382858de2c2efcf14a6ee7 100644 (file)
@@ -59,10 +59,11 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.banned = (
-        this.isoData.routeData[0] as BannedPersonsResponse
-      ).banned;
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned,
+        loading: false,
+      };
     } else {
       WebSocketService.Instance.send(
         wsClient.getBannedPersons({
@@ -103,14 +104,14 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
           </h5>
         ) : (
-          <div class="row">
-            <div class="col-12 col-md-6">
+          <div className="row">
+            <div className="col-12 col-md-6">
               <HtmlTags
                 title={this.documentTitle}
                 path={this.context.router.route.match.url}
@@ -127,7 +128,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
                 none: <></>,
               })}
             </div>
-            <div class="col-12 col-md-6">
+            <div className="col-12 col-md-6">
               {this.admins()}
               {this.bannedUsers()}
             </div>
@@ -141,9 +142,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
     return (
       <>
         <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
-        <ul class="list-unstyled">
+        <ul className="list-unstyled">
           {this.state.siteRes.admins.map(admin => (
-            <li class="list-inline-item">
+            <li key={admin.person.id} className="list-inline-item">
               <PersonListing person={admin.person} />
             </li>
           ))}
@@ -157,7 +158,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
     return (
       <button
         onClick={linkEvent(this, this.handleLeaveAdminTeam)}
-        class="btn btn-danger mb-2"
+        className="btn btn-danger mb-2"
       >
         {this.state.leaveAdminTeamLoading ? (
           <Spinner />
@@ -172,9 +173,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
     return (
       <>
         <h5>{i18n.t("banned_users")}</h5>
-        <ul class="list-unstyled">
+        <ul className="list-unstyled">
           {this.state.banned.map(banned => (
-            <li class="list-inline-item">
+            <li key={banned.person.id} className="list-inline-item">
               <PersonListing person={banned.person} />
             </li>
           ))}
@@ -184,11 +185,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
   }
 
   handleLeaveAdminTeam(i: AdminSettings) {
-    i.state.leaveAdminTeamLoading = true;
+    i.setState({ leaveAdminTeamLoading: true });
     WebSocketService.Instance.send(
       wsClient.leaveAdmin({ auth: auth().unwrap() })
     );
-    i.setState(i.state);
   }
 
   parseMessage(msg: any) {
@@ -197,26 +197,21 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
       this.context.router.history.push("/");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (op == UserOperation.EditSite) {
       let data = wsJsonToRes<SiteResponse>(msg, SiteResponse);
-      this.state.siteRes.site_view = Some(data.site_view);
-      this.setState(this.state);
+      this.setState(s => ((s.siteRes.site_view = Some(data.site_view)), s));
       toast(i18n.t("site_saved"));
     } else if (op == UserOperation.GetBannedPersons) {
       let data = wsJsonToRes<BannedPersonsResponse>(msg, BannedPersonsResponse);
-      this.state.banned = data.banned;
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ banned: data.banned, loading: false });
     } else if (op == UserOperation.LeaveAdmin) {
       let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse);
-      this.state.siteRes.site_view = data.site_view;
-      this.setState(this.state);
-      this.state.leaveAdminTeamLoading = false;
+      this.setState(s => ((s.siteRes.site_view = data.site_view), s));
+      this.setState({ leaveAdminTeamLoading: false });
+
       toast(i18n.t("left_admin_team"));
-      this.setState(this.state);
       this.context.router.history.push("/");
     }
   }
index 53559df9cbe5bc93defd43edc0f7d5a93cc888f2..3d163197fff63a4a0ee9010a740965baaaa2ff34 100644 (file)
@@ -38,6 +38,7 @@ import {
 import { UserService, WebSocketService } from "../../services";
 import {
   auth,
+  canCreateCommunity,
   commentsToFlatNodes,
   createCommentLikeRes,
   createPostLikeFindRes,
@@ -51,7 +52,9 @@ import {
   getPageFromProps,
   getSortTypeFromProps,
   isBrowser,
+  isPostBlocked,
   notifyPost,
+  nsfwCheck,
   postToCommentSortType,
   relTags,
   restoreScrollPosition,
@@ -157,22 +160,24 @@ export class Home extends Component<any, HomeState> {
       let commentsRes = Some(this.isoData.routeData[1] as GetCommentsResponse);
       let trendingRes = this.isoData.routeData[2] as ListCommunitiesResponse;
 
-      postsRes.match({
-        some: pvs => (this.state.posts = pvs.posts),
-        none: void 0,
-      });
-      commentsRes.match({
-        some: cvs => (this.state.comments = cvs.comments),
-        none: void 0,
-      });
-      this.state.trendingCommunities = trendingRes.communities;
+      if (postsRes.isSome()) {
+        this.state = { ...this.state, posts: postsRes.unwrap().posts };
+      }
+
+      if (commentsRes.isSome()) {
+        this.state = { ...this.state, comments: commentsRes.unwrap().comments };
+      }
 
       if (isBrowser()) {
         WebSocketService.Instance.send(
           wsClient.communityJoin({ community_id: 0 })
         );
       }
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        trendingCommunities: trendingRes.communities,
+        loading: false,
+      };
     } else {
       this.fetchTrendingCommunities();
       this.fetchData();
@@ -317,7 +322,7 @@ export class Home extends Component<any, HomeState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -325,12 +330,14 @@ export class Home extends Component<any, HomeState> {
           image={None}
         />
         {this.state.siteRes.site_view.isSome() && (
-          <div class="row">
-            <main role="main" class="col-12 col-md-8">
-              <div class="d-block d-md-none">{this.mobileView()}</div>
+          <div className="row">
+            <main role="main" className="col-12 col-md-8">
+              <div className="d-block d-md-none">{this.mobileView()}</div>
               {this.posts()}
             </main>
-            <aside class="d-none d-md-block col-md-4">{this.mySidebar()}</aside>
+            <aside className="d-none d-md-block col-md-4">
+              {this.mySidebar()}
+            </aside>
           </div>
         )}
       </div>
@@ -347,11 +354,11 @@ export class Home extends Component<any, HomeState> {
   mobileView() {
     let siteRes = this.state.siteRes;
     return (
-      <div class="row">
-        <div class="col-12">
+      <div className="row">
+        <div className="col-12">
           {this.hasFollows && (
             <button
-              class="btn btn-secondary d-inline-block mb-2 mr-3"
+              className="btn btn-secondary d-inline-block mb-2 mr-3"
               onClick={linkEvent(this, this.handleShowSubscribedMobile)}
             >
               {i18n.t("subscribed")}{" "}
@@ -366,7 +373,7 @@ export class Home extends Component<any, HomeState> {
             </button>
           )}
           <button
-            class="btn btn-secondary d-inline-block mb-2 mr-3"
+            className="btn btn-secondary d-inline-block mb-2 mr-3"
             onClick={linkEvent(this, this.handleShowTrendingMobile)}
           >
             {i18n.t("trending")}{" "}
@@ -378,7 +385,7 @@ export class Home extends Component<any, HomeState> {
             />
           </button>
           <button
-            class="btn btn-secondary d-inline-block mb-2 mr-3"
+            className="btn btn-secondary d-inline-block mb-2 mr-3"
             onClick={linkEvent(this, this.handleShowSidebarMobile)}
           >
             {i18n.t("sidebar")}{" "}
@@ -403,13 +410,13 @@ export class Home extends Component<any, HomeState> {
               none: <></>,
             })}
           {this.state.showTrendingMobile && (
-            <div class="col-12 card border-secondary mb-3">
-              <div class="card-body">{this.trendingCommunities()}</div>
+            <div className="col-12 card border-secondary mb-3">
+              <div className="card-body">{this.trendingCommunities()}</div>
             </div>
           )}
           {this.state.showSubscribedMobile && (
-            <div class="col-12 card border-secondary mb-3">
-              <div class="card-body">{this.subscribedCommunities()}</div>
+            <div className="col-12 card border-secondary mb-3">
+              <div className="card-body">{this.subscribedCommunities()}</div>
             </div>
           )}
         </div>
@@ -423,10 +430,11 @@ export class Home extends Component<any, HomeState> {
       <div>
         {!this.state.loading && (
           <div>
-            <div class="card border-secondary mb-3">
-              <div class="card-body">
+            <div className="card border-secondary mb-3">
+              <div className="card-body">
                 {this.trendingCommunities()}
-                {this.createCommunityButton()}
+                {canCreateCommunity(this.state.siteRes) &&
+                  this.createCommunityButton()}
                 {this.exploreCommunitiesButton()}
               </div>
             </div>
@@ -443,8 +451,8 @@ export class Home extends Component<any, HomeState> {
               none: <></>,
             })}
             {this.hasFollows && (
-              <div class="card border-secondary mb-3">
-                <div class="card-body">{this.subscribedCommunities()}</div>
+              <div className="card border-secondary mb-3">
+                <div className="card-body">{this.subscribedCommunities()}</div>
               </div>
             )}
           </div>
@@ -480,9 +488,12 @@ export class Home extends Component<any, HomeState> {
             </Link>
           </T>
         </h5>
-        <ul class="list-inline mb-0">
+        <ul className="list-inline mb-0">
           {this.state.trendingCommunities.map(cv => (
-            <li class="list-inline-item d-inline-block">
+            <li
+              key={cv.community.id}
+              className="list-inline-item d-inline-block"
+            >
               <CommunityLink community={cv.community} />
             </li>
           ))}
@@ -502,7 +513,7 @@ export class Home extends Component<any, HomeState> {
             </Link>
           </T>
           <button
-            class="btn btn-sm text-muted"
+            className="btn btn-sm text-muted"
             onClick={linkEvent(this, this.handleCollapseSubscribe)}
             aria-label={i18n.t("collapse")}
             data-tippy-content={i18n.t("collapse")}
@@ -515,12 +526,15 @@ export class Home extends Component<any, HomeState> {
           </button>
         </h5>
         {!this.state.subscribedCollapsed && (
-          <ul class="list-inline mb-0">
+          <ul className="list-inline mb-0">
             {UserService.Instance.myUserInfo
               .map(m => m.follows)
               .unwrapOr([])
               .map(cfv => (
-                <li class="list-inline-item d-inline-block">
+                <li
+                  key={cfv.community.id}
+                  className="list-inline-item d-inline-block"
+                >
                   <CommunityLink community={cfv.community} />
                 </li>
               ))}
@@ -542,7 +556,7 @@ export class Home extends Component<any, HomeState> {
 
   posts() {
     return (
-      <div class="main-content-wrapper">
+      <div className="main-content-wrapper">
         {this.state.loading ? (
           <h5>
             <Spinner large />
@@ -569,6 +583,7 @@ export class Home extends Component<any, HomeState> {
         removeDuplicates
         enableDownvotes={enableDownvotes(this.state.siteRes)}
         enableNsfw={enableNsfw(this.state.siteRes)}
+        allLanguages={this.state.siteRes.all_languages}
       />
     ) : (
       <CommentNodes
@@ -581,6 +596,7 @@ export class Home extends Component<any, HomeState> {
         showCommunity
         showContext
         enableDownvotes={enableDownvotes(this.state.siteRes)}
+        allLanguages={this.state.siteRes.all_languages}
       />
     );
   }
@@ -594,13 +610,13 @@ export class Home extends Component<any, HomeState> {
 
     return (
       <div className="mb-3">
-        <span class="mr-3">
+        <span className="mr-3">
           <DataTypeSelect
             type_={this.state.dataType}
             onChange={this.handleDataTypeChange}
           />
         </span>
-        <span class="mr-3">
+        <span className="mr-3">
           <ListingTypeSelect
             type_={this.state.listingType}
             showLocal={showLocal(this.isoData)}
@@ -608,7 +624,7 @@ export class Home extends Component<any, HomeState> {
             onChange={this.handleListingTypeChange}
           />
         </span>
-        <span class="mr-2">
+        <span className="mr-2">
           <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
         </span>
         {this.state.listingType == ListingType.All && (
@@ -644,23 +660,19 @@ export class Home extends Component<any, HomeState> {
   }
 
   handleShowSubscribedMobile(i: Home) {
-    i.state.showSubscribedMobile = !i.state.showSubscribedMobile;
-    i.setState(i.state);
+    i.setState({ showSubscribedMobile: !i.state.showSubscribedMobile });
   }
 
   handleShowTrendingMobile(i: Home) {
-    i.state.showTrendingMobile = !i.state.showTrendingMobile;
-    i.setState(i.state);
+    i.setState({ showTrendingMobile: !i.state.showTrendingMobile });
   }
 
   handleShowSidebarMobile(i: Home) {
-    i.state.showSidebarMobile = !i.state.showSidebarMobile;
-    i.setState(i.state);
+    i.setState({ showSidebarMobile: !i.state.showSidebarMobile });
   }
 
   handleCollapseSubscribe(i: Home) {
-    i.state.subscribedCollapsed = !i.state.subscribedCollapsed;
-    i.setState(i.state);
+    i.setState({ subscribedCollapsed: !i.state.subscribedCollapsed });
   }
 
   handlePageChange(page: number) {
@@ -731,18 +743,14 @@ export class Home extends Component<any, HomeState> {
         msg,
         ListCommunitiesResponse
       );
-      this.state.trendingCommunities = data.communities;
-      this.setState(this.state);
+      this.setState({ trendingCommunities: data.communities });
     } else if (op == UserOperation.EditSite) {
       let data = wsJsonToRes<SiteResponse>(msg, SiteResponse);
-      this.state.siteRes.site_view = Some(data.site_view);
-      this.setState(this.state);
+      this.setState(s => ((s.siteRes.site_view = Some(data.site_view)), s));
       toast(i18n.t("site_saved"));
     } else if (op == UserOperation.GetPosts) {
       let data = wsJsonToRes<GetPostsResponse>(msg, GetPostsResponse);
-      this.state.posts = data.posts;
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ posts: data.posts, loading: false });
       WebSocketService.Instance.send(
         wsClient.communityJoin({ community_id: 0 })
       );
@@ -750,21 +758,17 @@ export class Home extends Component<any, HomeState> {
       setupTippy();
     } else if (op == UserOperation.CreatePost) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
-      // NSFW check
-      let nsfw = data.post_view.post.nsfw || data.post_view.community.nsfw;
-      let nsfwCheck =
-        !nsfw ||
-        (nsfw &&
-          UserService.Instance.myUserInfo
-            .map(m => m.local_user_view.local_user.show_nsfw)
-            .unwrapOr(false));
 
       let showPostNotifs = UserService.Instance.myUserInfo
         .map(m => m.local_user_view.local_user.show_new_post_notifs)
         .unwrapOr(false);
 
-      // Only push these if you're on the first page, and you pass the nsfw check
-      if (this.state.page == 1 && nsfwCheck) {
+      // Only push these if you're on the first page, you pass the nsfw check, and it isn't blocked
+      if (
+        this.state.page == 1 &&
+        nsfwCheck(data.post_view) &&
+        !isPostBlocked(data.post_view)
+      ) {
         // If you're on subscribed, only push it if you're subscribed.
         if (this.state.listingType == ListingType.Subscribed) {
           if (
@@ -812,8 +816,7 @@ export class Home extends Component<any, HomeState> {
       this.setState(this.state);
     } else if (op == UserOperation.AddAdmin) {
       let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse);
-      this.state.siteRes.admins = data.admins;
-      this.setState(this.state);
+      this.setState(s => ((s.siteRes.admins = data.admins), s));
     } else if (op == UserOperation.BanPerson) {
       let data = wsJsonToRes<BanPersonResponse>(msg, BanPersonResponse);
       this.state.posts
@@ -823,9 +826,7 @@ export class Home extends Component<any, HomeState> {
       this.setState(this.state);
     } else if (op == UserOperation.GetComments) {
       let data = wsJsonToRes<GetCommentsResponse>(msg, GetCommentsResponse);
-      this.state.comments = data.comments;
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ comments: data.comments, loading: false });
     } else if (
       op == UserOperation.EditComment ||
       op == UserOperation.DeleteComment ||
index fe4064dec6a46cb05f9c96c33713e488e91aa6a6..f473ffa17446027559d04a8efa827aec5c866b27 100644 (file)
@@ -30,22 +30,22 @@ export class Instances extends Component<any, InstancesState> {
   render() {
     return this.state.siteRes.federated_instances.match({
       some: federated_instances => (
-        <div class="container">
+        <div className="container">
           <HtmlTags
             title={this.documentTitle}
             path={this.context.router.route.match.url}
             description={None}
             image={None}
           />
-          <div class="row">
-            <div class="col-md-6">
+          <div className="row">
+            <div className="col-md-6">
               <h5>{i18n.t("linked_instances")}</h5>
               {this.itemList(federated_instances.linked)}
             </div>
             {federated_instances.allowed.match({
               some: allowed =>
                 allowed.length > 0 && (
-                  <div class="col-md-6">
+                  <div className="col-md-6">
                     <h5>{i18n.t("allowed_instances")}</h5>
                     {this.itemList(allowed)}
                   </div>
@@ -55,7 +55,7 @@ export class Instances extends Component<any, InstancesState> {
             {federated_instances.blocked.match({
               some: blocked =>
                 blocked.length > 0 && (
-                  <div class="col-md-6">
+                  <div className="col-md-6">
                     <h5>{i18n.t("blocked_instances")}</h5>
                     {this.itemList(blocked)}
                   </div>
@@ -74,7 +74,7 @@ export class Instances extends Component<any, InstancesState> {
     return items.length > 0 ? (
       <ul>
         {items.map(i => (
-          <li>
+          <li key={i}>
             <a href={`https://${i}`} rel={relTags}>
               {i}
             </a>
index 590d7d84619104077574666597f4c9802320f55c..78c9bbba8ddfe87dc974405594016c9098a453ef 100644 (file)
@@ -26,7 +26,7 @@ export class Legal extends Component<any, LegalState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
index 753e9d8166f9ba03b4df9e4ddd87ccfd93aba2ee..001cfd4c99aec1f030aff5a4f86171b617e2ce87 100644 (file)
@@ -81,15 +81,15 @@ export class Login extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
           description={None}
           image={None}
         />
-        <div class="row">
-          <div class="col-12 col-lg-6 offset-lg-3">{this.loginForm()}</div>
+        <div className="row">
+          <div className="col-12 col-lg-6 offset-lg-3">{this.loginForm()}</div>
         </div>
       </div>
     );
@@ -100,17 +100,17 @@ export class Login extends Component<any, State> {
       <div>
         <form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
           <h5>{i18n.t("login")}</h5>
-          <div class="form-group row">
+          <div className="form-group row">
             <label
-              class="col-sm-2 col-form-label"
+              className="col-sm-2 col-form-label"
               htmlFor="login-email-or-username"
             >
               {i18n.t("email_or_username")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="text"
-                class="form-control"
+                className="form-control"
                 id="login-email-or-username"
                 value={this.state.loginForm.username_or_email}
                 onInput={linkEvent(this, this.handleLoginUsernameChange)}
@@ -120,17 +120,17 @@ export class Login extends Component<any, State> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="login-password">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label" htmlFor="login-password">
               {i18n.t("password")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="password"
                 id="login-password"
                 value={this.state.loginForm.password}
                 onInput={linkEvent(this, this.handleLoginPasswordChange)}
-                class="form-control"
+                className="form-control"
                 autoComplete="current-password"
                 required
                 maxLength={60}
@@ -146,9 +146,9 @@ export class Login extends Component<any, State> {
               </button>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-sm-10">
-              <button type="submit" class="btn btn-secondary">
+          <div className="form-group row">
+            <div className="col-sm-10">
+              <button type="submit" className="btn btn-secondary">
                 {this.state.loginLoading ? <Spinner /> : i18n.t("login")}
               </button>
             </div>
@@ -160,8 +160,7 @@ export class Login extends Component<any, State> {
 
   handleLoginSubmit(i: Login, event: any) {
     event.preventDefault();
-    i.state.loginLoading = true;
-    i.setState(i.state);
+    i.setState({ loginLoading: true });
     WebSocketService.Instance.send(wsClient.login(i.state.loginForm));
   }
 
@@ -188,21 +187,18 @@ export class Login extends Component<any, State> {
     console.log(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state = this.emptyState;
-      this.setState(this.state);
+      this.setState(this.emptyState);
       return;
     } else {
       if (op == UserOperation.Login) {
         let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
-        this.state = this.emptyState;
-        this.setState(this.state);
+        this.setState(this.emptyState);
         UserService.Instance.login(data);
       } else if (op == UserOperation.PasswordReset) {
         toast(i18n.t("reset_password_mail_sent"));
       } else if (op == UserOperation.GetSite) {
         let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse);
-        this.state.siteRes = data;
-        this.setState(this.state);
+        this.setState({ siteRes: data });
       }
     }
   }
index 46d225e24639db3b75077fcc73ce9c12f106f239..8e1c9fff06a214812a1e904797335fd6c1ee8a15 100644 (file)
@@ -67,10 +67,10 @@ export class Setup extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <Helmet title={this.documentTitle} />
-        <div class="row">
-          <div class="col-12 offset-lg-3 col-lg-6">
+        <div className="row">
+          <div className="col-12 offset-lg-3 col-lg-6">
             <h3>{i18n.t("lemmy_instance_setup")}</h3>
             {!this.state.doneRegisteringUser ? (
               this.registerUser()
@@ -87,14 +87,14 @@ export class Setup extends Component<any, State> {
     return (
       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
         <h5>{i18n.t("setup_admin")}</h5>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="username">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="username">
             {i18n.t("username")}
           </label>
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               type="text"
-              class="form-control"
+              className="form-control"
               id="username"
               value={this.state.userForm.username}
               onInput={linkEvent(this, this.handleRegisterUsernameChange)}
@@ -104,16 +104,16 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="email">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="email">
             {i18n.t("email")}
           </label>
 
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               type="email"
               id="email"
-              class="form-control"
+              className="form-control"
               placeholder={i18n.t("optional")}
               value={toUndefined(this.state.userForm.email)}
               onInput={linkEvent(this, this.handleRegisterEmailChange)}
@@ -121,17 +121,17 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="password">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="password">
             {i18n.t("password")}
           </label>
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               type="password"
               id="password"
               value={this.state.userForm.password}
               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
-              class="form-control"
+              className="form-control"
               required
               autoComplete="new-password"
               minLength={10}
@@ -139,17 +139,17 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="verify-password">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="verify-password">
             {i18n.t("verify_password")}
           </label>
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               type="password"
               id="verify-password"
               value={this.state.userForm.password_verify}
               onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
-              class="form-control"
+              className="form-control"
               required
               autoComplete="new-password"
               minLength={10}
@@ -157,9 +157,9 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div class="form-group row">
-          <div class="col-sm-10">
-            <button type="submit" class="btn btn-secondary">
+        <div className="form-group row">
+          <div className="col-sm-10">
+            <button type="submit" className="btn btn-secondary">
               {this.state.userLoading ? <Spinner /> : i18n.t("sign_up")}
             </button>
           </div>
@@ -170,8 +170,7 @@ export class Setup extends Component<any, State> {
 
   handleRegisterSubmit(i: Setup, event: any) {
     event.preventDefault();
-    i.state.userLoading = true;
-    i.setState(i.state);
+    i.setState({ userLoading: true });
     event.preventDefault();
     WebSocketService.Instance.send(wsClient.register(i.state.userForm));
   }
@@ -200,14 +199,12 @@ export class Setup extends Component<any, State> {
     let op = wsUserOp(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state.userLoading = false;
-      this.setState(this.state);
+      this.setState({ userLoading: false });
       return;
     } else if (op == UserOperation.Register) {
       let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
-      this.state.userLoading = false;
+      this.setState({ userLoading: false });
       UserService.Instance.login(data);
-      this.setState(this.state);
     } else if (op == UserOperation.CreateSite) {
       window.location.href = "/";
     }
index 9e6e3c7569e111843dec32d76f9821688e4c8c19..aa40aa0c38ab2e0cb4be3772896efd7fda9bbc16 100644 (file)
@@ -127,15 +127,17 @@ export class Signup extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
           description={None}
           image={None}
         />
-        <div class="row">
-          <div class="col-12 col-lg-6 offset-lg-3">{this.registerForm()}</div>
+        <div className="row">
+          <div className="col-12 col-lg-6 offset-lg-3">
+            {this.registerForm()}
+          </div>
         </div>
       </div>
     );
@@ -148,8 +150,8 @@ export class Signup extends Component<any, State> {
           <h5>{this.titleName(siteView)}</h5>
 
           {this.isLemmyMl && (
-            <div class="form-group row">
-              <div class="mt-2 mb-0 alert alert-warning" role="alert">
+            <div className="form-group row">
+              <div className="mt-2 mb-0 alert alert-warning" role="alert">
                 <T i18nKey="lemmy_ml_registration_message">
                   #<a href={joinLemmyUrl}>#</a>
                 </T>
@@ -157,16 +159,19 @@ export class Signup extends Component<any, State> {
             </div>
           )}
 
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="register-username">
+          <div className="form-group row">
+            <label
+              className="col-sm-2 col-form-label"
+              htmlFor="register-username"
+            >
               {i18n.t("username")}
             </label>
 
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="text"
                 id="register-username"
-                class="form-control"
+                className="form-control"
                 value={this.state.registerForm.username}
                 onInput={linkEvent(this, this.handleRegisterUsernameChange)}
                 required
@@ -177,15 +182,15 @@ export class Signup extends Component<any, State> {
             </div>
           </div>
 
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="register-email">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label" htmlFor="register-email">
               {i18n.t("email")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="email"
                 id="register-email"
-                class="form-control"
+                className="form-control"
                 placeholder={
                   siteView.site.require_email_verification
                     ? i18n.t("required")
@@ -201,7 +206,7 @@ export class Signup extends Component<any, State> {
                 !this.state.registerForm.email
                   .map(validEmail)
                   .unwrapOr(true) && (
-                  <div class="mt-2 mb-0 alert alert-warning" role="alert">
+                  <div className="mt-2 mb-0 alert alert-warning" role="alert">
                     <Icon icon="alert-triangle" classes="icon-inline mr-2" />
                     {i18n.t("no_password_reset")}
                   </div>
@@ -209,11 +214,14 @@ export class Signup extends Component<any, State> {
             </div>
           </div>
 
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="register-password">
+          <div className="form-group row">
+            <label
+              className="col-sm-2 col-form-label"
+              htmlFor="register-password"
+            >
               {i18n.t("password")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="password"
                 id="register-password"
@@ -222,25 +230,25 @@ export class Signup extends Component<any, State> {
                 onInput={linkEvent(this, this.handleRegisterPasswordChange)}
                 minLength={10}
                 maxLength={60}
-                class="form-control"
+                className="form-control"
                 required
               />
               {this.state.registerForm.password && (
-                <div class={this.passwordColorClass}>
+                <div className={this.passwordColorClass}>
                   {i18n.t(this.passwordStrength as I18nKeys)}
                 </div>
               )}
             </div>
           </div>
 
-          <div class="form-group row">
+          <div className="form-group row">
             <label
-              class="col-sm-2 col-form-label"
+              className="col-sm-2 col-form-label"
               htmlFor="register-verify-password"
             >
               {i18n.t("verify_password")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="password"
                 id="register-verify-password"
@@ -251,7 +259,7 @@ export class Signup extends Component<any, State> {
                   this.handleRegisterPasswordVerifyChange
                 )}
                 maxLength={60}
-                class="form-control"
+                className="form-control"
                 required
               />
             </div>
@@ -259,9 +267,9 @@ export class Signup extends Component<any, State> {
 
           {siteView.site.require_application && (
             <>
-              <div class="form-group row">
-                <div class="offset-sm-2 col-sm-10">
-                  <div class="mt-2 alert alert-warning" role="alert">
+              <div className="form-group row">
+                <div className="offset-sm-2 col-sm-10">
+                  <div className="mt-2 alert alert-warning" role="alert">
                     <Icon icon="alert-triangle" classes="icon-inline mr-2" />
                     {i18n.t("fill_out_application")}
                   </div>
@@ -277,21 +285,23 @@ export class Signup extends Component<any, State> {
                 </div>
               </div>
 
-              <div class="form-group row">
+              <div className="form-group row">
                 <label
-                  class="col-sm-2 col-form-label"
+                  className="col-sm-2 col-form-label"
                   htmlFor="application_answer"
                 >
                   {i18n.t("answer")}
                 </label>
-                <div class="col-sm-10">
+                <div className="col-sm-10">
                   <MarkdownTextArea
                     initialContent={None}
+                    initialLanguageId={None}
                     placeholder={None}
                     buttonTitle={None}
                     maxLength={None}
                     onContentChange={this.handleAnswerChange}
                     hideNavigationWarnings
+                    allLanguages={[]}
                   />
                 </div>
               </div>
@@ -299,12 +309,12 @@ export class Signup extends Component<any, State> {
           )}
 
           {this.state.captcha.isSome() && (
-            <div class="form-group row">
-              <label class="col-sm-2" htmlFor="register-captcha">
-                <span class="mr-2">{i18n.t("enter_code")}</span>
+            <div className="form-group row">
+              <label className="col-sm-2" htmlFor="register-captcha">
+                <span className="mr-2">{i18n.t("enter_code")}</span>
                 <button
                   type="button"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(this, this.handleRegenCaptcha)}
                   aria-label={i18n.t("captcha")}
                 >
@@ -312,10 +322,10 @@ export class Signup extends Component<any, State> {
                 </button>
               </label>
               {this.showCaptcha()}
-              <div class="col-sm-6">
+              <div className="col-sm-6">
                 <input
                   type="text"
-                  class="form-control"
+                  className="form-control"
                   id="register-captcha"
                   value={toUndefined(this.state.registerForm.captcha_answer)}
                   onInput={linkEvent(
@@ -328,11 +338,11 @@ export class Signup extends Component<any, State> {
             </div>
           )}
           {siteView.site.enable_nsfw && (
-            <div class="form-group row">
-              <div class="col-sm-10">
-                <div class="form-check">
+            <div className="form-group row">
+              <div className="col-sm-10">
+                <div className="form-check">
                   <input
-                    class="form-check-input"
+                    className="form-check-input"
                     id="register-show-nsfw"
                     type="checkbox"
                     checked={this.state.registerForm.show_nsfw}
@@ -341,7 +351,10 @@ export class Signup extends Component<any, State> {
                       this.handleRegisterShowNsfwChange
                     )}
                   />
-                  <label class="form-check-label" htmlFor="register-show-nsfw">
+                  <label
+                    className="form-check-label"
+                    htmlFor="register-show-nsfw"
+                  >
                     {i18n.t("show_nsfw")}
                   </label>
                 </div>
@@ -353,14 +366,14 @@ export class Signup extends Component<any, State> {
             autoComplete="false"
             name="a_password"
             type="text"
-            class="form-control honeypot"
+            className="form-control honeypot"
             id="register-honey"
             value={toUndefined(this.state.registerForm.honeypot)}
             onInput={linkEvent(this, this.handleHoneyPotChange)}
           />
-          <div class="form-group row">
-            <div class="col-sm-10">
-              <button type="submit" class="btn btn-secondary">
+          <div className="form-group row">
+            <div className="col-sm-10">
+              <button type="submit" className="btn btn-secondary">
                 {this.state.registerLoading ? (
                   <Spinner />
                 ) : (
@@ -378,19 +391,19 @@ export class Signup extends Component<any, State> {
   showCaptcha() {
     return this.state.captcha.match({
       some: captcha => (
-        <div class="col-sm-4">
+        <div className="col-sm-4">
           {captcha.ok.match({
             some: res => (
               <>
                 <img
-                  class="rounded-top img-fluid"
+                  className="rounded-top img-fluid"
                   src={this.captchaPngSrc(res)}
                   style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;"
                   alt={i18n.t("captcha")}
                 />
                 {res.wav.isSome() && (
                   <button
-                    class="rounded-bottom btn btn-sm btn-secondary btn-block"
+                    className="rounded-bottom btn btn-sm btn-secondary btn-block"
                     style="border-top-right-radius: 0; border-top-left-radius: 0;"
                     title={i18n.t("play_captcha_audio")}
                     onClick={linkEvent(this, this.handleCaptchaPlay)}
@@ -431,8 +444,7 @@ export class Signup extends Component<any, State> {
 
   handleRegisterSubmit(i: Signup, event: any) {
     event.preventDefault();
-    i.state.registerLoading = true;
-    i.setState(i.state);
+    i.setState({ registerLoading: true });
     WebSocketService.Instance.send(wsClient.register(i.state.registerForm));
   }
 
@@ -470,8 +482,7 @@ export class Signup extends Component<any, State> {
   }
 
   handleAnswerChange(val: string) {
-    this.state.registerForm.answer = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.registerForm.answer = Some(val)), s));
   }
 
   handleHoneyPotChange(i: Signup, event: any) {
@@ -481,8 +492,7 @@ export class Signup extends Component<any, State> {
 
   handleRegenCaptcha(i: Signup) {
     i.audio = null;
-    i.state.captchaPlaying = false;
-    i.setState(i.state);
+    i.setState({ captchaPlaying: false });
     WebSocketService.Instance.send(wsClient.getCaptcha());
   }
 
@@ -500,13 +510,11 @@ export class Signup extends Component<any, State> {
 
             i.audio.play();
 
-            i.state.captchaPlaying = true;
-            i.setState(i.state);
+            i.setState({ captchaPlaying: true });
 
             i.audio.addEventListener("ended", () => {
               i.audio.currentTime = 0;
-              i.state.captchaPlaying = false;
-              i.setState(i.state);
+              i.setState({ captchaPlaying: false });
             });
           },
           none: void 0,
@@ -524,17 +532,15 @@ export class Signup extends Component<any, State> {
     console.log(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state = this.emptyState;
-      this.state.registerForm.captcha_answer = undefined;
+      this.setState(this.emptyState);
+      this.setState(s => ((s.registerForm.captcha_answer = undefined), s));
       // Refetch another captcha
       // WebSocketService.Instance.send(wsClient.getCaptcha());
-      this.setState(this.state);
       return;
     } else {
       if (op == UserOperation.Register) {
         let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
-        this.state = this.emptyState;
-        this.setState(this.state);
+        this.setState(this.emptyState);
         // Only log them in if a jwt was set
         if (data.jwt.isSome()) {
           UserService.Instance.login(data);
@@ -552,9 +558,10 @@ export class Signup extends Component<any, State> {
         let data = wsJsonToRes<GetCaptchaResponse>(msg, GetCaptchaResponse);
         data.ok.match({
           some: res => {
-            this.state.captcha = Some(data);
-            this.state.registerForm.captcha_uuid = Some(res.uuid);
-            this.setState(this.state);
+            this.setState({ captcha: Some(data) });
+            this.setState(
+              s => ((s.registerForm.captcha_uuid = Some(res.uuid)), s)
+            );
           },
           none: void 0,
         });
@@ -562,8 +569,7 @@ export class Signup extends Component<any, State> {
         toast(i18n.t("reset_password_mail_sent"));
       } else if (op == UserOperation.GetSite) {
         let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse);
-        this.state.siteRes = data;
-        this.setState(this.state);
+        this.setState({ siteRes: data });
       }
     }
   }
index e9a5b14006cc863d15dd4daafc519199a6c9c264..bc0072c48a1e8d47aaa742c1382da99356066a96 100644 (file)
@@ -53,6 +53,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
       legal_information: None,
       description: None,
       community_creation_admin_only: None,
+      application_email_admins: None,
       auth: undefined,
       hide_modlog_mod_names: Some(true),
     }),
@@ -78,9 +79,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
     this.handleDefaultPostListingTypeChange =
       this.handleDefaultPostListingTypeChange.bind(this);
 
-    this.props.site.match({
-      some: site => {
-        this.state.siteForm = new EditSite({
+    if (this.props.site.isSome()) {
+      let site = this.props.site.unwrap();
+      this.state = {
+        ...this.state,
+        siteForm: new EditSite({
           name: Some(site.name),
           sidebar: site.sidebar,
           description: site.description,
@@ -99,23 +102,21 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
           default_theme: Some(site.default_theme),
           default_post_listing_type: Some(site.default_post_listing_type),
           legal_information: site.legal_information,
+          application_email_admins: Some(site.application_email_admins),
           hide_modlog_mod_names: site.hide_modlog_mod_names,
           auth: undefined,
-        });
-      },
-      none: void 0,
-    });
+        }),
+      };
+    }
   }
 
   async componentDidMount() {
-    this.state.themeList = Some(await fetchThemeList());
-    this.setState(this.state);
+    this.setState({ themeList: Some(await fetchThemeList()) });
   }
 
   // Necessary to stop the loading
   componentWillReceiveProps() {
-    this.state.loading = false;
-    this.setState(this.state);
+    this.setState({ loading: false });
   }
 
   componentDidUpdate() {
@@ -157,15 +158,15 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               ? capitalizeFirstLetter(i18n.t("save"))
               : capitalizeFirstLetter(i18n.t("name"))
           } ${i18n.t("your_site")}`}</h5>
-          <div class="form-group row">
-            <label class="col-12 col-form-label" htmlFor="create-site-name">
+          <div className="form-group row">
+            <label className="col-12 col-form-label" htmlFor="create-site-name">
               {i18n.t("name")}
             </label>
-            <div class="col-12">
+            <div className="col-12">
               <input
                 type="text"
                 id="create-site-name"
-                class="form-control"
+                className="form-control"
                 value={toUndefined(this.state.siteForm.name)}
                 onInput={linkEvent(this, this.handleSiteNameChange)}
                 required
@@ -174,7 +175,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               />
             </div>
           </div>
-          <div class="form-group">
+          <div className="form-group">
             <label>{i18n.t("icon")}</label>
             <ImageUploadForm
               uploadTitle={i18n.t("upload_icon")}
@@ -184,7 +185,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               rounded
             />
           </div>
-          <div class="form-group">
+          <div className="form-group">
             <label>{i18n.t("banner")}</label>
             <ImageUploadForm
               uploadTitle={i18n.t("upload_banner")}
@@ -193,14 +194,14 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               onRemove={this.handleBannerRemove}
             />
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-form-label" htmlFor="site-desc">
+          <div className="form-group row">
+            <label className="col-12 col-form-label" htmlFor="site-desc">
               {i18n.t("description")}
             </label>
-            <div class="col-12">
+            <div className="col-12">
               <input
                 type="text"
-                class="form-control"
+                className="form-control"
                 id="site-desc"
                 value={toUndefined(this.state.siteForm.description)}
                 onInput={linkEvent(this, this.handleSiteDescChange)}
@@ -208,56 +209,62 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-form-label">{i18n.t("sidebar")}</label>
-            <div class="col-12">
+          <div className="form-group row">
+            <label className="col-12 col-form-label">{i18n.t("sidebar")}</label>
+            <div className="col-12">
               <MarkdownTextArea
                 initialContent={this.state.siteForm.sidebar}
+                initialLanguageId={None}
                 placeholder={None}
                 buttonTitle={None}
                 maxLength={None}
                 onContentChange={this.handleSiteSidebarChange}
                 hideNavigationWarnings
+                allLanguages={[]}
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-12 col-form-label">
+          <div className="form-group row">
+            <label className="col-12 col-form-label">
               {i18n.t("legal_information")}
             </label>
-            <div class="col-12">
+            <div className="col-12">
               <MarkdownTextArea
                 initialContent={this.state.siteForm.legal_information}
+                initialLanguageId={None}
                 placeholder={None}
                 buttonTitle={None}
                 maxLength={None}
                 onContentChange={this.handleSiteLegalInfoChange}
                 hideNavigationWarnings
+                allLanguages={[]}
               />
             </div>
           </div>
           {this.state.siteForm.require_application.unwrapOr(false) && (
-            <div class="form-group row">
-              <label class="col-12 col-form-label">
+            <div className="form-group row">
+              <label className="col-12 col-form-label">
                 {i18n.t("application_questionnaire")}
               </label>
-              <div class="col-12">
+              <div className="col-12">
                 <MarkdownTextArea
                   initialContent={this.state.siteForm.application_question}
+                  initialLanguageId={None}
                   placeholder={None}
                   buttonTitle={None}
                   maxLength={None}
                   onContentChange={this.handleSiteApplicationQuestionChange}
                   hideNavigationWarnings
+                  allLanguages={[]}
                 />
               </div>
             </div>
           )}
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-downvotes"
                   type="checkbox"
                   checked={toUndefined(this.state.siteForm.enable_downvotes)}
@@ -266,24 +273,27 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                     this.handleSiteEnableDownvotesChange
                   )}
                 />
-                <label class="form-check-label" htmlFor="create-site-downvotes">
+                <label
+                  className="form-check-label"
+                  htmlFor="create-site-downvotes"
+                >
                   {i18n.t("enable_downvotes")}
                 </label>
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-enable-nsfw"
                   type="checkbox"
                   checked={toUndefined(this.state.siteForm.enable_nsfw)}
                   onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-enable-nsfw"
                 >
                   {i18n.t("enable_nsfw")}
@@ -291,11 +301,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-open-registration"
                   type="checkbox"
                   checked={toUndefined(this.state.siteForm.open_registration)}
@@ -305,7 +315,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                   )}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-open-registration"
                 >
                   {i18n.t("open_registration")}
@@ -313,11 +323,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-community-creation-admin-only"
                   type="checkbox"
                   checked={toUndefined(
@@ -329,7 +339,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                   )}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-community-creation-admin-only"
                 >
                   {i18n.t("community_creation_admin_only")}
@@ -337,11 +347,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-require-email-verification"
                   type="checkbox"
                   checked={toUndefined(
@@ -353,7 +363,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                   )}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-require-email-verification"
                 >
                   {i18n.t("require_email_verification")}
@@ -361,18 +371,18 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-require-application"
                   type="checkbox"
                   checked={toUndefined(this.state.siteForm.require_application)}
                   onChange={linkEvent(this, this.handleSiteRequireApplication)}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-require-application"
                 >
                   {i18n.t("require_registration_application")}
@@ -380,10 +390,34 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
+                <input
+                  className="form-check-input"
+                  id="create-site-application-email-admins"
+                  type="checkbox"
+                  checked={toUndefined(
+                    this.state.siteForm.application_email_admins
+                  )}
+                  onChange={linkEvent(
+                    this,
+                    this.handleSiteApplicationEmailAdmins
+                  )}
+                />
+                <label
+                  className="form-check-label"
+                  htmlFor="create-site-email-admins"
+                >
+                  {i18n.t("application_email_admins")}
+                </label>
+              </div>
+            </div>
+          </div>
+          <div className="form-group row">
+            <div className="col-12">
               <label
-                class="form-check-label mr-2"
+                className="form-check-label mr-2"
                 htmlFor="create-site-default-theme"
               >
                 {i18n.t("theme")}
@@ -392,19 +426,21 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                 id="create-site-default-theme"
                 value={toUndefined(this.state.siteForm.default_theme)}
                 onChange={linkEvent(this, this.handleSiteDefaultTheme)}
-                class="custom-select w-auto"
+                className="custom-select w-auto"
               >
                 <option value="browser">{i18n.t("browser_default")}</option>
                 {this.state.themeList.unwrapOr([]).map(theme => (
-                  <option value={theme}>{theme}</option>
+                  <option key={theme} value={theme}>
+                    {theme}
+                  </option>
                 ))}
               </select>
             </div>
           </div>
           {this.props.showLocal && (
             <form className="form-group row">
-              <label class="col-sm-3">{i18n.t("listing_type")}</label>
-              <div class="col-sm-9">
+              <label className="col-sm-3">{i18n.t("listing_type")}</label>
+              <div className="col-sm-9">
                 <ListingTypeSelect
                   type_={
                     ListingType[
@@ -420,18 +456,18 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </form>
           )}
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-private-instance"
                   type="checkbox"
-                  value={toUndefined(this.state.siteForm.default_theme)}
+                  checked={toUndefined(this.state.siteForm.private_instance)}
                   onChange={linkEvent(this, this.handleSitePrivateInstance)}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-private-instance"
                 >
                   {i18n.t("private_instance")}
@@ -439,11 +475,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
-              <div class="form-check">
+          <div className="form-group row">
+            <div className="col-12">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="create-site-hide-modlog-mod-names"
                   type="checkbox"
                   checked={toUndefined(
@@ -452,7 +488,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
                   onChange={linkEvent(this, this.handleSiteHideModlogModNames)}
                 />
                 <label
-                  class="form-check-label"
+                  className="form-check-label"
                   htmlFor="create-site-hide-modlog-mod-names"
                 >
                   {i18n.t("hide_modlog_mod_names")}
@@ -460,11 +496,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               </div>
             </div>
           </div>
-          <div class="form-group row">
-            <div class="col-12">
+          <div className="form-group row">
+            <div className="col-12">
               <button
                 type="submit"
-                class="btn btn-secondary mr-2"
+                className="btn btn-secondary mr-2"
                 disabled={this.state.loading}
               >
                 {this.state.loading ? (
@@ -478,7 +514,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               {this.props.site.isSome() && (
                 <button
                   type="button"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(this, this.handleCancel)}
                 >
                   {i18n.t("cancel")}
@@ -493,8 +529,8 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
 
   handleCreateSiteSubmit(i: SiteForm, event: any) {
     event.preventDefault();
-    i.state.loading = true;
-    i.state.siteForm.auth = auth().unwrap();
+    i.setState({ loading: true });
+    i.setState(s => ((s.siteForm.auth = auth().unwrap()), s));
 
     if (i.props.site.isSome()) {
       WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
@@ -517,6 +553,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
         private_instance: sForm.private_instance,
         default_theme: sForm.default_theme,
         default_post_listing_type: sForm.default_post_listing_type,
+        application_email_admins: sForm.application_email_admins,
         auth: auth().unwrap(),
         hide_modlog_mod_names: sForm.hide_modlog_mod_names,
       });
@@ -531,18 +568,15 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
   }
 
   handleSiteSidebarChange(val: string) {
-    this.state.siteForm.sidebar = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.sidebar = Some(val)), s));
   }
 
   handleSiteLegalInfoChange(val: string) {
-    this.state.siteForm.legal_information = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.legal_information = Some(val)), s));
   }
 
   handleSiteApplicationQuestionChange(val: string) {
-    this.state.siteForm.application_question = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.application_question = Some(val)), s));
   }
 
   handleSiteDescChange(i: SiteForm, event: any) {
@@ -580,6 +614,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
     i.setState(i.state);
   }
 
+  handleSiteApplicationEmailAdmins(i: SiteForm, event: any) {
+    i.state.siteForm.application_email_admins = Some(event.target.checked);
+    i.setState(i.state);
+  }
+
   handleSitePrivateInstance(i: SiteForm, event: any) {
     i.state.siteForm.private_instance = Some(event.target.checked);
     i.setState(i.state);
@@ -600,29 +639,29 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
   }
 
   handleIconUpload(url: string) {
-    this.state.siteForm.icon = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.icon = Some(url)), s));
   }
 
   handleIconRemove() {
-    this.state.siteForm.icon = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.icon = Some("")), s));
   }
 
   handleBannerUpload(url: string) {
-    this.state.siteForm.banner = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.banner = Some(url)), s));
   }
 
   handleBannerRemove() {
-    this.state.siteForm.banner = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.siteForm.banner = Some("")), s));
   }
 
   handleDefaultPostListingTypeChange(val: ListingType) {
-    this.state.siteForm.default_post_listing_type = Some(
-      ListingType[ListingType[val]]
+    this.setState(
+      s => (
+        (s.siteForm.default_post_listing_type = Some(
+          ListingType[ListingType[val]]
+        )),
+        s
+      )
     );
-    this.setState(this.state);
   }
 }
index 79a8a4306c410eaae00c68520b1799dbabff1762..e8642c78366e8da22ed206a5adbdb84fad8d8e1b 100644 (file)
@@ -38,11 +38,11 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
   render() {
     let site = this.props.site;
     return (
-      <div class="card border-secondary mb-3">
-        <div class="card-body">
+      <div className="card border-secondary mb-3">
+        <div className="card-body">
           {!this.state.showEdit ? (
             <div>
-              <div class="mb-2">
+              <div className="mb-2">
                 {this.siteName()}
                 {this.props.admins.isSome() && this.adminButtons()}
               </div>
@@ -69,10 +69,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
   siteName() {
     let site = this.props.site;
     return (
-      <h5 class="mb-0 d-inline">
+      <h5 className="mb-0 d-inline">
         {site.name}
         <button
-          class="btn btn-sm text-muted"
+          className="btn btn-sm text-muted"
           onClick={linkEvent(this, this.handleCollapseSidebar)}
           aria-label={i18n.t("collapse")}
           data-tippy-content={i18n.t("collapse")}
@@ -113,11 +113,11 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
 
   adminButtons() {
     return (
-      amAdmin(this.props.admins) && (
-        <ul class="list-inline mb-1 text-muted font-weight-bold">
+      amAdmin() && (
+        <ul className="list-inline mb-1 text-muted font-weight-bold">
           <li className="list-inline-item-action">
             <button
-              class="btn btn-link d-inline-block text-muted"
+              className="btn btn-link d-inline-block text-muted"
               onClick={linkEvent(this, this.handleEditClick)}
               aria-label={i18n.t("edit")}
               data-tippy-content={i18n.t("edit")}
@@ -138,10 +138,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
 
   admins(admins: PersonViewSafe[]) {
     return (
-      <ul class="mt-1 list-inline small mb-0">
-        <li class="list-inline-item">{i18n.t("admins")}:</li>
+      <ul className="mt-1 list-inline small mb-0">
+        <li className="list-inline-item">{i18n.t("admins")}:</li>
         {admins.map(av => (
-          <li class="list-inline-item">
+          <li key={av.person.id} className="list-inline-item">
             <PersonListing person={av.person} />
           </li>
         ))}
@@ -153,7 +153,7 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
     let counts = siteAggregates;
     let online = this.props.online.unwrapOr(1);
     return (
-      <ul class="my-2 list-inline">
+      <ul className="my-2 list-inline">
         <li className="list-inline-item badge badge-secondary">
           {i18n.t("number_online", {
             count: online,
@@ -246,22 +246,18 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
   }
 
   handleCollapseSidebar(i: SiteSidebar) {
-    i.state.collapsed = !i.state.collapsed;
-    i.setState(i.state);
+    i.setState({ collapsed: !i.state.collapsed });
   }
 
   handleEditClick(i: SiteSidebar) {
-    i.state.showEdit = true;
-    i.setState(i.state);
+    i.setState({ showEdit: true });
   }
 
   handleEditSite() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   handleEditCancel() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 }
index e8192d27caa21963f3203d428313e7839d726ab5..4bbf8180679bf6f19899beae3e60d5901ccaf16b 100644 (file)
@@ -38,7 +38,7 @@ import {
   amAdmin,
   amMod,
   auth,
-  choicesModLogConfig,
+  choicesConfig,
   debounce,
   fetchLimit,
   fetchUsers,
@@ -114,31 +114,41 @@ export class Modlog extends Component<any, ModlogState> {
     filter_user: None,
     filter_mod: None,
   };
+
   constructor(props: any, context: any) {
     super(props, context);
     this.state = this.emptyState;
     this.handlePageChange = this.handlePageChange.bind(this);
 
-    this.state.communityId = this.props.match.params.community_id
-      ? Some(Number(this.props.match.params.community_id))
-      : None;
-
     this.parseMessage = this.parseMessage.bind(this);
     this.subscription = wsSubscribe(this.parseMessage);
 
+    this.state = {
+      ...this.state,
+      communityId: this.props.match.params.community_id
+        ? Some(Number(this.props.match.params.community_id))
+        : None,
+    };
+
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.res = Some(this.isoData.routeData[0] as GetModlogResponse);
+      this.state = {
+        ...this.state,
+        res: Some(this.isoData.routeData[0] as GetModlogResponse),
+      };
 
       if (this.isoData.routeData[1]) {
         // Getting the moderators
         let communityRes = Some(
           this.isoData.routeData[1] as GetCommunityResponse
         );
-        this.state.communityMods = communityRes.map(c => c.moderators);
+        this.state = {
+          ...this.state,
+          communityMods: communityRes.map(c => c.moderators),
+        };
       }
 
-      this.state.loading = false;
+      this.state = { ...this.state, loading: false };
     } else {
       this.refetch();
     }
@@ -300,219 +310,283 @@ export class Modlog extends Component<any, ModlogState> {
     switch (i.type_) {
       case ModlogActionType.ModRemovePost: {
         let mrpv = i.view as ModRemovePostView;
-        return [
-          mrpv.mod_remove_post.removed.unwrapOr(false)
-            ? "Removed "
-            : "Restored ",
-          <span>
-            Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link>
-          </span>,
-          mrpv.mod_remove_post.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              {mrpv.mod_remove_post.removed.unwrapOr(false)
+                ? "Removed "
+                : "Restored "}
+            </span>
+            <span>
+              Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link>
+            </span>
+            <span>
+              {mrpv.mod_remove_post.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModLockPost: {
         let mlpv = i.view as ModLockPostView;
-        return [
-          mlpv.mod_lock_post.locked.unwrapOr(false) ? "Locked " : "Unlocked ",
-          <span>
-            Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link>
-          </span>,
-        ];
+        return (
+          <>
+            <span>
+              {mlpv.mod_lock_post.locked.unwrapOr(false)
+                ? "Locked "
+                : "Unlocked "}
+            </span>
+            <span>
+              Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link>
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModStickyPost: {
         let mspv = i.view as ModStickyPostView;
-        return [
-          mspv.mod_sticky_post.stickied.unwrapOr(false)
-            ? "Stickied "
-            : "Unstickied ",
-          <span>
-            Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
-          </span>,
-        ];
+        return (
+          <>
+            <span>
+              {mspv.mod_sticky_post.stickied.unwrapOr(false)
+                ? "Stickied "
+                : "Unstickied "}
+            </span>
+            <span>
+              Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModRemoveComment: {
         let mrc = i.view as ModRemoveCommentView;
-        return [
-          mrc.mod_remove_comment.removed.unwrapOr(false)
-            ? "Removed "
-            : "Restored ",
-          <span>
-            Comment{" "}
-            <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}>
-              {mrc.comment.content}
-            </Link>
-          </span>,
-          <span>
-            {" "}
-            by <PersonListing person={mrc.commenter} />
-          </span>,
-          mrc.mod_remove_comment.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              {mrc.mod_remove_comment.removed.unwrapOr(false)
+                ? "Removed "
+                : "Restored "}
+            </span>
+            <span>
+              Comment{" "}
+              <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}>
+                {mrc.comment.content}
+              </Link>
+            </span>
+            <span>
+              {" "}
+              by <PersonListing person={mrc.commenter} />
+            </span>
+            <span>
+              {mrc.mod_remove_comment.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModRemoveCommunity: {
         let mrco = i.view as ModRemoveCommunityView;
-        return [
-          mrco.mod_remove_community.removed.unwrapOr(false)
-            ? "Removed "
-            : "Restored ",
-          <span>
-            Community <CommunityLink community={mrco.community} />
-          </span>,
-          mrco.mod_remove_community.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-          mrco.mod_remove_community.expires.match({
-            some: expires => (
-              <div>expires: {moment.utc(expires).fromNow()}</div>
-            ),
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              {mrco.mod_remove_community.removed.unwrapOr(false)
+                ? "Removed "
+                : "Restored "}
+            </span>
+            <span>
+              Community <CommunityLink community={mrco.community} />
+            </span>
+            <span>
+              {mrco.mod_remove_community.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+            <span>
+              {mrco.mod_remove_community.expires.match({
+                some: expires => (
+                  <div>expires: {moment.utc(expires).fromNow()}</div>
+                ),
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModBanFromCommunity: {
         let mbfc = i.view as ModBanFromCommunityView;
-        return [
-          <span>
-            {mbfc.mod_ban_from_community.banned.unwrapOr(false)
-              ? "Banned "
-              : "Unbanned "}{" "}
-          </span>,
-          <span>
-            <PersonListing person={mbfc.banned_person} />
-          </span>,
-          <span> from the community </span>,
-          <span>
-            <CommunityLink community={mbfc.community} />
-          </span>,
-          mbfc.mod_ban_from_community.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-          mbfc.mod_ban_from_community.expires.match({
-            some: expires => (
-              <div>expires: {moment.utc(expires).fromNow()}</div>
-            ),
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              {mbfc.mod_ban_from_community.banned.unwrapOr(false)
+                ? "Banned "
+                : "Unbanned "}{" "}
+            </span>
+            <span>
+              <PersonListing person={mbfc.banned_person} />
+            </span>
+            <span> from the community </span>
+            <span>
+              <CommunityLink community={mbfc.community} />
+            </span>
+            <span>
+              {mbfc.mod_ban_from_community.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+            <span>
+              {mbfc.mod_ban_from_community.expires.match({
+                some: expires => (
+                  <div>expires: {moment.utc(expires).fromNow()}</div>
+                ),
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModAddCommunity: {
         let mac = i.view as ModAddCommunityView;
-        return [
-          <span>
-            {mac.mod_add_community.removed.unwrapOr(false)
-              ? "Removed "
-              : "Appointed "}{" "}
-          </span>,
-          <span>
-            <PersonListing person={mac.modded_person} />
-          </span>,
-          <span> as a mod to the community </span>,
-          <span>
-            <CommunityLink community={mac.community} />
-          </span>,
-        ];
+        return (
+          <>
+            <span>
+              {mac.mod_add_community.removed.unwrapOr(false)
+                ? "Removed "
+                : "Appointed "}{" "}
+            </span>
+            <span>
+              <PersonListing person={mac.modded_person} />
+            </span>
+            <span> as a mod to the community </span>
+            <span>
+              <CommunityLink community={mac.community} />
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModTransferCommunity: {
         let mtc = i.view as ModTransferCommunityView;
-        return [
-          <span>
-            {mtc.mod_transfer_community.removed.unwrapOr(false)
-              ? "Removed "
-              : "Transferred "}{" "}
-          </span>,
-          <span>
-            <CommunityLink community={mtc.community} />
-          </span>,
-          <span> to </span>,
-          <span>
-            <PersonListing person={mtc.modded_person} />
-          </span>,
-        ];
+        return (
+          <>
+            <span>
+              {mtc.mod_transfer_community.removed.unwrapOr(false)
+                ? "Removed "
+                : "Transferred "}{" "}
+            </span>
+            <span>
+              <CommunityLink community={mtc.community} />
+            </span>
+            <span> to </span>
+            <span>
+              <PersonListing person={mtc.modded_person} />
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModBan: {
         let mb = i.view as ModBanView;
-        return [
-          <span>
-            {mb.mod_ban.banned.unwrapOr(false) ? "Banned " : "Unbanned "}{" "}
-          </span>,
-          <span>
-            <PersonListing person={mb.banned_person} />
-          </span>,
-          mb.mod_ban.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-          mb.mod_ban.expires.match({
-            some: expires => (
-              <div>expires: {moment.utc(expires).fromNow()}</div>
-            ),
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              {mb.mod_ban.banned.unwrapOr(false) ? "Banned " : "Unbanned "}{" "}
+            </span>
+            <span>
+              <PersonListing person={mb.banned_person} />
+            </span>
+            <span>
+              {mb.mod_ban.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+            <span>
+              {mb.mod_ban.expires.match({
+                some: expires => (
+                  <div>expires: {moment.utc(expires).fromNow()}</div>
+                ),
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.ModAdd: {
         let ma = i.view as ModAddView;
-        return [
-          <span>
-            {ma.mod_add.removed.unwrapOr(false) ? "Removed " : "Appointed "}{" "}
-          </span>,
-          <span>
-            <PersonListing person={ma.modded_person} />
-          </span>,
-          <span> as an admin </span>,
-        ];
+        return (
+          <>
+            <span>
+              {ma.mod_add.removed.unwrapOr(false) ? "Removed " : "Appointed "}{" "}
+            </span>
+            <span>
+              <PersonListing person={ma.modded_person} />
+            </span>
+            <span> as an admin </span>
+          </>
+        );
       }
       case ModlogActionType.AdminPurgePerson: {
         let ap = i.view as AdminPurgePersonView;
-        return [
-          <span>Purged a Person</span>,
-          ap.admin_purge_person.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>Purged a Person</span>
+            <span>
+              {ap.admin_purge_person.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.AdminPurgeCommunity: {
         let ap = i.view as AdminPurgeCommunityView;
-        return [
-          <span>Purged a Community</span>,
-          ap.admin_purge_community.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>Purged a Community</span>
+            <span>
+              {ap.admin_purge_community.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.AdminPurgePost: {
         let ap = i.view as AdminPurgePostView;
-        return [
-          <span>Purged a Post from from </span>,
-          <CommunityLink community={ap.community} />,
-          ap.admin_purge_post.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>Purged a Post from from </span>
+            <CommunityLink community={ap.community} />
+            <span>
+              {ap.admin_purge_post.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       case ModlogActionType.AdminPurgeComment: {
         let ap = i.view as AdminPurgeCommentView;
-        return [
-          <span>
-            Purged a Comment from{" "}
-            <Link to={`/post/${ap.post.id}`}>{ap.post.name}</Link>
-          </span>,
-          ap.admin_purge_comment.reason.match({
-            some: reason => <div>reason: {reason}</div>,
-            none: <></>,
-          }),
-        ];
+        return (
+          <>
+            <span>
+              Purged a Comment from{" "}
+              <Link to={`/post/${ap.post.id}`}>{ap.post.name}</Link>
+            </span>
+            <span>
+              {ap.admin_purge_comment.reason.match({
+                some: reason => <div>reason: {reason}</div>,
+                none: <></>,
+              })}
+            </span>
+          </>
+        );
       }
       default:
         return <div />;
@@ -525,7 +599,7 @@ export class Modlog extends Component<any, ModlogState> {
     return (
       <tbody>
         {combined.map(i => (
-          <tr>
+          <tr key={i.id}>
             <td>
               <MomentTime published={i.when_} updated={None} />
             </td>
@@ -544,10 +618,7 @@ export class Modlog extends Component<any, ModlogState> {
   }
 
   get amAdminOrMod(): boolean {
-    return (
-      amAdmin(Some(this.state.siteRes.admins)) ||
-      amMod(this.state.communityMods)
-    );
+    return amAdmin() || amMod(this.state.communityMods);
   }
 
   modOrAdminText(person: Option<PersonSafe>): string {
@@ -593,67 +664,75 @@ export class Modlog extends Component<any, ModlogState> {
               })}
               <span>{i18n.t("modlog")}</span>
             </h5>
-            <form className="form-inline mr-2">
-              <select
-                value={this.state.filter_action}
-                onChange={linkEvent(this, this.handleFilterActionChange)}
-                className="custom-select col-4 mb-2"
-                aria-label="action"
-              >
-                <option disabled aria-hidden="true">
-                  {i18n.t("filter_by_action")}
-                </option>
-                <option value={ModlogActionType.All}>{i18n.t("all")}</option>
-                <option value={ModlogActionType.ModRemovePost}>
-                  Removing Posts
-                </option>
-                <option value={ModlogActionType.ModLockPost}>
-                  Locking Posts
-                </option>
-                <option value={ModlogActionType.ModStickyPost}>
-                  Stickying Posts
-                </option>
-                <option value={ModlogActionType.ModRemoveComment}>
-                  Removing Comments
-                </option>
-                <option value={ModlogActionType.ModRemoveCommunity}>
-                  Removing Communities
-                </option>
-                <option value={ModlogActionType.ModBanFromCommunity}>
-                  Banning From Communities
-                </option>
-                <option value={ModlogActionType.ModAddCommunity}>
-                  Adding Mod to Community
-                </option>
-                <option value={ModlogActionType.ModTransferCommunity}>
-                  Transfering Communities
-                </option>
-                <option value={ModlogActionType.ModAdd}>
-                  Adding Mod to Site
-                </option>
-                <option value={ModlogActionType.ModBan}>
-                  Banning From Site
-                </option>
-              </select>
+            <div className="form-row">
+              <div className="form-group col-sm-6">
+                <select
+                  value={this.state.filter_action}
+                  onChange={linkEvent(this, this.handleFilterActionChange)}
+                  className="custom-select mb-2"
+                  aria-label="action"
+                >
+                  <option disabled aria-hidden="true">
+                    {i18n.t("filter_by_action")}
+                  </option>
+                  <option value={ModlogActionType.All}>{i18n.t("all")}</option>
+                  <option value={ModlogActionType.ModRemovePost}>
+                    Removing Posts
+                  </option>
+                  <option value={ModlogActionType.ModLockPost}>
+                    Locking Posts
+                  </option>
+                  <option value={ModlogActionType.ModStickyPost}>
+                    Stickying Posts
+                  </option>
+                  <option value={ModlogActionType.ModRemoveComment}>
+                    Removing Comments
+                  </option>
+                  <option value={ModlogActionType.ModRemoveCommunity}>
+                    Removing Communities
+                  </option>
+                  <option value={ModlogActionType.ModBanFromCommunity}>
+                    Banning From Communities
+                  </option>
+                  <option value={ModlogActionType.ModAddCommunity}>
+                    Adding Mod to Community
+                  </option>
+                  <option value={ModlogActionType.ModTransferCommunity}>
+                    Transfering Communities
+                  </option>
+                  <option value={ModlogActionType.ModAdd}>
+                    Adding Mod to Site
+                  </option>
+                  <option value={ModlogActionType.ModBan}>
+                    Banning From Site
+                  </option>
+                </select>
+              </div>
               {this.state.siteRes.site_view.match({
                 some: site_view =>
                   !site_view.site.hide_modlog_mod_names.unwrapOr(false) && (
-                    <select
-                      id="filter-mod"
-                      value={toUndefined(this.state.filter_mod)}
-                    >
-                      <option>{i18n.t("filter_by_mod")}</option>
-                    </select>
+                    <div className="form-group col-sm-6">
+                      <select
+                        id="filter-mod"
+                        className="form-control"
+                        value={toUndefined(this.state.filter_mod)}
+                      >
+                        <option>{i18n.t("filter_by_mod")}</option>
+                      </select>
+                    </div>
                   ),
                 none: <></>,
               })}
-              <select
-                id="filter-user"
-                value={toUndefined(this.state.filter_user)}
-              >
-                <option>{i18n.t("filter_by_user")}</option>
-              </select>
-            </form>
+              <div className="form-group col-sm-6">
+                <select
+                  id="filter-user"
+                  className="form-control"
+                  value={toUndefined(this.state.filter_user)}
+                >
+                  <option>{i18n.t("filter_by_user")}</option>
+                </select>
+              </div>
+            </div>
             <div className="table-responsive">
               <table id="modlog_table" className="table table-sm table-hover">
                 <thead className="pointer">
@@ -715,12 +794,11 @@ export class Modlog extends Component<any, ModlogState> {
     if (isBrowser()) {
       let selectId: any = document.getElementById("filter-user");
       if (selectId) {
-        this.userChoices = new Choices(selectId, choicesModLogConfig);
+        this.userChoices = new Choices(selectId, choicesConfig);
         this.userChoices.passedElement.element.addEventListener(
           "choice",
           (e: any) => {
-            this.state.filter_user = Some(Number(e.detail.choice.value));
-            this.setState(this.state);
+            this.setState({ filter_user: Some(Number(e.detail.choice.value)) });
             this.refetch();
           },
           false
@@ -755,12 +833,11 @@ export class Modlog extends Component<any, ModlogState> {
     if (isBrowser()) {
       let selectId: any = document.getElementById("filter-mod");
       if (selectId) {
-        this.modChoices = new Choices(selectId, choicesModLogConfig);
+        this.modChoices = new Choices(selectId, choicesConfig);
         this.modChoices.passedElement.element.addEventListener(
           "choice",
           (e: any) => {
-            this.state.filter_mod = Some(Number(e.detail.choice.value));
-            this.setState(this.state);
+            this.setState({ filter_mod: Some(Number(e.detail.choice.value)) });
             this.refetch();
           },
           false
@@ -829,14 +906,16 @@ export class Modlog extends Component<any, ModlogState> {
       return;
     } else if (op == UserOperation.GetModlog) {
       let data = wsJsonToRes<GetModlogResponse>(msg, GetModlogResponse);
-      this.state.loading = false;
       window.scrollTo(0, 0);
-      this.state.res = Some(data);
-      this.setState(this.state);
+      this.setState({ res: Some(data), loading: false });
+      this.setupUserFilter();
+      this.setupModFilter();
     } else if (op == UserOperation.GetCommunity) {
       let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse);
-      this.state.communityMods = Some(data.moderators);
-      this.state.communityName = Some(data.community_view.community.name);
+      this.setState({
+        communityMods: Some(data.moderators),
+        communityName: Some(data.community_view.community.name),
+      });
     }
   }
 }
index 2a8a7b2984640cade3ebe22dc365fface8dc794f..cfc4bd7e1f9d9f8b6b8f9f55090951d5f861ca12 100644 (file)
@@ -17,6 +17,7 @@ import {
   PersonMentionResponse,
   PersonMentionView,
   PostReportResponse,
+  PrivateMessageReportResponse,
   PrivateMessageResponse,
   PrivateMessagesResponse,
   PrivateMessageView,
@@ -127,15 +128,19 @@ export class Inbox extends Component<any, InboxState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.replies =
-        (this.isoData.routeData[0] as GetRepliesResponse).replies || [];
-      this.state.mentions =
-        (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions || [];
-      this.state.messages =
-        (this.isoData.routeData[2] as PrivateMessagesResponse)
-          .private_messages || [];
-      this.state.combined = this.buildCombined();
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        replies:
+          (this.isoData.routeData[0] as GetRepliesResponse).replies || [],
+        mentions:
+          (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions ||
+          [],
+        messages:
+          (this.isoData.routeData[2] as PrivateMessagesResponse)
+            .private_messages || [],
+        loading: false,
+      };
+      this.state = { ...this.state, combined: this.buildCombined() };
     } else {
       this.refetch();
     }
@@ -166,21 +171,21 @@ export class Inbox extends Component<any, InboxState> {
       .ok()
       .map(a => `/feeds/inbox/${a}.xml`);
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
           </h5>
         ) : (
-          <div class="row">
-            <div class="col-12">
+          <div className="row">
+            <div className="col-12">
               <HtmlTags
                 title={this.documentTitle}
                 path={this.context.router.route.match.url}
                 description={None}
                 image={None}
               />
-              <h5 class="mb-2">
+              <h5 className="mb-2">
                 {i18n.t("inbox")}
                 {inboxRss.match({
                   some: rss => (
@@ -204,7 +209,7 @@ export class Inbox extends Component<any, InboxState> {
                 0 &&
                 this.state.unreadOrAll == UnreadOrAll.Unread && (
                   <button
-                    class="btn btn-secondary mb-2"
+                    className="btn btn-secondary mb-2"
                     onClick={linkEvent(this, this.markAllAsRead)}
                   >
                     {i18n.t("mark_all_as_read")}
@@ -230,7 +235,7 @@ export class Inbox extends Component<any, InboxState> {
 
   unreadOrAllRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
@@ -263,7 +268,7 @@ export class Inbox extends Component<any, InboxState> {
 
   messageTypeRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.messageType == MessageType.All && "active"}
@@ -323,8 +328,8 @@ export class Inbox extends Component<any, InboxState> {
   selects() {
     return (
       <div className="mb-2">
-        <span class="mr-3">{this.unreadOrAllRadios()}</span>
-        <span class="mr-3">{this.messageTypeRadios()}</span>
+        <span className="mr-3">{this.unreadOrAllRadios()}</span>
+        <span className="mr-3">{this.messageTypeRadios()}</span>
         <CommentSortSelect
           sort={this.state.sort}
           onChange={this.handleSortChange}
@@ -394,6 +399,7 @@ export class Inbox extends Component<any, InboxState> {
             showCommunity
             showContext
             enableDownvotes={enableDownvotes(this.state.siteRes)}
+            allLanguages={this.state.siteRes.all_languages}
           />
         );
       case ReplyEnum.Mention:
@@ -416,6 +422,7 @@ export class Inbox extends Component<any, InboxState> {
             showCommunity
             showContext
             enableDownvotes={enableDownvotes(this.state.siteRes)}
+            allLanguages={this.state.siteRes.all_languages}
           />
         );
       case ReplyEnum.Message:
@@ -448,6 +455,7 @@ export class Inbox extends Component<any, InboxState> {
           showCommunity
           showContext
           enableDownvotes={enableDownvotes(this.state.siteRes)}
+          allLanguages={this.state.siteRes.all_languages}
         />
       </div>
     );
@@ -469,6 +477,7 @@ export class Inbox extends Component<any, InboxState> {
             showCommunity
             showContext
             enableDownvotes={enableDownvotes(this.state.siteRes)}
+            allLanguages={this.state.siteRes.all_languages}
           />
         ))}
       </div>
@@ -494,16 +503,12 @@ export class Inbox extends Component<any, InboxState> {
   }
 
   handleUnreadOrAllChange(i: Inbox, event: any) {
-    i.state.unreadOrAll = Number(event.target.value);
-    i.state.page = 1;
-    i.setState(i.state);
+    i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
     i.refetch();
   }
 
   handleMessageTypeChange(i: Inbox, event: any) {
-    i.state.messageType = Number(event.target.value);
-    i.state.page = 1;
-    i.setState(i.state);
+    i.setState({ messageType: Number(event.target.value), page: 1 });
     i.refetch();
   }
 
@@ -580,9 +585,7 @@ export class Inbox extends Component<any, InboxState> {
   }
 
   handleSortChange(val: CommentSortType) {
-    this.state.sort = val;
-    this.state.page = 1;
-    this.setState(this.state);
+    this.setState({ sort: val, page: 1 });
     this.refetch();
   }
 
@@ -592,10 +595,8 @@ export class Inbox extends Component<any, InboxState> {
         auth: auth().unwrap(),
       })
     );
-    i.state.replies = [];
-    i.state.mentions = [];
-    i.state.messages = [];
-    i.state.combined = i.buildCombined();
+    i.setState({ replies: [], mentions: [], messages: [] });
+    i.setState({ combined: i.buildCombined() });
     UserService.Instance.unreadInboxCountSub.next(0);
     window.scrollTo(0, 0);
     i.setState(i.state);
@@ -620,31 +621,27 @@ export class Inbox extends Component<any, InboxState> {
       this.refetch();
     } else if (op == UserOperation.GetReplies) {
       let data = wsJsonToRes<GetRepliesResponse>(msg, GetRepliesResponse);
-      this.state.replies = data.replies;
-      this.state.combined = this.buildCombined();
-      this.state.loading = false;
+      this.setState({ replies: data.replies });
+      this.setState({ combined: this.buildCombined(), loading: false });
       window.scrollTo(0, 0);
-      this.setState(this.state);
       setupTippy();
     } else if (op == UserOperation.GetPersonMentions) {
       let data = wsJsonToRes<GetPersonMentionsResponse>(
         msg,
         GetPersonMentionsResponse
       );
-      this.state.mentions = data.mentions;
-      this.state.combined = this.buildCombined();
+      this.setState({ mentions: data.mentions });
+      this.setState({ combined: this.buildCombined() });
       window.scrollTo(0, 0);
-      this.setState(this.state);
       setupTippy();
     } else if (op == UserOperation.GetPrivateMessages) {
       let data = wsJsonToRes<PrivateMessagesResponse>(
         msg,
         PrivateMessagesResponse
       );
-      this.state.messages = data.private_messages;
-      this.state.combined = this.buildCombined();
+      this.setState({ messages: data.private_messages });
+      this.setState({ combined: this.buildCombined() });
       window.scrollTo(0, 0);
-      this.setState(this.state);
       setupTippy();
     } else if (op == UserOperation.EditPrivateMessage) {
       let data = wsJsonToRes<PrivateMessageResponse>(
@@ -696,7 +693,9 @@ export class Inbox extends Component<any, InboxState> {
 
       if (found) {
         let combinedView = this.state.combined.find(
-          i => i.id == data.private_message_view.private_message.id
+          i =>
+            i.id == data.private_message_view.private_message.id &&
+            i.type_ == ReplyEnum.Message
         ).view as PrivateMessageView;
         found.private_message.updated = combinedView.private_message.updated =
           data.private_message_view.private_message.updated;
@@ -706,14 +705,18 @@ export class Inbox extends Component<any, InboxState> {
           this.state.unreadOrAll == UnreadOrAll.Unread &&
           data.private_message_view.private_message.read
         ) {
-          this.state.messages = this.state.messages.filter(
-            r =>
-              r.private_message.id !==
-              data.private_message_view.private_message.id
-          );
-          this.state.combined = this.state.combined.filter(
-            r => r.id !== data.private_message_view.private_message.id
-          );
+          this.setState({
+            messages: this.state.messages.filter(
+              r =>
+                r.private_message.id !==
+                data.private_message_view.private_message.id
+            ),
+          });
+          this.setState({
+            combined: this.state.combined.filter(
+              r => r.id !== data.private_message_view.private_message.id
+            ),
+          });
         } else {
           found.private_message.read = combinedView.private_message.read =
             data.private_message_view.private_message.read;
@@ -733,7 +736,6 @@ export class Inbox extends Component<any, InboxState> {
       this.setState(this.state);
     } else if (op == UserOperation.MarkCommentReplyAsRead) {
       let data = wsJsonToRes<CommentReplyResponse>(msg, CommentReplyResponse);
-      console.log(data);
 
       let found = this.state.replies.find(
         c => c.comment_reply.id == data.comment_reply_view.comment_reply.id
@@ -741,7 +743,9 @@ export class Inbox extends Component<any, InboxState> {
 
       if (found) {
         let combinedView = this.state.combined.find(
-          i => i.id == data.comment_reply_view.comment_reply.id
+          i =>
+            i.id == data.comment_reply_view.comment_reply.id &&
+            i.type_ == ReplyEnum.Reply
         ).view as CommentReplyView;
         found.comment.content = combinedView.comment.content =
           data.comment_reply_view.comment.content;
@@ -763,12 +767,17 @@ export class Inbox extends Component<any, InboxState> {
           this.state.unreadOrAll == UnreadOrAll.Unread &&
           data.comment_reply_view.comment_reply.read
         ) {
-          this.state.replies = this.state.replies.filter(
-            r => r.comment_reply.id !== data.comment_reply_view.comment_reply.id
-          );
-          this.state.combined = this.state.combined.filter(
-            r => r.id !== data.comment_reply_view.comment_reply.id
-          );
+          this.setState({
+            replies: this.state.replies.filter(
+              r =>
+                r.comment_reply.id !== data.comment_reply_view.comment_reply.id
+            ),
+          });
+          this.setState({
+            combined: this.state.combined.filter(
+              r => r.id !== data.comment_reply_view.comment_reply.id
+            ),
+          });
         } else {
           found.comment_reply.read = combinedView.comment_reply.read =
             data.comment_reply_view.comment_reply.read;
@@ -786,7 +795,9 @@ export class Inbox extends Component<any, InboxState> {
 
       if (found) {
         let combinedView = this.state.combined.find(
-          i => i.id == data.person_mention_view.person_mention.id
+          i =>
+            i.id == data.person_mention_view.person_mention.id &&
+            i.type_ == ReplyEnum.Mention
         ).view as PersonMentionView;
         found.comment.content = combinedView.comment.content =
           data.person_mention_view.comment.content;
@@ -808,13 +819,18 @@ export class Inbox extends Component<any, InboxState> {
           this.state.unreadOrAll == UnreadOrAll.Unread &&
           data.person_mention_view.person_mention.read
         ) {
-          this.state.mentions = this.state.mentions.filter(
-            r =>
-              r.person_mention.id !== data.person_mention_view.person_mention.id
-          );
-          this.state.combined = this.state.combined.filter(
-            r => r.id !== data.person_mention_view.person_mention.id
-          );
+          this.setState({
+            mentions: this.state.mentions.filter(
+              r =>
+                r.person_mention.id !==
+                data.person_mention_view.person_mention.id
+            ),
+          });
+          this.setState({
+            combined: this.state.combined.filter(
+              r => r.id !== data.person_mention_view.person_mention.id
+            ),
+          });
         } else {
           // TODO test to make sure these mentions are getting marked as read
           found.person_mention.read = combinedView.person_mention.read =
@@ -865,6 +881,14 @@ export class Inbox extends Component<any, InboxState> {
       if (data) {
         toast(i18n.t("report_created"));
       }
+    } else if (op == UserOperation.CreatePrivateMessageReport) {
+      let data = wsJsonToRes<PrivateMessageReportResponse>(
+        msg,
+        PrivateMessageReportResponse
+      );
+      if (data) {
+        toast(i18n.t("report_created"));
+      }
     }
   }
 
index 8120fe97630e67d60a972b9103fdeb4d5071a7e7..42a287e6d591c43facf3d780fe48ee5c52d5bdbf 100644 (file)
@@ -66,15 +66,15 @@ export class PasswordChange extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
           description={None}
           image={None}
         />
-        <div class="row">
-          <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+        <div className="row">
+          <div className="col-12 col-lg-6 offset-lg-3 mb-4">
             <h5>{i18n.t("password_change")}</h5>
             {this.passwordChangeForm()}
           </div>
@@ -86,41 +86,41 @@ export class PasswordChange extends Component<any, State> {
   passwordChangeForm() {
     return (
       <form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="new-password">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="new-password">
             {i18n.t("new_password")}
           </label>
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               id="new-password"
               type="password"
               value={this.state.passwordChangeForm.password}
               onInput={linkEvent(this, this.handlePasswordChange)}
-              class="form-control"
+              className="form-control"
               required
               maxLength={60}
             />
           </div>
         </div>
-        <div class="form-group row">
-          <label class="col-sm-2 col-form-label" htmlFor="verify-password">
+        <div className="form-group row">
+          <label className="col-sm-2 col-form-label" htmlFor="verify-password">
             {i18n.t("verify_password")}
           </label>
-          <div class="col-sm-10">
+          <div className="col-sm-10">
             <input
               id="verify-password"
               type="password"
               value={this.state.passwordChangeForm.password_verify}
               onInput={linkEvent(this, this.handleVerifyPasswordChange)}
-              class="form-control"
+              className="form-control"
               required
               maxLength={60}
             />
           </div>
         </div>
-        <div class="form-group row">
-          <div class="col-sm-10">
-            <button type="submit" class="btn btn-secondary">
+        <div className="form-group row">
+          <div className="col-sm-10">
+            <button type="submit" className="btn btn-secondary">
               {this.state.loading ? (
                 <Spinner />
               ) : (
@@ -145,8 +145,7 @@ export class PasswordChange extends Component<any, State> {
 
   handlePasswordChangeSubmit(i: PasswordChange, event: any) {
     event.preventDefault();
-    i.state.loading = true;
-    i.setState(i.state);
+    i.setState({ loading: true });
 
     WebSocketService.Instance.send(
       wsClient.passwordChange(i.state.passwordChangeForm)
@@ -158,13 +157,11 @@ export class PasswordChange extends Component<any, State> {
     console.log(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (op == UserOperation.PasswordChange) {
       let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
-      this.state = this.emptyState;
-      this.setState(this.state);
+      this.setState(this.emptyState);
       UserService.Instance.login(data);
       this.props.history.push("/");
     }
index 6ce7a8b8d0b02c3070866adfa9983b15ed58de12..e228cbdf678a0bdfd8760195960f9279b8414c3a 100644 (file)
@@ -3,6 +3,7 @@ import { Component } from "inferno";
 import {
   CommentView,
   GetPersonDetailsResponse,
+  Language,
   PersonViewSafe,
   PostView,
   SortType,
@@ -16,6 +17,7 @@ import { PostListing } from "../post/post-listing";
 interface PersonDetailsProps {
   personRes: GetPersonDetailsResponse;
   admins: PersonViewSafe[];
+  allLanguages: Language[];
   page: number;
   limit: number;
   sort: SortType;
@@ -99,6 +101,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
             showCommunity
             showContext
             enableDownvotes={this.props.enableDownvotes}
+            allLanguages={this.props.allLanguages}
           />
         );
       }
@@ -114,6 +117,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
             showCommunity
             enableDownvotes={this.props.enableDownvotes}
             enableNsfw={this.props.enableNsfw}
+            allLanguages={this.props.allLanguages}
           />
         );
       }
@@ -150,7 +154,10 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
 
     return (
       <div>
-        {combined.map(i => [this.renderItemType(i), <hr class="my-3" />])}
+        {combined.map(i => [
+          this.renderItemType(i),
+          <hr key={i.type_} className="my-3" />,
+        ])}
       </div>
     );
   }
@@ -168,6 +175,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
           showCommunity
           showContext
           enableDownvotes={this.props.enableDownvotes}
+          allLanguages={this.props.allLanguages}
         />
       </div>
     );
@@ -186,8 +194,9 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
               moderators={None}
               enableDownvotes={this.props.enableDownvotes}
               enableNsfw={this.props.enableNsfw}
+              allLanguages={this.props.allLanguages}
             />
-            <hr class="my-3" />
+            <hr className="my-3" />
           </>
         ))}
       </div>
index 9de6d0b967abe06c9380d90eb3f3ef81697d5b8b..52e7a93bd17d7370067eef68842ed79b1585407b 100644 (file)
@@ -121,15 +121,14 @@ export class Profile extends Component<any, ProfileState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.personRes = Some(
-        this.isoData.routeData[0] as GetPersonDetailsResponse
-      );
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        personRes: Some(this.isoData.routeData[0] as GetPersonDetailsResponse),
+        loading: false,
+      };
     } else {
       this.fetchUserData();
     }
-
-    this.setPersonBlock();
   }
 
   fetchUserData() {
@@ -162,11 +161,12 @@ export class Profile extends Component<any, ProfileState> {
     UserService.Instance.myUserInfo.match({
       some: mui =>
         this.state.personRes.match({
-          some: res => {
-            this.state.personBlocked = mui.person_blocks
-              .map(a => a.target.id)
-              .includes(res.person_view.person.id);
-          },
+          some: res =>
+            this.setState({
+              personBlocked: mui.person_blocks
+                .map(a => a.target.id)
+                .includes(res.person_view.person.id),
+            }),
           none: void 0,
         }),
       none: void 0,
@@ -207,6 +207,7 @@ export class Profile extends Component<any, ProfileState> {
   }
 
   componentDidMount() {
+    this.setPersonBlock();
     setupTippy();
   }
 
@@ -250,7 +251,7 @@ export class Profile extends Component<any, ProfileState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
@@ -258,8 +259,8 @@ export class Profile extends Component<any, ProfileState> {
         ) : (
           this.state.personRes.match({
             some: res => (
-              <div class="row">
-                <div class="col-12 col-md-8">
+              <div className="row">
+                <div className="col-12 col-md-8">
                   <>
                     <HtmlTags
                       title={this.documentTitle}
@@ -281,11 +282,12 @@ export class Profile extends Component<any, ProfileState> {
                     enableNsfw={enableNsfw(this.state.siteRes)}
                     view={this.state.view}
                     onPageChange={this.handlePageChange}
+                    allLanguages={this.state.siteRes.all_languages}
                   />
                 </div>
 
                 {!this.state.loading && (
-                  <div class="col-12 col-md-4">
+                  <div className="col-12 col-md-4">
                     {this.moderates()}
                     {this.amCurrentUser && this.follows()}
                   </div>
@@ -301,7 +303,7 @@ export class Profile extends Component<any, ProfileState> {
 
   viewRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.view == PersonDetailsView.Overview && "active"}
@@ -363,7 +365,7 @@ export class Profile extends Component<any, ProfileState> {
 
     return (
       <div className="mb-2">
-        <span class="mr-3">{this.viewRadios()}</span>
+        <span className="mr-3">{this.viewRadios()}</span>
         <SortSelect
           sort={this.state.sort}
           onChange={this.handleSortChange}
@@ -406,14 +408,17 @@ export class Profile extends Component<any, ProfileState> {
               banner={pv.person.banner}
               icon={pv.person.avatar}
             />
-            <div class="mb-3">
-              <div class="">
-                <div class="mb-0 d-flex flex-wrap">
+            <div className="mb-3">
+              <div className="">
+                <div className="mb-0 d-flex flex-wrap">
                   <div>
-                    {pv.person.display_name && (
-                      <h5 class="mb-0">{pv.person.display_name}</h5>
-                    )}
-                    <ul class="list-inline mb-2">
+                    {pv.person.display_name.match({
+                      some: displayName => (
+                        <h5 className="mb-0">{displayName}</h5>
+                      ),
+                      none: <></>,
+                    })}
+                    <ul className="list-inline mb-2">
                       <li className="list-inline-item">
                         <PersonListing
                           person={pv.person}
@@ -531,7 +536,7 @@ export class Profile extends Component<any, ProfileState> {
                   none: <></>,
                 })}
                 <div>
-                  <ul class="list-inline mb-2">
+                  <ul className="list-inline mb-2">
                     <li className="list-inline-item badge badge-light">
                       {i18n.t("number_of_posts", {
                         count: pv.counts.post_count,
@@ -546,7 +551,7 @@ export class Profile extends Component<any, ProfileState> {
                     </li>
                   </ul>
                 </div>
-                <div class="text-muted">
+                <div className="text-muted">
                   {i18n.t("joined")}{" "}
                   <MomentTime
                     published={pv.person.published}
@@ -581,33 +586,36 @@ export class Profile extends Component<any, ProfileState> {
           <>
             {this.state.showBanDialog && (
               <form onSubmit={linkEvent(this, this.handleModBanSubmit)}>
-                <div class="form-group row col-12">
-                  <label class="col-form-label" htmlFor="profile-ban-reason">
+                <div className="form-group row col-12">
+                  <label
+                    className="col-form-label"
+                    htmlFor="profile-ban-reason"
+                  >
                     {i18n.t("reason")}
                   </label>
                   <input
                     type="text"
                     id="profile-ban-reason"
-                    class="form-control mr-2"
+                    className="form-control mr-2"
                     placeholder={i18n.t("reason")}
                     value={toUndefined(this.state.banReason)}
                     onInput={linkEvent(this, this.handleModBanReasonChange)}
                   />
-                  <label class="col-form-label" htmlFor={`mod-ban-expires`}>
+                  <label className="col-form-label" htmlFor={`mod-ban-expires`}>
                     {i18n.t("expires")}
                   </label>
                   <input
                     type="number"
                     id={`mod-ban-expires`}
-                    class="form-control mr-2"
+                    className="form-control mr-2"
                     placeholder={i18n.t("number_of_days")}
                     value={toUndefined(this.state.banExpireDays)}
                     onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
                   />
-                  <div class="form-group">
-                    <div class="form-check">
+                  <div className="form-group">
+                    <div className="form-check">
                       <input
-                        class="form-check-input"
+                        className="form-check-input"
                         id="mod-ban-remove-data"
                         type="checkbox"
                         checked={this.state.removeData}
@@ -617,7 +625,7 @@ export class Profile extends Component<any, ProfileState> {
                         )}
                       />
                       <label
-                        class="form-check-label"
+                        className="form-check-label"
                         htmlFor="mod-ban-remove-data"
                         title={i18n.t("remove_content_more")}
                       >
@@ -631,10 +639,10 @@ export class Profile extends Component<any, ProfileState> {
                 {/*   <label class="col-form-label">Expires</label> */}
                 {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
                 {/* </div> */}
-                <div class="form-group row">
+                <div className="form-group row">
                   <button
-                    type="cancel"
-                    class="btn btn-secondary mr-2"
+                    type="reset"
+                    className="btn btn-secondary mr-2"
                     aria-label={i18n.t("cancel")}
                     onClick={linkEvent(this, this.handleModBanSubmitCancel)}
                   >
@@ -642,7 +650,7 @@ export class Profile extends Component<any, ProfileState> {
                   </button>
                   <button
                     type="submit"
-                    class="btn btn-secondary"
+                    className="btn btn-secondary"
                     aria-label={i18n.t("ban")}
                   >
                     {i18n.t("ban")} {pv.person.name}
@@ -656,25 +664,28 @@ export class Profile extends Component<any, ProfileState> {
       });
   }
 
-  // TODO test this, make sure its good
   moderates() {
     return this.state.personRes
       .map(r => r.moderates)
       .match({
         some: moderates => {
           if (moderates.length > 0) {
-            <div class="card border-secondary mb-3">
-              <div class="card-body">
-                <h5>{i18n.t("moderates")}</h5>
-                <ul class="list-unstyled mb-0">
-                  {moderates.map(cmv => (
-                    <li>
-                      <CommunityLink community={cmv.community} />
-                    </li>
-                  ))}
-                </ul>
+            return (
+              <div className="card border-secondary mb-3">
+                <div className="card-body">
+                  <h5>{i18n.t("moderates")}</h5>
+                  <ul className="list-unstyled mb-0">
+                    {moderates.map(cmv => (
+                      <li key={cmv.community.id}>
+                        <CommunityLink community={cmv.community} />
+                      </li>
+                    ))}
+                  </ul>
+                </div>
               </div>
-            </div>;
+            );
+          } else {
+            return <></>;
           }
         },
         none: void 0,
@@ -687,18 +698,22 @@ export class Profile extends Component<any, ProfileState> {
       .match({
         some: follows => {
           if (follows.length > 0) {
-            <div class="card border-secondary mb-3">
-              <div class="card-body">
-                <h5>{i18n.t("subscribed")}</h5>
-                <ul class="list-unstyled mb-0">
-                  {follows.map(cfv => (
-                    <li>
-                      <CommunityLink community={cfv.community} />
-                    </li>
-                  ))}
-                </ul>
+            return (
+              <div className="card border-secondary mb-3">
+                <div className="card-body">
+                  <h5>{i18n.t("subscribed")}</h5>
+                  <ul className="list-unstyled mb-0">
+                    {follows.map(cfv => (
+                      <li key={cfv.community.id}>
+                        <CommunityLink community={cfv.community} />
+                      </li>
+                    ))}
+                  </ul>
+                </div>
               </div>
-            </div>;
+            );
+          } else {
+            return <></>;
           }
         },
         none: void 0,
@@ -715,8 +730,7 @@ export class Profile extends Component<any, ProfileState> {
     this.props.history.push(
       `${typeView}/view/${viewStr}/sort/${sortStr}/page/${page}`
     );
-    this.state.loading = true;
-    this.setState(this.state);
+    this.setState({ loading: true });
     this.fetchUserData();
   }
 
@@ -736,29 +750,24 @@ export class Profile extends Component<any, ProfileState> {
   }
 
   handleModBanShow(i: Profile) {
-    i.state.showBanDialog = true;
-    i.setState(i.state);
+    i.setState({ showBanDialog: true });
   }
 
   handleModBanReasonChange(i: Profile, event: any) {
-    i.state.banReason = event.target.value;
-    i.setState(i.state);
+    i.setState({ banReason: event.target.value });
   }
 
   handleModBanExpireDaysChange(i: Profile, event: any) {
-    i.state.banExpireDays = event.target.value;
-    i.setState(i.state);
+    i.setState({ banExpireDays: event.target.value });
   }
 
   handleModRemoveDataChange(i: Profile, event: any) {
-    i.state.removeData = event.target.checked;
-    i.setState(i.state);
+    i.setState({ removeData: event.target.checked });
   }
 
   handleModBanSubmitCancel(i: Profile, event?: any) {
     event.preventDefault();
-    i.state.showBanDialog = false;
-    i.setState(i.state);
+    i.setState({ showBanDialog: false });
   }
 
   handleModBanSubmit(i: Profile, event?: any) {
@@ -771,7 +780,7 @@ export class Profile extends Component<any, ProfileState> {
           // If its an unban, restore all their data
           let ban = !person.banned;
           if (ban == false) {
-            i.state.removeData = false;
+            i.setState({ removeData: false });
           }
           let form = new BanPerson({
             person_id: person.id,
@@ -783,8 +792,7 @@ export class Profile extends Component<any, ProfileState> {
           });
           WebSocketService.Instance.send(wsClient.banPerson(form));
 
-          i.state.showBanDialog = false;
-          i.setState(i.state);
+          i.setState({ showBanDialog: false });
         },
         none: void 0,
       });
@@ -809,15 +817,12 @@ export class Profile extends Component<any, ProfileState> {
         msg,
         GetPersonDetailsResponse
       );
-      this.state.personRes = Some(data);
-      this.state.loading = false;
+      this.setState({ personRes: Some(data), loading: false });
       this.setPersonBlock();
-      this.setState(this.state);
       restoreScrollPosition(this.context);
     } else if (op == UserOperation.AddAdmin) {
       let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse);
-      this.state.siteRes.admins = data.admins;
-      this.setState(this.state);
+      this.setState(s => ((s.siteRes.admins = data.admins), s));
     } else if (op == UserOperation.CreateCommentLike) {
       let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
       createCommentLikeRes(
index eec90319ad8cfb1f7b3cf4e2bf47b1b7e4209678..e2ef43467d1831a64d5150358eb2492275f3414e 100644 (file)
@@ -75,10 +75,13 @@ export class RegistrationApplications extends Component<
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.listRegistrationApplicationsResponse = Some(
-        this.isoData.routeData[0] as ListRegistrationApplicationsResponse
-      );
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        listRegistrationApplicationsResponse: Some(
+          this.isoData.routeData[0] as ListRegistrationApplicationsResponse
+        ),
+        loading: false,
+      };
     } else {
       this.refetch();
     }
@@ -110,21 +113,21 @@ export class RegistrationApplications extends Component<
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
           </h5>
         ) : (
-          <div class="row">
-            <div class="col-12">
+          <div className="row">
+            <div className="col-12">
               <HtmlTags
                 title={this.documentTitle}
                 path={this.context.router.route.match.url}
                 description={None}
                 image={None}
               />
-              <h5 class="mb-2">{i18n.t("registration_applications")}</h5>
+              <h5 className="mb-2">{i18n.t("registration_applications")}</h5>
               {this.selects()}
               {this.applicationList()}
               <Paginator
@@ -140,7 +143,7 @@ export class RegistrationApplications extends Component<
 
   unreadOrAllRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
@@ -174,7 +177,7 @@ export class RegistrationApplications extends Component<
   selects() {
     return (
       <div className="mb-2">
-        <span class="mr-3">{this.unreadOrAllRadios()}</span>
+        <span className="mr-3">{this.unreadOrAllRadios()}</span>
       </div>
     );
   }
@@ -199,9 +202,7 @@ export class RegistrationApplications extends Component<
   }
 
   handleUnreadOrAllChange(i: RegistrationApplications, event: any) {
-    i.state.unreadOrAll = Number(event.target.value);
-    i.state.page = 1;
-    i.setState(i.state);
+    i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
     i.refetch();
   }
 
@@ -248,10 +249,11 @@ export class RegistrationApplications extends Component<
         msg,
         ListRegistrationApplicationsResponse
       );
-      this.state.listRegistrationApplicationsResponse = Some(data);
-      this.state.loading = false;
+      this.setState({
+        listRegistrationApplicationsResponse: Some(data),
+        loading: false,
+      });
       window.scrollTo(0, 0);
-      this.setState(this.state);
     } else if (op == UserOperation.ApproveRegistrationApplication) {
       let data = wsJsonToRes<RegistrationApplicationResponse>(
         msg,
index f8a641b556032f24166efcda16f337448220b9bd..85411cc3b4226a89279cc4b4f0355f200f26dd61 100644 (file)
@@ -8,8 +8,12 @@ import {
   ListCommentReportsResponse,
   ListPostReports,
   ListPostReportsResponse,
+  ListPrivateMessageReports,
+  ListPrivateMessageReportsResponse,
   PostReportResponse,
   PostReportView,
+  PrivateMessageReportResponse,
+  PrivateMessageReportView,
   UserOperation,
   wsJsonToRes,
   wsUserOp,
@@ -19,6 +23,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
+  amAdmin,
   auth,
   fetchLimit,
   isBrowser,
@@ -27,6 +32,7 @@ import {
   toast,
   updateCommentReportRes,
   updatePostReportRes,
+  updatePrivateMessageReportRes,
   wsClient,
   wsSubscribe,
 } from "../../utils";
@@ -35,6 +41,7 @@ import { HtmlTags } from "../common/html-tags";
 import { Spinner } from "../common/icon";
 import { Paginator } from "../common/paginator";
 import { PostReport } from "../post/post-report";
+import { PrivateMessageReport } from "../private_message/private-message-report";
 
 enum UnreadOrAll {
   Unread,
@@ -45,23 +52,26 @@ enum MessageType {
   All,
   CommentReport,
   PostReport,
+  PrivateMessageReport,
 }
 
 enum MessageEnum {
   CommentReport,
   PostReport,
+  PrivateMessageReport,
 }
 
 type ItemType = {
   id: number;
   type_: MessageEnum;
-  view: CommentReportView | PostReportView;
+  view: CommentReportView | PostReportView | PrivateMessageReportView;
   published: string;
 };
 
 interface ReportsState {
   listCommentReportsResponse: Option<ListCommentReportsResponse>;
   listPostReportsResponse: Option<ListPostReportsResponse>;
+  listPrivateMessageReportsResponse: Option<ListPrivateMessageReportsResponse>;
   unreadOrAll: UnreadOrAll;
   messageType: MessageType;
   combined: ItemType[];
@@ -74,12 +84,14 @@ export class Reports extends Component<any, ReportsState> {
   private isoData = setIsoData(
     this.context,
     ListCommentReportsResponse,
-    ListPostReportsResponse
+    ListPostReportsResponse,
+    ListPrivateMessageReportsResponse
   );
   private subscription: Subscription;
   private emptyState: ReportsState = {
     listCommentReportsResponse: None,
     listPostReportsResponse: None,
+    listPrivateMessageReportsResponse: None,
     unreadOrAll: UnreadOrAll.Unread,
     messageType: MessageType.All,
     combined: [],
@@ -104,14 +116,28 @@ export class Reports extends Component<any, ReportsState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.listCommentReportsResponse = Some(
-        this.isoData.routeData[0] as ListCommentReportsResponse
-      );
-      this.state.listPostReportsResponse = Some(
-        this.isoData.routeData[1] as ListPostReportsResponse
-      );
-      this.state.combined = this.buildCombined();
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        listCommentReportsResponse: Some(
+          this.isoData.routeData[0] as ListCommentReportsResponse
+        ),
+        listPostReportsResponse: Some(
+          this.isoData.routeData[1] as ListPostReportsResponse
+        ),
+      };
+      if (amAdmin()) {
+        this.state = {
+          ...this.state,
+          listPrivateMessageReportsResponse: Some(
+            this.isoData.routeData[2] as ListPrivateMessageReportsResponse
+          ),
+        };
+      }
+      this.state = {
+        ...this.state,
+        combined: this.buildCombined(),
+        loading: false,
+      };
     } else {
       this.refetch();
     }
@@ -139,27 +165,29 @@ export class Reports extends Component<any, ReportsState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
           </h5>
         ) : (
-          <div class="row">
-            <div class="col-12">
+          <div className="row">
+            <div className="col-12">
               <HtmlTags
                 title={this.documentTitle}
                 path={this.context.router.route.match.url}
                 description={None}
                 image={None}
               />
-              <h5 class="mb-2">{i18n.t("reports")}</h5>
+              <h5 className="mb-2">{i18n.t("reports")}</h5>
               {this.selects()}
               {this.state.messageType == MessageType.All && this.all()}
               {this.state.messageType == MessageType.CommentReport &&
                 this.commentReports()}
               {this.state.messageType == MessageType.PostReport &&
                 this.postReports()}
+              {this.state.messageType == MessageType.PrivateMessageReport &&
+                this.privateMessageReports()}
               <Paginator
                 page={this.state.page}
                 onChange={this.handlePageChange}
@@ -173,7 +201,7 @@ export class Reports extends Component<any, ReportsState> {
 
   unreadOrAllRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
@@ -206,7 +234,7 @@ export class Reports extends Component<any, ReportsState> {
 
   messageTypeRadios() {
     return (
-      <div class="btn-group btn-group-toggle flex-wrap mb-2">
+      <div className="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.messageType == MessageType.All && "active"}
@@ -246,6 +274,26 @@ export class Reports extends Component<any, ReportsState> {
           />
           {i18n.t("posts")}
         </label>
+        {amAdmin() && (
+          <label
+            className={`btn btn-outline-secondary pointer
+            ${
+              this.state.messageType == MessageType.PrivateMessageReport &&
+              "active"
+            }
+          `}
+          >
+            <input
+              type="radio"
+              value={MessageType.PrivateMessageReport}
+              checked={
+                this.state.messageType == MessageType.PrivateMessageReport
+              }
+              onChange={linkEvent(this, this.handleMessageTypeChange)}
+            />
+            {i18n.t("messages")}
+          </label>
+        )}
       </div>
     );
   }
@@ -253,13 +301,13 @@ export class Reports extends Component<any, ReportsState> {
   selects() {
     return (
       <div className="mb-2">
-        <span class="mr-3">{this.unreadOrAllRadios()}</span>
-        <span class="mr-3">{this.messageTypeRadios()}</span>
+        <span className="mr-3">{this.unreadOrAllRadios()}</span>
+        <span className="mr-3">{this.messageTypeRadios()}</span>
       </div>
     );
   }
 
-  replyToReplyType(r: CommentReportView): ItemType {
+  commentReportToItemType(r: CommentReportView): ItemType {
     return {
       id: r.comment_report.id,
       type_: MessageEnum.CommentReport,
@@ -268,7 +316,7 @@ export class Reports extends Component<any, ReportsState> {
     };
   }
 
-  mentionToReplyType(r: PostReportView): ItemType {
+  postReportToItemType(r: PostReportView): ItemType {
     return {
       id: r.post_report.id,
       type_: MessageEnum.PostReport,
@@ -277,17 +325,31 @@ export class Reports extends Component<any, ReportsState> {
     };
   }
 
+  privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
+    return {
+      id: r.private_message_report.id,
+      type_: MessageEnum.PrivateMessageReport,
+      view: r,
+      published: r.private_message_report.published,
+    };
+  }
+
   buildCombined(): ItemType[] {
     let comments: ItemType[] = this.state.listCommentReportsResponse
       .map(r => r.comment_reports)
       .unwrapOr([])
-      .map(r => this.replyToReplyType(r));
+      .map(r => this.commentReportToItemType(r));
     let posts: ItemType[] = this.state.listPostReportsResponse
       .map(r => r.post_reports)
       .unwrapOr([])
-      .map(r => this.mentionToReplyType(r));
-
-    return [...comments, ...posts].sort((a, b) =>
+      .map(r => this.postReportToItemType(r));
+    let privateMessages: ItemType[] =
+      this.state.listPrivateMessageReportsResponse
+        .map(r => r.private_message_reports)
+        .unwrapOr([])
+        .map(r => this.privateMessageReportToItemType(r));
+
+    return [...comments, ...posts, ...privateMessages].sort((a, b) =>
       b.published.localeCompare(a.published)
     );
   }
@@ -300,6 +362,13 @@ export class Reports extends Component<any, ReportsState> {
         );
       case MessageEnum.PostReport:
         return <PostReport key={i.id} report={i.view as PostReportView} />;
+      case MessageEnum.PrivateMessageReport:
+        return (
+          <PrivateMessageReport
+            key={i.id}
+            report={i.view as PrivateMessageReportView}
+          />
+        );
       default:
         return <div />;
     }
@@ -350,22 +419,37 @@ export class Reports extends Component<any, ReportsState> {
     });
   }
 
+  privateMessageReports() {
+    return this.state.listPrivateMessageReportsResponse.match({
+      some: res => (
+        <div>
+          {res.private_message_reports.map(pmr => (
+            <>
+              <hr />
+              <PrivateMessageReport
+                key={pmr.private_message_report.id}
+                report={pmr}
+              />
+            </>
+          ))}
+        </div>
+      ),
+      none: <></>,
+    });
+  }
+
   handlePageChange(page: number) {
     this.setState({ page });
     this.refetch();
   }
 
   handleUnreadOrAllChange(i: Reports, event: any) {
-    i.state.unreadOrAll = Number(event.target.value);
-    i.state.page = 1;
-    i.setState(i.state);
+    i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
     i.refetch();
   }
 
   handleMessageTypeChange(i: Reports, event: any) {
-    i.state.messageType = Number(event.target.value);
-    i.state.page = 1;
-    i.setState(i.state);
+    i.setState({ messageType: Number(event.target.value), page: 1 });
     i.refetch();
   }
 
@@ -398,6 +482,18 @@ export class Reports extends Component<any, ReportsState> {
     });
     promises.push(req.client.listPostReports(postReportsForm));
 
+    if (amAdmin()) {
+      let privateMessageReportsForm = new ListPrivateMessageReports({
+        unresolved_only,
+        page,
+        limit,
+        auth,
+      });
+      promises.push(
+        req.client.listPrivateMessageReports(privateMessageReportsForm)
+      );
+    }
+
     return promises;
   }
 
@@ -428,6 +524,18 @@ export class Reports extends Component<any, ReportsState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
+
+    if (amAdmin()) {
+      let privateMessageReportsForm = new ListPrivateMessageReports({
+        unresolved_only,
+        page,
+        limit,
+        auth: auth().unwrap(),
+      });
+      WebSocketService.Instance.send(
+        wsClient.listPrivateMessageReports(privateMessageReportsForm)
+      );
+    }
   }
 
   parseMessage(msg: any) {
@@ -443,24 +551,30 @@ export class Reports extends Component<any, ReportsState> {
         msg,
         ListCommentReportsResponse
       );
-      this.state.listCommentReportsResponse = Some(data);
-      this.state.combined = this.buildCombined();
-      this.state.loading = false;
+      this.setState({ listCommentReportsResponse: Some(data) });
+      this.setState({ combined: this.buildCombined(), loading: false });
       // this.sendUnreadCount();
       window.scrollTo(0, 0);
-      this.setState(this.state);
       setupTippy();
     } else if (op == UserOperation.ListPostReports) {
       let data = wsJsonToRes<ListPostReportsResponse>(
         msg,
         ListPostReportsResponse
       );
-      this.state.listPostReportsResponse = Some(data);
-      this.state.combined = this.buildCombined();
-      this.state.loading = false;
+      this.setState({ listPostReportsResponse: Some(data) });
+      this.setState({ combined: this.buildCombined(), loading: false });
+      // this.sendUnreadCount();
+      window.scrollTo(0, 0);
+      setupTippy();
+    } else if (op == UserOperation.ListPrivateMessageReports) {
+      let data = wsJsonToRes<ListPrivateMessageReportsResponse>(
+        msg,
+        ListPrivateMessageReportsResponse
+      );
+      this.setState({ listPrivateMessageReportsResponse: Some(data) });
+      this.setState({ combined: this.buildCombined(), loading: false });
       // this.sendUnreadCount();
       window.scrollTo(0, 0);
-      this.setState(this.state);
       setupTippy();
     } else if (op == UserOperation.ResolvePostReport) {
       let data = wsJsonToRes<PostReportResponse>(msg, PostReportResponse);
@@ -490,6 +604,24 @@ export class Reports extends Component<any, ReportsState> {
         urcs.next(urcs.getValue() + 1);
       }
       this.setState(this.state);
+    } else if (op == UserOperation.ResolvePrivateMessageReport) {
+      let data = wsJsonToRes<PrivateMessageReportResponse>(
+        msg,
+        PrivateMessageReportResponse
+      );
+      updatePrivateMessageReportRes(
+        data.private_message_report_view,
+        this.state.listPrivateMessageReportsResponse
+          .map(r => r.private_message_reports)
+          .unwrapOr([])
+      );
+      let urcs = UserService.Instance.unreadReportCountSub;
+      if (data.private_message_report_view.private_message_report.resolved) {
+        urcs.next(urcs.getValue() - 1);
+      } else {
+        urcs.next(urcs.getValue() + 1);
+      }
+      this.setState(this.state);
     }
   }
 }
index 532d92204ab9ae624a24e586b7d1a35a5cff1bc2..06e460b593bb9dedcec9b812e67891fcf907b01e 100644 (file)
@@ -54,6 +54,7 @@ import {
 import { HtmlTags } from "../common/html-tags";
 import { Icon, Spinner } from "../common/icon";
 import { ImageUploadForm } from "../common/image-upload-form";
+import { LanguageSelect } from "../common/language-select";
 import { ListingTypeSelect } from "../common/listing-type-select";
 import { MarkdownTextArea } from "../common/markdown-textarea";
 import { SortSelect } from "../common/sort-select";
@@ -99,7 +100,8 @@ export class Settings extends Component<any, SettingsState> {
       default_sort_type: None,
       default_listing_type: None,
       theme: None,
-      lang: None,
+      interface_language: None,
+      discussion_languages: None,
       avatar: None,
       banner: None,
       display_name: None,
@@ -140,6 +142,8 @@ export class Settings extends Component<any, SettingsState> {
     this.handleSortTypeChange = this.handleSortTypeChange.bind(this);
     this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
     this.handleBioChange = this.handleBioChange.bind(this);
+    this.handleDiscussionLanguageChange =
+      this.handleDiscussionLanguageChange.bind(this);
 
     this.handleAvatarUpload = this.handleAvatarUpload.bind(this);
     this.handleAvatarRemove = this.handleAvatarRemove.bind(this);
@@ -150,13 +154,44 @@ export class Settings extends Component<any, SettingsState> {
     this.parseMessage = this.parseMessage.bind(this);
     this.subscription = wsSubscribe(this.parseMessage);
 
-    this.setUserInfo();
+    if (UserService.Instance.myUserInfo.isSome()) {
+      let mui = UserService.Instance.myUserInfo.unwrap();
+      let luv = mui.local_user_view;
+      this.state = {
+        ...this.state,
+        personBlocks: mui.person_blocks,
+        communityBlocks: mui.community_blocks,
+        saveUserSettingsForm: {
+          ...this.state.saveUserSettingsForm,
+          show_nsfw: Some(luv.local_user.show_nsfw),
+          theme: Some(luv.local_user.theme ? luv.local_user.theme : "browser"),
+          default_sort_type: Some(luv.local_user.default_sort_type),
+          default_listing_type: Some(luv.local_user.default_listing_type),
+          interface_language: Some(luv.local_user.interface_language),
+          discussion_languages: Some(mui.discussion_languages.map(l => l.id)),
+          avatar: luv.person.avatar,
+          banner: luv.person.banner,
+          display_name: luv.person.display_name,
+          show_avatars: Some(luv.local_user.show_avatars),
+          bot_account: Some(luv.person.bot_account),
+          show_bot_accounts: Some(luv.local_user.show_bot_accounts),
+          show_scores: Some(luv.local_user.show_scores),
+          show_read_posts: Some(luv.local_user.show_read_posts),
+          show_new_post_notifs: Some(luv.local_user.show_new_post_notifs),
+          email: luv.local_user.email,
+          bio: luv.person.bio,
+          send_notifications_to_email: Some(
+            luv.local_user.send_notifications_to_email
+          ),
+          matrix_user_id: luv.person.matrix_user_id,
+        },
+      };
+    }
   }
 
   async componentDidMount() {
     setupTippy();
-    this.state.themeList = await fetchThemeList();
-    this.setState(this.state);
+    this.setState({ themeList: await fetchThemeList() });
   }
 
   componentWillUnmount() {
@@ -169,7 +204,7 @@ export class Settings extends Component<any, SettingsState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <>
           <HtmlTags
             title={this.documentTitle}
@@ -177,10 +212,10 @@ export class Settings extends Component<any, SettingsState> {
             description={Some(this.documentTitle)}
             image={this.state.saveUserSettingsForm.avatar}
           />
-          <ul class="nav nav-tabs mb-2">
-            <li class="nav-item">
+          <ul className="nav nav-tabs mb-2">
+            <li className="nav-item">
               <button
-                class={`nav-link btn ${
+                className={`nav-link btn ${
                   this.state.currentTab == "settings" && "active"
                 }`}
                 onClick={linkEvent(
@@ -191,9 +226,9 @@ export class Settings extends Component<any, SettingsState> {
                 {i18n.t("settings")}
               </button>
             </li>
-            <li class="nav-item">
+            <li className="nav-item">
               <button
-                class={`nav-link btn ${
+                className={`nav-link btn ${
                   this.state.currentTab == "blocks" && "active"
                 }`}
                 onClick={linkEvent(
@@ -214,15 +249,15 @@ export class Settings extends Component<any, SettingsState> {
 
   userSettings() {
     return (
-      <div class="row">
-        <div class="col-12 col-md-6">
-          <div class="card border-secondary mb-3">
-            <div class="card-body">{this.saveUserSettingsHtmlForm()}</div>
+      <div className="row">
+        <div className="col-12 col-md-6">
+          <div className="card border-secondary mb-3">
+            <div className="card-body">{this.saveUserSettingsHtmlForm()}</div>
           </div>
         </div>
-        <div class="col-12 col-md-6">
-          <div class="card border-secondary mb-3">
-            <div class="card-body">{this.changePasswordHtmlForm()}</div>
+        <div className="col-12 col-md-6">
+          <div className="card border-secondary mb-3">
+            <div className="card-body">{this.changePasswordHtmlForm()}</div>
           </div>
         </div>
       </div>
@@ -231,15 +266,15 @@ export class Settings extends Component<any, SettingsState> {
 
   blockCards() {
     return (
-      <div class="row">
-        <div class="col-12 col-md-6">
-          <div class="card border-secondary mb-3">
-            <div class="card-body">{this.blockUserCard()}</div>
+      <div className="row">
+        <div className="col-12 col-md-6">
+          <div className="card border-secondary mb-3">
+            <div className="card-body">{this.blockUserCard()}</div>
           </div>
         </div>
-        <div class="col-12 col-md-6">
-          <div class="card border-secondary mb-3">
-            <div class="card-body">{this.blockCommunityCard()}</div>
+        <div className="col-12 col-md-6">
+          <div className="card border-secondary mb-3">
+            <div className="card-body">{this.blockCommunityCard()}</div>
           </div>
         </div>
       </div>
@@ -251,15 +286,15 @@ export class Settings extends Component<any, SettingsState> {
       <>
         <h5>{i18n.t("change_password")}</h5>
         <form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}>
-          <div class="form-group row">
-            <label class="col-sm-5 col-form-label" htmlFor="user-password">
+          <div className="form-group row">
+            <label className="col-sm-5 col-form-label" htmlFor="user-password">
               {i18n.t("new_password")}
             </label>
-            <div class="col-sm-7">
+            <div className="col-sm-7">
               <input
                 type="password"
                 id="user-password"
-                class="form-control"
+                className="form-control"
                 value={this.state.changePasswordForm.new_password}
                 autoComplete="new-password"
                 maxLength={60}
@@ -267,18 +302,18 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
+          <div className="form-group row">
             <label
-              class="col-sm-5 col-form-label"
+              className="col-sm-5 col-form-label"
               htmlFor="user-verify-password"
             >
               {i18n.t("verify_password")}
             </label>
-            <div class="col-sm-7">
+            <div className="col-sm-7">
               <input
                 type="password"
                 id="user-verify-password"
-                class="form-control"
+                className="form-control"
                 value={this.state.changePasswordForm.new_password_verify}
                 autoComplete="new-password"
                 maxLength={60}
@@ -286,15 +321,18 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-5 col-form-label" htmlFor="user-old-password">
+          <div className="form-group row">
+            <label
+              className="col-sm-5 col-form-label"
+              htmlFor="user-old-password"
+            >
               {i18n.t("old_password")}
             </label>
-            <div class="col-sm-7">
+            <div className="col-sm-7">
               <input
                 type="password"
                 id="user-old-password"
-                class="form-control"
+                className="form-control"
                 value={this.state.changePasswordForm.old_password}
                 autoComplete="new-password"
                 maxLength={60}
@@ -302,8 +340,8 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group">
-            <button type="submit" class="btn btn-block btn-secondary mr-4">
+          <div className="form-group">
+            <button type="submit" className="btn btn-block btn-secondary mr-4">
               {this.state.changePasswordLoading ? (
                 <Spinner />
               ) : (
@@ -329,9 +367,9 @@ export class Settings extends Component<any, SettingsState> {
     return (
       <>
         <h5>{i18n.t("blocked_users")}</h5>
-        <ul class="list-unstyled mb-0">
+        <ul className="list-unstyled mb-0">
           {this.state.personBlocks.map(pb => (
-            <li>
+            <li key={pb.target.id}>
               <span>
                 <PersonListing person={pb.target} />
                 <button
@@ -354,13 +392,16 @@ export class Settings extends Component<any, SettingsState> {
 
   blockUserForm() {
     return (
-      <div class="form-group row">
-        <label class="col-md-4 col-form-label" htmlFor="block-person-filter">
+      <div className="form-group row">
+        <label
+          className="col-md-4 col-form-label"
+          htmlFor="block-person-filter"
+        >
           {i18n.t("block_user")}
         </label>
-        <div class="col-md-8">
+        <div className="col-md-8">
           <select
-            class="form-control"
+            className="form-control"
             id="block-person-filter"
             value={this.state.blockPerson.map(p => p.person.id).unwrapOr(0)}
           >
@@ -392,9 +433,9 @@ export class Settings extends Component<any, SettingsState> {
     return (
       <>
         <h5>{i18n.t("blocked_communities")}</h5>
-        <ul class="list-unstyled mb-0">
+        <ul className="list-unstyled mb-0">
           {this.state.communityBlocks.map(cb => (
-            <li>
+            <li key={cb.community.id}>
               <span>
                 <CommunityLink community={cb.community} />
                 <button
@@ -417,13 +458,16 @@ export class Settings extends Component<any, SettingsState> {
 
   blockCommunityForm() {
     return (
-      <div class="form-group row">
-        <label class="col-md-4 col-form-label" htmlFor="block-community-filter">
+      <div className="form-group row">
+        <label
+          className="col-md-4 col-form-label"
+          htmlFor="block-community-filter"
+        >
           {i18n.t("block_community")}
         </label>
-        <div class="col-md-8">
+        <div className="col-md-8">
           <select
-            class="form-control"
+            className="form-control"
             id="block-community-filter"
             value={this.state.blockCommunityId}
           >
@@ -440,19 +484,21 @@ export class Settings extends Component<any, SettingsState> {
   }
 
   saveUserSettingsHtmlForm() {
+    let selectedLangs = this.state.saveUserSettingsForm.discussion_languages;
+
     return (
       <>
         <h5>{i18n.t("settings")}</h5>
         <form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}>
-          <div class="form-group row">
-            <label class="col-sm-5 col-form-label" htmlFor="display-name">
+          <div className="form-group row">
+            <label className="col-sm-5 col-form-label" htmlFor="display-name">
               {i18n.t("display_name")}
             </label>
-            <div class="col-sm-7">
+            <div className="col-sm-7">
               <input
                 id="display-name"
                 type="text"
-                class="form-control"
+                className="form-control"
                 placeholder={i18n.t("optional")}
                 value={toUndefined(
                   this.state.saveUserSettingsForm.display_name
@@ -463,30 +509,32 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3 col-form-label" htmlFor="user-bio">
+          <div className="form-group row">
+            <label className="col-sm-3 col-form-label" htmlFor="user-bio">
               {i18n.t("bio")}
             </label>
-            <div class="col-sm-9">
+            <div className="col-sm-9">
               <MarkdownTextArea
                 initialContent={this.state.saveUserSettingsForm.bio}
+                initialLanguageId={None}
                 onContentChange={this.handleBioChange}
                 maxLength={Some(300)}
                 placeholder={None}
                 buttonTitle={None}
                 hideNavigationWarnings
+                allLanguages={this.state.siteRes.all_languages}
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3 col-form-label" htmlFor="user-email">
+          <div className="form-group row">
+            <label className="col-sm-3 col-form-label" htmlFor="user-email">
               {i18n.t("email")}
             </label>
-            <div class="col-sm-9">
+            <div className="col-sm-9">
               <input
                 type="email"
                 id="user-email"
-                class="form-control"
+                className="form-control"
                 placeholder={i18n.t("optional")}
                 value={toUndefined(this.state.saveUserSettingsForm.email)}
                 onInput={linkEvent(this, this.handleEmailChange)}
@@ -494,17 +542,17 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-5 col-form-label" htmlFor="matrix-user-id">
+          <div className="form-group row">
+            <label className="col-sm-5 col-form-label" htmlFor="matrix-user-id">
               <a href={elementUrl} rel={relTags}>
                 {i18n.t("matrix_user_id")}
               </a>
             </label>
-            <div class="col-sm-7">
+            <div className="col-sm-7">
               <input
                 id="matrix-user-id"
                 type="text"
-                class="form-control"
+                className="form-control"
                 placeholder="@user:example.com"
                 value={toUndefined(
                   this.state.saveUserSettingsForm.matrix_user_id
@@ -514,9 +562,9 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3">{i18n.t("avatar")}</label>
-            <div class="col-sm-9">
+          <div className="form-group row">
+            <label className="col-sm-3">{i18n.t("avatar")}</label>
+            <div className="col-sm-9">
               <ImageUploadForm
                 uploadTitle={i18n.t("upload_avatar")}
                 imageSrc={this.state.saveUserSettingsForm.avatar}
@@ -526,9 +574,9 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3">{i18n.t("banner")}</label>
-            <div class="col-sm-9">
+          <div className="form-group row">
+            <label className="col-sm-3">{i18n.t("banner")}</label>
+            <div className="col-sm-9">
               <ImageUploadForm
                 uploadTitle={i18n.t("upload_banner")}
                 imageSrc={this.state.saveUserSettingsForm.banner}
@@ -537,19 +585,21 @@ export class Settings extends Component<any, SettingsState> {
               />
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3" htmlFor="user-language">
-              {i18n.t("language")}
+          <div className="form-group row">
+            <label className="col-sm-3" htmlFor="user-language">
+              {i18n.t("interface_language")}
             </label>
-            <div class="col-sm-9">
+            <div className="col-sm-9">
               <select
                 id="user-language"
-                value={toUndefined(this.state.saveUserSettingsForm.lang)}
-                onChange={linkEvent(this, this.handleLangChange)}
-                class="custom-select w-auto"
+                value={toUndefined(
+                  this.state.saveUserSettingsForm.interface_language
+                )}
+                onChange={linkEvent(this, this.handleInterfaceLangChange)}
+                className="custom-select w-auto"
               >
                 <option disabled aria-hidden="true">
-                  {i18n.t("language")}
+                  {i18n.t("interface_language")}
                 </option>
                 <option value="browser">{i18n.t("browser_default")}</option>
                 <option disabled aria-hidden="true">
@@ -558,35 +608,45 @@ export class Settings extends Component<any, SettingsState> {
                 {languages
                   .sort((a, b) => a.code.localeCompare(b.code))
                   .map(lang => (
-                    <option value={lang.code}>{lang.name}</option>
+                    <option key={lang.code} value={lang.code}>
+                      {lang.name}
+                    </option>
                   ))}
               </select>
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-3" htmlFor="user-theme">
+          <LanguageSelect
+            allLanguages={this.state.siteRes.all_languages}
+            selectedLanguageIds={selectedLangs}
+            multiple={true}
+            onChange={this.handleDiscussionLanguageChange}
+          />
+          <div className="form-group row">
+            <label className="col-sm-3" htmlFor="user-theme">
               {i18n.t("theme")}
             </label>
-            <div class="col-sm-9">
+            <div className="col-sm-9">
               <select
                 id="user-theme"
                 value={toUndefined(this.state.saveUserSettingsForm.theme)}
                 onChange={linkEvent(this, this.handleThemeChange)}
-                class="custom-select w-auto"
+                className="custom-select w-auto"
               >
                 <option disabled aria-hidden="true">
                   {i18n.t("theme")}
                 </option>
                 <option value="browser">{i18n.t("browser_default")}</option>
                 {this.state.themeList.map(theme => (
-                  <option value={theme}>{theme}</option>
+                  <option key={theme} value={theme}>
+                    {theme}
+                  </option>
                 ))}
               </select>
             </div>
           </div>
           <form className="form-group row">
-            <label class="col-sm-3">{i18n.t("type")}</label>
-            <div class="col-sm-9">
+            <label className="col-sm-3">{i18n.t("type")}</label>
+            <div className="col-sm-9">
               <ListingTypeSelect
                 type_={
                   Object.values(ListingType)[
@@ -602,8 +662,8 @@ export class Settings extends Component<any, SettingsState> {
             </div>
           </form>
           <form className="form-group row">
-            <label class="col-sm-3">{i18n.t("sort_type")}</label>
-            <div class="col-sm-9">
+            <label className="col-sm-3">{i18n.t("sort_type")}</label>
+            <div className="col-sm-9">
               <SortSelect
                 sort={
                   Object.values(SortType)[
@@ -617,10 +677,10 @@ export class Settings extends Component<any, SettingsState> {
             </div>
           </form>
           {enableNsfw(this.state.siteRes) && (
-            <div class="form-group">
-              <div class="form-check">
+            <div className="form-group">
+              <div className="form-check">
                 <input
-                  class="form-check-input"
+                  className="form-check-input"
                   id="user-show-nsfw"
                   type="checkbox"
                   checked={toUndefined(
@@ -628,16 +688,16 @@ export class Settings extends Component<any, SettingsState> {
                   )}
                   onChange={linkEvent(this, this.handleShowNsfwChange)}
                 />
-                <label class="form-check-label" htmlFor="user-show-nsfw">
+                <label className="form-check-label" htmlFor="user-show-nsfw">
                   {i18n.t("show_nsfw")}
                 </label>
               </div>
             </div>
           )}
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-show-scores"
                 type="checkbox"
                 checked={toUndefined(
@@ -645,15 +705,15 @@ export class Settings extends Component<any, SettingsState> {
                 )}
                 onChange={linkEvent(this, this.handleShowScoresChange)}
               />
-              <label class="form-check-label" htmlFor="user-show-scores">
+              <label className="form-check-label" htmlFor="user-show-scores">
                 {i18n.t("show_scores")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-show-avatars"
                 type="checkbox"
                 checked={toUndefined(
@@ -661,15 +721,15 @@ export class Settings extends Component<any, SettingsState> {
                 )}
                 onChange={linkEvent(this, this.handleShowAvatarsChange)}
               />
-              <label class="form-check-label" htmlFor="user-show-avatars">
+              <label className="form-check-label" htmlFor="user-show-avatars">
                 {i18n.t("show_avatars")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-bot-account"
                 type="checkbox"
                 checked={toUndefined(
@@ -677,15 +737,15 @@ export class Settings extends Component<any, SettingsState> {
                 )}
                 onChange={linkEvent(this, this.handleBotAccount)}
               />
-              <label class="form-check-label" htmlFor="user-bot-account">
+              <label className="form-check-label" htmlFor="user-bot-account">
                 {i18n.t("bot_account")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-show-bot-accounts"
                 type="checkbox"
                 checked={toUndefined(
@@ -693,15 +753,18 @@ export class Settings extends Component<any, SettingsState> {
                 )}
                 onChange={linkEvent(this, this.handleShowBotAccounts)}
               />
-              <label class="form-check-label" htmlFor="user-show-bot-accounts">
+              <label
+                className="form-check-label"
+                htmlFor="user-show-bot-accounts"
+              >
                 {i18n.t("show_bot_accounts")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-show-read-posts"
                 type="checkbox"
                 checked={toUndefined(
@@ -709,15 +772,18 @@ export class Settings extends Component<any, SettingsState> {
                 )}
                 onChange={linkEvent(this, this.handleReadPosts)}
               />
-              <label class="form-check-label" htmlFor="user-show-read-posts">
+              <label
+                className="form-check-label"
+                htmlFor="user-show-read-posts"
+              >
                 {i18n.t("show_read_posts")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-show-new-post-notifs"
                 type="checkbox"
                 checked={toUndefined(
@@ -726,17 +792,17 @@ export class Settings extends Component<any, SettingsState> {
                 onChange={linkEvent(this, this.handleShowNewPostNotifs)}
               />
               <label
-                class="form-check-label"
+                className="form-check-label"
                 htmlFor="user-show-new-post-notifs"
               >
                 {i18n.t("show_new_post_notifs")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <div class="form-check">
+          <div className="form-group">
+            <div className="form-check">
               <input
-                class="form-check-input"
+                className="form-check-input"
                 id="user-send-notifications-to-email"
                 type="checkbox"
                 disabled={!this.state.saveUserSettingsForm.email}
@@ -749,15 +815,15 @@ export class Settings extends Component<any, SettingsState> {
                 )}
               />
               <label
-                class="form-check-label"
+                className="form-check-label"
                 htmlFor="user-send-notifications-to-email"
               >
                 {i18n.t("send_notifications_to_email")}
               </label>
             </div>
           </div>
-          <div class="form-group">
-            <button type="submit" class="btn btn-block btn-secondary mr-4">
+          <div className="form-group">
+            <button type="submit" className="btn btn-block btn-secondary mr-4">
               {this.state.saveUserSettingsLoading ? (
                 <Spinner />
               ) : (
@@ -766,9 +832,9 @@ export class Settings extends Component<any, SettingsState> {
             </button>
           </div>
           <hr />
-          <div class="form-group">
+          <div className="form-group">
             <button
-              class="btn btn-block btn-danger"
+              className="btn btn-block btn-danger"
               onClick={linkEvent(
                 this,
                 this.handleDeleteAccountShowConfirmToggle
@@ -778,7 +844,7 @@ export class Settings extends Component<any, SettingsState> {
             </button>
             {this.state.deleteAccountShowConfirm && (
               <>
-                <div class="my-2 alert alert-danger" role="alert">
+                <div className="my-2 alert alert-danger" role="alert">
                   {i18n.t("delete_account_confirm")}
                 </div>
                 <input
@@ -790,10 +856,10 @@ export class Settings extends Component<any, SettingsState> {
                     this,
                     this.handleDeleteAccountPasswordChange
                   )}
-                  class="form-control my-2"
+                  className="form-control my-2"
                 />
                 <button
-                  class="btn btn-danger mr-4"
+                  className="btn btn-danger mr-4"
                   disabled={!this.state.deleteAccountForm.password}
                   onClick={linkEvent(this, this.handleDeleteAccount)}
                 >
@@ -804,7 +870,7 @@ export class Settings extends Component<any, SettingsState> {
                   )}
                 </button>
                 <button
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(
                     this,
                     this.handleDeleteAccountShowConfirmToggle
@@ -991,26 +1057,40 @@ export class Settings extends Component<any, SettingsState> {
     i.setState(i.state);
   }
 
-  handleLangChange(i: Settings, event: any) {
-    i.state.saveUserSettingsForm.lang = Some(event.target.value);
+  handleInterfaceLangChange(i: Settings, event: any) {
+    i.state.saveUserSettingsForm.interface_language = Some(event.target.value);
     i18n.changeLanguage(
-      getLanguages(i.state.saveUserSettingsForm.lang.unwrap())[0]
+      getLanguages(i.state.saveUserSettingsForm.interface_language.unwrap())[0]
     );
     i.setState(i.state);
   }
 
+  handleDiscussionLanguageChange(val: number[]) {
+    this.setState(
+      s => ((s.saveUserSettingsForm.discussion_languages = Some(val)), s)
+    );
+  }
+
   handleSortTypeChange(val: SortType) {
-    this.state.saveUserSettingsForm.default_sort_type = Some(
-      Object.keys(SortType).indexOf(val)
+    this.setState(
+      s => (
+        (s.saveUserSettingsForm.default_sort_type = Some(
+          Object.keys(SortType).indexOf(val)
+        )),
+        s
+      )
     );
-    this.setState(this.state);
   }
 
   handleListingTypeChange(val: ListingType) {
-    this.state.saveUserSettingsForm.default_listing_type = Some(
-      Object.keys(ListingType).indexOf(val)
+    this.setState(
+      s => (
+        (s.saveUserSettingsForm.default_listing_type = Some(
+          Object.keys(ListingType).indexOf(val)
+        )),
+        s
+      )
     );
-    this.setState(this.state);
   }
 
   handleEmailChange(i: Settings, event: any) {
@@ -1019,28 +1099,23 @@ export class Settings extends Component<any, SettingsState> {
   }
 
   handleBioChange(val: string) {
-    this.state.saveUserSettingsForm.bio = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.saveUserSettingsForm.bio = Some(val)), s));
   }
 
   handleAvatarUpload(url: string) {
-    this.state.saveUserSettingsForm.avatar = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.saveUserSettingsForm.avatar = Some(url)), s));
   }
 
   handleAvatarRemove() {
-    this.state.saveUserSettingsForm.avatar = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.saveUserSettingsForm.avatar = Some("")), s));
   }
 
   handleBannerUpload(url: string) {
-    this.state.saveUserSettingsForm.banner = Some(url);
-    this.setState(this.state);
+    this.setState(s => ((s.saveUserSettingsForm.banner = Some(url)), s));
   }
 
   handleBannerRemove() {
-    this.state.saveUserSettingsForm.banner = Some("");
-    this.setState(this.state);
+    this.setState(s => ((s.saveUserSettingsForm.banner = Some("")), s));
   }
 
   handleDisplayNameChange(i: Settings, event: any) {
@@ -1079,30 +1154,26 @@ export class Settings extends Component<any, SettingsState> {
 
   handleSaveSettingsSubmit(i: Settings, event: any) {
     event.preventDefault();
-    i.state.saveUserSettingsLoading = true;
-    i.state.saveUserSettingsForm.auth = auth().unwrap();
-    i.setState(i.state);
+    i.setState({ saveUserSettingsLoading: true });
+    i.setState(s => ((s.saveUserSettingsForm.auth = auth().unwrap()), s));
 
-    WebSocketService.Instance.send(
-      wsClient.saveUserSettings(i.state.saveUserSettingsForm)
-    );
+    let form = new SaveUserSettings({ ...i.state.saveUserSettingsForm });
+    WebSocketService.Instance.send(wsClient.saveUserSettings(form));
   }
 
   handleChangePasswordSubmit(i: Settings, event: any) {
     event.preventDefault();
-    i.state.changePasswordLoading = true;
-    i.state.changePasswordForm.auth = auth().unwrap();
-    i.setState(i.state);
+    i.setState({ changePasswordLoading: true });
+    i.setState(s => ((s.changePasswordForm.auth = auth().unwrap()), s));
 
-    WebSocketService.Instance.send(
-      wsClient.changePassword(i.state.changePasswordForm)
-    );
+    let form = new ChangePassword({ ...i.state.changePasswordForm });
+
+    WebSocketService.Instance.send(wsClient.changePassword(form));
   }
 
   handleDeleteAccountShowConfirmToggle(i: Settings, event: any) {
     event.preventDefault();
-    i.state.deleteAccountShowConfirm = !i.state.deleteAccountShowConfirm;
-    i.setState(i.state);
+    i.setState({ deleteAccountShowConfirm: !i.state.deleteAccountShowConfirm });
   }
 
   handleDeleteAccountPasswordChange(i: Settings, event: any) {
@@ -1112,13 +1183,12 @@ export class Settings extends Component<any, SettingsState> {
 
   handleDeleteAccount(i: Settings, event: any) {
     event.preventDefault();
-    i.state.deleteAccountLoading = true;
-    i.state.deleteAccountForm.auth = auth().unwrap();
-    i.setState(i.state);
+    i.setState({ deleteAccountLoading: true });
+    i.setState(s => ((s.deleteAccountForm.auth = auth().unwrap()), s));
 
-    WebSocketService.Instance.send(
-      wsClient.deleteAccount(i.state.deleteAccountForm)
-    );
+    let form = new DeleteAccount({ ...i.state.deleteAccountForm });
+
+    WebSocketService.Instance.send(wsClient.deleteAccount(form));
   }
 
   handleSwitchTab(i: { ctx: Settings; tab: string }) {
@@ -1130,58 +1200,6 @@ export class Settings extends Component<any, SettingsState> {
     }
   }
 
-  setUserInfo() {
-    UserService.Instance.myUserInfo.match({
-      some: mui => {
-        let luv = mui.local_user_view;
-        this.state.saveUserSettingsForm.show_nsfw = Some(
-          luv.local_user.show_nsfw
-        );
-        this.state.saveUserSettingsForm.theme = Some(
-          luv.local_user.theme ? luv.local_user.theme : "browser"
-        );
-        this.state.saveUserSettingsForm.default_sort_type = Some(
-          luv.local_user.default_sort_type
-        );
-        this.state.saveUserSettingsForm.default_listing_type = Some(
-          luv.local_user.default_listing_type
-        );
-        this.state.saveUserSettingsForm.lang = Some(luv.local_user.lang);
-        this.state.saveUserSettingsForm.avatar = luv.person.avatar;
-        this.state.saveUserSettingsForm.banner = luv.person.banner;
-        this.state.saveUserSettingsForm.display_name = luv.person.display_name;
-        this.state.saveUserSettingsForm.show_avatars = Some(
-          luv.local_user.show_avatars
-        );
-        this.state.saveUserSettingsForm.bot_account = Some(
-          luv.person.bot_account
-        );
-        this.state.saveUserSettingsForm.show_bot_accounts = Some(
-          luv.local_user.show_bot_accounts
-        );
-        this.state.saveUserSettingsForm.show_scores = Some(
-          luv.local_user.show_scores
-        );
-        this.state.saveUserSettingsForm.show_read_posts = Some(
-          luv.local_user.show_read_posts
-        );
-        this.state.saveUserSettingsForm.show_new_post_notifs = Some(
-          luv.local_user.show_new_post_notifs
-        );
-        this.state.saveUserSettingsForm.email = luv.local_user.email;
-        this.state.saveUserSettingsForm.bio = luv.person.bio;
-        this.state.saveUserSettingsForm.send_notifications_to_email = Some(
-          luv.local_user.send_notifications_to_email
-        );
-        this.state.saveUserSettingsForm.matrix_user_id =
-          luv.person.matrix_user_id;
-        this.state.personBlocks = mui.person_blocks;
-        this.state.communityBlocks = mui.community_blocks;
-      },
-      none: void 0,
-    });
-  }
-
   parseMessage(msg: any) {
     let op = wsUserOp(msg);
     console.log(msg);
@@ -1196,15 +1214,13 @@ export class Settings extends Component<any, SettingsState> {
     } else if (op == UserOperation.SaveUserSettings) {
       let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
       UserService.Instance.login(data);
-      this.state.saveUserSettingsLoading = false;
-      this.setState(this.state);
+      this.setState({ saveUserSettingsLoading: false });
       toast(i18n.t("saved"));
       window.scrollTo(0, 0);
     } else if (op == UserOperation.ChangePassword) {
       let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
       UserService.Instance.login(data);
-      this.state.changePasswordLoading = false;
-      this.setState(this.state);
+      this.setState({ changePasswordLoading: false });
       window.scrollTo(0, 0);
       toast(i18n.t("password_changed"));
     } else if (op == UserOperation.DeleteAccount) {
index fed026fdff2419aa6829623012653bc6e249bb10..e5389584d41e045d44033537542385863fc2e080 100644 (file)
@@ -66,15 +66,15 @@ export class VerifyEmail extends Component<any, State> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
           description={None}
           image={None}
         />
-        <div class="row">
-          <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+        <div className="row">
+          <div className="col-12 col-lg-6 offset-lg-3 mb-4">
             <h5>{i18n.t("verify_email")}</h5>
           </div>
         </div>
@@ -94,8 +94,7 @@ export class VerifyEmail extends Component<any, State> {
       let data = wsJsonToRes<VerifyEmailResponse>(msg, VerifyEmailResponse);
       if (data) {
         toast(i18n.t("email_verified"));
-        this.state = this.emptyState;
-        this.setState(this.state);
+        this.setState(this.emptyState);
         this.props.history.push("/login");
       }
     }
index 68d546e2e376f5009b81095d1bf0d33f82ef2787..3d3396c040745c9b8dc875f4b3ff2dce5ed4ae6d 100644 (file)
@@ -50,23 +50,27 @@ export class CreatePost extends Component<any, CreatePostState> {
 
   constructor(props: any, context: any) {
     super(props, context);
-    this.handlePostCreate = this.handlePostCreate.bind(this);
     this.state = this.emptyState;
 
+    this.handlePostCreate = this.handlePostCreate.bind(this);
+
+    this.parseMessage = this.parseMessage.bind(this);
+    this.subscription = wsSubscribe(this.parseMessage);
+
     if (UserService.Instance.myUserInfo.isNone() && isBrowser()) {
       toast(i18n.t("not_logged_in"), "danger");
       this.context.router.history.push(`/login`);
     }
 
-    this.parseMessage = this.parseMessage.bind(this);
-    this.subscription = wsSubscribe(this.parseMessage);
-
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.listCommunitiesResponse = Some(
-        this.isoData.routeData[0] as ListCommunitiesResponse
-      );
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        listCommunitiesResponse: Some(
+          this.isoData.routeData[0] as ListCommunitiesResponse
+        ),
+        loading: false,
+      };
     } else {
       this.refetch();
     }
@@ -123,7 +127,7 @@ export class CreatePost extends Component<any, CreatePostState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -137,8 +141,8 @@ export class CreatePost extends Component<any, CreatePostState> {
         ) : (
           this.state.listCommunitiesResponse.match({
             some: res => (
-              <div class="row">
-                <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+              <div className="row">
+                <div className="col-12 col-lg-6 offset-lg-3 mb-4">
                   <h5>{i18n.t("create_post")}</h5>
                   <PostForm
                     post_view={None}
@@ -147,6 +151,7 @@ export class CreatePost extends Component<any, CreatePostState> {
                     params={Some(this.params)}
                     enableDownvotes={enableDownvotes(this.state.siteRes)}
                     enableNsfw={enableNsfw(this.state.siteRes)}
+                    allLanguages={this.state.siteRes.all_languages}
                   />
                 </div>
               </div>
@@ -230,16 +235,15 @@ export class CreatePost extends Component<any, CreatePostState> {
         msg,
         ListCommunitiesResponse
       );
-      this.state.listCommunitiesResponse = Some(data);
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ listCommunitiesResponse: Some(data), loading: false });
     } else if (op == UserOperation.GetCommunity) {
       let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse);
-      this.state.listCommunitiesResponse = Some({
-        communities: [data.community_view],
+      this.setState({
+        listCommunitiesResponse: Some({
+          communities: [data.community_view],
+        }),
+        loading: false,
       });
-      this.state.loading = false;
-      this.setState(this.state);
     }
   }
 }
index 116cdc9a4ea3ba281f8a43afda09f2dbebeaec55..4dc68fdf0f5df4e590200495a7450b8c02db3f2a 100644 (file)
@@ -34,27 +34,33 @@ export class MetadataCard extends Component<
             some: embedTitle =>
               post.url.match({
                 some: url => (
-                  <div class="card border-secondary mt-3 mb-2">
-                    <div class="row">
-                      <div class="col-12">
-                        <div class="card-body">
-                          {post.name !== embedTitle && [
-                            <h5 class="card-title d-inline">
-                              <a class="text-body" href={url} rel={relTags}>
-                                {embedTitle}
-                              </a>
-                            </h5>,
-                            <span class="d-inline-block ml-2 mb-2 small text-muted">
-                              <a
-                                class="text-muted font-italic"
-                                href={url}
-                                rel={relTags}
-                              >
-                                {new URL(url).hostname}
-                                <Icon icon="external-link" classes="ml-1" />
-                              </a>
-                            </span>,
-                          ]}
+                  <div className="card border-secondary mt-3 mb-2">
+                    <div className="row">
+                      <div className="col-12">
+                        <div className="card-body">
+                          {post.name !== embedTitle && (
+                            <>
+                              <h5 className="card-title d-inline">
+                                <a
+                                  className="text-body"
+                                  href={url}
+                                  rel={relTags}
+                                >
+                                  {embedTitle}
+                                </a>
+                              </h5>
+                              <span className="d-inline-block ml-2 mb-2 small text-muted">
+                                <a
+                                  className="text-muted font-italic"
+                                  href={url}
+                                  rel={relTags}
+                                >
+                                  {new URL(url).hostname}
+                                  <Icon icon="external-link" classes="ml-1" />
+                                </a>
+                              </span>
+                            </>
+                          )}
                           {post.embed_description.match({
                             some: desc => (
                               <div
@@ -66,9 +72,9 @@ export class MetadataCard extends Component<
                             ),
                             none: <></>,
                           })}
-                          {post.embed_html.isSome() && (
+                          {post.embed_video_url.isSome() && (
                             <button
-                              class="mt-2 btn btn-secondary text-monospace"
+                              className="mt-2 btn btn-secondary text-monospace"
                               onClick={linkEvent(this, this.handleIframeExpand)}
                               data-tippy-content={i18n.t("expand_here")}
                             >
@@ -85,10 +91,10 @@ export class MetadataCard extends Component<
             none: <></>,
           })}
         {this.state.expanded &&
-          post.embed_html.match({
+          post.embed_video_url.match({
             some: html => (
               <div
-                class="mt-3 mb-2"
+                className="mt-3 mb-2"
                 dangerouslySetInnerHTML={{ __html: html }}
               />
             ),
@@ -99,7 +105,6 @@ export class MetadataCard extends Component<
   }
 
   handleIframeExpand(i: MetadataCard) {
-    i.state.expanded = !i.state.expanded;
-    i.setState(i.state);
+    i.setState({ expanded: !i.state.expanded });
   }
 }
index dde1cb4237d88ce60eb0eefadb49e592b80e4d4b..8addc859fc03bcba2303f85982bede3b35c43cd8 100644 (file)
@@ -6,6 +6,7 @@ import {
   CommunityView,
   CreatePost,
   EditPost,
+  Language,
   ListingType,
   PostResponse,
   PostView,
@@ -36,6 +37,7 @@ import {
   ghostArchiveUrl,
   isBrowser,
   isImage,
+  myFirstDiscussionLanguageId,
   pictrsDeleteToast,
   relTags,
   setupTippy,
@@ -48,6 +50,7 @@ import {
   wsSubscribe,
 } from "../../utils";
 import { Icon, Spinner } from "../common/icon";
+import { LanguageSelect } from "../common/language-select";
 import { MarkdownTextArea } from "../common/markdown-textarea";
 import { PostListings } from "./post-listings";
 
@@ -60,6 +63,7 @@ const MAX_POST_TITLE_LENGTH = 200;
 
 interface PostFormProps {
   post_view: Option<PostView>; // If a post is given, that means this is an edit
+  allLanguages: Language[];
   communities: Option<CommunityView[]>;
   params: Option<PostFormParams>;
   onCancel?(): any;
@@ -76,6 +80,7 @@ interface PostFormState {
   crossPosts: Option<PostView[]>;
   loading: boolean;
   imageLoading: boolean;
+  communitySearchLoading: boolean;
   previewMode: boolean;
 }
 
@@ -90,10 +95,12 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
       url: None,
       body: None,
       honeypot: None,
+      language_id: None,
       auth: undefined,
     }),
     loading: false,
     imageLoading: false,
+    communitySearchLoading: false,
     previewMode: false,
     suggestedTitle: None,
     suggestedPosts: None,
@@ -105,35 +112,44 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     this.fetchSimilarPosts = debounce(this.fetchSimilarPosts.bind(this));
     this.fetchPageTitle = debounce(this.fetchPageTitle.bind(this));
     this.handlePostBodyChange = this.handlePostBodyChange.bind(this);
+    this.handleLanguageChange = this.handleLanguageChange.bind(this);
 
     this.state = this.emptyState;
 
+    this.parseMessage = this.parseMessage.bind(this);
+    this.subscription = wsSubscribe(this.parseMessage);
+
     // Means its an edit
-    this.props.post_view.match({
-      some: pv =>
-        (this.state.postForm = new CreatePost({
+    if (this.props.post_view.isSome()) {
+      let pv = this.props.post_view.unwrap();
+
+      this.state = {
+        ...this.state,
+        postForm: new CreatePost({
           body: pv.post.body,
           name: pv.post.name,
           community_id: pv.community.id,
           url: pv.post.url,
           nsfw: Some(pv.post.nsfw),
           honeypot: None,
+          language_id: Some(pv.post.language_id),
           auth: auth().unwrap(),
-        })),
-      none: void 0,
-    });
-
-    this.props.params.match({
-      some: params => {
-        this.state.postForm.name = toUndefined(params.name);
-        this.state.postForm.url = params.url;
-        this.state.postForm.body = params.body;
-      },
-      none: void 0,
-    });
+        }),
+      };
+    }
 
-    this.parseMessage = this.parseMessage.bind(this);
-    this.subscription = wsSubscribe(this.parseMessage);
+    if (this.props.params.isSome()) {
+      let params = this.props.params.unwrap();
+      this.state = {
+        ...this.state,
+        postForm: {
+          ...this.state.postForm,
+          name: toUndefined(params.name),
+          url: params.url,
+          body: params.body,
+        },
+      };
+    }
   }
 
   componentDidMount() {
@@ -165,6 +181,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
   }
 
   render() {
+    let selectedLangs = this.state.postForm.language_id
+      .or(myFirstDiscussionLanguageId(UserService.Instance.myUserInfo))
+      .map(Array.of);
+
     return (
       <div>
         <Prompt
@@ -177,15 +197,15 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
           message={i18n.t("block_leaving")}
         />
         <form onSubmit={linkEvent(this, this.handlePostSubmit)}>
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="post-url">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label" htmlFor="post-url">
               {i18n.t("url")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <input
                 type="url"
                 id="post-url"
-                class="form-control"
+                className="form-control"
                 value={toUndefined(this.state.postForm.url)}
                 onInput={linkEvent(this, this.handlePostUrlChange)}
                 onPaste={linkEvent(this, this.handleImageUploadPaste)}
@@ -193,7 +213,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               {this.state.suggestedTitle.match({
                 some: title => (
                   <div
-                    class="mt-1 text-muted small font-weight-bold pointer"
+                    className="mt-1 text-muted small font-weight-bold pointer"
                     role="button"
                     onClick={linkEvent(this, this.copySuggestedTitle)}
                   >
@@ -217,7 +237,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                   type="file"
                   accept="image/*,video/*"
                   name="file"
-                  class="d-none"
+                  className="d-none"
                   disabled={UserService.Instance.myUserInfo.isNone()}
                   onChange={linkEvent(this, this.handleImageUpload)}
                 />
@@ -230,7 +250,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                         href={`${webArchiveUrl}/save/${encodeURIComponent(
                           url
                         )}`}
-                        class="mr-2 d-inline-block float-right text-muted small font-weight-bold"
+                        className="mr-2 d-inline-block float-right text-muted small font-weight-bold"
                         rel={relTags}
                       >
                         archive.org {i18n.t("archive_link")}
@@ -239,7 +259,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                         href={`${ghostArchiveUrl}/search?term=${encodeURIComponent(
                           url
                         )}`}
-                        class="mr-2 d-inline-block float-right text-muted small font-weight-bold"
+                        className="mr-2 d-inline-block float-right text-muted small font-weight-bold"
                         rel={relTags}
                       >
                         ghostarchive.org {i18n.t("archive_link")}
@@ -248,7 +268,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                         href={`${archiveTodayUrl}/?run=1&url=${encodeURIComponent(
                           url
                         )}`}
-                        class="mr-2 d-inline-block float-right text-muted small font-weight-bold"
+                        className="mr-2 d-inline-block float-right text-muted small font-weight-bold"
                         rel={relTags}
                       >
                         archive.today {i18n.t("archive_link")}
@@ -260,14 +280,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               {this.state.imageLoading && <Spinner />}
               {this.state.postForm.url.match({
                 some: url =>
-                  isImage(url) && <img src={url} class="img-fluid" alt="" />,
+                  isImage(url) && (
+                    <img src={url} className="img-fluid" alt="" />
+                  ),
                 none: <></>,
               })}
               {this.state.crossPosts.match({
                 some: xPosts =>
                   xPosts.length > 0 && (
                     <>
-                      <div class="my-1 text-muted small font-weight-bold">
+                      <div className="my-1 text-muted small font-weight-bold">
                         {i18n.t("cross_posts")}
                       </div>
                       <PostListings
@@ -275,6 +297,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                         posts={xPosts}
                         enableDownvotes={this.props.enableDownvotes}
                         enableNsfw={this.props.enableNsfw}
+                        allLanguages={this.props.allLanguages}
                       />
                     </>
                   ),
@@ -282,16 +305,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               })}
             </div>
           </div>
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label" htmlFor="post-title">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label" htmlFor="post-title">
               {i18n.t("title")}
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <textarea
                 value={this.state.postForm.name}
                 id="post-title"
                 onInput={linkEvent(this, this.handlePostNameChange)}
-                class={`form-control ${
+                className={`form-control ${
                   !validTitle(this.state.postForm.name) && "is-invalid"
                 }`}
                 required
@@ -300,7 +323,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                 maxLength={MAX_POST_TITLE_LENGTH}
               />
               {!validTitle(this.state.postForm.name) && (
-                <div class="invalid-feedback">
+                <div className="invalid-feedback">
                   {i18n.t("invalid_post_title")}
                 </div>
               )}
@@ -308,7 +331,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                 some: sPosts =>
                   sPosts.length > 0 && (
                     <>
-                      <div class="my-1 text-muted small font-weight-bold">
+                      <div className="my-1 text-muted small font-weight-bold">
                         {i18n.t("related_posts")}
                       </div>
                       <PostListings
@@ -316,6 +339,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                         posts={sPosts}
                         enableDownvotes={this.props.enableDownvotes}
                         enableNsfw={this.props.enableNsfw}
+                        allLanguages={this.props.allLanguages}
                       />
                     </>
                   ),
@@ -324,33 +348,42 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
             </div>
           </div>
 
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label">{i18n.t("body")}</label>
-            <div class="col-sm-10">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label">{i18n.t("body")}</label>
+            <div className="col-sm-10">
               <MarkdownTextArea
                 initialContent={this.state.postForm.body}
+                initialLanguageId={None}
                 onContentChange={this.handlePostBodyChange}
                 placeholder={None}
                 buttonTitle={None}
                 maxLength={None}
+                allLanguages={this.props.allLanguages}
               />
             </div>
           </div>
           {this.props.post_view.isNone() && (
-            <div class="form-group row">
-              <label class="col-sm-2 col-form-label" htmlFor="post-community">
-                {i18n.t("community")}
+            <div className="form-group row">
+              <label
+                className="col-sm-2 col-form-label"
+                htmlFor="post-community"
+              >
+                {this.state.communitySearchLoading ? (
+                  <Spinner />
+                ) : (
+                  i18n.t("community")
+                )}
               </label>
-              <div class="col-sm-10">
+              <div className="col-sm-10">
                 <select
-                  class="form-control"
+                  className="form-control"
                   id="post-community"
                   value={this.state.postForm.community_id}
                   onInput={linkEvent(this, this.handlePostCommunityChange)}
                 >
                   <option>{i18n.t("select_a_community")}</option>
                   {this.props.communities.unwrapOr([]).map(cv => (
-                    <option value={cv.community.id}>
+                    <option key={cv.community.id} value={cv.community.id}>
                       {communitySelectName(cv)}
                     </option>
                   ))}
@@ -359,14 +392,14 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
             </div>
           )}
           {this.props.enableNsfw && (
-            <div class="form-group row">
-              <legend class="col-form-label col-sm-2 pt-0">
+            <div className="form-group row">
+              <legend className="col-form-label col-sm-2 pt-0">
                 {i18n.t("nsfw")}
               </legend>
-              <div class="col-sm-10">
-                <div class="form-check">
+              <div className="col-sm-10">
+                <div className="form-check">
                   <input
-                    class="form-check-input position-static"
+                    className="form-check-input position-static"
                     id="post-nsfw"
                     type="checkbox"
                     checked={toUndefined(this.state.postForm.nsfw)}
@@ -376,24 +409,30 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               </div>
             </div>
           )}
+          <LanguageSelect
+            allLanguages={this.props.allLanguages}
+            selectedLanguageIds={selectedLangs}
+            multiple={false}
+            onChange={this.handleLanguageChange}
+          />
           <input
             tabIndex={-1}
             autoComplete="false"
             name="a_password"
             type="text"
-            class="form-control honeypot"
+            className="form-control honeypot"
             id="register-honey"
             value={toUndefined(this.state.postForm.honeypot)}
             onInput={linkEvent(this, this.handleHoneyPotChange)}
           />
-          <div class="form-group row">
-            <div class="col-sm-10">
+          <div className="form-group row">
+            <div className="col-sm-10">
               <button
                 disabled={
                   !this.state.postForm.community_id || this.state.loading
                 }
                 type="submit"
-                class="btn btn-secondary mr-2"
+                className="btn btn-secondary mr-2"
               >
                 {this.state.loading ? (
                   <Spinner />
@@ -406,7 +445,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               {this.props.post_view.isSome() && (
                 <button
                   type="button"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(this, this.handleCancel)}
                 >
                   {i18n.t("cancel")}
@@ -422,12 +461,14 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
   handlePostSubmit(i: PostForm, event: any) {
     event.preventDefault();
 
+    i.setState({ loading: true });
+
     // Coerce empty url string to undefined
     if (
       i.state.postForm.url.isSome() &&
       i.state.postForm.url.unwrapOr("blank") === ""
     ) {
-      i.state.postForm.url = None;
+      i.setState(s => ((s.postForm.url = None), s));
     }
 
     let pForm = i.state.postForm;
@@ -439,37 +480,39 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
           body: pForm.body,
           nsfw: pForm.nsfw,
           post_id: pv.post.id,
+          language_id: Some(pv.post.language_id),
           auth: auth().unwrap(),
         });
         WebSocketService.Instance.send(wsClient.editPost(form));
       },
       none: () => {
-        i.state.postForm.auth = auth().unwrap();
-        WebSocketService.Instance.send(wsClient.createPost(i.state.postForm));
+        i.setState(s => ((s.postForm.auth = auth().unwrap()), s));
+        let form = new CreatePost({ ...i.state.postForm });
+        WebSocketService.Instance.send(wsClient.createPost(form));
       },
     });
-    i.state.loading = true;
-    i.setState(i.state);
   }
 
   copySuggestedTitle(i: PostForm) {
     i.state.suggestedTitle.match({
       some: sTitle => {
-        i.state.postForm.name = sTitle.substring(0, MAX_POST_TITLE_LENGTH);
-        i.state.suggestedTitle = None;
+        i.setState(
+          s => (
+            (s.postForm.name = sTitle.substring(0, MAX_POST_TITLE_LENGTH)), s
+          )
+        );
+        i.setState({ suggestedTitle: None });
         setTimeout(() => {
           let textarea: any = document.getElementById("post-title");
           autosize.update(textarea);
         }, 10);
-        i.setState(i.state);
       },
       none: void 0,
     });
   }
 
   handlePostUrlChange(i: PostForm, event: any) {
-    i.state.postForm.url = Some(event.target.value);
-    i.setState(i.state);
+    i.setState(s => ((s.postForm.url = Some(event.target.value)), s));
     i.fetchPageTitle();
   }
 
@@ -494,12 +537,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
 
           // Fetch the page title
           getSiteMetadata(url).then(d => {
-            this.state.suggestedTitle = d.metadata.title;
-            this.setState(this.state);
+            this.setState({ suggestedTitle: d.metadata.title });
           });
         } else {
-          this.state.suggestedTitle = None;
-          this.state.crossPosts = None;
+          this.setState({ suggestedTitle: None, crossPosts: None });
         }
       },
       none: void 0,
@@ -507,8 +548,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
   }
 
   handlePostNameChange(i: PostForm, event: any) {
-    i.state.postForm.name = event.target.value;
-    i.setState(i.state);
+    i.setState(s => ((s.postForm.name = event.target.value), s));
     i.fetchSimilarPosts();
   }
 
@@ -529,30 +569,30 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     if (this.state.postForm.name !== "") {
       WebSocketService.Instance.send(wsClient.search(form));
     } else {
-      this.state.suggestedPosts = None;
+      this.setState({ suggestedPosts: None });
     }
-
-    this.setState(this.state);
   }
 
   handlePostBodyChange(val: string) {
-    this.state.postForm.body = Some(val);
-    this.setState(this.state);
+    this.setState(s => ((s.postForm.body = Some(val)), s));
   }
 
   handlePostCommunityChange(i: PostForm, event: any) {
-    i.state.postForm.community_id = Number(event.target.value);
-    i.setState(i.state);
+    i.setState(
+      s => ((s.postForm.community_id = Number(event.target.value)), s)
+    );
   }
 
   handlePostNsfwChange(i: PostForm, event: any) {
-    i.state.postForm.nsfw = Some(event.target.checked);
-    i.setState(i.state);
+    i.setState(s => ((s.postForm.nsfw = Some(event.target.checked)), s));
+  }
+
+  handleLanguageChange(val: number[]) {
+    this.setState(s => ((s.postForm.language_id = Some(val[0])), s));
   }
 
   handleHoneyPotChange(i: PostForm, event: any) {
-    i.state.postForm.honeypot = Some(event.target.value);
-    i.setState(i.state);
+    i.setState(s => ((s.postForm.honeypot = Some(event.target.value)), s));
   }
 
   handleCancel(i: PostForm) {
@@ -561,8 +601,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
 
   handlePreviewToggle(i: PostForm, event: any) {
     event.preventDefault();
-    i.state.previewMode = !i.state.previewMode;
-    i.setState(i.state);
+    i.setState({ previewMode: !i.state.previewMode });
   }
 
   handleImageUploadPaste(i: PostForm, event: any) {
@@ -584,8 +623,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     const formData = new FormData();
     formData.append("images[]", file);
 
-    i.state.imageLoading = true;
-    i.setState(i.state);
+    i.setState({ imageLoading: true });
 
     fetch(pictrsUri, {
       method: "POST",
@@ -601,22 +639,19 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
           let deleteToken = res.files[0].delete_token;
           let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`;
           i.state.postForm.url = Some(url);
-          i.state.imageLoading = false;
-          i.setState(i.state);
+          i.setState({ imageLoading: false });
           pictrsDeleteToast(
             i18n.t("click_to_delete_picture"),
             i18n.t("picture_deleted"),
             deleteUrl
           );
         } else {
-          i.state.imageLoading = false;
-          i.setState(i.state);
+          i.setState({ imageLoading: false });
           toast(JSON.stringify(res), "danger");
         }
       })
       .catch(error => {
-        i.state.imageLoading = false;
-        i.setState(i.state);
+        i.setState({ imageLoading: false });
         console.error(error);
         toast(error, "danger");
       });
@@ -631,11 +666,17 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
         this.choices.passedElement.element.addEventListener(
           "choice",
           (e: any) => {
-            this.state.postForm.community_id = Number(e.detail.choice.value);
-            this.setState(this.state);
+            this.setState(
+              s => (
+                (s.postForm.community_id = Number(e.detail.choice.value)), s
+              )
+            );
           },
           false
         );
+        this.choices.passedElement.element.addEventListener("search", () => {
+          this.setState({ communitySearchLoading: true });
+        });
         this.choices.passedElement.element.addEventListener(
           "search",
           debounce(async (e: any) => {
@@ -648,6 +689,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                 "label",
                 true
               );
+              this.setState({ communitySearchLoading: false });
             } catch (err) {
               console.log(err);
             }
@@ -658,7 +700,8 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     }
 
     this.props.post_view.match({
-      some: pv => (this.state.postForm.community_id = pv.community.id),
+      some: pv =>
+        this.setState(s => ((s.postForm.community_id = pv.community.id), s)),
       none: void 0,
     });
     this.props.params.match({
@@ -670,9 +713,12 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                 let foundCommunityId = this.props.communities
                   .unwrapOr([])
                   .find(r => r.community.name == name).community.id;
-                this.state.postForm.community_id = foundCommunityId;
+                this.setState(
+                  s => ((s.postForm.community_id = foundCommunityId), s)
+                );
               },
-              right: id => (this.state.postForm.community_id = id),
+              right: id =>
+                this.setState(s => ((s.postForm.community_id = id), s)),
             }),
           none: void 0,
         }),
@@ -693,15 +739,13 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     if (msg.error) {
       // Errors handled by top level pages
       // toast(i18n.t(msg.error), "danger");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (op == UserOperation.CreatePost) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
       UserService.Instance.myUserInfo.match({
         some: mui => {
           if (data.post_view.creator.id == mui.local_user_view.person.id) {
-            this.state.loading = false;
             this.props.onCreate(data.post_view);
           }
         },
@@ -712,7 +756,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
       UserService.Instance.myUserInfo.match({
         some: mui => {
           if (data.post_view.creator.id == mui.local_user_view.person.id) {
-            this.state.loading = false;
+            this.setState({ loading: false });
             this.props.onEdit(data.post_view);
           }
         },
@@ -722,11 +766,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
       let data = wsJsonToRes<SearchResponse>(msg, SearchResponse);
 
       if (data.type_ == SearchType[SearchType.Posts]) {
-        this.state.suggestedPosts = Some(data.posts);
+        this.setState({ suggestedPosts: Some(data.posts) });
       } else if (data.type_ == SearchType[SearchType.Url]) {
-        this.state.crossPosts = Some(data.posts);
+        this.setState({ crossPosts: Some(data.posts) });
       }
-      this.setState(this.state);
     }
   }
 }
index 672d3d6925d28a13d245c29eeaaaf158dcdd1994..c14ea2f41edb3d97332aa0ef81f1c5465b5e90c4 100644 (file)
@@ -12,6 +12,7 @@ import {
   CreatePostLike,
   CreatePostReport,
   DeletePost,
+  Language,
   LockPost,
   PersonViewSafe,
   PostView,
@@ -88,6 +89,7 @@ interface PostListingProps {
   duplicates: Option<PostView[]>;
   moderators: Option<CommunityModeratorView[]>;
   admins: Option<PersonViewSafe[]>;
+  allLanguages: Language[];
   showCommunity?: boolean;
   showBody?: boolean;
   enableDownvotes?: boolean;
@@ -135,20 +137,21 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   componentWillReceiveProps(nextProps: PostListingProps) {
-    this.state.my_vote = nextProps.post_view.my_vote;
-    this.state.upvotes = nextProps.post_view.counts.upvotes;
-    this.state.downvotes = nextProps.post_view.counts.downvotes;
-    this.state.score = nextProps.post_view.counts.score;
+    this.setState({
+      my_vote: nextProps.post_view.my_vote,
+      upvotes: nextProps.post_view.counts.upvotes,
+      downvotes: nextProps.post_view.counts.downvotes,
+      score: nextProps.post_view.counts.score,
+    });
     if (this.props.post_view.post.id !== nextProps.post_view.post.id) {
-      this.state.imageExpanded = false;
+      this.setState({ imageExpanded: false });
     }
-    this.setState(this.state);
   }
 
   render() {
     let post = this.props.post_view.post;
     return (
-      <div class="post-listing">
+      <div className="post-listing">
         {!this.state.showEdit ? (
           <>
             {this.listing()}
@@ -159,7 +162,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             {this.showBody && this.body()}
           </>
         ) : (
-          <div class="col-12">
+          <div className="col-12">
             <PostForm
               post_view={Some(this.props.post_view)}
               communities={None}
@@ -168,6 +171,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               onCancel={this.handleEditCancel}
               enableNsfw={this.props.enableNsfw}
               enableDownvotes={this.props.enableDownvotes}
+              allLanguages={this.props.allLanguages}
             />
           </div>
         )}
@@ -178,7 +182,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   body() {
     return this.props.post_view.post.body.match({
       some: body => (
-        <div class="col-12 card my-2 p-2">
+        <div className="col-12 card my-2 p-2">
           {this.state.viewSource ? (
             <pre>{body}</pre>
           ) : (
@@ -194,14 +198,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     return this.imageSrc.match({
       some: src => (
         <>
-          <div class="offset-sm-3 my-2 d-none d-sm-block">
-            <a href={src} class="d-inline-block">
+          <div className="offset-sm-3 my-2 d-none d-sm-block">
+            <a href={src} className="d-inline-block">
               <PictrsImage src={src} />
             </a>
           </div>
           <div className="my-2 d-block d-sm-none">
             <a
-              class="d-inline-block"
+              className="d-inline-block"
               onClick={linkEvent(this, this.handleImageExpandClick)}
             >
               <PictrsImage src={src} />
@@ -254,7 +258,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       return (
         <a
           href={this.imageSrc.unwrap()}
-          class="text-body d-inline-block position-relative mb-2"
+          className="text-body d-inline-block position-relative mb-2"
           data-tippy-content={i18n.t("expand_here")}
           onClick={linkEvent(this, this.handleImageExpandClick)}
           aria-label={i18n.t("expand_here")}
@@ -266,7 +270,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     } else if (url.isSome() && thumbnail.isSome()) {
       return (
         <a
-          class="text-body d-inline-block position-relative mb-2"
+          className="text-body d-inline-block position-relative mb-2"
           href={url.unwrap()}
           rel={relTags}
           title={url.unwrap()}
@@ -278,13 +282,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     } else if (url.isSome()) {
       if (isVideo(url.unwrap())) {
         return (
-          <div class="embed-responsive embed-responsive-16by9">
+          <div className="embed-responsive embed-responsive-16by9">
             <video
-              playsinline
+              playsInline
               muted
               loop
               controls
-              class="embed-responsive-item"
+              className="embed-responsive-item"
             >
               <source src={url.unwrap()} type="video/mp4" />
             </video>
@@ -298,7 +302,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             title={url.unwrap()}
             rel={relTags}
           >
-            <div class="thumbnail rounded bg-light d-flex justify-content-center">
+            <div className="thumbnail rounded bg-light d-flex justify-content-center">
               <Icon icon="external-link" classes="d-flex align-items-center" />
             </div>
           </a>
@@ -311,7 +315,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           to={`/post/${post.id}`}
           title={i18n.t("comments")}
         >
-          <div class="thumbnail rounded bg-light d-flex justify-content-center">
+          <div className="thumbnail rounded bg-light d-flex justify-content-center">
             <Icon icon="message-square" classes="d-flex align-items-center" />
           </div>
         </Link>
@@ -322,7 +326,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   createdLine() {
     let post_view = this.props.post_view;
     return (
-      <ul class="list-inline mb-1 text-muted small">
+      <ul className="list-inline mb-1 text-muted small">
         <li className="list-inline-item">
           <PersonListing person={post_view.creator} />
 
@@ -346,7 +350,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           )}
           {this.props.showCommunity && (
             <span>
-              <span class="mx-1"> {i18n.t("to")} </span>
+              <span className="mx-1"> {i18n.t("to")} </span>
               <CommunityLink community={post_view.community} />
             </span>
           )}
@@ -416,13 +420,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         </button>
         {showScores() ? (
           <div
-            class={`unselectable pointer font-weight-bold text-muted px-1`}
+            className={`unselectable pointer font-weight-bold text-muted px-1`}
             data-tippy-content={this.pointsTippy}
           >
             {numToSI(this.state.score)}
           </div>
         ) : (
-          <div class="p-1"></div>
+          <div className="p-1"></div>
         )}
         {this.props.enableDownvotes && (
           <button
@@ -470,7 +474,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           })}
           {post.url.map(isImage).or(post.thumbnail_url).unwrapOr(false) && (
             <button
-              class="btn btn-link text-monospace text-muted small d-inline-block ml-2"
+              className="btn btn-link text-monospace text-muted small d-inline-block ml-2"
               data-tippy-content={i18n.t("expand_here")}
               onClick={linkEvent(this, this.handleImageExpandClick)}
             >
@@ -525,13 +529,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     return this.props.duplicates.match({
       some: dupes =>
         dupes.length > 0 && (
-          <ul class="list-inline mb-1 small text-muted">
+          <ul className="list-inline mb-1 small text-muted">
             <>
               <li className="list-inline-item mr-2">
                 {i18n.t("cross_posted_to")}
               </li>
               {dupes.map(pv => (
-                <li className="list-inline-item mr-2">
+                <li key={pv.post.id} className="list-inline-item mr-2">
                   <Link to={`/post/${pv.post.id}`}>
                     {pv.community.local
                       ? pv.community.name
@@ -551,7 +555,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   commentsLine(mobile = false) {
     let post = this.props.post_view.post;
     return (
-      <div class="d-flex justify-content-start flex-wrap text-muted font-weight-bold mb-1">
+      <div className="d-flex justify-content-start flex-wrap text-muted font-weight-bold mb-1">
         {this.commentsButton}
         {!post.local && (
           <a
@@ -617,7 +621,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get commentsButton() {
     let post_view = this.props.post_view;
     return (
-      <button class="btn btn-link text-muted py-0 pl-0">
+      <button className="btn btn-link text-muted py-0 pl-0">
         <Link
           className="text-muted"
           title={i18n.t("number_of_comments", {
@@ -627,15 +631,34 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           to={`/post/${post_view.post.id}?scrollToComments=true`}
         >
           <Icon icon="message-square" classes="mr-1" inline />
-          {i18n.t("number_of_comments", {
-            count: post_view.counts.comments,
-            formattedCount: numToSI(post_view.counts.comments),
+          <span className="mr-2">
+            {i18n.t("number_of_comments", {
+              count: post_view.counts.comments,
+              formattedCount: numToSI(post_view.counts.comments),
+            })}
+          </span>
+          {this.unreadCount.match({
+            some: unreadCount => (
+              <span className="small text-warning">
+                ({unreadCount} {i18n.t("new")})
+              </span>
+            ),
+            none: <></>,
           })}
         </Link>
       </button>
     );
   }
 
+  get unreadCount(): Option<number> {
+    let pv = this.props.post_view;
+    if (pv.unread_comments == pv.counts.comments || pv.unread_comments == 0) {
+      return None;
+    } else {
+      return Some(pv.unread_comments);
+    }
+  }
+
   get mobileVotes() {
     // TODO: make nicer
     let tippy = showScores() ? { "data-tippy-content": this.pointsTippy } : {};
@@ -652,7 +675,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           >
             <Icon icon="arrow-up1" classes="icon-inline small" />
             {showScores() && (
-              <span class="ml-2">{numToSI(this.state.upvotes)}</span>
+              <span className="ml-2">{numToSI(this.state.upvotes)}</span>
             )}
           </button>
           {this.props.enableDownvotes && (
@@ -669,7 +692,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               <Icon icon="arrow-down1" classes="icon-inline small" />
               {showScores() && (
                 <span
-                  class={classNames("ml-2", {
+                  className={classNames("ml-2", {
                     invisible: this.state.downvotes === 0,
                   })}
                 >
@@ -688,7 +711,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let label = saved ? i18n.t("unsave") : i18n.t("save");
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleSavePostClick)}
         data-tippy-content={label}
         aria-label={label}
@@ -717,7 +740,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get reportButton() {
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleShowReportDialog)}
         data-tippy-content={i18n.t("show_report_dialog")}
         aria-label={i18n.t("show_report_dialog")}
@@ -730,7 +753,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get blockButton() {
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleBlockUserClick)}
         data-tippy-content={i18n.t("block_user")}
         aria-label={i18n.t("block_user")}
@@ -743,7 +766,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get editButton() {
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleEditClick)}
         data-tippy-content={i18n.t("edit")}
         aria-label={i18n.t("edit")}
@@ -758,7 +781,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let label = !deleted ? i18n.t("delete") : i18n.t("restore");
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleDeleteClick)}
         data-tippy-content={label}
         aria-label={label}
@@ -775,7 +798,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get showMoreButton() {
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleShowAdvanced)}
         data-tippy-content={i18n.t("more")}
         aria-label={i18n.t("more")}
@@ -788,7 +811,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   get viewSourceButton() {
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleViewSource)}
         data-tippy-content={i18n.t("view_source")}
         aria-label={i18n.t("view_source")}
@@ -807,7 +830,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let label = locked ? i18n.t("unlock") : i18n.t("lock");
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleModLock)}
         data-tippy-content={label}
         aria-label={label}
@@ -826,7 +849,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let label = stickied ? i18n.t("unsticky") : i18n.t("sticky");
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(this, this.handleModSticky)}
         data-tippy-content={label}
         aria-label={label}
@@ -844,7 +867,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let removed = this.props.post_view.post.removed;
     return (
       <button
-        class="btn btn-link btn-animate text-muted py-0"
+        className="btn btn-link btn-animate text-muted py-0"
         onClick={linkEvent(
           this,
           !removed ? this.handleModRemoveShow : this.handleModRemoveSubmit
@@ -870,7 +893,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               {!this.creatorIsMod_ &&
                 (!post_view.creator_banned_from_community ? (
                   <button
-                    class="btn btn-link btn-animate text-muted py-0"
+                    className="btn btn-link btn-animate text-muted py-0"
                     onClick={linkEvent(
                       this,
                       this.handleModBanFromCommunityShow
@@ -881,7 +904,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                   </button>
                 ) : (
                   <button
-                    class="btn btn-link btn-animate text-muted py-0"
+                    className="btn btn-link btn-animate text-muted py-0"
                     onClick={linkEvent(
                       this,
                       this.handleModBanFromCommunitySubmit
@@ -893,7 +916,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                 ))}
               {!post_view.creator_banned_from_community && (
                 <button
-                  class="btn btn-link btn-animate text-muted py-0"
+                  className="btn btn-link btn-animate text-muted py-0"
                   onClick={linkEvent(this, this.handleAddModToCommunity)}
                   aria-label={
                     this.creatorIsMod_
@@ -914,7 +937,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             this.creatorIsMod_ &&
             (!this.state.showConfirmTransferCommunity ? (
               <button
-                class="btn btn-link btn-animate text-muted py-0"
+                className="btn btn-link btn-animate text-muted py-0"
                 onClick={linkEvent(
                   this,
                   this.handleShowConfirmTransferCommunity
@@ -926,20 +949,20 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             ) : (
               <>
                 <button
-                  class="d-inline-block mr-1 btn btn-link btn-animate text-muted py-0"
+                  className="d-inline-block mr-1 btn btn-link btn-animate text-muted py-0"
                   aria-label={i18n.t("are_you_sure")}
                 >
                   {i18n.t("are_you_sure")}
                 </button>
                 <button
-                  class="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1"
+                  className="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1"
                   aria-label={i18n.t("yes")}
                   onClick={linkEvent(this, this.handleTransferCommunity)}
                 >
                   {i18n.t("yes")}
                 </button>
                 <button
-                  class="btn btn-link btn-animate text-muted py-0 d-inline-block"
+                  className="btn btn-link btn-animate text-muted py-0 d-inline-block"
                   onClick={linkEvent(
                     this,
                     this.handleCancelShowConfirmTransferCommunity
@@ -957,7 +980,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                 <>
                   {!isBanned(post_view.creator) ? (
                     <button
-                      class="btn btn-link btn-animate text-muted py-0"
+                      className="btn btn-link btn-animate text-muted py-0"
                       onClick={linkEvent(this, this.handleModBanShow)}
                       aria-label={i18n.t("ban_from_site")}
                     >
@@ -965,7 +988,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                     </button>
                   ) : (
                     <button
-                      class="btn btn-link btn-animate text-muted py-0"
+                      className="btn btn-link btn-animate text-muted py-0"
                       onClick={linkEvent(this, this.handleModBanSubmit)}
                       aria-label={i18n.t("unban_from_site")}
                     >
@@ -973,14 +996,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                     </button>
                   )}
                   <button
-                    class="btn btn-link btn-animate text-muted py-0"
+                    className="btn btn-link btn-animate text-muted py-0"
                     onClick={linkEvent(this, this.handlePurgePersonShow)}
                     aria-label={i18n.t("purge_user")}
                   >
                     {i18n.t("purge_user")}
                   </button>
                   <button
-                    class="btn btn-link btn-animate text-muted py-0"
+                    className="btn btn-link btn-animate text-muted py-0"
                     onClick={linkEvent(this, this.handlePurgePostShow)}
                     aria-label={i18n.t("purge_post")}
                   >
@@ -990,7 +1013,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               )}
               {!isBanned(post_view.creator) && post_view.creator.local && (
                 <button
-                  class="btn btn-link btn-animate text-muted py-0"
+                  className="btn btn-link btn-animate text-muted py-0"
                   onClick={linkEvent(this, this.handleAddAdmin)}
                   aria-label={
                     this.creatorIsAdmin_
@@ -1022,23 +1045,23 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       <>
         {this.state.showRemoveDialog && (
           <form
-            class="form-inline"
+            className="form-inline"
             onSubmit={linkEvent(this, this.handleModRemoveSubmit)}
           >
-            <label class="sr-only" htmlFor="post-listing-remove-reason">
+            <label className="sr-only" htmlFor="post-listing-remove-reason">
               {i18n.t("reason")}
             </label>
             <input
               type="text"
               id="post-listing-remove-reason"
-              class="form-control mr-2"
+              className="form-control mr-2"
               placeholder={i18n.t("reason")}
               value={toUndefined(this.state.removeReason)}
               onInput={linkEvent(this, this.handleModRemoveReasonChange)}
             />
             <button
               type="submit"
-              class="btn btn-secondary"
+              className="btn btn-secondary"
               aria-label={i18n.t("remove_post")}
             >
               {i18n.t("remove_post")}
@@ -1047,40 +1070,43 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         )}
         {this.state.showBanDialog && (
           <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
-            <div class="form-group row col-12">
-              <label class="col-form-label" htmlFor="post-listing-ban-reason">
+            <div className="form-group row col-12">
+              <label
+                className="col-form-label"
+                htmlFor="post-listing-ban-reason"
+              >
                 {i18n.t("reason")}
               </label>
               <input
                 type="text"
                 id="post-listing-ban-reason"
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("reason")}
                 value={toUndefined(this.state.banReason)}
                 onInput={linkEvent(this, this.handleModBanReasonChange)}
               />
-              <label class="col-form-label" htmlFor={`mod-ban-expires`}>
+              <label className="col-form-label" htmlFor={`mod-ban-expires`}>
                 {i18n.t("expires")}
               </label>
               <input
                 type="number"
                 id={`mod-ban-expires`}
-                class="form-control mr-2"
+                className="form-control mr-2"
                 placeholder={i18n.t("number_of_days")}
                 value={toUndefined(this.state.banExpireDays)}
                 onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
               />
-              <div class="form-group">
-                <div class="form-check">
+              <div className="form-group">
+                <div className="form-check">
                   <input
-                    class="form-check-input"
+                    className="form-check-input"
                     id="mod-ban-remove-data"
                     type="checkbox"
                     checked={this.state.removeData}
                     onChange={linkEvent(this, this.handleModRemoveDataChange)}
                   />
                   <label
-                    class="form-check-label"
+                    className="form-check-label"
                     htmlFor="mod-ban-remove-data"
                     title={i18n.t("remove_content_more")}
                   >
@@ -1094,10 +1120,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             {/*   <label class="col-form-label">Expires</label> */}
             {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
             {/* </div> */}
-            <div class="form-group row">
+            <div className="form-group row">
               <button
                 type="submit"
-                class="btn btn-secondary"
+                className="btn btn-secondary"
                 aria-label={i18n.t("ban")}
               >
                 {i18n.t("ban")} {post.creator.name}
@@ -1107,16 +1133,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         )}
         {this.state.showReportDialog && (
           <form
-            class="form-inline"
+            className="form-inline"
             onSubmit={linkEvent(this, this.handleReportSubmit)}
           >
-            <label class="sr-only" htmlFor="post-report-reason">
+            <label className="sr-only" htmlFor="post-report-reason">
               {i18n.t("reason")}
             </label>
             <input
               type="text"
               id="post-report-reason"
-              class="form-control mr-2"
+              className="form-control mr-2"
               placeholder={i18n.t("reason")}
               required
               value={toUndefined(this.state.reportReason)}
@@ -1124,7 +1150,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             />
             <button
               type="submit"
-              class="btn btn-secondary"
+              className="btn btn-secondary"
               aria-label={i18n.t("create_report")}
             >
               {i18n.t("create_report")}
@@ -1133,17 +1159,17 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         )}
         {this.state.showPurgeDialog && (
           <form
-            class="form-inline"
+            className="form-inline"
             onSubmit={linkEvent(this, this.handlePurgeSubmit)}
           >
             <PurgeWarning />
-            <label class="sr-only" htmlFor="purge-reason">
+            <label className="sr-only" htmlFor="purge-reason">
               {i18n.t("reason")}
             </label>
             <input
               type="text"
               id="purge-reason"
-              class="form-control mr-2"
+              className="form-control mr-2"
               placeholder={i18n.t("reason")}
               value={toUndefined(this.state.purgeReason)}
               onInput={linkEvent(this, this.handlePurgeReasonChange)}
@@ -1153,7 +1179,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             ) : (
               <button
                 type="submit"
-                class="btn btn-secondary"
+                className="btn btn-secondary"
                 aria-label={purgeTypeText}
               >
                 {purgeTypeText}
@@ -1169,11 +1195,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let post = this.props.post_view.post;
     return post.thumbnail_url.isSome() ||
       post.url.map(isImage).unwrapOr(false) ? (
-      <div class="row">
+      <div className="row">
         <div className={`${this.state.imageExpanded ? "col-12" : "col-8"}`}>
           {this.postTitleLine()}
         </div>
-        <div class="col-4">
+        <div className="col-4">
           {/* Post body prev or thumbnail */}
           {!this.state.imageExpanded && this.thumbnail()}
         </div>
@@ -1198,9 +1224,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     return (
       <>
         {/* The mobile view*/}
-        <div class="d-block d-sm-none">
-          <div class="row">
-            <div class="col-12">
+        <div className="d-block d-sm-none">
+          <div className="row">
+            <div className="col-12">
               {this.createdLine()}
 
               {/* If it has a thumbnail, do a right aligned thumbnail */}
@@ -1218,14 +1244,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         </div>
 
         {/* The larger view*/}
-        <div class="d-none d-sm-block">
-          <div class="row">
+        <div className="d-none d-sm-block">
+          <div className="row">
             {!this.props.viewOnly && this.voteBar()}
-            <div class="col-sm-2 pr-0">
-              <div class="">{this.thumbnail()}</div>
+            <div className="col-sm-2 pr-0">
+              <div className="">{this.thumbnail()}</div>
             </div>
-            <div class="col-12 col-sm-9">
-              <div class="row">
+            <div className="col-12 col-sm-9">
+              <div className="row">
                 <div className="col-12">
                   {this.postTitleLine()}
                   {this.createdLine()}
@@ -1260,18 +1286,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let newVote = myVote == 1 ? 0 : 1;
 
     if (myVote == 1) {
-      this.state.score--;
-      this.state.upvotes--;
+      this.setState({
+        score: this.state.score - 1,
+        upvotes: this.state.upvotes - 1,
+      });
     } else if (myVote == -1) {
-      this.state.downvotes--;
-      this.state.upvotes++;
-      this.state.score += 2;
+      this.setState({
+        score: this.state.score + 2,
+        upvotes: this.state.upvotes + 1,
+        downvotes: this.state.downvotes - 1,
+      });
     } else {
-      this.state.upvotes++;
-      this.state.score++;
+      this.setState({
+        score: this.state.score + 1,
+        upvotes: this.state.upvotes + 1,
+      });
     }
 
-    this.state.my_vote = Some(newVote);
+    this.setState({ my_vote: Some(newVote) });
 
     let form = new CreatePostLike({
       post_id: this.props.post_view.post.id,
@@ -1294,18 +1326,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let newVote = myVote == -1 ? 0 : -1;
 
     if (myVote == 1) {
-      this.state.score -= 2;
-      this.state.upvotes--;
-      this.state.downvotes++;
+      this.setState({
+        score: this.state.score - 2,
+        upvotes: this.state.upvotes - 1,
+        downvotes: this.state.downvotes + 1,
+      });
     } else if (myVote == -1) {
-      this.state.downvotes--;
-      this.state.score++;
+      this.setState({
+        score: this.state.score + 1,
+        downvotes: this.state.downvotes - 1,
+      });
     } else {
-      this.state.downvotes++;
-      this.state.score--;
+      this.setState({
+        score: this.state.score - 1,
+        downvotes: this.state.downvotes + 1,
+      });
     }
 
-    this.state.my_vote = Some(newVote);
+    this.setState({ my_vote: Some(newVote) });
 
     let form = new CreatePostLike({
       post_id: this.props.post_view.post.id,
@@ -1319,29 +1357,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   handleEditClick(i: PostListing) {
-    i.state.showEdit = true;
-    i.setState(i.state);
+    i.setState({ showEdit: true });
   }
 
   handleEditCancel() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   // The actual editing is done in the recieve for post
   handleEditPost() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   handleShowReportDialog(i: PostListing) {
-    i.state.showReportDialog = !i.state.showReportDialog;
-    i.setState(this.state);
+    i.setState({ showReportDialog: !i.state.showReportDialog });
   }
 
   handleReportReasonChange(i: PostListing, event: any) {
-    i.state.reportReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ reportReason: Some(event.target.value) });
   }
 
   handleReportSubmit(i: PostListing, event: any) {
@@ -1353,8 +1386,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     });
     WebSocketService.Instance.send(wsClient.createPostReport(form));
 
-    i.state.showReportDialog = false;
-    i.setState(i.state);
+    i.setState({ showReportDialog: false });
   }
 
   handleBlockUserClick(i: PostListing) {
@@ -1413,19 +1445,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   handleModRemoveShow(i: PostListing) {
-    i.state.showRemoveDialog = !i.state.showRemoveDialog;
-    i.state.showBanDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showRemoveDialog: !i.state.showRemoveDialog,
+      showBanDialog: false,
+    });
   }
 
   handleModRemoveReasonChange(i: PostListing, event: any) {
-    i.state.removeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ removeReason: Some(event.target.value) });
   }
 
   handleModRemoveDataChange(i: PostListing, event: any) {
-    i.state.removeData = event.target.checked;
-    i.setState(i.state);
+    i.setState({ removeData: event.target.checked });
   }
 
   handleModRemoveSubmit(i: PostListing, event: any) {
@@ -1438,8 +1469,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     });
     WebSocketService.Instance.send(wsClient.removePost(form));
 
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({ showRemoveDialog: false });
   }
 
   handleModLock(i: PostListing) {
@@ -1461,36 +1491,39 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   handleModBanFromCommunityShow(i: PostListing) {
-    i.state.showBanDialog = true;
-    i.state.banType = BanType.Community;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showBanDialog: true,
+      banType: BanType.Community,
+      showRemoveDialog: false,
+    });
   }
 
   handleModBanShow(i: PostListing) {
-    i.state.showBanDialog = true;
-    i.state.banType = BanType.Site;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showBanDialog: true,
+      banType: BanType.Site,
+      showRemoveDialog: false,
+    });
   }
 
   handlePurgePersonShow(i: PostListing) {
-    i.state.showPurgeDialog = true;
-    i.state.purgeType = PurgeType.Person;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showPurgeDialog: true,
+      purgeType: PurgeType.Person,
+      showRemoveDialog: false,
+    });
   }
 
   handlePurgePostShow(i: PostListing) {
-    i.state.showPurgeDialog = true;
-    i.state.purgeType = PurgeType.Post;
-    i.state.showRemoveDialog = false;
-    i.setState(i.state);
+    i.setState({
+      showPurgeDialog: true,
+      purgeType: PurgeType.Post,
+      showRemoveDialog: false,
+    });
   }
 
   handlePurgeReasonChange(i: PostListing, event: any) {
-    i.state.purgeReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ purgeReason: Some(event.target.value) });
   }
 
   handlePurgeSubmit(i: PostListing, event: any) {
@@ -1512,29 +1545,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       WebSocketService.Instance.send(wsClient.purgePost(form));
     }
 
-    i.state.purgeLoading = true;
-    i.setState(i.state);
+    i.setState({ purgeLoading: true });
   }
 
   handleModBanReasonChange(i: PostListing, event: any) {
-    i.state.banReason = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ banReason: Some(event.target.value) });
   }
 
   handleModBanExpireDaysChange(i: PostListing, event: any) {
-    i.state.banExpireDays = Some(event.target.value);
-    i.setState(i.state);
+    i.setState({ banExpireDays: Some(event.target.value) });
   }
 
   handleModBanFromCommunitySubmit(i: PostListing) {
-    i.state.banType = BanType.Community;
-    i.setState(i.state);
+    i.setState({ banType: BanType.Community });
     i.handleModBanBothSubmit(i);
   }
 
   handleModBanSubmit(i: PostListing) {
-    i.state.banType = BanType.Site;
-    i.setState(i.state);
+    i.setState({ banType: BanType.Site });
     i.handleModBanBothSubmit(i);
   }
 
@@ -1545,7 +1573,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       // If its an unban, restore all their data
       let ban = !i.props.post_view.creator_banned_from_community;
       if (ban == false) {
-        i.state.removeData = false;
+        i.setState({ removeData: false });
       }
       let form = new BanFromCommunity({
         person_id: i.props.post_view.creator.id,
@@ -1561,7 +1589,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       // If its an unban, restore all their data
       let ban = !i.props.post_view.creator.banned;
       if (ban == false) {
-        i.state.removeData = false;
+        i.setState({ removeData: false });
       }
       let form = new BanPerson({
         person_id: i.props.post_view.creator.id,
@@ -1574,8 +1602,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       WebSocketService.Instance.send(wsClient.banPerson(form));
     }
 
-    i.state.showBanDialog = false;
-    i.setState(i.state);
+    i.setState({ showBanDialog: false });
   }
 
   handleAddModToCommunity(i: PostListing) {
@@ -1600,13 +1627,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   handleShowConfirmTransferCommunity(i: PostListing) {
-    i.state.showConfirmTransferCommunity = true;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: true });
   }
 
   handleCancelShowConfirmTransferCommunity(i: PostListing) {
-    i.state.showConfirmTransferCommunity = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: false });
   }
 
   handleTransferCommunity(i: PostListing) {
@@ -1616,48 +1641,42 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       auth: auth().unwrap(),
     });
     WebSocketService.Instance.send(wsClient.transferCommunity(form));
-    i.state.showConfirmTransferCommunity = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferCommunity: false });
   }
 
   handleShowConfirmTransferSite(i: PostListing) {
-    i.state.showConfirmTransferSite = true;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferSite: true });
   }
 
   handleCancelShowConfirmTransferSite(i: PostListing) {
-    i.state.showConfirmTransferSite = false;
-    i.setState(i.state);
+    i.setState({ showConfirmTransferSite: false });
   }
 
   handleImageExpandClick(i: PostListing, event: any) {
     event.preventDefault();
-    i.state.imageExpanded = !i.state.imageExpanded;
-    i.setState(i.state);
+    i.setState({ imageExpanded: !i.state.imageExpanded });
     setupTippy();
   }
 
   handleViewSource(i: PostListing) {
-    i.state.viewSource = !i.state.viewSource;
-    i.setState(i.state);
+    i.setState({ viewSource: !i.state.viewSource });
   }
 
   handleShowAdvanced(i: PostListing) {
-    i.state.showAdvanced = !i.state.showAdvanced;
-    i.setState(i.state);
+    i.setState({ showAdvanced: !i.state.showAdvanced });
     setupTippy();
   }
 
   handleShowMoreMobile(i: PostListing) {
-    i.state.showMoreMobile = !i.state.showMoreMobile;
-    i.state.showAdvanced = !i.state.showAdvanced;
-    i.setState(i.state);
+    i.setState({
+      showMoreMobile: !i.state.showMoreMobile,
+      showAdvanced: !i.state.showAdvanced,
+    });
     setupTippy();
   }
 
   handleShowBody(i: PostListing) {
-    i.state.showBody = !i.state.showBody;
-    i.setState(i.state);
+    i.setState({ showBody: !i.state.showBody });
     setupTippy();
   }
 
index a26d9d6d4483b3731753d16dcb11e1bfe2f81478..39d46a71a563ee897b47a8f105f272b361346a9d 100644 (file)
@@ -2,12 +2,13 @@ import { None, Some } from "@sniptt/monads";
 import { Component } from "inferno";
 import { T } from "inferno-i18next-dess";
 import { Link } from "inferno-router";
-import { PostView } from "lemmy-js-client";
+import { Language, PostView } from "lemmy-js-client";
 import { i18n } from "../../i18next";
 import { PostListing } from "./post-listing";
 
 interface PostListingsProps {
   posts: PostView[];
+  allLanguages: Language[];
   showCommunity?: boolean;
   removeDuplicates?: boolean;
   enableDownvotes: boolean;
@@ -41,8 +42,9 @@ export class PostListings extends Component<PostListingsProps, any> {
                 showCommunity={this.props.showCommunity}
                 enableDownvotes={this.props.enableDownvotes}
                 enableNsfw={this.props.enableNsfw}
+                allLanguages={this.props.allLanguages}
               />
-              <hr class="my-3" />
+              <hr className="my-3" />
             </>
           ))
         ) : (
index 220a5a9eefab8082726b34d55159db7a4711cbc0..b7110486de128410c00790b63a635d71e1015de5 100644 (file)
@@ -45,6 +45,7 @@ export class PostReport extends Component<PostReportProps, any> {
       read: false,
       creator_blocked: false,
       my_vote: r.my_vote,
+      unread_comments: 0,
     };
 
     return (
@@ -58,6 +59,7 @@ export class PostReport extends Component<PostReportProps, any> {
           enableDownvotes={true}
           enableNsfw={true}
           viewOnly={true}
+          allLanguages={[]}
         />
         <div>
           {i18n.t("reporter")}: <PersonListing person={r.creator} />
index 58cf71e8158150850fef8eef730f8733e5686081..a7ffad5831c1787b2a26c91064503536aebc5287 100644 (file)
@@ -120,28 +120,31 @@ export class Post extends Component<any, PostState> {
     super(props, context);
 
     this.state = this.emptyState;
-    this.state.commentSectionRef = createRef();
 
     this.parseMessage = this.parseMessage.bind(this);
     this.subscription = wsSubscribe(this.parseMessage);
 
+    this.state = { ...this.state, commentSectionRef: createRef() };
+
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.postRes = Some(this.isoData.routeData[0] as GetPostResponse);
-      this.state.commentsRes = Some(
-        this.isoData.routeData[1] as GetCommentsResponse
-      );
-
-      this.state.commentsRes.match({
-        some: res => {
-          this.state.commentTree = buildCommentsTree(
-            res.comments,
+      this.state = {
+        ...this.state,
+        postRes: Some(this.isoData.routeData[0] as GetPostResponse),
+        commentsRes: Some(this.isoData.routeData[1] as GetCommentsResponse),
+      };
+
+      if (this.state.commentsRes.isSome()) {
+        this.state = {
+          ...this.state,
+          commentTree: buildCommentsTree(
+            this.state.commentsRes.unwrap().comments,
             this.state.commentId.isSome()
-          );
-        },
-        none: void 0,
-      });
-      this.state.loading = false;
+          ),
+        };
+      }
+
+      this.state = { ...this.state, loading: false };
 
       if (isBrowser()) {
         WebSocketService.Instance.send(
@@ -305,8 +308,9 @@ export class Post extends Component<any, PostState> {
   trackCommentsBoxScrolling = () => {
     const wrappedElement = document.getElementsByClassName("comments")[0];
     if (wrappedElement && this.isBottom(wrappedElement)) {
-      this.state.maxCommentsShown += commentsShownInterval;
-      this.setState(this.state);
+      this.setState({
+        maxCommentsShown: this.state.maxCommentsShown + commentsShownInterval,
+      });
     }
   };
 
@@ -341,7 +345,7 @@ export class Post extends Component<any, PostState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         {this.state.loading ? (
           <h5>
             <Spinner large />
@@ -349,8 +353,8 @@ export class Post extends Component<any, PostState> {
         ) : (
           this.state.postRes.match({
             some: res => (
-              <div class="row">
-                <div class="col-12 col-md-8 mb-3">
+              <div className="row">
+                <div className="col-12 col-md-8 mb-3">
                   <HtmlTags
                     title={this.documentTitle}
                     path={this.context.router.route.match.url}
@@ -366,15 +370,17 @@ export class Post extends Component<any, PostState> {
                     admins={Some(this.state.siteRes.admins)}
                     enableDownvotes={enableDownvotes(this.state.siteRes)}
                     enableNsfw={enableNsfw(this.state.siteRes)}
+                    allLanguages={this.state.siteRes.all_languages}
                   />
                   <div ref={this.state.commentSectionRef} className="mb-2" />
                   <CommentForm
                     node={Right(res.post_view.post.id)}
                     disabled={res.post_view.post.locked}
+                    allLanguages={this.state.siteRes.all_languages}
                   />
-                  <div class="d-block d-md-none">
+                  <div className="d-block d-md-none">
                     <button
-                      class="btn btn-secondary d-inline-block mb-2 mr-3"
+                      className="btn btn-secondary d-inline-block mb-2 mr-3"
                       onClick={linkEvent(this, this.handleShowSidebarMobile)}
                     >
                       {i18n.t("sidebar")}{" "}
@@ -395,7 +401,9 @@ export class Post extends Component<any, PostState> {
                   {this.state.commentViewType == CommentViewType.Flat &&
                     this.commentsFlat()}
                 </div>
-                <div class="d-none d-md-block col-md-4">{this.sidebar()}</div>
+                <div className="d-none d-md-block col-md-4">
+                  {this.sidebar()}
+                </div>
               </div>
             ),
             none: <></>,
@@ -408,7 +416,7 @@ export class Post extends Component<any, PostState> {
   sortRadios() {
     return (
       <>
-        <div class="btn-group btn-group-toggle flex-wrap mr-3 mb-2">
+        <div className="btn-group btn-group-toggle flex-wrap mr-3 mb-2">
           <label
             className={`btn btn-outline-secondary pointer ${
               CommentSortType[this.state.commentSort] === CommentSortType.Hot &&
@@ -466,7 +474,7 @@ export class Post extends Component<any, PostState> {
             />
           </label>
         </div>
-        <div class="btn-group btn-group-toggle flex-wrap mb-2">
+        <div className="btn-group btn-group-toggle flex-wrap mb-2">
           <label
             className={`btn btn-outline-secondary pointer ${
               this.state.commentViewType === CommentViewType.Flat && "active"
@@ -502,6 +510,7 @@ export class Post extends Component<any, PostState> {
                 admins={Some(this.state.siteRes.admins)}
                 enableDownvotes={enableDownvotes(this.state.siteRes)}
                 showContext
+                allLanguages={this.state.siteRes.all_languages}
               />
             </div>
           ),
@@ -514,7 +523,7 @@ export class Post extends Component<any, PostState> {
   sidebar() {
     return this.state.postRes.match({
       some: res => (
-        <div class="mb-3">
+        <div className="mb-3">
           <Sidebar
             community_view={res.community_view}
             moderators={res.moderators}
@@ -530,25 +539,26 @@ export class Post extends Component<any, PostState> {
   }
 
   handleCommentSortChange(i: Post, event: any) {
-    i.state.commentSort = CommentSortType[event.target.value];
-    i.state.commentViewType = CommentViewType.Tree;
-    i.setState(i.state);
+    i.setState({
+      commentSort: CommentSortType[event.target.value],
+      commentViewType: CommentViewType.Tree,
+    });
     i.fetchPost();
   }
 
   handleCommentViewTypeChange(i: Post, event: any) {
-    i.state.commentViewType = Number(event.target.value);
-    i.state.commentSort = CommentSortType.New;
-    i.state.commentTree = buildCommentsTree(
-      i.state.commentsRes.map(r => r.comments).unwrapOr([]),
-      i.state.commentId.isSome()
-    );
-    i.setState(i.state);
+    i.setState({
+      commentViewType: Number(event.target.value),
+      commentSort: CommentSortType.New,
+      commentTree: buildCommentsTree(
+        i.state.commentsRes.map(r => r.comments).unwrapOr([]),
+        i.state.commentId.isSome()
+      ),
+    });
   }
 
   handleShowSidebarMobile(i: Post) {
-    i.state.showSidebarMobile = !i.state.showSidebarMobile;
-    i.setState(i.state);
+    i.setState({ showSidebarMobile: !i.state.showSidebarMobile });
   }
 
   handleViewPost(i: Post) {
@@ -581,14 +591,14 @@ export class Post extends Component<any, PostState> {
           {this.state.commentId.isSome() && (
             <>
               <button
-                class="pl-0 d-block btn btn-link text-muted"
+                className="pl-0 d-block btn btn-link text-muted"
                 onClick={linkEvent(this, this.handleViewPost)}
               >
                 {i18n.t("view_all_comments")} âž”
               </button>
               {showContextButton && (
                 <button
-                  class="pl-0 d-block btn btn-link text-muted"
+                  className="pl-0 d-block btn btn-link text-muted"
                   onClick={linkEvent(this, this.handleViewContext)}
                 >
                   {i18n.t("show_context")} âž”
@@ -604,6 +614,7 @@ export class Post extends Component<any, PostState> {
             moderators={Some(res.moderators)}
             admins={Some(this.state.siteRes.admins)}
             enableDownvotes={enableDownvotes(this.state.siteRes)}
+            allLanguages={this.state.siteRes.all_languages}
           />
         </div>
       ),
@@ -636,7 +647,7 @@ export class Post extends Component<any, PostState> {
       });
     } else if (op == UserOperation.GetPost) {
       let data = wsJsonToRes<GetPostResponse>(msg, GetPostResponse);
-      this.state.postRes = Some(data);
+      this.setState({ postRes: Some(data) });
 
       // join the rooms
       WebSocketService.Instance.send(
@@ -651,7 +662,6 @@ export class Post extends Component<any, PostState> {
       // Get cross-posts
       // TODO move this into initial fetch and refetch
       this.fetchCrossPosts();
-      this.setState(this.state);
       setupTippy();
       if (this.state.commentId.isNone()) restoreScrollPosition(this.context);
 
@@ -668,16 +678,16 @@ export class Post extends Component<any, PostState> {
           newComments.shift();
           res.comments.push(...newComments);
         },
-        none: () => {
-          this.state.commentsRes = Some(data);
-        },
+        none: () => this.setState({ commentsRes: Some(data) }),
       });
       // this.state.commentsRes = Some(data);
-      this.state.commentTree = buildCommentsTree(
-        this.state.commentsRes.map(r => r.comments).unwrapOr([]),
-        this.state.commentId.isSome()
-      );
-      this.state.loading = false;
+      this.setState({
+        commentTree: buildCommentsTree(
+          this.state.commentsRes.map(r => r.comments).unwrapOr([]),
+          this.state.commentId.isSome()
+        ),
+        loading: false,
+      });
       this.setState(this.state);
     } else if (op == UserOperation.CreateComment) {
       let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
@@ -827,19 +837,16 @@ export class Post extends Component<any, PostState> {
       });
     } else if (op == UserOperation.AddAdmin) {
       let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse);
-      this.state.siteRes.admins = data.admins;
-      this.setState(this.state);
+      this.setState(s => ((s.siteRes.admins = data.admins), s));
     } else if (op == UserOperation.Search) {
       let data = wsJsonToRes<SearchResponse>(msg, SearchResponse);
       let xPosts = data.posts.filter(
         p => p.post.id != Number(this.props.match.params.id)
       );
-      this.state.crossPosts = xPosts.length > 0 ? Some(xPosts) : None;
-      this.setState(this.state);
+      this.setState({ crossPosts: xPosts.length > 0 ? Some(xPosts) : None });
     } else if (op == UserOperation.LeaveAdmin) {
       let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse);
-      this.state.siteRes = data;
-      this.setState(this.state);
+      this.setState({ siteRes: data });
     } else if (op == UserOperation.TransferCommunity) {
       let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse);
       this.state.postRes.match({
index a93ba99ccf42a330a83dce42e90ab5166cb99e03..9cbe47a9f737d723825167036e2b9554f264726f 100644 (file)
@@ -45,6 +45,7 @@ export class CreatePrivateMessage extends Component<
     recipient_id: getRecipientIdFromProps(this.props),
     loading: true,
   };
+
   constructor(props: any, context: any) {
     super(props, context);
     this.state = this.emptyState;
@@ -61,10 +62,13 @@ export class CreatePrivateMessage extends Component<
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.recipientDetailsRes = Some(
-        this.isoData.routeData[0] as GetPersonDetailsResponse
-      );
-      this.state.loading = false;
+      this.state = {
+        ...this.state,
+        recipientDetailsRes: Some(
+          this.isoData.routeData[0] as GetPersonDetailsResponse
+        ),
+        loading: false,
+      };
     } else {
       this.fetchPersonDetails();
     }
@@ -115,7 +119,7 @@ export class CreatePrivateMessage extends Component<
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -129,8 +133,8 @@ export class CreatePrivateMessage extends Component<
         ) : (
           this.state.recipientDetailsRes.match({
             some: res => (
-              <div class="row">
-                <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+              <div className="row">
+                <div className="col-12 col-lg-6 offset-lg-3 mb-4">
                   <h5>{i18n.t("create_private_message")}</h5>
                   <PrivateMessageForm
                     privateMessageView={None}
@@ -151,7 +155,7 @@ export class CreatePrivateMessage extends Component<
     toast(i18n.t("message_sent"));
 
     // Navigate to the front
-    this.context.router.history.push(`/`);
+    this.context.router.history.push("/");
   }
 
   parseMessage(msg: any) {
@@ -159,17 +163,14 @@ export class CreatePrivateMessage extends Component<
     console.log(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (op == UserOperation.GetPersonDetails) {
       let data = wsJsonToRes<GetPersonDetailsResponse>(
         msg,
         GetPersonDetailsResponse
       );
-      this.state.recipientDetailsRes = Some(data);
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ recipientDetailsRes: Some(data), loading: false });
     }
   }
 }
index 62649816d0ea37b72efd84deadb97a2f96532582..6c74e2c8bbb96c6e8780a24e881d975c41e29f6b 100644 (file)
@@ -71,11 +71,10 @@ export class PrivateMessageForm extends Component<
     this.subscription = wsSubscribe(this.parseMessage);
 
     // Its an edit
-    this.props.privateMessageView.match({
-      some: pm =>
-        (this.state.privateMessageForm.content = pm.private_message.content),
-      none: void 0,
-    });
+    if (this.props.privateMessageView.isSome()) {
+      this.state.privateMessageForm.content =
+        this.props.privateMessageView.unwrap().private_message.content;
+    }
   }
 
   componentDidMount() {
@@ -106,21 +105,21 @@ export class PrivateMessageForm extends Component<
         />
         <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
           {this.props.privateMessageView.isNone() && (
-            <div class="form-group row">
-              <label class="col-sm-2 col-form-label">
+            <div className="form-group row">
+              <label className="col-sm-2 col-form-label">
                 {capitalizeFirstLetter(i18n.t("to"))}
               </label>
 
-              <div class="col-sm-10 form-control-plaintext">
+              <div className="col-sm-10 form-control-plaintext">
                 <PersonListing person={this.props.recipient} />
               </div>
             </div>
           )}
-          <div class="form-group row">
-            <label class="col-sm-2 col-form-label">
+          <div className="form-group row">
+            <label className="col-sm-2 col-form-label">
               {i18n.t("message")}
               <button
-                class="btn btn-link text-warning d-inline-block"
+                className="btn btn-link text-warning d-inline-block"
                 onClick={linkEvent(this, this.handleShowDisclaimer)}
                 data-tippy-content={i18n.t("private_message_disclaimer")}
                 aria-label={i18n.t("private_message_disclaimer")}
@@ -128,25 +127,27 @@ export class PrivateMessageForm extends Component<
                 <Icon icon="alert-triangle" classes="icon-inline" />
               </button>
             </label>
-            <div class="col-sm-10">
+            <div className="col-sm-10">
               <MarkdownTextArea
                 initialContent={Some(this.state.privateMessageForm.content)}
+                initialLanguageId={None}
                 placeholder={None}
                 buttonTitle={None}
                 maxLength={None}
                 onContentChange={this.handleContentChange}
+                allLanguages={[]}
               />
             </div>
           </div>
 
           {this.state.showDisclaimer && (
-            <div class="form-group row">
-              <div class="offset-sm-2 col-sm-10">
-                <div class="alert alert-danger" role="alert">
+            <div className="form-group row">
+              <div className="offset-sm-2 col-sm-10">
+                <div className="alert alert-danger" role="alert">
                   <T i18nKey="private_message_disclaimer">
                     #
                     <a
-                      class="alert-link"
+                      className="alert-link"
                       rel={relTags}
                       href="https://element.io/get-started"
                     >
@@ -157,11 +158,11 @@ export class PrivateMessageForm extends Component<
               </div>
             </div>
           )}
-          <div class="form-group row">
-            <div class="offset-sm-2 col-sm-10">
+          <div className="form-group row">
+            <div className="offset-sm-2 col-sm-10">
               <button
                 type="submit"
-                class="btn btn-secondary mr-2"
+                className="btn btn-secondary mr-2"
                 disabled={this.state.loading}
               >
                 {this.state.loading ? (
@@ -175,14 +176,14 @@ export class PrivateMessageForm extends Component<
               {this.props.privateMessageView.isSome() && (
                 <button
                   type="button"
-                  class="btn btn-secondary"
+                  className="btn btn-secondary"
                   onClick={linkEvent(this, this.handleCancel)}
                 >
                   {i18n.t("cancel")}
                 </button>
               )}
-              <ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
-                <li class="list-inline-item"></li>
+              <ul className="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
+                <li className="list-inline-item"></li>
               </ul>
             </div>
           </div>
@@ -206,13 +207,11 @@ export class PrivateMessageForm extends Component<
         wsClient.createPrivateMessage(i.state.privateMessageForm)
       ),
     });
-    i.state.loading = true;
-    i.setState(i.state);
+    i.setState({ loading: true });
   }
 
   handleContentChange(val: string) {
-    this.state.privateMessageForm.content = val;
-    this.setState(this.state);
+    this.setState(s => ((s.privateMessageForm.content = val), s));
   }
 
   handleCancel(i: PrivateMessageForm) {
@@ -221,13 +220,11 @@ export class PrivateMessageForm extends Component<
 
   handlePreviewToggle(i: PrivateMessageForm, event: any) {
     event.preventDefault();
-    i.state.previewMode = !i.state.previewMode;
-    i.setState(i.state);
+    i.setState({ previewMode: !i.state.previewMode });
   }
 
   handleShowDisclaimer(i: PrivateMessageForm) {
-    i.state.showDisclaimer = !i.state.showDisclaimer;
-    i.setState(i.state);
+    i.setState({ showDisclaimer: !i.state.showDisclaimer });
   }
 
   parseMessage(msg: any) {
@@ -235,8 +232,7 @@ export class PrivateMessageForm extends Component<
     console.log(msg);
     if (msg.error) {
       toast(i18n.t(msg.error), "danger");
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
       return;
     } else if (
       op == UserOperation.EditPrivateMessage ||
@@ -247,16 +243,14 @@ export class PrivateMessageForm extends Component<
         msg,
         PrivateMessageResponse
       );
-      this.state.loading = false;
+      this.setState({ loading: false });
       this.props.onEdit(data.private_message_view);
     } else if (op == UserOperation.CreatePrivateMessage) {
       let data = wsJsonToRes<PrivateMessageResponse>(
         msg,
         PrivateMessageResponse
       );
-      this.state.loading = false;
       this.props.onCreate(data.private_message_view);
-      this.setState(this.state);
     }
   }
 }
diff --git a/src/shared/components/private_message/private-message-report.tsx b/src/shared/components/private_message/private-message-report.tsx
new file mode 100644 (file)
index 0000000..3d6198c
--- /dev/null
@@ -0,0 +1,92 @@
+import { Component, linkEvent } from "inferno";
+import { T } from "inferno-i18next-dess";
+import {
+  PrivateMessageReportView,
+  ResolvePrivateMessageReport,
+} from "lemmy-js-client";
+import { i18n } from "../../i18next";
+import { WebSocketService } from "../../services";
+import { auth, mdToHtml, wsClient } from "../../utils";
+import { Icon } from "../common/icon";
+import { PersonListing } from "../person/person-listing";
+
+interface Props {
+  report: PrivateMessageReportView;
+}
+
+export class PrivateMessageReport extends Component<Props, any> {
+  constructor(props: any, context: any) {
+    super(props, context);
+  }
+
+  render() {
+    let r = this.props.report;
+    let pmr = r.private_message_report;
+    let tippyContent = i18n.t(
+      r.private_message_report.resolved ? "unresolve_report" : "resolve_report"
+    );
+
+    return (
+      <div>
+        <div>
+          {i18n.t("creator")}:{" "}
+          <PersonListing person={r.private_message_creator} />
+        </div>
+        <div>
+          {i18n.t("message")}:
+          <div
+            className="md-div"
+            dangerouslySetInnerHTML={mdToHtml(pmr.original_pm_text)}
+          />
+        </div>
+        <div>
+          {i18n.t("reporter")}: <PersonListing person={r.creator} />
+        </div>
+        <div>
+          {i18n.t("reason")}: {pmr.reason}
+        </div>
+        {r.resolver.match({
+          some: resolver => (
+            <div>
+              {pmr.resolved ? (
+                <T i18nKey="resolved_by">
+                  #
+                  <PersonListing person={resolver} />
+                </T>
+              ) : (
+                <T i18nKey="unresolved_by">
+                  #
+                  <PersonListing person={resolver} />
+                </T>
+              )}
+            </div>
+          ),
+          none: <></>,
+        })}
+        <button
+          className="btn btn-link btn-animate text-muted py-0"
+          onClick={linkEvent(this, this.handleResolveReport)}
+          data-tippy-content={tippyContent}
+          aria-label={tippyContent}
+        >
+          <Icon
+            icon="check"
+            classes={`icon-inline ${
+              pmr.resolved ? "text-success" : "text-danger"
+            }`}
+          />
+        </button>
+      </div>
+    );
+  }
+
+  handleResolveReport(i: PrivateMessageReport) {
+    let pmr = i.props.report.private_message_report;
+    let form = new ResolvePrivateMessageReport({
+      report_id: pmr.id,
+      resolved: !pmr.resolved,
+      auth: auth().unwrap(),
+    });
+    WebSocketService.Instance.send(wsClient.resolvePrivateMessageReport(form));
+  }
+}
index 57662606518f421cd08e384c3368b28269e28464..b7d1bd1f7a164e40fc70d9eb0b2711004185c224 100644 (file)
@@ -1,10 +1,12 @@
-import { None, Some } from "@sniptt/monads/build";
+import { None, Option, Some } from "@sniptt/monads/build";
 import { Component, linkEvent } from "inferno";
 import {
+  CreatePrivateMessageReport,
   DeletePrivateMessage,
   MarkPrivateMessageAsRead,
   PersonSafe,
   PrivateMessageView,
+  toUndefined,
 } from "lemmy-js-client";
 import { i18n } from "../../i18next";
 import { UserService, WebSocketService } from "../../services";
@@ -19,6 +21,8 @@ interface PrivateMessageState {
   showEdit: boolean;
   collapsed: boolean;
   viewSource: boolean;
+  showReportDialog: boolean;
+  reportReason: Option<string>;
 }
 
 interface PrivateMessageProps {
@@ -34,6 +38,8 @@ export class PrivateMessage extends Component<
     showEdit: false,
     collapsed: false,
     viewSource: false,
+    showReportDialog: false,
+    reportReason: None,
   };
 
   constructor(props: any, context: any) {
@@ -63,9 +69,9 @@ export class PrivateMessage extends Component<
       : message_view.creator;
 
     return (
-      <div class="border-top border-light">
+      <div className="border-top border-light">
         <div>
-          <ul class="list-inline mb-0 text-muted small">
+          <ul className="list-inline mb-0 text-muted small">
             {/* TODO refactor this */}
             <li className="list-inline-item">
               {this.mine ? i18n.t("to") : i18n.t("from")}
@@ -114,12 +120,12 @@ export class PrivateMessage extends Component<
                   dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
                 />
               )}
-              <ul class="list-inline mb-0 text-muted font-weight-bold">
+              <ul className="list-inline mb-0 text-muted font-weight-bold">
                 {!this.mine && (
                   <>
                     <li className="list-inline-item">
                       <button
-                        class="btn btn-link btn-animate text-muted"
+                        className="btn btn-link btn-animate text-muted"
                         onClick={linkEvent(this, this.handleMarkRead)}
                         data-tippy-content={
                           message_view.private_message.read
@@ -140,9 +146,10 @@ export class PrivateMessage extends Component<
                         />
                       </button>
                     </li>
+                    <li className="list-inline-item">{this.reportButton}</li>
                     <li className="list-inline-item">
                       <button
-                        class="btn btn-link btn-animate text-muted"
+                        className="btn btn-link btn-animate text-muted"
                         onClick={linkEvent(this, this.handleReplyClick)}
                         data-tippy-content={i18n.t("reply")}
                         aria-label={i18n.t("reply")}
@@ -156,7 +163,7 @@ export class PrivateMessage extends Component<
                   <>
                     <li className="list-inline-item">
                       <button
-                        class="btn btn-link btn-animate text-muted"
+                        className="btn btn-link btn-animate text-muted"
                         onClick={linkEvent(this, this.handleEditClick)}
                         data-tippy-content={i18n.t("edit")}
                         aria-label={i18n.t("edit")}
@@ -166,7 +173,7 @@ export class PrivateMessage extends Component<
                     </li>
                     <li className="list-inline-item">
                       <button
-                        class="btn btn-link btn-animate text-muted"
+                        className="btn btn-link btn-animate text-muted"
                         onClick={linkEvent(this, this.handleDeleteClick)}
                         data-tippy-content={
                           !message_view.private_message.deleted
@@ -192,7 +199,7 @@ export class PrivateMessage extends Component<
                 )}
                 <li className="list-inline-item">
                   <button
-                    class="btn btn-link btn-animate text-muted"
+                    className="btn btn-link btn-animate text-muted"
                     onClick={linkEvent(this, this.handleViewSource)}
                     data-tippy-content={i18n.t("view_source")}
                     aria-label={i18n.t("view_source")}
@@ -209,6 +216,32 @@ export class PrivateMessage extends Component<
             </div>
           )}
         </div>
+        {this.state.showReportDialog && (
+          <form
+            className="form-inline"
+            onSubmit={linkEvent(this, this.handleReportSubmit)}
+          >
+            <label className="sr-only" htmlFor="pm-report-reason">
+              {i18n.t("reason")}
+            </label>
+            <input
+              type="text"
+              id="pm-report-reason"
+              className="form-control mr-2"
+              placeholder={i18n.t("reason")}
+              required
+              value={toUndefined(this.state.reportReason)}
+              onInput={linkEvent(this, this.handleReportReasonChange)}
+            />
+            <button
+              type="submit"
+              className="btn btn-secondary"
+              aria-label={i18n.t("create_report")}
+            >
+              {i18n.t("create_report")}
+            </button>
+          </form>
+        )}
         {this.state.showReply && (
           <PrivateMessageForm
             recipient={otherPerson}
@@ -217,23 +250,35 @@ export class PrivateMessage extends Component<
           />
         )}
         {/* A collapsed clearfix */}
-        {this.state.collapsed && <div class="row col-12"></div>}
+        {this.state.collapsed && <div className="row col-12"></div>}
       </div>
     );
   }
 
+  get reportButton() {
+    return (
+      <button
+        className="btn btn-link btn-animate text-muted py-0"
+        onClick={linkEvent(this, this.handleShowReportDialog)}
+        data-tippy-content={i18n.t("show_report_dialog")}
+        aria-label={i18n.t("show_report_dialog")}
+      >
+        <Icon icon="flag" inline />
+      </button>
+    );
+  }
+
   get messageUnlessRemoved(): string {
     let message = this.props.private_message_view.private_message;
     return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
   }
 
   handleReplyClick(i: PrivateMessage) {
-    i.state.showReply = true;
-    i.setState(i.state);
+    i.setState({ showReply: true });
   }
 
   handleEditClick(i: PrivateMessage) {
-    i.state.showEdit = true;
+    i.setState({ showEdit: true });
     i.setState(i.state);
   }
 
@@ -247,9 +292,7 @@ export class PrivateMessage extends Component<
   }
 
   handleReplyCancel() {
-    this.state.showReply = false;
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showReply: false, showEdit: false });
   }
 
   handleMarkRead(i: PrivateMessage) {
@@ -262,26 +305,42 @@ export class PrivateMessage extends Component<
   }
 
   handleMessageCollapse(i: PrivateMessage) {
-    i.state.collapsed = !i.state.collapsed;
-    i.setState(i.state);
+    i.setState({ collapsed: !i.state.collapsed });
   }
 
   handleViewSource(i: PrivateMessage) {
-    i.state.viewSource = !i.state.viewSource;
-    i.setState(i.state);
+    i.setState({ viewSource: !i.state.viewSource });
+  }
+
+  handleShowReportDialog(i: PrivateMessage) {
+    i.setState({ showReportDialog: !i.state.showReportDialog });
+  }
+
+  handleReportReasonChange(i: PrivateMessage, event: any) {
+    i.setState({ reportReason: Some(event.target.value) });
+  }
+
+  handleReportSubmit(i: PrivateMessage, event: any) {
+    event.preventDefault();
+    let form = new CreatePrivateMessageReport({
+      private_message_id: i.props.private_message_view.private_message.id,
+      reason: toUndefined(i.state.reportReason),
+      auth: auth().unwrap(),
+    });
+    WebSocketService.Instance.send(wsClient.createPrivateMessageReport(form));
+
+    i.setState({ showReportDialog: false });
   }
 
   handlePrivateMessageEdit() {
-    this.state.showEdit = false;
-    this.setState(this.state);
+    this.setState({ showEdit: false });
   }
 
   handlePrivateMessageCreate(message: PrivateMessageView) {
     UserService.Instance.myUserInfo.match({
       some: mui => {
         if (message.creator.id == mui.local_user_view.person.id) {
-          this.state.showReply = false;
-          this.setState(this.state);
+          this.setState({ showReply: false });
           toast(i18n.t("message_sent"));
         }
       },
index 431681ee4d5820f2dcf1491e23024846def63a20..6712b95d852f34bc99a666a26c58cc668b1fff66 100644 (file)
@@ -200,28 +200,36 @@ export class Search extends Component<any, SearchState> {
       );
 
       // This can be single or multiple communities given
-      communitiesRes.match({
-        some: res => (this.state.communities = res.communities),
-        none: void 0,
-      });
+      if (communitiesRes.isSome()) {
+        this.state = {
+          ...this.state,
+          communities: communitiesRes.unwrap().communities,
+        };
+      }
 
-      communityRes.match({
-        some: res => (this.state.communities = [res.community_view]),
-        none: void 0,
-      });
+      if (communityRes.isSome()) {
+        this.state = {
+          ...this.state,
+          communities: [communityRes.unwrap().community_view],
+        };
+      }
 
-      this.state.creatorDetails = Some(
-        this.isoData.routeData[2] as GetPersonDetailsResponse
-      );
+      this.state = {
+        ...this.state,
+        creatorDetails: Some(
+          this.isoData.routeData[2] as GetPersonDetailsResponse
+        ),
+      };
 
       if (this.state.q != "") {
-        this.state.searchResponse = Some(
-          this.isoData.routeData[3] as SearchResponse
-        );
-        this.state.resolveObjectResponse = Some(
-          this.isoData.routeData[4] as ResolveObjectResponse
-        );
-        this.state.loading = false;
+        this.state = {
+          ...this.state,
+          searchResponse: Some(this.isoData.routeData[3] as SearchResponse),
+          resolveObjectResponse: Some(
+            this.isoData.routeData[4] as ResolveObjectResponse
+          ),
+          loading: false,
+        };
       } else {
         this.search();
       }
@@ -382,7 +390,7 @@ export class Search extends Component<any, SearchState> {
 
   render() {
     return (
-      <div class="container">
+      <div className="container">
         <HtmlTags
           title={this.documentTitle}
           path={this.context.router.route.match.url}
@@ -407,12 +415,12 @@ export class Search extends Component<any, SearchState> {
   searchForm() {
     return (
       <form
-        class="form-inline"
+        className="form-inline"
         onSubmit={linkEvent(this, this.handleSearchSubmit)}
       >
         <input
           type="text"
-          class="form-control mr-2 mb-2"
+          className="form-control mr-2 mb-2"
           value={this.state.searchText}
           placeholder={`${i18n.t("search")}...`}
           aria-label={i18n.t("search")}
@@ -420,7 +428,7 @@ export class Search extends Component<any, SearchState> {
           required
           minLength={1}
         />
-        <button type="submit" class="btn btn-secondary mr-2 mb-2">
+        <button type="submit" className="btn btn-secondary mr-2 mb-2">
           {this.state.loading ? <Spinner /> : <span>{i18n.t("search")}</span>}
         </button>
       </form>
@@ -433,7 +441,7 @@ export class Search extends Component<any, SearchState> {
         <select
           value={this.state.type_}
           onChange={linkEvent(this, this.handleTypeChange)}
-          class="custom-select w-auto mb-2"
+          className="custom-select w-auto mb-2"
           aria-label={i18n.t("type")}
         >
           <option disabled aria-hidden="true">
@@ -448,7 +456,7 @@ export class Search extends Component<any, SearchState> {
           <option value={SearchType.Users}>{i18n.t("users")}</option>
           <option value={SearchType.Url}>{i18n.t("url")}</option>
         </select>
-        <span class="ml-2">
+        <span className="ml-2">
           <ListingTypeSelect
             type_={this.state.listingType}
             showLocal={showLocal(this.isoData)}
@@ -456,7 +464,7 @@ export class Search extends Component<any, SearchState> {
             onChange={this.handleListingTypeChange}
           />
         </span>
-        <span class="ml-2">
+        <span className="ml-2">
           <SortSelect
             sort={this.state.sort}
             onChange={this.handleSortChange}
@@ -464,7 +472,7 @@ export class Search extends Component<any, SearchState> {
             hideMostComments
           />
         </span>
-        <div class="form-row">
+        <div className="form-row">
           {this.state.communities.length > 0 && this.communityFilter()}
           {this.creatorFilter()}
         </div>
@@ -577,8 +585,8 @@ export class Search extends Component<any, SearchState> {
     return (
       <div>
         {combined.map(i => (
-          <div class="row">
-            <div class="col-12">
+          <div key={i.published} className="row">
+            <div className="col-12">
               {i.type_ == "posts" && (
                 <PostListing
                   key={(i.data as PostView).post.id}
@@ -589,6 +597,8 @@ export class Search extends Component<any, SearchState> {
                   showCommunity
                   enableDownvotes={enableDownvotes(this.state.siteRes)}
                   enableNsfw={enableNsfw(this.state.siteRes)}
+                  allLanguages={this.state.siteRes.all_languages}
+                  viewOnly
                 />
               )}
               {i.type_ == "comments" && (
@@ -602,19 +612,21 @@ export class Search extends Component<any, SearchState> {
                     },
                   ]}
                   viewType={CommentViewType.Flat}
+                  viewOnly
                   moderators={None}
                   admins={None}
                   maxCommentsShown={None}
                   locked
                   noIndent
                   enableDownvotes={enableDownvotes(this.state.siteRes)}
+                  allLanguages={this.state.siteRes.all_languages}
                 />
               )}
               {i.type_ == "communities" && (
                 <div>{this.communityListing(i.data as CommunityView)}</div>
               )}
               {i.type_ == "users" && (
-                <div>{this.userListing(i.data as PersonViewSafe)}</div>
+                <div>{this.personListing(i.data as PersonViewSafe)}</div>
               )}
             </div>
           </div>
@@ -639,12 +651,14 @@ export class Search extends Component<any, SearchState> {
       <CommentNodes
         nodes={commentsToFlatNodes(comments)}
         viewType={CommentViewType.Flat}
+        viewOnly
         locked
         noIndent
         moderators={None}
         admins={None}
         maxCommentsShown={None}
         enableDownvotes={enableDownvotes(this.state.siteRes)}
+        allLanguages={this.state.siteRes.all_languages}
       />
     );
   }
@@ -663,17 +677,19 @@ export class Search extends Component<any, SearchState> {
 
     return (
       <>
-        {posts.map(post => (
-          <div class="row">
-            <div class="col-12">
+        {posts.map(pv => (
+          <div key={pv.post.id} className="row">
+            <div className="col-12">
               <PostListing
-                post_view={post}
+                post_view={pv}
                 showCommunity
                 duplicates={None}
                 moderators={None}
                 admins={None}
                 enableDownvotes={enableDownvotes(this.state.siteRes)}
                 enableNsfw={enableNsfw(this.state.siteRes)}
+                allLanguages={this.state.siteRes.all_languages}
+                viewOnly
               />
             </div>
           </div>
@@ -696,9 +712,9 @@ export class Search extends Component<any, SearchState> {
 
     return (
       <>
-        {communities.map(community => (
-          <div class="row">
-            <div class="col-12">{this.communityListing(community)}</div>
+        {communities.map(cv => (
+          <div key={cv.community.id} className="row">
+            <div className="col-12">{this.communityListing(cv)}</div>
           </div>
         ))}
       </>
@@ -719,9 +735,9 @@ export class Search extends Component<any, SearchState> {
 
     return (
       <>
-        {users.map(user => (
-          <div class="row">
-            <div class="col-12">{this.userListing(user)}</div>
+        {users.map(pvs => (
+          <div key={pvs.person.id} className="row">
+            <div className="col-12">{this.personListing(pvs)}</div>
           </div>
         ))}
       </>
@@ -744,33 +760,37 @@ export class Search extends Component<any, SearchState> {
     );
   }
 
-  userListing(person_view: PersonViewSafe) {
-    return [
-      <span>
-        <PersonListing person={person_view.person} showApubName />
-      </span>,
-      <span>{` - ${i18n.t("number_of_comments", {
-        count: person_view.counts.comment_count,
-        formattedCount: numToSI(person_view.counts.comment_count),
-      })}`}</span>,
-    ];
+  personListing(person_view: PersonViewSafe) {
+    return (
+      <>
+        <span>
+          <PersonListing person={person_view.person} showApubName />
+        </span>
+        <span>{` - ${i18n.t("number_of_comments", {
+          count: person_view.counts.comment_count,
+          formattedCount: numToSI(person_view.counts.comment_count),
+        })}`}</span>
+      </>
+    );
   }
 
   communityFilter() {
     return (
-      <div class="form-group col-sm-6">
-        <label class="col-form-label" htmlFor="community-filter">
+      <div className="form-group col-sm-6">
+        <label className="col-form-label" htmlFor="community-filter">
           {i18n.t("community")}
         </label>
         <div>
           <select
-            class="form-control"
+            className="form-control"
             id="community-filter"
             value={this.state.communityId}
           >
             <option value="0">{i18n.t("all")}</option>
             {this.state.communities.map(cv => (
-              <option value={cv.community.id}>{communitySelectName(cv)}</option>
+              <option key={cv.community.id} value={cv.community.id}>
+                {communitySelectName(cv)}
+              </option>
             ))}
           </select>
         </div>
@@ -780,13 +800,13 @@ export class Search extends Component<any, SearchState> {
 
   creatorFilter() {
     return (
-      <div class="form-group col-sm-6">
-        <label class="col-form-label" htmlFor="creator-filter">
+      <div className="form-group col-sm-6">
+        <label className="col-form-label" htmlFor="creator-filter">
           {capitalizeFirstLetter(i18n.t("creator"))}
         </label>
         <div>
           <select
-            class="form-control"
+            className="form-control"
             id="creator-filter"
             value={this.state.creatorId}
           >
@@ -852,10 +872,11 @@ export class Search extends Component<any, SearchState> {
     });
 
     if (this.state.q != "") {
-      this.state.searchResponse = None;
-      this.state.resolveObjectResponse = None;
-      this.state.loading = true;
-      this.setState(this.state);
+      this.setState({
+        searchResponse: None,
+        resolveObjectResponse: None,
+        loading: true,
+      });
       WebSocketService.Instance.send(wsClient.search(form));
       WebSocketService.Instance.send(wsClient.resolveObject(resolveObjectForm));
     }
@@ -996,11 +1017,13 @@ export class Search extends Component<any, SearchState> {
     let op = wsUserOp(msg);
     if (msg.error) {
       if (msg.error == "couldnt_find_object") {
-        this.state.resolveObjectResponse = Some({
-          comment: None,
-          post: None,
-          community: None,
-          person: None,
+        this.setState({
+          resolveObjectResponse: Some({
+            comment: None,
+            post: None,
+            community: None,
+            person: None,
+          }),
         });
         this.checkFinishedLoading();
       } else {
@@ -1009,7 +1032,7 @@ export class Search extends Component<any, SearchState> {
       }
     } else if (op == UserOperation.Search) {
       let data = wsJsonToRes<SearchResponse>(msg, SearchResponse);
-      this.state.searchResponse = Some(data);
+      this.setState({ searchResponse: Some(data) });
       window.scrollTo(0, 0);
       this.checkFinishedLoading();
       restoreScrollPosition(this.context);
@@ -1032,12 +1055,11 @@ export class Search extends Component<any, SearchState> {
         msg,
         ListCommunitiesResponse
       );
-      this.state.communities = data.communities;
-      this.setState(this.state);
+      this.setState({ communities: data.communities });
       this.setupCommunityFilter();
     } else if (op == UserOperation.ResolveObject) {
       let data = wsJsonToRes<ResolveObjectResponse>(msg, ResolveObjectResponse);
-      this.state.resolveObjectResponse = Some(data);
+      this.setState({ resolveObjectResponse: Some(data) });
       this.checkFinishedLoading();
     }
   }
@@ -1047,8 +1069,7 @@ export class Search extends Component<any, SearchState> {
       this.state.searchResponse.isSome() &&
       this.state.resolveObjectResponse.isSome()
     ) {
-      this.state.loading = false;
-      this.setState(this.state);
+      this.setState({ loading: false });
     }
   }
 }
index 8fa399eb30859402c0601543d60d611c8964f63f..d0b9b4bf6de888d1802a9271aef856c0d6f870ad 100644 (file)
@@ -1,4 +1,4 @@
-import { None, Option, Result, Some } from "@sniptt/monads";
+import { Err, None, Ok, Option, Result, Some } from "@sniptt/monads";
 import { ClassConstructor, deserialize, serialize } from "class-transformer";
 import emojiShortName from "emoji-short-name";
 import {
@@ -23,6 +23,7 @@ import {
   PersonViewSafe,
   PostReportView,
   PostView,
+  PrivateMessageReportView,
   PrivateMessageView,
   RegistrationApplicationView,
   Search,
@@ -69,7 +70,7 @@ export const webArchiveUrl = "https://web.archive.org";
 export const elementUrl = "https://element.io";
 
 export const postRefetchSeconds: number = 60 * 1000;
-export const fetchLimit = 20;
+export const fetchLimit = 40;
 export const trendingFetchLimit = 6;
 export const mentionDropdownFetchLimit = 10;
 export const commentTreeMaxDepth = 8;
@@ -246,14 +247,10 @@ export function isAdmin(
   });
 }
 
-export function amAdmin(
-  admins: Option<PersonViewSafe[]>,
-  myUserInfo = UserService.Instance.myUserInfo
-): boolean {
-  return myUserInfo.match({
-    some: mui => isAdmin(admins, mui.local_user_view.person.id),
-    none: false,
-  });
+export function amAdmin(myUserInfo = UserService.Instance.myUserInfo): boolean {
+  return myUserInfo
+    .map(mui => mui.local_user_view.person.admin)
+    .unwrapOr(false);
 }
 
 export function amCommunityCreator(
@@ -418,7 +415,7 @@ export function getLanguages(
   myUserInfo = UserService.Instance.myUserInfo
 ): string[] {
   let myLang = myUserInfo
-    .map(m => m.local_user_view.local_user.lang)
+    .map(m => m.local_user_view.local_user.interface_language)
     .unwrapOr("browser");
   let lang = override || myLang;
 
@@ -638,21 +635,18 @@ export function notifyPrivateMessage(pmv: PrivateMessageView, router: any) {
 function notify(info: NotifyInfo, router: any) {
   messageToastify(info, router);
 
-  // TODO absolute nightmare bug, but notifs are currently broken.
-  // Notification.new will try to do a browser fetch ???
-
-  // if (Notification.permission !== "granted") Notification.requestPermission();
-  // else {
-  //   var notification = new Notification(info.name, {
-  //     icon: info.icon,
-  //     body: info.body,
-  //   });
+  if (Notification.permission !== "granted") Notification.requestPermission();
+  else {
+    var notification = new Notification(info.name, {
+      ...{ body: info.body },
+      ...(info.icon.isSome() && { icon: info.icon.unwrap() }),
+    });
 
-  //   notification.onclick = (ev: Event): any => {
-  //     ev.preventDefault();
-  //     router.history.push(info.link);
-  //   };
-  // }
+    notification.onclick = (ev: Event): any => {
+      ev.preventDefault();
+      router.history.push(info.link);
+    };
+  }
 }
 
 export function setupTribute() {
@@ -959,6 +953,7 @@ export function editPostRes(data: PostView, post: PostView) {
   }
 }
 
+// TODO possible to make these generic?
 export function updatePostReportRes(
   data: PostReportView,
   reports: PostReportView[]
@@ -979,6 +974,18 @@ export function updateCommentReportRes(
   }
 }
 
+export function updatePrivateMessageReportRes(
+  data: PrivateMessageReportView,
+  reports: PrivateMessageReportView[]
+) {
+  let found = reports.find(
+    c => c.private_message_report.id == data.private_message_report.id
+  );
+  if (found) {
+    found.private_message_report = data.private_message_report;
+  }
+}
+
 export function updateRegistrationApplicationRes(
   data: RegistrationApplicationView,
   applications: RegistrationApplicationView[]
@@ -1338,44 +1345,11 @@ export const choicesConfig = {
   shouldSort: false,
   searchResultLimit: fetchLimit,
   classNames: {
-    containerOuter: "choices",
-    containerInner: "choices__inner bg-secondary border-0",
-    input: "form-control",
-    inputCloned: "choices__input--cloned",
-    list: "choices__list",
-    listItems: "choices__list--multiple",
-    listSingle: "choices__list--single",
-    listDropdown: "choices__list--dropdown",
-    item: "choices__item bg-secondary",
-    itemSelectable: "choices__item--selectable",
-    itemDisabled: "choices__item--disabled",
-    itemChoice: "choices__item--choice",
-    placeholder: "choices__placeholder",
-    group: "choices__group",
-    groupHeading: "choices__heading",
-    button: "choices__button",
-    activeState: "is-active",
-    focusState: "is-focused",
-    openState: "is-open",
-    disabledState: "is-disabled",
-    highlightedState: "text-info",
-    selectedState: "text-info",
-    flippedState: "is-flipped",
-    loadingState: "is-loading",
-    noResults: "has-no-results",
-    noChoices: "has-no-choices",
-  },
-};
-
-export const choicesModLogConfig = {
-  shouldSort: false,
-  searchResultLimit: fetchLimit,
-  classNames: {
-    containerOuter: "choices mb-2 custom-select col-4 px-0",
+    containerOuter: "choices custom-select px-0",
     containerInner:
       "choices__inner bg-secondary border-0 py-0 modlog-choices-font-size",
     input: "form-control",
-    inputCloned: "choices__input--cloned w-100",
+    inputCloned: "choices__input--cloned",
     list: "choices__list",
     listItems: "choices__list--multiple",
     listSingle: "choices__list--single py-0",
@@ -1472,3 +1446,62 @@ export function postToCommentSortType(sort: SortType): CommentSortType {
     return CommentSortType.Top;
   }
 }
+
+export function arrayGet<T>(arr: Array<T>, index: number): Result<T, string> {
+  let out = arr.at(index);
+  if (out == undefined) {
+    return Err("Index undefined");
+  } else {
+    return Ok(out);
+  }
+}
+
+export function myFirstDiscussionLanguageId(
+  myUserInfo = UserService.Instance.myUserInfo
+): Option<number> {
+  return myUserInfo.andThen(mui =>
+    arrayGet(mui.discussion_languages, 0)
+      .ok()
+      .map(i => i.id)
+  );
+}
+
+export function canCreateCommunity(
+  siteRes: GetSiteResponse,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  let adminOnly = siteRes.site_view
+    .map(s => s.site.community_creation_admin_only)
+    .unwrapOr(false);
+  return !adminOnly || amAdmin(myUserInfo);
+}
+
+export function isPostBlocked(
+  pv: PostView,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  return myUserInfo
+    .map(
+      mui =>
+        mui.community_blocks
+          .map(c => c.community.id)
+          .includes(pv.community.id) ||
+        mui.person_blocks.map(p => p.target.id).includes(pv.creator.id)
+    )
+    .unwrapOr(false);
+}
+
+/// Checks to make sure you can view NSFW posts. Returns true if you can.
+export function nsfwCheck(
+  pv: PostView,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  let nsfw = pv.post.nsfw || pv.community.nsfw;
+  return (
+    !nsfw ||
+    (nsfw &&
+      myUserInfo
+        .map(m => m.local_user_view.local_user.show_nsfw)
+        .unwrapOr(false))
+  );
+}
index 93f1f5d0f233e6a7b8ce15bdffd9dfdc74cc4c59..de62e68b0c933736c7c81704cafc6b98b69f2ea7 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -3,18 +3,12 @@
 
 
 "@ampproject/remapping@^2.1.0":
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34"
-  integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==
-  dependencies:
-    "@jridgewell/trace-mapping" "^0.3.0"
-
-"@babel/code-frame@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
-  integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
+  integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
   dependencies:
-    "@babel/highlight" "^7.16.7"
+    "@jridgewell/gen-mapping" "^0.1.0"
+    "@jridgewell/trace-mapping" "^0.3.9"
 
 "@babel/code-frame@^7.18.6":
   version "7.18.6"
   dependencies:
     "@babel/highlight" "^7.18.6"
 
-"@babel/compat-data@^7.16.4":
-  version "7.16.8"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60"
-  integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==
-
-"@babel/compat-data@^7.17.7":
-  version "7.17.7"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2"
-  integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==
-
-"@babel/compat-data@^7.18.8":
-  version "7.18.8"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d"
-  integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==
+"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151"
+  integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==
 
-"@babel/core@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59"
-  integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==
+"@babel/core@^7.18.9", "@babel/core@^7.2.2":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c"
+  integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==
   dependencies:
     "@ampproject/remapping" "^2.1.0"
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.18.9"
-    "@babel/helper-compilation-targets" "^7.18.9"
-    "@babel/helper-module-transforms" "^7.18.9"
-    "@babel/helpers" "^7.18.9"
-    "@babel/parser" "^7.18.9"
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/generator" "^7.19.3"
+    "@babel/helper-compilation-targets" "^7.19.3"
+    "@babel/helper-module-transforms" "^7.19.0"
+    "@babel/helpers" "^7.19.0"
+    "@babel/parser" "^7.19.3"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.3"
+    "@babel/types" "^7.19.3"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.2"
     json5 "^2.2.1"
     semver "^6.3.0"
 
-"@babel/core@^7.2.2":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf"
-  integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==
-  dependencies:
-    "@babel/code-frame" "^7.16.7"
-    "@babel/generator" "^7.16.7"
-    "@babel/helper-compilation-targets" "^7.16.7"
-    "@babel/helper-module-transforms" "^7.16.7"
-    "@babel/helpers" "^7.16.7"
-    "@babel/parser" "^7.16.7"
-    "@babel/template" "^7.16.7"
-    "@babel/traverse" "^7.16.7"
-    "@babel/types" "^7.16.7"
-    convert-source-map "^1.7.0"
-    debug "^4.1.0"
-    gensync "^1.0.0-beta.2"
-    json5 "^2.1.2"
-    semver "^6.3.0"
-    source-map "^0.5.0"
-
-"@babel/generator@^7.16.7", "@babel/generator@^7.16.8":
-  version "7.16.8"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe"
-  integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==
-  dependencies:
-    "@babel/types" "^7.16.8"
-    jsesc "^2.5.1"
-    source-map "^0.5.0"
-
-"@babel/generator@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5"
-  integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==
+"@babel/generator@^7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59"
+  integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==
   dependencies:
-    "@babel/types" "^7.18.9"
+    "@babel/types" "^7.19.3"
     "@jridgewell/gen-mapping" "^0.3.2"
     jsesc "^2.5.1"
 
-"@babel/helper-annotate-as-pure@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862"
-  integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
-  dependencies:
-    "@babel/types" "^7.16.7"
-
 "@babel/helper-annotate-as-pure@^7.18.6":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
     "@babel/helper-explode-assignable-expression" "^7.18.6"
     "@babel/types" "^7.18.9"
 
-"@babel/helper-compilation-targets@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b"
-  integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==
-  dependencies:
-    "@babel/compat-data" "^7.16.4"
-    "@babel/helper-validator-option" "^7.16.7"
-    browserslist "^4.17.5"
-    semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.17.7":
-  version "7.17.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46"
-  integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==
-  dependencies:
-    "@babel/compat-data" "^7.17.7"
-    "@babel/helper-validator-option" "^7.16.7"
-    browserslist "^4.17.5"
-    semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf"
-  integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==
+"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca"
+  integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==
   dependencies:
-    "@babel/compat-data" "^7.18.8"
+    "@babel/compat-data" "^7.19.3"
     "@babel/helper-validator-option" "^7.18.6"
-    browserslist "^4.20.2"
+    browserslist "^4.21.3"
     semver "^6.3.0"
 
-"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce"
-  integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw==
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b"
+  integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-function-name" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-member-expression-to-functions" "^7.18.9"
     "@babel/helper-optimise-call-expression" "^7.18.6"
     "@babel/helper-replace-supers" "^7.18.9"
     "@babel/helper-split-export-declaration" "^7.18.6"
 
-"@babel/helper-create-regexp-features-plugin@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48"
-  integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.16.7"
-    regexpu-core "^4.7.1"
-
-"@babel/helper-create-regexp-features-plugin@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c"
-  integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
+  integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
     regexpu-core "^5.1.0"
 
-"@babel/helper-define-polyfill-provider@^0.3.1", "@babel/helper-define-polyfill-provider@^0.3.2":
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073"
-  integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==
+"@babel/helper-define-polyfill-provider@^0.3.3":
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a"
+  integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==
   dependencies:
     "@babel/helper-compilation-targets" "^7.17.7"
     "@babel/helper-plugin-utils" "^7.16.7"
     resolve "^1.14.2"
     semver "^6.1.2"
 
-"@babel/helper-environment-visitor@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7"
-  integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==
-  dependencies:
-    "@babel/types" "^7.16.7"
-
-"@babel/helper-environment-visitor@^7.18.6", "@babel/helper-environment-visitor@^7.18.9":
+"@babel/helper-environment-visitor@^7.18.9":
   version "7.18.9"
   resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
   integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-function-name@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f"
-  integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==
-  dependencies:
-    "@babel/helper-get-function-arity" "^7.16.7"
-    "@babel/template" "^7.16.7"
-    "@babel/types" "^7.16.7"
-
-"@babel/helper-function-name@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0"
-  integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==
-  dependencies:
-    "@babel/template" "^7.18.6"
-    "@babel/types" "^7.18.9"
-
-"@babel/helper-get-function-arity@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419"
-  integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
+"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+  integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
   dependencies:
-    "@babel/types" "^7.16.7"
-
-"@babel/helper-hoist-variables@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
-  integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
-  dependencies:
-    "@babel/types" "^7.16.7"
+    "@babel/template" "^7.18.10"
+    "@babel/types" "^7.19.0"
 
 "@babel/helper-hoist-variables@^7.18.6":
   version "7.18.6"
   dependencies:
     "@babel/types" "^7.18.9"
 
-"@babel/helper-module-imports@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
-  integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
-  dependencies:
-    "@babel/types" "^7.16.7"
-
 "@babel/helper-module-imports@^7.18.6":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-module-transforms@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41"
-  integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==
-  dependencies:
-    "@babel/helper-environment-visitor" "^7.16.7"
-    "@babel/helper-module-imports" "^7.16.7"
-    "@babel/helper-simple-access" "^7.16.7"
-    "@babel/helper-split-export-declaration" "^7.16.7"
-    "@babel/helper-validator-identifier" "^7.16.7"
-    "@babel/template" "^7.16.7"
-    "@babel/traverse" "^7.16.7"
-    "@babel/types" "^7.16.7"
-
-"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712"
-  integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+  integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-module-imports" "^7.18.6"
     "@babel/helper-simple-access" "^7.18.6"
     "@babel/helper-split-export-declaration" "^7.18.6"
     "@babel/helper-validator-identifier" "^7.18.6"
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
 
 "@babel/helper-optimise-call-expression@^7.18.6":
   version "7.18.6"
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
-  integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
-
-"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f"
-  integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf"
+  integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==
 
-"@babel/helper-remap-async-to-generator@^7.18.6":
+"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
   version "7.18.9"
   resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
   integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
     "@babel/helper-wrap-function" "^7.18.9"
     "@babel/types" "^7.18.9"
 
-"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6"
-  integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9", "@babel/helper-replace-supers@^7.19.1":
+  version "7.19.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78"
+  integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-member-expression-to-functions" "^7.18.9"
     "@babel/helper-optimise-call-expression" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
-
-"@babel/helper-simple-access@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7"
-  integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==
-  dependencies:
-    "@babel/types" "^7.16.7"
+    "@babel/traverse" "^7.19.1"
+    "@babel/types" "^7.19.0"
 
 "@babel/helper-simple-access@^7.18.6":
   version "7.18.6"
   dependencies:
     "@babel/types" "^7.18.9"
 
-"@babel/helper-split-export-declaration@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
-  integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
-  dependencies:
-    "@babel/types" "^7.16.7"
-
 "@babel/helper-split-export-declaration@^7.18.6":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-validator-identifier@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
-  integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
+"@babel/helper-string-parser@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56"
+  integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==
 
-"@babel/helper-validator-identifier@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
-  integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
-
-"@babel/helper-validator-option@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
-  integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+  version "7.19.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+  integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
 
 "@babel/helper-validator-option@^7.18.6":
   version "7.18.6"
   integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
 
 "@babel/helper-wrap-function@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.9.tgz#ae1feddc6ebbaa2fd79346b77821c3bd73a39646"
-  integrity sha512-cG2ru3TRAL6a60tfQflpEfs4ldiPwF6YW3zfJiRgmoFVIaC1vGnBBgatfec+ZUziPHkHSaXAuEck3Cdkf3eRpQ==
-  dependencies:
-    "@babel/helper-function-name" "^7.18.9"
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
-
-"@babel/helpers@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc"
-  integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==
-  dependencies:
-    "@babel/template" "^7.16.7"
-    "@babel/traverse" "^7.16.7"
-    "@babel/types" "^7.16.7"
-
-"@babel/helpers@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9"
-  integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1"
+  integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==
   dependencies:
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
 
-"@babel/highlight@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b"
-  integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==
+"@babel/helpers@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
+  integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
   dependencies:
-    "@babel/helper-validator-identifier" "^7.16.7"
-    chalk "^2.0.0"
-    js-tokens "^4.0.0"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
 
 "@babel/highlight@^7.18.6":
   version "7.18.6"
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.0.0-beta.54", "@babel/parser@^7.16.7", "@babel/parser@^7.16.8":
-  version "7.16.8"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17"
-  integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==
-
-"@babel/parser@^7.18.6", "@babel/parser@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539"
-  integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==
+"@babel/parser@^7.0.0-beta.54", "@babel/parser@^7.18.10", "@babel/parser@^7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a"
+  integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==
 
 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
   version "7.18.6"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
     "@babel/plugin-proposal-optional-chaining" "^7.18.9"
 
-"@babel/plugin-proposal-async-generator-functions@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17"
-  integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==
+"@babel/plugin-proposal-async-generator-functions@^7.19.1":
+  version "7.19.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7"
+  integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==
   dependencies:
-    "@babel/helper-environment-visitor" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.6"
-    "@babel/helper-remap-async-to-generator" "^7.18.6"
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-remap-async-to-generator" "^7.18.9"
     "@babel/plugin-syntax-async-generators" "^7.8.4"
 
 "@babel/plugin-proposal-class-properties@^7.18.6":
     "@babel/plugin-syntax-class-static-block" "^7.14.5"
 
 "@babel/plugin-proposal-decorators@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.9.tgz#d09d41ffc74af8499d2ac706ed0dbd5474711665"
-  integrity sha512-KD7zDNaD14CRpjQjVbV4EnH9lsKYlcpUrhZH37ei2IY+AlXrfAPy5pTmRUE4X6X1k8EsKXPraykxeaogqQvSGA==
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz#c1977e4902a18cdf9051bf7bf08d97db2fd8b110"
+  integrity sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.18.9"
-    "@babel/helper-plugin-utils" "^7.18.9"
-    "@babel/helper-replace-supers" "^7.18.9"
+    "@babel/helper-create-class-features-plugin" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-replace-supers" "^7.19.1"
     "@babel/helper-split-export-declaration" "^7.18.6"
-    "@babel/plugin-syntax-decorators" "^7.18.6"
+    "@babel/plugin-syntax-decorators" "^7.19.0"
 
 "@babel/plugin-proposal-dynamic-import@^7.18.6":
   version "7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
     "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.18.6":
+"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e"
   integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==
     "@babel/helper-create-regexp-features-plugin" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2"
-  integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==
-  dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.16.7"
-    "@babel/helper-plugin-utils" "^7.16.7"
-
 "@babel/plugin-syntax-async-generators@^7.8.4":
   version "7.8.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/plugin-syntax-decorators@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.18.6.tgz#2e45af22835d0b0f8665da2bfd4463649ce5dbc1"
-  integrity sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ==
+"@babel/plugin-syntax-decorators@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599"
+  integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.19.0"
 
 "@babel/plugin-syntax-dynamic-import@^7.8.3":
   version "7.8.3"
     "@babel/helper-plugin-utils" "^7.8.0"
 
 "@babel/plugin-syntax-jsx@^7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
-  integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0"
+  integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.16.7"
+    "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
   version "7.10.4"
   dependencies:
     "@babel/helper-plugin-utils" "^7.18.9"
 
-"@babel/plugin-transform-classes@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da"
-  integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==
+"@babel/plugin-transform-classes@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20"
+  integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
+    "@babel/helper-compilation-targets" "^7.19.0"
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-function-name" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-optimise-call-expression" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.19.0"
     "@babel/helper-replace-supers" "^7.18.9"
     "@babel/helper-split-export-declaration" "^7.18.6"
     globals "^11.1.0"
   dependencies:
     "@babel/helper-plugin-utils" "^7.18.9"
 
-"@babel/plugin-transform-destructuring@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292"
-  integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA==
+"@babel/plugin-transform-destructuring@^7.18.13":
+  version "7.18.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5"
+  integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==
   dependencies:
     "@babel/helper-plugin-utils" "^7.18.9"
 
-"@babel/plugin-transform-dotall-regex@^7.18.6":
+"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8"
   integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==
     "@babel/helper-create-regexp-features-plugin" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/plugin-transform-dotall-regex@^7.4.4":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241"
-  integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==
-  dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.16.7"
-    "@babel/helper-plugin-utils" "^7.16.7"
-
 "@babel/plugin-transform-duplicate-keys@^7.18.9":
   version "7.18.9"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e"
     "@babel/helper-simple-access" "^7.18.6"
     babel-plugin-dynamic-import-node "^2.3.3"
 
-"@babel/plugin-transform-modules-systemjs@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06"
-  integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==
+"@babel/plugin-transform-modules-systemjs@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f"
+  integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==
   dependencies:
     "@babel/helper-hoist-variables" "^7.18.6"
-    "@babel/helper-module-transforms" "^7.18.9"
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-module-transforms" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
     "@babel/helper-validator-identifier" "^7.18.6"
     babel-plugin-dynamic-import-node "^2.3.3"
 
     "@babel/helper-module-transforms" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d"
-  integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1":
+  version "7.19.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888"
+  integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-create-regexp-features-plugin" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
 
 "@babel/plugin-transform-new-target@^7.18.6":
   version "7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-transform-runtime@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.9.tgz#d9e4b1b25719307bfafbf43065ed7fb3a83adb8f"
-  integrity sha512-wS8uJwBt7/b/mzE13ktsJdmS4JP/j7PQSaADtnb4I2wL0zK51MQ0pmF8/Jy0wUIS96fr+fXT6S/ifiPXnvrlSg==
+  version "7.19.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz#a3df2d7312eea624c7889a2dcd37fd1dfd25b2c6"
+  integrity sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==
   dependencies:
     "@babel/helper-module-imports" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.9"
-    babel-plugin-polyfill-corejs2 "^0.3.1"
-    babel-plugin-polyfill-corejs3 "^0.5.2"
-    babel-plugin-polyfill-regenerator "^0.3.1"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    babel-plugin-polyfill-corejs2 "^0.3.3"
+    babel-plugin-polyfill-corejs3 "^0.6.0"
+    babel-plugin-polyfill-regenerator "^0.4.1"
     semver "^6.3.0"
 
 "@babel/plugin-transform-shorthand-properties@^7.18.6":
   dependencies:
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/plugin-transform-spread@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664"
-  integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==
+"@babel/plugin-transform-spread@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6"
+  integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.19.0"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
 
 "@babel/plugin-transform-sticky-regex@^7.18.6":
     "@babel/helper-plugin-utils" "^7.18.9"
 
 "@babel/plugin-transform-typescript@^7.18.6", "@babel/plugin-transform-typescript@^7.18.8":
-  version "7.18.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0"
-  integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA==
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz#4f1db1e0fe278b42ddbc19ec2f6cd2f8262e35d6"
+  integrity sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-create-class-features-plugin" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
     "@babel/plugin-syntax-typescript" "^7.18.6"
 
-"@babel/plugin-transform-unicode-escapes@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27"
-  integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==
+"@babel/plugin-transform-unicode-escapes@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246"
+  integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.9"
 
 "@babel/plugin-transform-unicode-regex@^7.18.6":
   version "7.18.6"
     "@babel/helper-create-regexp-features-plugin" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/preset-env@7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.9.tgz#9b3425140d724fbe590322017466580844c7eaff"
-  integrity sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg==
+"@babel/preset-env@7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.3.tgz#52cd19abaecb3f176a4ff9cc5e15b7bf06bec754"
+  integrity sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==
   dependencies:
-    "@babel/compat-data" "^7.18.8"
-    "@babel/helper-compilation-targets" "^7.18.9"
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/compat-data" "^7.19.3"
+    "@babel/helper-compilation-targets" "^7.19.3"
+    "@babel/helper-plugin-utils" "^7.19.0"
     "@babel/helper-validator-option" "^7.18.6"
     "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
     "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9"
-    "@babel/plugin-proposal-async-generator-functions" "^7.18.6"
+    "@babel/plugin-proposal-async-generator-functions" "^7.19.1"
     "@babel/plugin-proposal-class-properties" "^7.18.6"
     "@babel/plugin-proposal-class-static-block" "^7.18.6"
     "@babel/plugin-proposal-dynamic-import" "^7.18.6"
     "@babel/plugin-transform-async-to-generator" "^7.18.6"
     "@babel/plugin-transform-block-scoped-functions" "^7.18.6"
     "@babel/plugin-transform-block-scoping" "^7.18.9"
-    "@babel/plugin-transform-classes" "^7.18.9"
+    "@babel/plugin-transform-classes" "^7.19.0"
     "@babel/plugin-transform-computed-properties" "^7.18.9"
-    "@babel/plugin-transform-destructuring" "^7.18.9"
+    "@babel/plugin-transform-destructuring" "^7.18.13"
     "@babel/plugin-transform-dotall-regex" "^7.18.6"
     "@babel/plugin-transform-duplicate-keys" "^7.18.9"
     "@babel/plugin-transform-exponentiation-operator" "^7.18.6"
     "@babel/plugin-transform-member-expression-literals" "^7.18.6"
     "@babel/plugin-transform-modules-amd" "^7.18.6"
     "@babel/plugin-transform-modules-commonjs" "^7.18.6"
-    "@babel/plugin-transform-modules-systemjs" "^7.18.9"
+    "@babel/plugin-transform-modules-systemjs" "^7.19.0"
     "@babel/plugin-transform-modules-umd" "^7.18.6"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1"
     "@babel/plugin-transform-new-target" "^7.18.6"
     "@babel/plugin-transform-object-super" "^7.18.6"
     "@babel/plugin-transform-parameters" "^7.18.8"
     "@babel/plugin-transform-regenerator" "^7.18.6"
     "@babel/plugin-transform-reserved-words" "^7.18.6"
     "@babel/plugin-transform-shorthand-properties" "^7.18.6"
-    "@babel/plugin-transform-spread" "^7.18.9"
+    "@babel/plugin-transform-spread" "^7.19.0"
     "@babel/plugin-transform-sticky-regex" "^7.18.6"
     "@babel/plugin-transform-template-literals" "^7.18.9"
     "@babel/plugin-transform-typeof-symbol" "^7.18.9"
-    "@babel/plugin-transform-unicode-escapes" "^7.18.6"
+    "@babel/plugin-transform-unicode-escapes" "^7.18.10"
     "@babel/plugin-transform-unicode-regex" "^7.18.6"
     "@babel/preset-modules" "^0.1.5"
-    "@babel/types" "^7.18.9"
-    babel-plugin-polyfill-corejs2 "^0.3.1"
-    babel-plugin-polyfill-corejs3 "^0.5.2"
-    babel-plugin-polyfill-regenerator "^0.3.1"
-    core-js-compat "^3.22.1"
+    "@babel/types" "^7.19.3"
+    babel-plugin-polyfill-corejs2 "^0.3.3"
+    babel-plugin-polyfill-corejs3 "^0.6.0"
+    babel-plugin-polyfill-regenerator "^0.4.1"
+    core-js-compat "^3.25.1"
     semver "^6.3.0"
 
 "@babel/preset-modules@^0.1.5":
     "@babel/helper-validator-option" "^7.18.6"
     "@babel/plugin-transform-typescript" "^7.18.6"
 
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
-  integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
-  dependencies:
-    regenerator-runtime "^0.13.4"
-
-"@babel/runtime@^7.17.2":
-  version "7.17.8"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2"
-  integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==
-  dependencies:
-    regenerator-runtime "^0.13.4"
-
-"@babel/runtime@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
-  integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
+"@babel/runtime@^7.17.2", "@babel/runtime@^7.18.9", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
+  integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
   dependencies:
     regenerator-runtime "^0.13.4"
 
-"@babel/template@^7.16.7":
-  version "7.16.7"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
-  integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
-  dependencies:
-    "@babel/code-frame" "^7.16.7"
-    "@babel/parser" "^7.16.7"
-    "@babel/types" "^7.16.7"
-
-"@babel/template@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31"
-  integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==
+"@babel/template@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
+  integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
   dependencies:
     "@babel/code-frame" "^7.18.6"
-    "@babel/parser" "^7.18.6"
-    "@babel/types" "^7.18.6"
-
-"@babel/traverse@^7.0.0-beta.54", "@babel/traverse@^7.16.7":
-  version "7.16.8"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c"
-  integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ==
-  dependencies:
-    "@babel/code-frame" "^7.16.7"
-    "@babel/generator" "^7.16.8"
-    "@babel/helper-environment-visitor" "^7.16.7"
-    "@babel/helper-function-name" "^7.16.7"
-    "@babel/helper-hoist-variables" "^7.16.7"
-    "@babel/helper-split-export-declaration" "^7.16.7"
-    "@babel/parser" "^7.16.8"
-    "@babel/types" "^7.16.8"
-    debug "^4.1.0"
-    globals "^11.1.0"
+    "@babel/parser" "^7.18.10"
+    "@babel/types" "^7.18.10"
 
-"@babel/traverse@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98"
-  integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==
+"@babel/traverse@^7.0.0-beta.54", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4"
+  integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==
   dependencies:
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.18.9"
+    "@babel/generator" "^7.19.3"
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-function-name" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-hoist-variables" "^7.18.6"
     "@babel/helper-split-export-declaration" "^7.18.6"
-    "@babel/parser" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/parser" "^7.19.3"
+    "@babel/types" "^7.19.3"
     debug "^4.1.0"
     globals "^11.1.0"
 
-"@babel/types@^7", "@babel/types@^7.0.0-beta.54", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.4.4":
-  version "7.16.8"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1"
-  integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==
+"@babel/types@^7", "@babel/types@^7.0.0-beta.54", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.4.4":
+  version "7.19.3"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624"
+  integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==
   dependencies:
-    "@babel/helper-validator-identifier" "^7.16.7"
-    to-fast-properties "^2.0.0"
-
-"@babel/types@^7.18.6", "@babel/types@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f"
-  integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==
-  dependencies:
-    "@babel/helper-validator-identifier" "^7.18.6"
+    "@babel/helper-string-parser" "^7.18.10"
+    "@babel/helper-validator-identifier" "^7.19.1"
     to-fast-properties "^2.0.0"
 
 "@discoveryjs/json-ext@^0.5.0":
-  version "0.5.6"
-  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
-  integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
+  version "0.5.7"
+  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
+  integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
 
-"@eslint/eslintrc@^1.3.0":
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"
-  integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==
+"@eslint/eslintrc@^1.3.2":
+  version "1.3.2"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356"
+  integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==
   dependencies:
     ajv "^6.12.4"
     debug "^4.3.2"
-    espree "^9.3.2"
+    espree "^9.4.0"
     globals "^13.15.0"
     ignore "^5.2.0"
     import-fresh "^3.2.1"
     minimatch "^3.1.2"
     strip-json-comments "^3.1.1"
 
-"@humanwhocodes/config-array@^0.9.2":
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914"
-  integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==
+"@humanwhocodes/config-array@^0.10.5":
+  version "0.10.5"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.5.tgz#bb679745224745fff1e9a41961c1d45a49f81c04"
+  integrity sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==
   dependencies:
     "@humanwhocodes/object-schema" "^1.2.1"
     debug "^4.1.1"
     minimatch "^3.0.4"
 
+"@humanwhocodes/gitignore-to-minimatch@^1.0.2":
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"
+  integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==
+
+"@humanwhocodes/module-importer@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+  integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
 "@humanwhocodes/object-schema@^1.2.1":
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
     update-notifier "^2.2.0"
     yargs "^8.0.2"
 
-"@jridgewell/gen-mapping@^0.3.0":
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9"
-  integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==
+"@jridgewell/gen-mapping@^0.1.0":
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
+  integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==
   dependencies:
     "@jridgewell/set-array" "^1.0.0"
     "@jridgewell/sourcemap-codec" "^1.4.10"
-    "@jridgewell/trace-mapping" "^0.3.9"
 
-"@jridgewell/gen-mapping@^0.3.2":
+"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
   integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
     "@jridgewell/trace-mapping" "^0.3.9"
 
 "@jridgewell/resolve-uri@^3.0.3":
-  version "3.0.5"
-  resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
-  integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==
-
-"@jridgewell/set-array@^1.0.0":
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea"
-  integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+  integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
 
-"@jridgewell/set-array@^1.0.1":
+"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
   integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
     "@jridgewell/trace-mapping" "^0.3.9"
 
 "@jridgewell/sourcemap-codec@^1.4.10":
-  version "1.4.11"
-  resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec"
-  integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==
+  version "1.4.14"
+  resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+  integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
 
-"@jridgewell/trace-mapping@^0.3.0":
-  version "0.3.4"
-  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3"
-  integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==
-  dependencies:
-    "@jridgewell/resolve-uri" "^3.0.3"
-    "@jridgewell/sourcemap-codec" "^1.4.10"
-
-"@jridgewell/trace-mapping@^0.3.9":
-  version "0.3.13"
-  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea"
-  integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==
+"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9":
+  version "0.3.15"
+  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
+  integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
   dependencies:
     "@jridgewell/resolve-uri" "^3.0.3"
     "@jridgewell/sourcemap-codec" "^1.4.10"
 
 "@leichtgewicht/ip-codec@^2.0.1":
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0"
-  integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
+  integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
 
 "@nodelib/fs.scandir@2.1.5":
   version "2.1.5"
     fastq "^1.6.0"
 
 "@popperjs/core@^2.9.0":
-  version "2.11.2"
-  resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9"
-  integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==
+  version "2.11.6"
+  resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45"
+  integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
 
 "@sniptt/monads@^0.5.10":
   version "0.5.10"
     "@types/node" "*"
 
 "@types/eslint-scope@^3.7.3":
-  version "3.7.3"
-  resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
-  integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==
+  version "3.7.4"
+  resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
+  integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==
   dependencies:
     "@types/eslint" "*"
     "@types/estree" "*"
 
 "@types/eslint@*":
-  version "8.2.2"
-  resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.2.tgz#b64dbdb64b1957cfc8a698c68297fcf8983e94c7"
-  integrity sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A==
+  version "8.4.6"
+  resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207"
+  integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==
   dependencies:
     "@types/estree" "*"
     "@types/json-schema" "*"
 
 "@types/estree@*":
-  version "0.0.50"
-  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
-  integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2"
+  integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
 
 "@types/estree@^0.0.51":
   version "0.0.51"
   integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
 
 "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18":
-  version "4.17.27"
-  resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz#7a776191e47295d2a05962ecbb3a4ce97e38b401"
-  integrity sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==
+  version "4.17.31"
+  resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f"
+  integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==
   dependencies:
     "@types/node" "*"
     "@types/qs" "*"
     "@types/range-parser" "*"
 
 "@types/express@*", "@types/express@^4.17.13":
-  version "4.17.13"
-  resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034"
-  integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==
+  version "4.17.14"
+  resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c"
+  integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==
   dependencies:
     "@types/body-parser" "*"
     "@types/express-serve-static-core" "^4.17.18"
     "@types/node" "*"
 
 "@types/http-proxy@^1.17.8":
-  version "1.17.8"
-  resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55"
-  integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==
+  version "1.17.9"
+  resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a"
+  integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==
   dependencies:
     "@types/node" "*"
 
 "@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
-  version "7.0.9"
-  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
-  integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+  version "7.0.11"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
+  integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
 
-"@types/mime@^1":
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
-  integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
+"@types/mime@*":
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
+  integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
 
 "@types/minimatch@*":
-  version "3.0.5"
-  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
-  integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
+  integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
 
 "@types/node-fetch@^2.6.2":
   version "2.6.2"
     "@types/node" "*"
     form-data "^3.0.0"
 
-"@types/node@*":
-  version "17.0.8"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b"
-  integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==
-
-"@types/node@^18.6.2":
-  version "18.6.2"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.2.tgz#ffc5f0f099d27887c8d9067b54e55090fcd54126"
-  integrity sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==
+"@types/node@*", "@types/node@^18.6.2":
+  version "18.7.23"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f"
+  integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==
 
 "@types/qs@*":
   version "6.9.7"
   resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
   integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
 
-"@types/retry@^0.12.0":
-  version "0.12.1"
-  resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
-  integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==
+"@types/retry@0.12.0":
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
+  integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
 
 "@types/serialize-javascript@^5.0.1":
   version "5.0.2"
     "@types/express" "*"
 
 "@types/serve-static@*", "@types/serve-static@^1.13.10":
-  version "1.13.10"
-  resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9"
-  integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==
+  version "1.15.0"
+  resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
+  integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==
   dependencies:
-    "@types/mime" "^1"
+    "@types/mime" "*"
     "@types/node" "*"
 
 "@types/sockjs@^0.3.33":
     "@types/node" "*"
 
 "@typescript-eslint/eslint-plugin@^5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.31.0.tgz#cae1967b1e569e6171bbc6bec2afa4e0c8efccfe"
-  integrity sha512-VKW4JPHzG5yhYQrQ1AzXgVgX8ZAJEvCz0QI6mLRX4tf7rnFfh5D8SKm0Pq6w5PyNfAWJk6sv313+nEt3ohWMBQ==
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz#9f05d42fa8fb9f62304cc2f5c2805e03c01c2620"
+  integrity sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.31.0"
-    "@typescript-eslint/type-utils" "5.31.0"
-    "@typescript-eslint/utils" "5.31.0"
+    "@typescript-eslint/scope-manager" "5.38.1"
+    "@typescript-eslint/type-utils" "5.38.1"
+    "@typescript-eslint/utils" "5.38.1"
     debug "^4.3.4"
-    functional-red-black-tree "^1.0.1"
     ignore "^5.2.0"
     regexpp "^3.2.0"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
 "@typescript-eslint/parser@^5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.31.0.tgz#7f42d7dcc68a0a6d80a0f3d9a65063aee7bb8d2c"
-  integrity sha512-UStjQiZ9OFTFReTrN+iGrC6O/ko9LVDhreEK5S3edmXgR396JGq7CoX2TWIptqt/ESzU2iRKXAHfSF2WJFcWHw==
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.38.1.tgz#c577f429f2c32071b92dff4af4f5fbbbd2414bd0"
+  integrity sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.31.0"
-    "@typescript-eslint/types" "5.31.0"
-    "@typescript-eslint/typescript-estree" "5.31.0"
+    "@typescript-eslint/scope-manager" "5.38.1"
+    "@typescript-eslint/types" "5.38.1"
+    "@typescript-eslint/typescript-estree" "5.38.1"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.31.0.tgz#f47a794ba84d9b818ab7f8f44fff55a61016c606"
-  integrity sha512-8jfEzBYDBG88rcXFxajdVavGxb5/XKXyvWgvD8Qix3EEJLCFIdVloJw+r9ww0wbyNLOTYyBsR+4ALNGdlalLLg==
+"@typescript-eslint/scope-manager@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz#f87b289ef8819b47189351814ad183e8801d5764"
+  integrity sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==
   dependencies:
-    "@typescript-eslint/types" "5.31.0"
-    "@typescript-eslint/visitor-keys" "5.31.0"
+    "@typescript-eslint/types" "5.38.1"
+    "@typescript-eslint/visitor-keys" "5.38.1"
 
-"@typescript-eslint/type-utils@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.31.0.tgz#70a0b7201360b5adbddb0c36080495aa08f6f3d9"
-  integrity sha512-7ZYqFbvEvYXFn9ax02GsPcEOmuWNg+14HIf4q+oUuLnMbpJ6eHAivCg7tZMVwzrIuzX3QCeAOqKoyMZCv5xe+w==
+"@typescript-eslint/type-utils@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz#7f038fcfcc4ade4ea76c7c69b2aa25e6b261f4c1"
+  integrity sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==
   dependencies:
-    "@typescript-eslint/utils" "5.31.0"
+    "@typescript-eslint/typescript-estree" "5.38.1"
+    "@typescript-eslint/utils" "5.38.1"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.31.0.tgz#7aa389122b64b18e473c1672fb3b8310e5f07a9a"
-  integrity sha512-/f/rMaEseux+I4wmR6mfpM2wvtNZb1p9hAV77hWfuKc3pmaANp5dLAZSiE3/8oXTYTt3uV9KW5yZKJsMievp6g==
+"@typescript-eslint/types@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.1.tgz#74f9d6dcb8dc7c58c51e9fbc6653ded39e2e225c"
+  integrity sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==
 
-"@typescript-eslint/typescript-estree@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.31.0.tgz#eb92970c9d6e3946690d50c346fb9b1d745ee882"
-  integrity sha512-3S625TMcARX71wBc2qubHaoUwMEn+l9TCsaIzYI/ET31Xm2c9YQ+zhGgpydjorwQO9pLfR/6peTzS/0G3J/hDw==
+"@typescript-eslint/typescript-estree@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz#657d858d5d6087f96b638ee383ee1cff52605a1e"
+  integrity sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==
   dependencies:
-    "@typescript-eslint/types" "5.31.0"
-    "@typescript-eslint/visitor-keys" "5.31.0"
+    "@typescript-eslint/types" "5.38.1"
+    "@typescript-eslint/visitor-keys" "5.38.1"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.31.0.tgz#e146fa00dca948bfe547d665b2138a2dc1b79acd"
-  integrity sha512-kcVPdQS6VIpVTQ7QnGNKMFtdJdvnStkqS5LeALr4rcwx11G6OWb2HB17NMPnlRHvaZP38hL9iK8DdE9Fne7NYg==
+"@typescript-eslint/utils@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.38.1.tgz#e3ac37d7b33d1362bb5adf4acdbe00372fb813ef"
+  integrity sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==
   dependencies:
     "@types/json-schema" "^7.0.9"
-    "@typescript-eslint/scope-manager" "5.31.0"
-    "@typescript-eslint/types" "5.31.0"
-    "@typescript-eslint/typescript-estree" "5.31.0"
+    "@typescript-eslint/scope-manager" "5.38.1"
+    "@typescript-eslint/types" "5.38.1"
+    "@typescript-eslint/typescript-estree" "5.38.1"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/visitor-keys@5.31.0":
-  version "5.31.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.31.0.tgz#b0eca264df01ce85dceb76aebff3784629258f54"
-  integrity sha512-ZK0jVxSjS4gnPirpVjXHz7mgdOsZUHzNYSfTw2yPa3agfbt9YfqaBiBZFSSxeBWnpWkzCxTfUpnzA3Vily/CSg==
+"@typescript-eslint/visitor-keys@5.38.1":
+  version "5.38.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz#508071bfc6b96d194c0afe6a65ad47029059edbc"
+  integrity sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==
   dependencies:
-    "@typescript-eslint/types" "5.31.0"
+    "@typescript-eslint/types" "5.38.1"
     eslint-visitor-keys "^3.3.0"
 
 "@webassemblyjs/ast@1.11.1":
@@ -1764,15 +1515,7 @@ abbrev@1, abbrev@~1.1.1:
   resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
   integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
 
-accepts@~1.3.4, accepts@~1.3.5:
-  version "1.3.7"
-  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
-  integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
-  dependencies:
-    mime-types "~2.1.24"
-    negotiator "0.6.2"
-
-accepts@~1.3.8:
+accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
   version "1.3.8"
   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
   integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
@@ -1790,12 +1533,7 @@ acorn-jsx@^5.3.2:
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
   integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
 
-acorn@^8.5.0:
-  version "8.7.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
-  integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
-
-acorn@^8.7.1:
+acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
   version "8.8.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
   integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
@@ -1859,9 +1597,9 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
     uri-js "^4.2.2"
 
 ajv@^8.0.0, ajv@^8.8.0:
-  version "8.8.2"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb"
-  integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==
+  version "8.11.0"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
+  integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
   dependencies:
     fast-deep-equal "^3.1.1"
     json-schema-traverse "^1.0.0"
@@ -1871,7 +1609,7 @@ ajv@^8.0.0, ajv@^8.8.0:
 ansi-align@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
-  integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
+  integrity sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==
   dependencies:
     string-width "^2.0.0"
 
@@ -1890,17 +1628,17 @@ ansi-html-community@^0.0.8:
 ansi-regex@^2.0.0:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
-  integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
+  integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
 
 ansi-regex@^3.0.0, ansi-regex@~3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
-  integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
+  integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
 
 ansi-regex@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
-  integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
+  integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
 
 ansi-regex@^5.0.1:
   version "5.0.1"
@@ -1927,19 +1665,19 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
     color-convert "^2.0.1"
 
 ansi-styles@^6.0.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3"
-  integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.1.tgz#63cd61c72283a71cb30bd881dbb60adada74bc70"
+  integrity sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg==
 
 ansicolors@~0.3.2:
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
-  integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=
+  integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==
 
 ansistyles@~0.1.3:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
-  integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=
+  integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g==
 
 anymatch@~3.1.2:
   version "3.1.2"
@@ -1962,7 +1700,7 @@ aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2, aproba@~1.2.0:
 archy@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
-  integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
+  integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==
 
 are-we-there-yet@~1.1.2:
   version "1.1.7"
@@ -1987,17 +1725,28 @@ argparse@^2.0.1:
 array-flatten@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
-  integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
+  integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
 
 array-flatten@^2.1.2:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
   integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
 
+array-includes@^3.1.5:
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
+  integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
+    get-intrinsic "^1.1.1"
+    is-string "^1.0.7"
+
 array-union@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
-  integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
+  integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==
   dependencies:
     array-uniq "^1.0.1"
 
@@ -2009,12 +1758,23 @@ array-union@^2.1.0:
 array-uniq@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
-  integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
+  integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==
+
+array.prototype.reduce@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz#8167e80089f78bff70a99e20bd4201d4663b0a6f"
+  integrity sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.19.2"
+    es-array-method-boxes-properly "^1.0.0"
+    is-string "^1.0.7"
 
 asap@^2.0.0:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
-  integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
+  integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
 
 asn1@~0.2.3:
   version "0.2.6"
@@ -2026,7 +1786,7 @@ asn1@~0.2.3:
 assert-plus@1.0.0, assert-plus@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
-  integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+  integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
 
 astral-regex@^2.0.0:
   version "2.0.0"
@@ -2036,7 +1796,7 @@ astral-regex@^2.0.0:
 asynckit@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
-  integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+  integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
 
 autosize@^5.0.1:
   version "5.0.1"
@@ -2046,7 +1806,7 @@ autosize@^5.0.1:
 aws-sign2@~0.7.0:
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
-  integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
+  integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
 
 aws4@^1.8.0:
   version "1.11.0"
@@ -2078,29 +1838,29 @@ babel-plugin-inferno@^6.5.0:
     "@babel/plugin-syntax-jsx" "^7"
     "@babel/types" "^7"
 
-babel-plugin-polyfill-corejs2@^0.3.1:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d"
-  integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==
+babel-plugin-polyfill-corejs2@^0.3.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122"
+  integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==
   dependencies:
     "@babel/compat-data" "^7.17.7"
-    "@babel/helper-define-polyfill-provider" "^0.3.2"
+    "@babel/helper-define-polyfill-provider" "^0.3.3"
     semver "^6.1.1"
 
-babel-plugin-polyfill-corejs3@^0.5.2:
-  version "0.5.3"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7"
-  integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==
+babel-plugin-polyfill-corejs3@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a"
+  integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==
   dependencies:
-    "@babel/helper-define-polyfill-provider" "^0.3.2"
-    core-js-compat "^3.21.0"
+    "@babel/helper-define-polyfill-provider" "^0.3.3"
+    core-js-compat "^3.25.1"
 
-babel-plugin-polyfill-regenerator@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990"
-  integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==
+babel-plugin-polyfill-regenerator@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747"
+  integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==
   dependencies:
-    "@babel/helper-define-polyfill-provider" "^0.3.1"
+    "@babel/helper-define-polyfill-provider" "^0.3.3"
 
 balanced-match@^1.0.0:
   version "1.0.2"
@@ -2110,12 +1870,12 @@ balanced-match@^1.0.0:
 batch@0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
-  integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
+  integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
 
 bcrypt-pbkdf@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
-  integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
+  integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
   dependencies:
     tweetnacl "^0.14.3"
 
@@ -2144,7 +1904,7 @@ binary-extensions@^2.0.0:
 block-stream@*:
   version "0.0.9"
   resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
-  integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=
+  integrity sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ==
   dependencies:
     inherits "~2.0.0"
 
@@ -2177,24 +1937,24 @@ body-parser@1.20.0:
     unpipe "1.0.0"
 
 bonjour-service@^1.0.11:
-  version "1.0.12"
-  resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.12.tgz#28fbd4683f5f2e36feedb833e24ba661cac960c3"
-  integrity sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw==
+  version "1.0.14"
+  resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7"
+  integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==
   dependencies:
     array-flatten "^2.1.2"
     dns-equal "^1.0.0"
     fast-deep-equal "^3.1.3"
-    multicast-dns "^7.2.4"
+    multicast-dns "^7.2.5"
 
 bootstrap@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.0.tgz#838727fb60f1630db370fe57c63cbcf2962bb3d3"
-  integrity sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A==
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.1.tgz#45f97ff05cbe828bad807b014d8425f3aeb8ec3a"
+  integrity sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA==
 
 bootswatch@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-5.2.0.tgz#c02a0d84e0382552f8a7b9bdd055f36b758ffed9"
-  integrity sha512-v9krdPdybb5hUwVwlv3f7/FhOa5cXbCb5U5CI4gdnalcxR3ekclXE6kPZWL5O8V8qwNI9BB73apASO1MLmRpIA==
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-5.2.1.tgz#80c49ac3ad394e58be630978c95e3bce1d1679ac"
+  integrity sha512-tbuZb0nJ1XUvRO8KYoEULsbAlAqazcFS6S5dTeJOkw2RxQgg0RJqKkngRTfNSFfqfI4mTdFPpC4mKkaw0YoDFA==
 
 boxen@^1.2.1:
   version "1.3.0"
@@ -2217,33 +1977,29 @@ brace-expansion@^1.1.7:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
 
-braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
+brace-expansion@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
+  integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
+  dependencies:
+    balanced-match "^1.0.0"
+
+braces@^3.0.2, braces@~3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
   integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
   dependencies:
     fill-range "^7.0.1"
 
-browserslist@^4.14.5, browserslist@^4.17.5:
-  version "4.19.1"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3"
-  integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==
-  dependencies:
-    caniuse-lite "^1.0.30001286"
-    electron-to-chromium "^1.4.17"
-    escalade "^3.1.1"
-    node-releases "^2.0.1"
-    picocolors "^1.0.0"
-
-browserslist@^4.20.2, browserslist@^4.21.2:
-  version "4.21.3"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a"
-  integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==
+browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4:
+  version "4.21.4"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
+  integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
   dependencies:
-    caniuse-lite "^1.0.30001370"
-    electron-to-chromium "^1.4.202"
+    caniuse-lite "^1.0.30001400"
+    electron-to-chromium "^1.4.251"
     node-releases "^2.0.6"
-    update-browserslist-db "^1.0.5"
+    update-browserslist-db "^1.0.9"
 
 buffer-from@^1.0.0:
   version "1.1.2"
@@ -2253,22 +2009,22 @@ buffer-from@^1.0.0:
 builtin-modules@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
-  integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
+  integrity sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==
 
-builtin-modules@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
-  integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
+builtin-modules@^3.3.0:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
+  integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
 
 builtins@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
-  integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
+  integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==
 
 byline@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
-  integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
+  integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==
 
 byte-size@^4.0.2:
   version "4.0.4"
@@ -2278,7 +2034,7 @@ byte-size@^4.0.2:
 bytes@3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
-  integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
+  integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
 
 bytes@3.1.2:
   version "3.1.2"
@@ -2340,21 +2096,21 @@ call-limit@~1.1.0:
 caller-callsite@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
-  integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
+  integrity sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==
   dependencies:
     callsites "^2.0.0"
 
 caller-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
-  integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
+  integrity sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==
   dependencies:
     caller-callsite "^2.0.0"
 
 callsites@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
-  integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
+  integrity sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==
 
 callsites@^3.0.0:
   version "3.1.0"
@@ -2364,22 +2120,17 @@ callsites@^3.0.0:
 camelcase@^4.0.0, camelcase@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
-  integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
+  integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==
 
 camelcase@^5.0.0:
   version "5.3.1"
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
   integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
 
-caniuse-lite@^1.0.30001286:
-  version "1.0.30001298"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52"
-  integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ==
-
-caniuse-lite@^1.0.30001370:
-  version "1.0.30001373"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be"
-  integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==
+caniuse-lite@^1.0.30001400:
+  version "1.0.30001412"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz#30f67d55a865da43e0aeec003f073ea8764d5d7c"
+  integrity sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==
 
 capture-stack-trace@^1.0.0:
   version "1.0.1"
@@ -2389,7 +2140,7 @@ capture-stack-trace@^1.0.0:
 caseless@~0.12.0:
   version "0.12.0"
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
-  integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+  integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
 
 chalk@^2.0.0, chalk@^2.0.1:
   version "2.4.2"
@@ -2422,22 +2173,7 @@ choices.js@^10.1.0:
     fuse.js "^6.5.3"
     redux "^4.1.2"
 
-"chokidar@>=3.0.0 <4.0.0":
-  version "3.5.2"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
-  integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
-  dependencies:
-    anymatch "~3.1.2"
-    braces "~3.0.2"
-    glob-parent "~5.1.2"
-    is-binary-path "~2.1.0"
-    is-glob "~4.0.1"
-    normalize-path "~3.0.0"
-    readdirp "~3.6.0"
-  optionalDependencies:
-    fsevents "~2.3.2"
-
-chokidar@^3.5.3:
+"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3:
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
   integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -2460,7 +2196,7 @@ chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4:
 chownr@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
-  integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=
+  integrity sha512-cKnqUJAC8G6cuN1DiRRTifu+s1BlAQNtalzGphFEV0pl0p46dsxJD4l1AOlyKJeLZOFzo3c34R7F3djxaCu8Kw==
 
 chrome-trace-event@^1.0.2:
   version "1.0.3"
@@ -2475,7 +2211,7 @@ ci-info@^1.5.0:
 cidr-regex@1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-1.0.6.tgz#74abfd619df370b9d54ab14475568e97dd64c0c1"
-  integrity sha1-dKv9YZ3zcLnVSrFEdVaOl91kwME=
+  integrity sha512-vIIQZtDT0y3GmcVqi4Uhd43s7HKn5DtH8/CcmHe/XG1Vb4JpUgOfTynZzYSo1zeB+j4GbA38Eu2P9UTbIzDw5g==
 
 class-transformer@^0.5.1:
   version "0.5.1"
@@ -2483,9 +2219,9 @@ class-transformer@^0.5.1:
   integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==
 
 classnames@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
-  integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
+  integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
 
 clean-stack@^2.0.0:
   version "2.2.0"
@@ -2502,12 +2238,12 @@ clean-webpack-plugin@^4.0.0:
 cli-boxes@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
-  integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
+  integrity sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==
 
 cli-columns@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e"
-  integrity sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=
+  integrity sha512-iQYpDgpPPmCjn534ikQOhi+ydP6uMar+DtJ6a0In4aGL/PKqWfao75s6eF81quQQaz7isGz+goNECLARRZswdg==
   dependencies:
     string-width "^2.0.0"
     strip-ansi "^3.0.1"
@@ -2522,7 +2258,7 @@ cli-cursor@^3.1.0:
 cli-table2@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97"
-  integrity sha1-LR738hig54biFFQFYtS9F3/jLZc=
+  integrity sha512-rNig1Ons+B0eTcophmN0nlbsROa7B3+Yfo1J3leU56awc8IuKDW3MLMv9gayl4zUnYaLGg8CrecKso+hSmUvUw==
   dependencies:
     lodash "^3.10.1"
     string-width "^1.0.1"
@@ -2558,7 +2294,7 @@ cli-truncate@^3.1.0:
 cliui@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
-  integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
+  integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==
   dependencies:
     string-width "^1.0.1"
     strip-ansi "^3.0.1"
@@ -2585,7 +2321,7 @@ clone-deep@^4.0.1:
 clone@^1.0.2:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
-  integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
+  integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
 
 cmd-shim@^3.0.0, cmd-shim@^3.0.3:
   version "3.0.3"
@@ -2598,7 +2334,7 @@ cmd-shim@^3.0.0, cmd-shim@^3.0.3:
 cmd-shim@~2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb"
-  integrity sha1-b8vamUg6j9FdfTChlspp1oii79s=
+  integrity sha512-NLt0ntM0kvuSNrToO0RTFiNRHdioWsLW+OgDAEVDvIivsYwR+AjlzvLaMJ2Z+SNRpV3vdsDrHp1WI00eetDYzw==
   dependencies:
     graceful-fs "^4.1.2"
     mkdirp "~0.5.0"
@@ -2606,7 +2342,7 @@ cmd-shim@~2.0.2:
 code-point-at@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
-  integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+  integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
 
 color-convert@^1.9.0:
   version "1.9.3"
@@ -2625,19 +2361,14 @@ color-convert@^2.0.1:
 color-name@1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
-  integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+  integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
 
 color-name@~1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
-colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16:
-  version "2.0.16"
-  resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
-  integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
-
-colorette@^2.0.17:
+colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16, colorette@^2.0.17:
   version "2.0.19"
   resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
   integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
@@ -2650,7 +2381,7 @@ colors@^1.1.2:
 columnify@~1.5.4:
   version "1.5.4"
   resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
-  integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=
+  integrity sha512-rFl+iXVT1nhLQPfGDw+3WcS8rmm7XsLKUmhsGE3ihzzpIikeGrTaZPIRKYWeLsLBypsHzjXIvYEltVUZS84XxQ==
   dependencies:
     strip-ansi "^3.0.0"
     wcwidth "^1.0.0"
@@ -2680,7 +2411,7 @@ commander@^9.3.0:
 commondir@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
-  integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
+  integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
 
 compressible@~2.0.16:
   version "2.0.18"
@@ -2705,7 +2436,7 @@ compression@^1.7.4:
 concat-map@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+  integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
 
 concat-stream@^1.5.0, concat-stream@^1.5.2:
   version "1.6.2"
@@ -2745,7 +2476,7 @@ connect-history-api-fallback@^2.0.0:
 console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
-  integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
+  integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==
 
 content-disposition@0.5.4:
   version "0.5.4"
@@ -2769,7 +2500,7 @@ convert-source-map@^1.7.0:
 cookie-signature@1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
-  integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
+  integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
 
 cookie@0.5.0:
   version "0.5.0"
@@ -2779,7 +2510,7 @@ cookie@0.5.0:
 cookie@^0.1.2:
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.5.tgz#6ab9948a4b1ae21952cd2588530a4722d4044d7c"
-  integrity sha1-armUiksa4hlSzSWIUwpHItQETXw=
+  integrity sha512-/lhu+NGBI5pOLXILS07DrPXYX0QDD/ejVhbwoCUcLPBqMEK9b++f9rUhAlhLkcTz9mV6QSeD+w3cHJ96rMZaFQ==
 
 copy-concurrently@^1.0.0:
   version "1.0.5"
@@ -2805,18 +2536,17 @@ copy-webpack-plugin@^11.0.0:
     schema-utils "^4.0.0"
     serialize-javascript "^6.0.0"
 
-core-js-compat@^3.21.0, core-js-compat@^3.22.1:
-  version "3.24.0"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.0.tgz#885958fac38bf3f4464a90f2663b4620f6aee6e3"
-  integrity sha512-F+2E63X3ff/nj8uIrf8Rf24UDGIz7p838+xjEp+Bx3y8OWXj+VTPPZNCtdqovPaS9o7Tka5mCH01Zn5vOd6UQg==
+core-js-compat@^3.25.1:
+  version "3.25.3"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.3.tgz#d6a442a03f4eade4555d4e640e6a06151dd95d38"
+  integrity sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==
   dependencies:
-    browserslist "^4.21.2"
-    semver "7.0.0"
+    browserslist "^4.21.4"
 
 core-util-is@1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
-  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+  integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
 
 core-util-is@~1.0.0:
   version "1.0.3"
@@ -2836,14 +2566,14 @@ cosmiconfig@^5.0.5:
 create-error-class@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
-  integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=
+  integrity sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==
   dependencies:
     capture-stack-trace "^1.0.0"
 
 cross-spawn@^5.0.1:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
-  integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
+  integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==
   dependencies:
     lru-cache "^4.0.1"
     shebang-command "^1.2.0"
@@ -2861,7 +2591,7 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
 crypto-random-string@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
-  integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
+  integrity sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==
 
 css-loader@^6.7.1:
   version "6.7.1"
@@ -2882,15 +2612,20 @@ cssesc@^3.0.0:
   resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
   integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
 
+csstype@^3.1.0:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
+  integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
+
 cyclist@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
-  integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
+  integrity sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==
 
 dashdash@^1.12.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
-  integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
+  integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
   dependencies:
     assert-plus "^1.0.0"
 
@@ -2915,14 +2650,7 @@ debug@^3.1.0:
   dependencies:
     ms "^2.1.1"
 
-debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
-  version "4.3.3"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
-  integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
-  dependencies:
-    ms "2.1.2"
-
-debug@^4.3.4:
+debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
   integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2932,17 +2660,17 @@ debug@^4.3.4:
 debuglog@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
-  integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
+  integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==
 
 decamelize@^1.1.1, decamelize@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
-  integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+  integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
 
 decode-uri-component@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
-  integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+  integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==
 
 deep-equal@^1.0.1:
   version "1.1.1"
@@ -2981,7 +2709,7 @@ default-gateway@^6.0.3:
 defaults@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
-  integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
+  integrity sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==
   dependencies:
     clone "^1.0.2"
 
@@ -2990,12 +2718,13 @@ define-lazy-prop@^2.0.0:
   resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
   integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
 
-define-properties@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
-  integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
+define-properties@^1.1.3, define-properties@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
+  integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
   dependencies:
-    object-keys "^1.0.12"
+    has-property-descriptors "^1.0.0"
+    object-keys "^1.1.1"
 
 del@^4.1.1:
   version "4.1.1"
@@ -3013,12 +2742,12 @@ del@^4.1.1:
 delayed-stream@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
-  integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+  integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
 
 delegates@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-  integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
+  integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
 
 depd@2.0.0:
   version "2.0.0"
@@ -3028,7 +2757,7 @@ depd@2.0.0:
 depd@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
-  integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
+  integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
 
 destroy@1.2.0:
   version "1.2.0"
@@ -3043,7 +2772,7 @@ detect-indent@^6.0.0:
 detect-indent@~5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
-  integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
+  integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==
 
 detect-newline@3.1.0:
   version "3.1.0"
@@ -3053,7 +2782,7 @@ detect-newline@3.1.0:
 detect-newline@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
-  integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
+  integrity sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==
 
 detect-node@^2.0.4:
   version "2.1.0"
@@ -3061,9 +2790,9 @@ detect-node@^2.0.4:
   integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
 
 dezalgo@^1.0.0, dezalgo@~1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
-  integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81"
+  integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==
   dependencies:
     asap "^2.0.0"
     wrappy "1"
@@ -3078,12 +2807,12 @@ dir-glob@^3.0.1:
 dns-equal@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
-  integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
+  integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==
 
 dns-packet@^5.2.2:
-  version "5.3.1"
-  resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d"
-  integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b"
+  integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==
   dependencies:
     "@leichtgewicht/ip-codec" "^2.0.1"
 
@@ -3107,9 +2836,9 @@ dotenv@^5.0.1:
   integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==
 
 duplexer3@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
-  integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
+  integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
 
 duplexify@^3.4.2, duplexify@^3.6.0:
   version "3.7.1"
@@ -3129,7 +2858,7 @@ eastasianwidth@^0.2.0:
 ecc-jsbn@~0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
-  integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
+  integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
   dependencies:
     jsbn "~0.1.0"
     safer-buffer "^2.1.0"
@@ -3137,22 +2866,17 @@ ecc-jsbn@~0.1.1:
 editor@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
-  integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=
+  integrity sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw==
 
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-  integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
+  integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
 
-electron-to-chromium@^1.4.17:
-  version "1.4.41"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.41.tgz#0b2e126796e7fafb9fd71e29304468b9d0af5d65"
-  integrity sha512-VQEXEJc+8rJIva85H8EPtB5Ux9g8TzkNGBanqphM9ZWMZ34elueKJ+5g+BPhz3Lk8gkujfQRcIZ+fpA0btUIuw==
-
-electron-to-chromium@^1.4.202:
-  version "1.4.206"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4"
-  integrity sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==
+electron-to-chromium@^1.4.251:
+  version "1.4.264"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz#2f68a062c38b7a04bf57f3e6954b868672fbdcd3"
+  integrity sha512-AZ6ZRkucHOQT8wke50MktxtmcWZr67kE17X/nAXFf62NIdMdgY6xfsaJD5Szoy84lnkuPWH+4tTNE3s2+bPCiw==
 
 emoji-regex@^7.0.1:
   version "7.0.3"
@@ -3182,7 +2906,7 @@ emojis-list@^3.0.0:
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
-  integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
+  integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
 
 encoding@^0.1.11:
   version "0.1.13"
@@ -3224,7 +2948,7 @@ envinfo@^7.7.3:
 err-code@^1.0.0:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
-  integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
+  integrity sha512-CJAN+O0/yA1CKfRn9SXOGctSpEM7DCon/r/5r2eXFMY2zCCJBasFhcM5I+1kh3Ap11FsQCX+vGHceNPvpWKhoA==
 
 errno@~0.1.7:
   version "0.1.8"
@@ -3240,31 +2964,40 @@ error-ex@^1.2.0, error-ex@^1.3.1:
   dependencies:
     is-arrayish "^0.2.1"
 
-es-abstract@^1.19.1:
-  version "1.19.1"
-  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
-  integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
+es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.1:
+  version "1.20.3"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1"
+  integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==
   dependencies:
     call-bind "^1.0.2"
     es-to-primitive "^1.2.1"
     function-bind "^1.1.1"
-    get-intrinsic "^1.1.1"
+    function.prototype.name "^1.1.5"
+    get-intrinsic "^1.1.3"
     get-symbol-description "^1.0.0"
     has "^1.0.3"
-    has-symbols "^1.0.2"
+    has-property-descriptors "^1.0.0"
+    has-symbols "^1.0.3"
     internal-slot "^1.0.3"
-    is-callable "^1.2.4"
-    is-negative-zero "^2.0.1"
+    is-callable "^1.2.6"
+    is-negative-zero "^2.0.2"
     is-regex "^1.1.4"
-    is-shared-array-buffer "^1.0.1"
+    is-shared-array-buffer "^1.0.2"
     is-string "^1.0.7"
-    is-weakref "^1.0.1"
-    object-inspect "^1.11.0"
+    is-weakref "^1.0.2"
+    object-inspect "^1.12.2"
     object-keys "^1.1.1"
-    object.assign "^4.1.2"
-    string.prototype.trimend "^1.0.4"
-    string.prototype.trimstart "^1.0.4"
-    unbox-primitive "^1.0.1"
+    object.assign "^4.1.4"
+    regexp.prototype.flags "^1.4.3"
+    safe-regex-test "^1.0.0"
+    string.prototype.trimend "^1.0.5"
+    string.prototype.trimstart "^1.0.5"
+    unbox-primitive "^1.0.2"
+
+es-array-method-boxes-properly@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
+  integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
 
 es-module-lexer@^0.9.0:
   version "0.9.3"
@@ -3288,7 +3021,7 @@ es6-promise@^4.0.3:
 es6-promisify@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
-  integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
+  integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==
   dependencies:
     es6-promise "^4.0.3"
 
@@ -3300,18 +3033,34 @@ escalade@^3.1.1:
 escape-html@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
-  integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+  integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
 
 escape-string-regexp@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+  integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
 
 escape-string-regexp@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
   integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
 
+eslint-plugin-inferno@^7.31.8:
+  version "7.31.8"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-inferno/-/eslint-plugin-inferno-7.31.8.tgz#4f83ed446a14d428a791188cc10ea07080563f77"
+  integrity sha512-3ZfdlZB8qDzKgRo28MuNWXOwwpxPuDBvwl6SwgBmz9uRKrAUTvxWT3/GzVCoYvhFTLmgo6Z7UVKV5wvJucnNbw==
+  dependencies:
+    doctrine "^3.0.0"
+    estraverse "^5.3.0"
+    jsx-ast-utils "^3.3.3"
+    minimatch "^5.1.0"
+    object.entries "^1.1.5"
+    object.fromentries "^2.0.5"
+    object.hasown "^1.1.1"
+    object.values "^1.1.5"
+    prop-types "^15.8.1"
+    resolve "^2.0.0-next.4"
+
 eslint-plugin-prettier@^4.2.1:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b"
@@ -3353,12 +3102,14 @@ eslint-visitor-keys@^3.3.0:
   integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
 
 eslint@^8.20.0:
-  version "8.20.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b"
-  integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==
-  dependencies:
-    "@eslint/eslintrc" "^1.3.0"
-    "@humanwhocodes/config-array" "^0.9.2"
+  version "8.24.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.24.0.tgz#489516c927a5da11b3979dbfb2679394523383c8"
+  integrity sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==
+  dependencies:
+    "@eslint/eslintrc" "^1.3.2"
+    "@humanwhocodes/config-array" "^0.10.5"
+    "@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
+    "@humanwhocodes/module-importer" "^1.0.1"
     ajv "^6.10.0"
     chalk "^4.0.0"
     cross-spawn "^7.0.2"
@@ -3368,18 +3119,21 @@ eslint@^8.20.0:
     eslint-scope "^7.1.1"
     eslint-utils "^3.0.0"
     eslint-visitor-keys "^3.3.0"
-    espree "^9.3.2"
+    espree "^9.4.0"
     esquery "^1.4.0"
     esutils "^2.0.2"
     fast-deep-equal "^3.1.3"
     file-entry-cache "^6.0.1"
-    functional-red-black-tree "^1.0.1"
+    find-up "^5.0.0"
     glob-parent "^6.0.1"
     globals "^13.15.0"
+    globby "^11.1.0"
+    grapheme-splitter "^1.0.4"
     ignore "^5.2.0"
     import-fresh "^3.0.0"
     imurmurhash "^0.1.4"
     is-glob "^4.0.0"
+    js-sdsl "^4.1.4"
     js-yaml "^4.1.0"
     json-stable-stringify-without-jsonify "^1.0.1"
     levn "^0.4.1"
@@ -3391,14 +3145,13 @@ eslint@^8.20.0:
     strip-ansi "^6.0.1"
     strip-json-comments "^3.1.0"
     text-table "^0.2.0"
-    v8-compile-cache "^2.0.3"
 
-espree@^9.3.2:
-  version "9.3.2"
-  resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596"
-  integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==
+espree@^9.4.0:
+  version "9.4.0"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
+  integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
   dependencies:
-    acorn "^8.7.1"
+    acorn "^8.8.0"
     acorn-jsx "^5.3.2"
     eslint-visitor-keys "^3.3.0"
 
@@ -3426,7 +3179,7 @@ estraverse@^4.1.1:
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
   integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
-estraverse@^5.1.0, estraverse@^5.2.0:
+estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
   version "5.3.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
   integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
@@ -3439,7 +3192,7 @@ esutils@^2.0.2:
 etag@~1.8.1:
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
-  integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+  integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
 
 eventemitter3@^4.0.0:
   version "4.0.7"
@@ -3454,7 +3207,7 @@ events@^3.2.0:
 execa@^0.7.0:
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
-  integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
+  integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==
   dependencies:
     cross-spawn "^5.0.1"
     get-stream "^3.0.0"
@@ -3497,46 +3250,9 @@ execa@^6.1.0:
 exenv@^1.2.1:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
-  integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
-
-express@^4.17.3:
-  version "4.18.0"
-  resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2"
-  integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==
-  dependencies:
-    accepts "~1.3.8"
-    array-flatten "1.1.1"
-    body-parser "1.20.0"
-    content-disposition "0.5.4"
-    content-type "~1.0.4"
-    cookie "0.5.0"
-    cookie-signature "1.0.6"
-    debug "2.6.9"
-    depd "2.0.0"
-    encodeurl "~1.0.2"
-    escape-html "~1.0.3"
-    etag "~1.8.1"
-    finalhandler "1.2.0"
-    fresh "0.5.2"
-    http-errors "2.0.0"
-    merge-descriptors "1.0.1"
-    methods "~1.1.2"
-    on-finished "2.4.1"
-    parseurl "~1.3.3"
-    path-to-regexp "0.1.7"
-    proxy-addr "~2.0.7"
-    qs "6.10.3"
-    range-parser "~1.2.1"
-    safe-buffer "5.2.1"
-    send "0.18.0"
-    serve-static "1.15.0"
-    setprototypeof "1.2.0"
-    statuses "2.0.1"
-    type-is "~1.6.18"
-    utils-merge "1.0.1"
-    vary "~1.1.2"
+  integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
 
-express@~4.18.1:
+express@^4.17.3, express@~4.18.1:
   version "4.18.1"
   resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf"
   integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==
@@ -3581,7 +3297,7 @@ extend@~3.0.2:
 extsprintf@1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
-  integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
+  integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
 
 extsprintf@^1.2.0:
   version "1.4.1"
@@ -3598,21 +3314,10 @@ fast-diff@^1.1.2:
   resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
   integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
 
-fast-glob@^3.0.3, fast-glob@^3.2.9:
-  version "3.2.10"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.10.tgz#2734f83baa7f43b7fd41e13bc34438f4ffe284ee"
-  integrity sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A==
-  dependencies:
-    "@nodelib/fs.stat" "^2.0.2"
-    "@nodelib/fs.walk" "^1.2.3"
-    glob-parent "^5.1.2"
-    merge2 "^1.3.0"
-    micromatch "^4.0.4"
-
-fast-glob@^3.2.11:
-  version "3.2.11"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
-  integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
+fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.9:
+  version "3.2.12"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
+  integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
   dependencies:
     "@nodelib/fs.stat" "^2.0.2"
     "@nodelib/fs.walk" "^1.2.3"
@@ -3628,12 +3333,12 @@ fast-json-stable-stringify@^2.0.0:
 fast-levenshtein@^2.0.6:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
-  integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+  integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
 
 fastest-levenshtein@^1.0.12:
-  version "1.0.12"
-  resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
-  integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+  version "1.0.16"
+  resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
+  integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
 
 fastq@^1.6.0:
   version "1.13.0"
@@ -3671,7 +3376,7 @@ fill-range@^7.0.1:
 filter-obj@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
-  integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
+  integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==
 
 finalhandler@1.2.0:
   version "1.2.0"
@@ -3698,7 +3403,7 @@ find-cache-dir@^3.3.1:
 find-line-column@^0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/find-line-column/-/find-line-column-0.5.2.tgz#db00238ff868551a182e74a103416d295a98c8ca"
-  integrity sha1-2wAjj/hoVRoYLnShA0FtKVqYyMo=
+  integrity sha512-eNhNkDt5RbxY4X++JwyDURP62FYhV1bh9LF4dfOiwpVCTk5vvfEANhnui5ypUEELGR02QZSrWFtaTgd4ulW5tw==
 
 find-npm-prefix@^1.0.2:
   version "1.0.2"
@@ -3713,7 +3418,7 @@ find-root@^1.0.0:
 find-up@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
-  integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
+  integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==
   dependencies:
     locate-path "^2.0.0"
 
@@ -3732,6 +3437,14 @@ find-up@^4.0.0:
     locate-path "^5.0.0"
     path-exists "^4.0.0"
 
+find-up@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+  integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+  dependencies:
+    locate-path "^6.0.0"
+    path-exists "^4.0.0"
+
 flat-cache@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
@@ -3741,9 +3454,9 @@ flat-cache@^3.0.4:
     rimraf "^3.0.2"
 
 flatted@^3.1.0:
-  version "3.2.4"
-  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2"
-  integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==
+  version "3.2.7"
+  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
+  integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
 
 flush-write-stream@^1.0.0:
   version "1.1.1"
@@ -3754,14 +3467,14 @@ flush-write-stream@^1.0.0:
     readable-stream "^2.3.6"
 
 follow-redirects@^1.0.0:
-  version "1.14.7"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
-  integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
+  version "1.15.2"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+  integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
 
 forever-agent@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
-  integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+  integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
 
 form-data@^3.0.0:
   version "3.0.1"
@@ -3789,12 +3502,12 @@ forwarded@0.2.0:
 fresh@0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
-  integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
+  integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
 
 from2@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd"
-  integrity sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=
+  integrity sha512-1eKYoECvhpM4IT70THQV8XNfmZoIlnROymbwOSazfmQO3kK+zCV+LSqUDzl7gDo3MZddCFeVa9Zg3Hi6FXqcgg==
   dependencies:
     inherits "~2.0.1"
     readable-stream "~1.1.10"
@@ -3802,7 +3515,7 @@ from2@^1.3.0:
 from2@^2.1.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
-  integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
+  integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==
   dependencies:
     inherits "^2.0.1"
     readable-stream "^2.0.0"
@@ -3814,7 +3527,7 @@ fs-minipass@^1.2.7:
   dependencies:
     minipass "^2.6.0"
 
-fs-monkey@1.0.3:
+fs-monkey@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3"
   integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==
@@ -3822,7 +3535,7 @@ fs-monkey@1.0.3:
 fs-vacuum@^1.2.10, fs-vacuum@~1.2.10:
   version "1.2.10"
   resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36"
-  integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY=
+  integrity sha512-bwbv1FcWYwxN1F08I1THN8nS4Qe/pGq0gM8dy1J34vpxxp3qgZKJPPaqex36RyZO0sD2J+2ocnbwC2d/OjYICQ==
   dependencies:
     graceful-fs "^4.1.2"
     path-is-inside "^1.0.1"
@@ -3831,7 +3544,7 @@ fs-vacuum@^1.2.10, fs-vacuum@~1.2.10:
 fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10:
   version "1.0.10"
   resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
-  integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=
+  integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==
   dependencies:
     graceful-fs "^4.1.2"
     iferr "^0.1.5"
@@ -3841,7 +3554,7 @@ fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10:
 fs.realpath@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+  integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
 
 fsevents@~2.3.2:
   version "2.3.2"
@@ -3863,20 +3576,30 @@ function-bind@^1.1.1:
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 
-functional-red-black-tree@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
-  integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+function.prototype.name@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
+  integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.19.0"
+    functions-have-names "^1.2.2"
+
+functions-have-names@^1.2.2:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
+  integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
 
 fuse.js@^6.5.3:
-  version "6.5.3"
-  resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.5.3.tgz#7446c0acbc4ab0ab36fa602e97499bdb69452b93"
-  integrity sha512-sA5etGE7yD/pOqivZRBvUBd/NaL2sjAu6QuSaFoe1H2BrJSkH/T/UXAJ8CdXdw7DvY3Hs8CXKYkDWX7RiP5KOg==
+  version "6.6.2"
+  resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.6.2.tgz#fe463fed4b98c0226ac3da2856a415576dc9a111"
+  integrity sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==
 
 gauge@~2.7.3:
   version "2.7.4"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
-  integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
+  integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==
   dependencies:
     aproba "^1.0.3"
     console-control-strings "^1.0.0"
@@ -3924,19 +3647,19 @@ get-caller-file@^2.0.1:
   resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
   integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
 
-get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
-  integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
+  integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
   dependencies:
     function-bind "^1.1.1"
     has "^1.0.3"
-    has-symbols "^1.0.1"
+    has-symbols "^1.0.3"
 
 get-stream@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
-  integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
+  integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
 
 get-stream@^6.0.0, get-stream@^6.0.1:
   version "6.0.1"
@@ -3954,7 +3677,7 @@ get-symbol-description@^1.0.0:
 getpass@^0.1.1:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
-  integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
+  integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
   dependencies:
     assert-plus "^1.0.0"
 
@@ -3983,14 +3706,14 @@ glob-to-regexp@^0.4.1:
   integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
 
 glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
-  integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+  integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
   dependencies:
     fs.realpath "^1.0.0"
     inflight "^1.0.4"
     inherits "2"
-    minimatch "^3.0.4"
+    minimatch "^3.1.1"
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
@@ -4009,7 +3732,7 @@ glob@~7.1.2:
 global-dirs@^0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
-  integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
+  integrity sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==
   dependencies:
     ini "^1.3.4"
 
@@ -4065,7 +3788,7 @@ globby@^13.1.1:
 globby@^6.1.0:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
-  integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
+  integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==
   dependencies:
     array-union "^1.0.1"
     glob "^7.0.3"
@@ -4076,7 +3799,7 @@ globby@^6.1.0:
 got@^6.7.1:
   version "6.7.1"
   resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
-  integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=
+  integrity sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==
   dependencies:
     create-error-class "^3.0.0"
     duplexer3 "^0.1.4"
@@ -4091,15 +3814,20 @@ got@^6.7.1:
     url-parse-lax "^1.0.0"
 
 graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
-  version "4.2.9"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
-  integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
+  version "4.2.10"
+  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
+  integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
 
 graceful-fs@~4.1.11:
   version "4.1.15"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
   integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
 
+grapheme-splitter@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
+  integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
+
 handle-thing@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@@ -4108,7 +3836,7 @@ handle-thing@^2.0.0:
 har-schema@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
-  integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
+  integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
 
 har-validator@~5.1.3:
   version "5.1.5"
@@ -4118,25 +3846,32 @@ har-validator@~5.1.3:
     ajv "^6.12.3"
     har-schema "^2.0.0"
 
-has-bigints@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
-  integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
+has-bigints@^1.0.1, has-bigints@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
+  integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
 
 has-flag@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
-  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+  integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
 
 has-flag@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-has-symbols@^1.0.1, has-symbols@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
-  integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
+has-property-descriptors@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
+  integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+  dependencies:
+    get-intrinsic "^1.1.1"
+
+has-symbols@^1.0.2, has-symbols@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+  integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
 
 has-tostringtag@^1.0.0:
   version "1.0.0"
@@ -4148,7 +3883,7 @@ has-tostringtag@^1.0.0:
 has-unicode@^2.0.0, has-unicode@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
-  integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
+  integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==
 
 has@^1.0.3:
   version "1.0.3"
@@ -4157,22 +3892,17 @@ has@^1.0.3:
   dependencies:
     function-bind "^1.1.1"
 
-history@^4.10.1:
-  version "4.10.1"
-  resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
-  integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
+history@^5.3.0:
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
+  integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
   dependencies:
-    "@babel/runtime" "^7.1.2"
-    loose-envify "^1.2.0"
-    resolve-pathname "^3.0.0"
-    tiny-invariant "^1.0.2"
-    tiny-warning "^1.0.0"
-    value-equal "^1.0.1"
+    "@babel/runtime" "^7.7.6"
 
 hoist-non-inferno-statics@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/hoist-non-inferno-statics/-/hoist-non-inferno-statics-1.1.3.tgz#7d870f4160bfb6a59269b45c343c027f0e30ab35"
-  integrity sha1-fYcPQWC/tqWSabRcNDwCfw4wqzU=
+  integrity sha512-mPrAYwL0lUL2jbJyqsg64gKbk3e4x9ESPsiejFVdhQP3IO4Ykuu8ZssIh1aKshAekk3aSVqxFVEkhzf1LpkzYg==
 
 hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1:
   version "2.8.9"
@@ -4182,7 +3912,7 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1:
 hpack.js@^2.1.6:
   version "2.1.6"
   resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
-  integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=
+  integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==
   dependencies:
     inherits "^2.0.1"
     obuf "^1.0.0"
@@ -4190,14 +3920,14 @@ hpack.js@^2.1.6:
     wbuf "^1.1.0"
 
 html-entities@^2.3.2:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488"
-  integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46"
+  integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==
 
 html-parse-stringify2@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
-  integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
+  integrity sha512-wMKQ3aJ/dwXzDHPpA7XgsRXXCkEhHkAF6Ioh7D51lgZO7Qy0LmcFddC9TI/qNQJvSM1KL8KbcR3FtuybsrzFlQ==
   dependencies:
     void-elements "^2.0.1"
 
@@ -4209,7 +3939,7 @@ http-cache-semantics@^3.8.0, http-cache-semantics@^3.8.1:
 http-deceiver@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
-  integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
+  integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==
 
 http-errors@2.0.0:
   version "2.0.0"
@@ -4225,7 +3955,7 @@ http-errors@2.0.0:
 http-errors@~1.6.2:
   version "1.6.3"
   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
-  integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
+  integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==
   dependencies:
     depd "~1.1.2"
     inherits "2.0.3"
@@ -4233,9 +3963,9 @@ http-errors@~1.6.2:
     statuses ">= 1.4.0 < 2"
 
 http-parser-js@>=0.5.1:
-  version "0.5.5"
-  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5"
-  integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==
+  version "0.5.8"
+  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3"
+  integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==
 
 http-proxy-agent@^2.0.0, http-proxy-agent@^2.1.0:
   version "2.1.0"
@@ -4268,7 +3998,7 @@ http-proxy@^1.18.1:
 http-signature@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
-  integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+  integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
   dependencies:
     assert-plus "^1.0.0"
     jsprim "^1.2.2"
@@ -4295,7 +4025,7 @@ human-signals@^3.0.1:
 humanize-ms@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
-  integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=
+  integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==
   dependencies:
     ms "^2.0.0"
 
@@ -4305,9 +4035,9 @@ husky@^8.0.1:
   integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==
 
 i18next@^21.8.14:
-  version "21.8.14"
-  resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.14.tgz#03a3a669ef4520aadd9d152c80596f600e287c6a"
-  integrity sha512-4Yi+DtexvMm/Yw3Q9fllzY12SgLk+Mcmar+rCAccsOPul/2UmnBzoHbTGn/L48IPkFcmrNaH7xTLboBWIbH6pw==
+  version "21.9.2"
+  resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.9.2.tgz#3f7c5594393eb27117c1db4c38f5ec766e68de0e"
+  integrity sha512-00fVrLQOwy45nm3OtC9l1WiLK3nJlIYSljgCt0qzTaAy65aciMdRy9GsuW+a2AtKtdg9/njUGfRH30LRupV7ZQ==
   dependencies:
     "@babel/runtime" "^7.17.2"
 
@@ -4333,7 +4063,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0:
 iferr@^0.1.5, iferr@~0.1.5:
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
-  integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
+  integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==
 
 ignore-walk@^3.0.1:
   version "3.0.4"
@@ -4348,14 +4078,14 @@ ignore@^5.1.1, ignore@^5.2.0:
   integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
 
 immutable@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
-  integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
+  integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
 
 import-fresh@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
-  integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
+  integrity sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==
   dependencies:
     caller-path "^2.0.0"
     resolve-from "^3.0.0"
@@ -4371,7 +4101,7 @@ import-fresh@^3.0.0, import-fresh@^3.2.1:
 import-lazy@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
-  integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
+  integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==
 
 import-local@^3.0.2:
   version "3.1.0"
@@ -4438,7 +4168,7 @@ import-sort@^6.0.0:
 imurmurhash@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
-  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+  integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
 
 indent-string@^4.0.0:
   version "4.0.0"
@@ -4450,19 +4180,19 @@ infer-owner@^1.0.4:
   resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
   integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
 
-inferno-clone-vnode@^7.4.2:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-clone-vnode/-/inferno-clone-vnode-7.4.11.tgz#1bcce4ff6ac9ea2986766b17aee1d1a22b158558"
-  integrity sha512-6/newyzWO/lrwcA9q5DBAfslccPWqhpgrDQg/wWiHKZwRBe1kJjtiALsR+/1wLq1Z+YO3L1MPnlEnFu+nltUbA==
+inferno-clone-vnode@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-clone-vnode/-/inferno-clone-vnode-8.0.3.tgz#01feac1f06226f59cbdcc07d513d4d23fbbe3d03"
+  integrity sha512-WPwbxwKHgT6rO++RLvJvF5pPuwxPwpH6dupDorWqkRmRwEyzszvtUJG5C2VSA3LEhH2iyV4+wC28hhtRwHN6+w==
   dependencies:
-    inferno "7.4.11"
+    inferno "8.0.3"
 
-inferno-create-element@^7.4.11, inferno-create-element@^7.4.2:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-create-element/-/inferno-create-element-7.4.11.tgz#1690b3ad28b61be93765b11b409dc9a9a35bf63a"
-  integrity sha512-kE6XIx2hPAd5qpDli2iGjNXgubvuyxdLvoiW71WnSzIIxA+Uxa/s8lY8m03VyHHVypFV3n329ZY5dFvKc7UQMg==
+inferno-create-element@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-create-element/-/inferno-create-element-8.0.3.tgz#883961e497b4ab7359c1ef19a1f5388fe81137d6"
+  integrity sha512-eQ7GLpC1lGB8+BaeFvNHo6Dl3fKfbv3kobWgw5qYttRPeMaufIfn0lEkhzx2anx1Hv99INwPl+9jbpybciQLTQ==
   dependencies:
-    inferno "7.4.11"
+    inferno "8.0.3"
 
 inferno-helmet@^5.2.1:
   version "5.2.1"
@@ -4473,46 +4203,46 @@ inferno-helmet@^5.2.1:
     inferno-side-effect "^1.1.5"
     object-assign "^4.1.1"
 
-inferno-hydrate@^7.4.11:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-hydrate/-/inferno-hydrate-7.4.11.tgz#275027585268055f7d741c21978d7b5065169a3a"
-  integrity sha512-hF9Ke4GHAkj8GQrMXBZPfsUqhq6WjkoDCAfXhPBuF1Wiceqyy8KerOOXEnuocHky77fuEXq0AzVnQcC064Bkfw==
+inferno-hydrate@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-hydrate/-/inferno-hydrate-8.0.3.tgz#75c3c53300a7b7b550dfa93f363956201d86f71f"
+  integrity sha512-7q1BDuVIy3XCmyKlAJhe+s1CLJhl3+gfFcBpjCq9iA7J/Z3kwo/6xjwJQbcQHNrCr/XZvTM+2uVwfxiX6wgYCQ==
   dependencies:
-    inferno "7.4.11"
+    inferno "8.0.3"
 
-inferno-i18next-dess@^0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/inferno-i18next-dess/-/inferno-i18next-dess-0.0.1.tgz#48ae6bb4c3a617e59ff8dc97b9ed70f2ef762206"
-  integrity sha512-z/6UnuWFMyBivfR3SI9AmgA0/JvXARqtG/9BQryaLPenlG7iAb4cN2TeSt0mHIgFOo01QHVWZ8dqn7jZRijp2Q==
+inferno-i18next-dess@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/inferno-i18next-dess/-/inferno-i18next-dess-0.0.2.tgz#4cd4e3e2e1d900212b399a85dbfd4015e887039b"
+  integrity sha512-TkpBTZzfqgK7O8gIJ7gLB9CvP1bEOfO8OA7vUfJpd2kgGom9eoj6xbAMUPk5BNH6nBN5Y+mCaG/dInQjW5Jkug==
   dependencies:
     html-parse-stringify2 "^2.0.1"
-    inferno "^7.4.2"
-    inferno-clone-vnode "^7.4.2"
-    inferno-create-element "^7.4.2"
-    inferno-shared "^7.4.2"
-    inferno-vnode-flags "^7.4.2"
-
-inferno-router@^7.4.11:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-7.4.11.tgz#80bd47bf7c059a219cad9f3857585023fd55781f"
-  integrity sha512-7H5OTpoxGjRl2wtF1exFdlFVmO3k6EhNm0yMSfk34DOEEDqiIpy0QiWx0Q0nn7Mm2Wddgdt31RAl69/k/GuBYA==
-  dependencies:
-    history "^4.10.1"
+    inferno "^8.0.3"
+    inferno-clone-vnode "^8.0.3"
+    inferno-create-element "^8.0.3"
+    inferno-shared "^8.0.3"
+    inferno-vnode-flags "^8.0.3"
+
+inferno-router@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-8.0.3.tgz#ef08da8b0cb158b8920147b260a4f84c64bc3877"
+  integrity sha512-bWkrFfIBDued0LfS/x6Bot3+J3VwGImH3ukSdIFe/GLFPBljDbvayc1JotriJtNFKA1E+1T/OZyw1E6UqIcDaA==
+  dependencies:
+    history "^5.3.0"
     hoist-non-inferno-statics "^1.1.3"
-    inferno "7.4.11"
+    inferno "8.0.3"
     path-to-regexp-es6 "1.7.0"
 
-inferno-server@^7.4.11:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-server/-/inferno-server-7.4.11.tgz#05ec0f7ceea4a30da412baaccbbfeca258db27cf"
-  integrity sha512-SUnkCqZNWOIrjRVoVk/E1/70O1f1ImkCX9H2gDPbS0uc3GDxuzIeCgn0rpcc0XV9KzZJ2LTGxuBtEoQQOjUn2Q==
+inferno-server@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-server/-/inferno-server-8.0.3.tgz#4030ac5f20d9ddf191163daa10d3ef4e8b0c4593"
+  integrity sha512-YG9f9e0KsVGV6qByWCkFoGI80SckqIptHtTHMoVHsAbw3krzX414zxwA5H9OTnkubJJsSHBjVtFxaq6hHT/YcA==
   dependencies:
-    inferno "7.4.11"
+    inferno "8.0.3"
 
-inferno-shared@7.4.11, inferno-shared@^7.4.2:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-7.4.11.tgz#6e06e0668c4dad5f8b1fd4c688e1072faa6f1e87"
-  integrity sha512-pN725bDSTxkQmRS3e/3H02/xAqgHl+xgddCMjPm8M0etRdRcVCisi3NGPhzSbDDmiftrxhY31exs7+dwsngcDA==
+inferno-shared@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-8.0.3.tgz#74c0cdd523937763d01945b50b65690a7064a957"
+  integrity sha512-+1ZV0DtBnYFfb5WF2FXSnCYjejGGl2BZhN5hMNRwfColRKd08N2r2i0EyLSDlTM1yB5n7BW2YdOegMf3YsV4yQ==
 
 inferno-side-effect@^1.1.5:
   version "1.1.5"
@@ -4523,24 +4253,24 @@ inferno-side-effect@^1.1.5:
     npm "^5.8.0"
     shallowequal "^1.0.1"
 
-inferno-vnode-flags@7.4.11, inferno-vnode-flags@^7.4.2:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-7.4.11.tgz#642a835a8dde514f244296b27c176a2b8704fbac"
-  integrity sha512-L7lslEQCq3IfwgT/b9zhuMf8fv6KXCNXXHZevk/WYxnqJsOWGDcKpJn0zkzXfvmj0otbB149iLUQVBq3oe2sfA==
+inferno-vnode-flags@8.0.3, inferno-vnode-flags@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-8.0.3.tgz#1bd78745033719596211155ae673bd648b266a78"
+  integrity sha512-r+wJZNliJWvtcwBd66L3fMSp+M0rinHLilZeLiAX87+ZVPoXKiTDLVmTRI+1j8dm1XmC3IuAHijVfwELnEmoCQ==
 
-inferno@7.4.11, inferno@^7.4.11, inferno@^7.4.2:
-  version "7.4.11"
-  resolved "https://registry.yarnpkg.com/inferno/-/inferno-7.4.11.tgz#fcee308cf0e4a2f6066d96da74e3b425583bfc66"
-  integrity sha512-N+cs33ESWI8fdToCd98yMRYl7jkLnCkJskxov3FKKlaKOvk3PRlAttbhmUaYdWXlRvt2WeXi+J4MbzNj3V6G0w==
+inferno@8.0.3, inferno@^8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/inferno/-/inferno-8.0.3.tgz#99124f050a9c60995dbdeef8ac258a936df7e62e"
+  integrity sha512-EZJyGfnlNoX4rQj9oX09ZqPmG8Ejrzqb/Y5O1D+QBN84VJ8uQGTqhZdmz3n7mhUnSyHg7VLt+rlbLnlTI4bs4g==
   dependencies:
-    inferno-shared "7.4.11"
-    inferno-vnode-flags "7.4.11"
+    csstype "^3.1.0"
+    inferno-vnode-flags "8.0.3"
     opencollective-postinstall "^2.0.3"
 
 inflight@^1.0.4, inflight@~1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
-  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+  integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
   dependencies:
     once "^1.3.0"
     wrappy "1"
@@ -4553,7 +4283,7 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, i
 inherits@2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
+  integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
 
 ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
   version "1.3.8"
@@ -4591,12 +4321,17 @@ interpret@^2.2.0:
 invert-kv@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
-  integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
+  integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==
 
-ip@1.1.5, ip@^1.1.4:
+ip@1.1.5:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
-  integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
+  integrity sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA==
+
+ip@^1.1.4:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
+  integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==
 
 ipaddr.js@1.9.1:
   version "1.9.1"
@@ -4619,7 +4354,7 @@ is-arguments@^1.0.4:
 is-arrayish@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
-  integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+  integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
 
 is-bigint@^1.0.1:
   version "1.0.4"
@@ -4646,21 +4381,21 @@ is-boolean-object@^1.1.0:
 is-builtin-module@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
-  integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74=
+  integrity sha512-C2wz7Juo5pUZTFQVer9c+9b4qw3I5T/CHQxQyhVu7BJel6C22FmsLIWsdseYyOw6xz9Pqy9eJWSkQ7+3iN1HVw==
   dependencies:
     builtin-modules "^1.0.0"
 
 is-builtin-module@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.1.0.tgz#6fdb24313b1c03b75f8b9711c0feb8c30b903b00"
-  integrity sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.0.tgz#bb0310dfe881f144ca83f30100ceb10cf58835e0"
+  integrity sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==
   dependencies:
-    builtin-modules "^3.0.0"
+    builtin-modules "^3.3.0"
 
-is-callable@^1.1.4, is-callable@^1.2.4:
-  version "1.2.4"
-  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
-  integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
+is-callable@^1.1.4, is-callable@^1.2.6:
+  version "1.2.7"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
+  integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
 
 is-ci@^1.0.10:
   version "1.2.1"
@@ -4672,14 +4407,14 @@ is-ci@^1.0.10:
 is-cidr@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-1.0.0.tgz#fb5aacf659255310359da32cae03e40c6a1c2afc"
-  integrity sha1-+1qs9lklUxA1naMsrgPkDGocKvw=
+  integrity sha512-IaCvhzobhmspClNQF750EuOF4PZu0BXfS8P/sQcOOoGaffcZhJZ0C523mlWrKmK0BFY30Nz2FF7Cik0i+C0CBA==
   dependencies:
     cidr-regex "1.0.6"
 
-is-core-module@^2.8.0:
-  version "2.8.1"
-  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
-  integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
+is-core-module@^2.9.0:
+  version "2.10.0"
+  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed"
+  integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==
   dependencies:
     has "^1.0.3"
 
@@ -4693,7 +4428,7 @@ is-date-object@^1.0.1:
 is-directory@^0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
-  integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
+  integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==
 
 is-docker@^2.0.0, is-docker@^2.1.1:
   version "2.2.1"
@@ -4703,19 +4438,19 @@ is-docker@^2.0.0, is-docker@^2.1.1:
 is-extglob@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
-  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+  integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
 
 is-fullwidth-code-point@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
-  integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
+  integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
   dependencies:
     number-is-nan "^1.0.0"
 
 is-fullwidth-code-point@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
-  integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+  integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
 
 is-fullwidth-code-point@^3.0.0:
   version "3.0.0"
@@ -4737,12 +4472,12 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
 is-installed-globally@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80"
-  integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=
+  integrity sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==
   dependencies:
     global-dirs "^0.1.0"
     is-path-inside "^1.0.0"
 
-is-negative-zero@^2.0.1:
+is-negative-zero@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
   integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
@@ -4750,12 +4485,12 @@ is-negative-zero@^2.0.1:
 is-npm@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
-  integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
+  integrity sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==
 
 is-number-object@^1.0.4:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0"
-  integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
+  integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
   dependencies:
     has-tostringtag "^1.0.0"
 
@@ -4767,7 +4502,7 @@ is-number@^7.0.0:
 is-obj@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
-  integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
+  integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==
 
 is-path-cwd@^2.0.0:
   version "2.2.0"
@@ -4784,7 +4519,7 @@ is-path-in-cwd@^2.0.0:
 is-path-inside@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
-  integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
+  integrity sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==
   dependencies:
     path-is-inside "^1.0.1"
 
@@ -4815,7 +4550,7 @@ is-plain-object@^2.0.4:
 is-redirect@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
-  integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
+  integrity sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==
 
 is-regex@^1.0.4, is-regex@^1.1.4:
   version "1.1.4"
@@ -4830,15 +4565,17 @@ is-retry-allowed@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
   integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
 
-is-shared-array-buffer@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
-  integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
+is-shared-array-buffer@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
+  integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
+  dependencies:
+    call-bind "^1.0.2"
 
 is-stream@^1.0.0, is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-  integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+  integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
 
 is-stream@^2.0.0:
   version "2.0.1"
@@ -4867,9 +4604,9 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
 is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
-  integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+  integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
 
-is-weakref@^1.0.1:
+is-weakref@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
   integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
@@ -4886,22 +4623,22 @@ is-wsl@^2.2.0:
 isarray@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
-  integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
+  integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
 
 isarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
-  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+  integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
 
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
-  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
 
 isobject@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
-  integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
+  integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
 
 isomorphic-cookie@^1.2.4:
   version "1.2.4"
@@ -4914,17 +4651,22 @@ isomorphic-cookie@^1.2.4:
 isstream@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-  integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+  integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
 
-jest-worker@^27.4.1:
-  version "27.4.6"
-  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e"
-  integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==
+jest-worker@^27.4.5:
+  version "27.5.1"
+  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
+  integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
   dependencies:
     "@types/node" "*"
     merge-stream "^2.0.0"
     supports-color "^8.0.0"
 
+js-sdsl@^4.1.4:
+  version "4.1.4"
+  resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6"
+  integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==
+
 "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -4948,7 +4690,7 @@ js-yaml@^4.1.0:
 jsbn@~0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
-  integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+  integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
 
 jsesc@^2.5.1:
   version "2.5.2"
@@ -4958,7 +4700,7 @@ jsesc@^2.5.1:
 jsesc@~0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
-  integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
+  integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==
 
 json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
   version "1.0.2"
@@ -4988,21 +4730,14 @@ json-schema@0.4.0:
 json-stable-stringify-without-jsonify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
-  integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+  integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
 
 json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-json5@^2.1.2:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
-  integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
-  dependencies:
-    minimist "^1.2.5"
+  integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
 
-json5@^2.2.1:
+json5@^2.1.2, json5@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
   integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
@@ -5010,7 +4745,7 @@ json5@^2.2.1:
 jsonparse@^1.2.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
-  integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
+  integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
 
 jsprim@^1.2.2:
   version "1.4.2"
@@ -5022,6 +4757,14 @@ jsprim@^1.2.2:
     json-schema "0.4.0"
     verror "1.10.0"
 
+jsx-ast-utils@^3.3.3:
+  version "3.3.3"
+  resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea"
+  integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==
+  dependencies:
+    array-includes "^3.1.5"
+    object.assign "^4.1.3"
+
 jwt-decode@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
@@ -5040,26 +4783,26 @@ klona@^2.0.4:
 latest-version@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
-  integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=
+  integrity sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==
   dependencies:
     package-json "^4.0.0"
 
 lazy-property@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147"
-  integrity sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=
+  integrity sha512-O52TK7FHpBPzdtvc5GoF0EPLQIBMqrAupANPGBidPkrDpl9IXlzuma3T+m0o0OpkRVPmTu3SDoT7985lw4KbNQ==
 
 lcid@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
-  integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
+  integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==
   dependencies:
     invert-kv "^1.0.0"
 
-lemmy-js-client@0.17.0-rc.43:
-  version "0.17.0-rc.43"
-  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.43.tgz#30e985365a93d72184646fdfe359f39ccc2e2091"
-  integrity sha512-/+TOTZazoi74zwc8H2AJMd/Znrdnqfi0+TrfnmqvQ3fzrOl741ojEURxAHw3NsgW9b8HkubXZFLsi1RVR99UqA==
+lemmy-js-client@0.17.0-rc.46:
+  version "0.17.0-rc.46"
+  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.46.tgz#c2820821ca46394fd17d1045e54c00a04b15700c"
+  integrity sha512-9HqKKsvToSB397ywXpl0jPa7KIhDaULWel0g35CgmfOkylvuTlpF8UZW20vMXr02Br9qvbRf0hRvi9s5uaji+Q==
 
 levn@^0.4.1:
   version "0.4.1"
@@ -5157,7 +4900,7 @@ listr2@^4.0.5:
 load-json-file@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
-  integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=
+  integrity sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==
   dependencies:
     graceful-fs "^4.1.2"
     parse-json "^2.2.0"
@@ -5165,9 +4908,9 @@ load-json-file@^2.0.0:
     strip-bom "^3.0.0"
 
 loader-runner@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
-  integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
+  integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
 
 loader-utils@^2.0.0:
   version "2.0.2"
@@ -5181,7 +4924,7 @@ loader-utils@^2.0.0:
 locate-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
-  integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
+  integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==
   dependencies:
     p-locate "^2.0.0"
     path-exists "^3.0.0"
@@ -5201,6 +4944,13 @@ locate-path@^5.0.0:
   dependencies:
     p-locate "^4.1.0"
 
+locate-path@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+  integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+  dependencies:
+    p-locate "^5.0.0"
+
 lock-verify@^2.0.2:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1"
@@ -5220,7 +4970,7 @@ lockfile@^1.0.4:
 lodash._baseuniq@~4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
-  integrity sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=
+  integrity sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==
   dependencies:
     lodash._createset "~4.0.0"
     lodash._root "~3.0.0"
@@ -5228,22 +4978,22 @@ lodash._baseuniq@~4.6.0:
 lodash._createset@~4.0.0:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
-  integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
+  integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==
 
 lodash._root@~3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
-  integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=
+  integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==
 
 lodash.clonedeep@~4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
-  integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
+  integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
 
 lodash.debounce@^4.0.8:
   version "4.0.8"
   resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
-  integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
+  integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
 
 lodash.merge@^4.6.2:
   version "4.6.2"
@@ -5253,27 +5003,27 @@ lodash.merge@^4.6.2:
 lodash.pick@^4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
-  integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
+  integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
 
 lodash.union@~4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
-  integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
+  integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==
 
 lodash.uniq@~4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-  integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
+  integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
 
 lodash.without@~4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
-  integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
+  integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ==
 
 lodash@^3.10.1:
   version "3.10.1"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
-  integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
+  integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==
 
 log-update@^4.0.0:
   version "4.0.0"
@@ -5285,7 +5035,7 @@ log-update@^4.0.0:
     slice-ansi "^4.0.0"
     wrap-ansi "^6.2.0"
 
-loose-envify@^1.2.0:
+loose-envify@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
   integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -5405,12 +5155,12 @@ markdown-it-html5-embed@^1.0.0:
 markdown-it-sub@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz#375fd6026eae7ddcb012497f6411195ea1e3afe8"
-  integrity sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g=
+  integrity sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==
 
 markdown-it-sup@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz#cb9c9ff91a5255ac08f3fd3d63286e15df0a1fc3"
-  integrity sha1-y5yf+RpSVawI8/09YyhuFd8KH8M=
+  integrity sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==
 
 markdown-it@^13.0.1:
   version "13.0.1"
@@ -5437,7 +5187,7 @@ markdown-it@^8.4.0:
 mdurl@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
-  integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
+  integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
 
 meant@~1.0.1:
   version "1.0.3"
@@ -5447,26 +5197,26 @@ meant@~1.0.1:
 media-typer@0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
-  integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
+  integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
 
 mem@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
-  integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
+  integrity sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ==
   dependencies:
     mimic-fn "^1.0.0"
 
-memfs@^3.4.1:
-  version "3.4.1"
-  resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305"
-  integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==
+memfs@^3.4.3:
+  version "3.4.7"
+  resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a"
+  integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==
   dependencies:
-    fs-monkey "1.0.3"
+    fs-monkey "^1.0.3"
 
 merge-descriptors@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
-  integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
+  integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
 
 merge-stream@^2.0.0:
   version "2.0.0"
@@ -5481,17 +5231,9 @@ merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1:
 methods@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
-  integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
+  integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
 
-micromatch@^4.0.2, micromatch@^4.0.4:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
-  integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
-  dependencies:
-    braces "^3.0.1"
-    picomatch "^2.2.3"
-
-micromatch@^4.0.5:
+micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
   version "4.0.5"
   resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
   integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
@@ -5499,24 +5241,12 @@ micromatch@^4.0.5:
     braces "^3.0.2"
     picomatch "^2.3.1"
 
-mime-db@1.51.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.6.0:
-  version "1.51.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
-  integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
-
-mime-db@1.52.0:
+mime-db@1.52.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.6.0:
   version "1.52.0"
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
   integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
 
-mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
-  version "2.1.34"
-  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
-  integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
-  dependencies:
-    mime-db "1.51.0"
-
-mime-types@~2.1.34:
+mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
   version "2.1.35"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
   integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
@@ -5546,7 +5276,7 @@ mimic-fn@^4.0.0:
 mimoza@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/mimoza/-/mimoza-1.0.0.tgz#d74aa4fe08932f005e430bdc7bfcfa95fcab4e62"
-  integrity sha1-10qk/giTLwBeQwvce/z6lfyrTmI=
+  integrity sha512-+j7SSye/hablu66K/jjeyPmk6WL8RoXfeZ+MMn37vSNDGuaWY/5wm10LpSpxAHX4kNoEwkTWYHba8ePVip+Hqg==
   dependencies:
     mime-db "^1.6.0"
 
@@ -5562,24 +5292,24 @@ minimalistic-assert@^1.0.0:
   resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
   integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
 
-minimatch@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
-  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
-  dependencies:
-    brace-expansion "^1.1.7"
-
-minimatch@^3.1.2:
+minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
   integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
   dependencies:
     brace-expansion "^1.1.7"
 
-minimist@^1.2.0, minimist@^1.2.5:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
-  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimatch@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
+  integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
+  dependencies:
+    brace-expansion "^2.0.1"
+
+minimist@^1.2.0, minimist@^1.2.6:
+  version "1.2.6"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+  integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
 
 minipass@^2.3.3, minipass@^2.6.0, minipass@^2.9.0:
   version "2.9.0"
@@ -5645,11 +5375,11 @@ mississippi@^3.0.0:
     through2 "^2.0.0"
 
 "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1:
-  version "0.5.5"
-  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
-  integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
+  version "0.5.6"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
+  integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
   dependencies:
-    minimist "^1.2.5"
+    minimist "^1.2.6"
 
 moment@^2.29.4:
   version "2.29.4"
@@ -5659,7 +5389,7 @@ moment@^2.29.4:
 move-concurrently@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
-  integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=
+  integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==
   dependencies:
     aproba "^1.1.1"
     copy-concurrently "^1.0.0"
@@ -5671,7 +5401,7 @@ move-concurrently@^1.0.1:
 ms@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
-  integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+  integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
 
 ms@2.1.2:
   version "2.1.2"
@@ -5683,10 +5413,10 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1:
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
   integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
 
-multicast-dns@^7.2.4:
-  version "7.2.4"
-  resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.4.tgz#cf0b115c31e922aeb20b64e6556cbeb34cf0dd19"
-  integrity sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==
+multicast-dns@^7.2.5:
+  version "7.2.5"
+  resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced"
+  integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==
   dependencies:
     dns-packet "^5.2.2"
     thunky "^1.0.2"
@@ -5696,20 +5426,15 @@ mute-stream@~0.0.4:
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
   integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
 
-nanoid@^3.3.1:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
-  integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==
+nanoid@^3.3.4:
+  version "3.3.4"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
+  integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
 
 natural-compare@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
-  integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-
-negotiator@0.6.2:
-  version "0.6.2"
-  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
-  integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+  integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
 
 negotiator@0.6.3:
   version "0.6.3"
@@ -5731,9 +5456,9 @@ node-fetch-npm@^2.0.2:
     safe-buffer "^5.1.1"
 
 node-fetch@^2.6.1:
-  version "2.6.6"
-  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
-  integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
+  version "2.6.7"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
+  integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
   dependencies:
     whatwg-url "^5.0.0"
 
@@ -5777,11 +5502,6 @@ node-gyp@^4.0.0:
     tar "^4.4.8"
     which "1"
 
-node-releases@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
-  integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
-
 node-releases@^2.0.6:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
@@ -5790,7 +5510,7 @@ node-releases@^2.0.6:
 "nopt@2 || 3":
   version "3.0.6"
   resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
-  integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k=
+  integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==
   dependencies:
     abbrev "1"
 
@@ -5845,7 +5565,7 @@ npm-bundled@^1.0.1:
 npm-cache-filename@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11"
-  integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=
+  integrity sha512-5v2y1KG06izpGvZJDSBR5q1Ej+NaPDO05yAAWBJE6+3eiId0R176Gz3Qc2vEmJnE+VGul84g6Qpq8fXzD82/JA==
 
 npm-install-checks@~3.0.0:
   version "3.0.2"
@@ -5956,7 +5676,7 @@ npm-registry-fetch@^1.1.0:
 npm-run-path@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
-  integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
+  integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
   dependencies:
     path-key "^2.0.0"
 
@@ -6105,7 +5825,7 @@ npm@^5.8.0:
 number-is-nan@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
-  integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
+  integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
 
 oauth-sign@~0.9.0:
   version "0.9.0"
@@ -6115,14 +5835,9 @@ oauth-sign@~0.9.0:
 object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
-  integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-object-inspect@^1.11.0, object-inspect@^1.9.0:
-  version "1.12.0"
-  resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
-  integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
+  integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
 
-object-inspect@^1.12.2:
+object-inspect@^1.12.2, object-inspect@^1.9.0:
   version "1.12.2"
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
   integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
@@ -6135,25 +5850,61 @@ object-is@^1.0.1:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
 
-object-keys@^1.0.12, object-keys@^1.1.1:
+object-keys@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
   integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
 
-object.assign@^4.1.0, object.assign@^4.1.2:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
-  integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
+object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4:
+  version "4.1.4"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
+  integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
   dependencies:
-    call-bind "^1.0.0"
-    define-properties "^1.1.3"
-    has-symbols "^1.0.1"
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    has-symbols "^1.0.3"
     object-keys "^1.1.1"
 
+object.entries@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
+  integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.19.1"
+
+object.fromentries@^2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
+  integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.19.1"
+
 object.getownpropertydescriptors@^2.0.3:
-  version "2.1.3"
-  resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e"
-  integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==
+  version "2.1.4"
+  resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz#7965e6437a57278b587383831a9b829455a4bc37"
+  integrity sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==
+  dependencies:
+    array.prototype.reduce "^1.0.4"
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    es-abstract "^1.20.1"
+
+object.hasown@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3"
+  integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==
+  dependencies:
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
+
+object.values@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
+  integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
   dependencies:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
@@ -6179,7 +5930,7 @@ on-headers@~1.0.2:
 once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
-  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+  integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
   dependencies:
     wrappy "1"
 
@@ -6214,7 +5965,7 @@ opencollective-postinstall@^2.0.3:
 opener@~1.4.3:
   version "1.4.3"
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
-  integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=
+  integrity sha512-4Im9TrPJcjAYyGR5gBe3yZnBzw5n3Bfh1ceHHGNOpMurINKc6RdSIPXMyon4BZacJbJc36lLkhipioGbWh5pwg==
 
 optionator@^0.9.1:
   version "0.9.1"
@@ -6231,7 +5982,7 @@ optionator@^0.9.1:
 os-homedir@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
-  integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
+  integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==
 
 os-locale@^2.0.0:
   version "2.1.0"
@@ -6245,7 +5996,7 @@ os-locale@^2.0.0:
 os-tmpdir@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
-  integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
+  integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
 
 osenv@0, osenv@^0.1.4, osenv@^0.1.5:
   version "0.1.5"
@@ -6258,7 +6009,7 @@ osenv@0, osenv@^0.1.4, osenv@^0.1.5:
 p-finally@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-  integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
+  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
 
 p-limit@^1.1.0:
   version "1.3.0"
@@ -6274,10 +6025,17 @@ p-limit@^2.0.0, p-limit@^2.2.0:
   dependencies:
     p-try "^2.0.0"
 
+p-limit@^3.0.2:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+  integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+  dependencies:
+    yocto-queue "^0.1.0"
+
 p-locate@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
-  integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
+  integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==
   dependencies:
     p-limit "^1.1.0"
 
@@ -6295,6 +6053,13 @@ p-locate@^4.1.0:
   dependencies:
     p-limit "^2.2.0"
 
+p-locate@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+  integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+  dependencies:
+    p-limit "^3.0.2"
+
 p-map@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
@@ -6308,17 +6073,17 @@ p-map@^4.0.0:
     aggregate-error "^3.0.0"
 
 p-retry@^4.5.0:
-  version "4.6.1"
-  resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c"
-  integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==
+  version "4.6.2"
+  resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16"
+  integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==
   dependencies:
-    "@types/retry" "^0.12.0"
+    "@types/retry" "0.12.0"
     retry "^0.13.1"
 
 p-try@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
-  integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
+  integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==
 
 p-try@^2.0.0:
   version "2.2.0"
@@ -6328,7 +6093,7 @@ p-try@^2.0.0:
 package-json@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed"
-  integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=
+  integrity sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==
   dependencies:
     got "^6.7.1"
     registry-auth-token "^3.0.1"
@@ -6415,14 +6180,14 @@ parent-module@^1.0.0:
 parse-json@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
-  integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
+  integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==
   dependencies:
     error-ex "^1.2.0"
 
 parse-json@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
-  integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
+  integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==
   dependencies:
     error-ex "^1.3.1"
     json-parse-better-errors "^1.0.1"
@@ -6435,7 +6200,7 @@ parseurl@~1.3.2, parseurl@~1.3.3:
 path-exists@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
-  integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+  integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
 
 path-exists@^4.0.0:
   version "4.0.0"
@@ -6445,17 +6210,17 @@ path-exists@^4.0.0:
 path-is-absolute@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
-  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+  integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
 
 path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
-  integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
+  integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==
 
 path-key@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
-  integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
+  integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
 
 path-key@^3.0.0, path-key@^3.1.0:
   version "3.1.1"
@@ -6482,19 +6247,19 @@ path-to-regexp-es6@1.7.0:
 path-to-regexp@0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
-  integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+  integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
 
 path-to-regexp@1.7.0:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
-  integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
+  integrity sha512-nifX1uj4S9IrK/w3Xe7kKvNEepXivANs9ng60Iq7PU/BlouV3yL/VUhFqTuTq33ykwUqoNcTeGo5vdOBP4jS/Q==
   dependencies:
     isarray "0.0.1"
 
 path-type@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
-  integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=
+  integrity sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==
   dependencies:
     pify "^2.0.0"
 
@@ -6506,14 +6271,14 @@ path-type@^4.0.0:
 performance-now@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
-  integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+  integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
 
 picocolors@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
   integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
 
-picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
   version "2.3.1"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
   integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -6526,12 +6291,12 @@ pidtree@^0.6.0:
 pify@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
-  integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
+  integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
 
 pify@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
-  integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
+  integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==
 
 pify@^4.0.1:
   version "4.0.1"
@@ -6541,14 +6306,14 @@ pify@^4.0.1:
 pinkie-promise@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
-  integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
+  integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==
   dependencies:
     pinkie "^2.0.0"
 
 pinkie@^2.0.0:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
-  integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
+  integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
 
 pkg-dir@^4.1.0, pkg-dir@^4.2.0:
   version "4.2.0"
@@ -6586,9 +6351,9 @@ postcss-modules-values@^4.0.0:
     icss-utils "^5.0.0"
 
 postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
-  version "6.0.8"
-  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914"
-  integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==
+  version "6.0.10"
+  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
+  integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
   dependencies:
     cssesc "^3.0.0"
     util-deprecate "^1.0.2"
@@ -6599,11 +6364,11 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
   integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
 
 postcss@^8.4.7:
-  version "8.4.12"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905"
-  integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==
+  version "8.4.16"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c"
+  integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==
   dependencies:
-    nanoid "^3.3.1"
+    nanoid "^3.3.4"
     picocolors "^1.0.0"
     source-map-js "^1.0.2"
 
@@ -6615,7 +6380,7 @@ prelude-ls@^1.2.1:
 prepend-http@^1.0.1:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
-  integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
+  integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==
 
 prettier-linter-helpers@^1.0.0:
   version "1.0.0"
@@ -6635,9 +6400,9 @@ prettier-plugin-import-sort@^0.0.7:
     import-sort-parser-typescript "^6.0.0"
 
 prettier-plugin-organize-imports@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.0.tgz#39739423cc7069f2a3bfa58d14f8a502ff163df2"
-  integrity sha512-juSCJs5TMOqGGPaN/A/1xzWFzRPH2LG1LPLCr64dzKaVnPafJdtgDNmDVlU+8A4LbQzVJg0DTvgA8swBuIUhlg==
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.1.1.tgz#e581cb6fa528cf72f7d95b807ce38c3e51c3c27c"
+  integrity sha512-6bHIQzybqA644h0WGUW3gpWEVbMBvzui5wCMRBi7qA++d5ov2xjjfDk8pxJJ/ardfZrGAwizKMq/fQMFdJ+0Zw==
 
 prettier-plugin-packagejson@^2.2.18:
   version "2.2.18"
@@ -6659,12 +6424,12 @@ process-nextick-args@~2.0.0:
 promise-inflight@^1.0.1, promise-inflight@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
-  integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
+  integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==
 
 promise-retry@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d"
-  integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=
+  integrity sha512-StEy2osPr28o17bIW776GtwO6+Q+M9zPiZkYfosciUUMYqjhU/ffwRAH0zN2+uvGyUsn8/YICIHRzLbPacpZGw==
   dependencies:
     err-code "^1.0.0"
     retry "^0.10.0"
@@ -6672,14 +6437,23 @@ promise-retry@^1.1.1:
 promzard@^0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee"
-  integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=
+  integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw==
   dependencies:
     read "1"
 
+prop-types@^15.8.1:
+  version "15.8.1"
+  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+  integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+  dependencies:
+    loose-envify "^1.4.0"
+    object-assign "^4.1.1"
+    react-is "^16.13.1"
+
 proto-list@~1.2.1:
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
-  integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
+  integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
 
 protoduck@^5.0.0:
   version "5.0.1"
@@ -6699,17 +6473,17 @@ proxy-addr@~2.0.7:
 prr@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
-  integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
+  integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==
 
 pseudomap@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
-  integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
+  integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==
 
 psl@^1.1.28:
-  version "1.8.0"
-  resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
-  integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
+  integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
 
 pump@^1.0.0:
   version "1.0.3"
@@ -6818,6 +6592,11 @@ rc@^1.0.1, rc@^1.1.6:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
+react-is@^16.13.1:
+  version "16.13.1"
+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
 read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16"
@@ -6828,7 +6607,7 @@ read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1:
 read-installed@~4.0.3:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067"
-  integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=
+  integrity sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==
   dependencies:
     debuglog "^1.0.1"
     read-package-json "^2.0.0"
@@ -6861,7 +6640,7 @@ read-package-tree@^5.2.1:
 read-pkg-up@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
-  integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=
+  integrity sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==
   dependencies:
     find-up "^2.0.0"
     read-pkg "^2.0.0"
@@ -6869,7 +6648,7 @@ read-pkg-up@^2.0.0:
 read-pkg@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
-  integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=
+  integrity sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==
   dependencies:
     load-json-file "^2.0.0"
     normalize-package-data "^2.3.2"
@@ -6878,7 +6657,7 @@ read-pkg@^2.0.0:
 read@1, read@~1.0.1, read@~1.0.7:
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
-  integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=
+  integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==
   dependencies:
     mute-stream "~0.0.4"
 
@@ -6907,7 +6686,7 @@ readable-stream@^3.0.6:
 readable-stream@~1.1.10:
   version "1.1.14"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
-  integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
+  integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==
   dependencies:
     core-util-is "~1.0.0"
     inherits "~2.0.1"
@@ -6939,9 +6718,9 @@ rechoir@^0.7.0:
     resolve "^1.9.0"
 
 redux@^4.1.2:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
-  integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
+  integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
   dependencies:
     "@babel/runtime" "^7.9.2"
 
@@ -6950,17 +6729,10 @@ reflect-metadata@^0.1.13:
   resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
   integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
 
-regenerate-unicode-properties@^10.0.1:
-  version "10.0.1"
-  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56"
-  integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==
-  dependencies:
-    regenerate "^1.4.2"
-
-regenerate-unicode-properties@^9.0.0:
-  version "9.0.0"
-  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326"
-  integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==
+regenerate-unicode-properties@^10.1.0:
+  version "10.1.0"
+  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
+  integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==
   dependencies:
     regenerate "^1.4.2"
 
@@ -6981,40 +6753,29 @@ regenerator-transform@^0.15.0:
   dependencies:
     "@babel/runtime" "^7.8.4"
 
-regexp.prototype.flags@^1.2.0:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
-  integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==
+regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
+  integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
   dependencies:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
+    functions-have-names "^1.2.2"
 
 regexpp@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
   integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
 
-regexpu-core@^4.7.1:
-  version "4.8.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0"
-  integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==
-  dependencies:
-    regenerate "^1.4.2"
-    regenerate-unicode-properties "^9.0.0"
-    regjsgen "^0.5.2"
-    regjsparser "^0.7.0"
-    unicode-match-property-ecmascript "^2.0.0"
-    unicode-match-property-value-ecmascript "^2.0.0"
-
 regexpu-core@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d"
-  integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139"
+  integrity sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==
   dependencies:
     regenerate "^1.4.2"
-    regenerate-unicode-properties "^10.0.1"
-    regjsgen "^0.6.0"
-    regjsparser "^0.8.2"
+    regenerate-unicode-properties "^10.1.0"
+    regjsgen "^0.7.1"
+    regjsparser "^0.9.1"
     unicode-match-property-ecmascript "^2.0.0"
     unicode-match-property-value-ecmascript "^2.0.0"
 
@@ -7034,31 +6795,19 @@ registry-auth-token@^3.0.1:
 registry-url@^3.0.3:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
-  integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI=
+  integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==
   dependencies:
     rc "^1.0.1"
 
-regjsgen@^0.5.2:
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733"
-  integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==
-
-regjsgen@^0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d"
-  integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==
-
-regjsparser@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968"
-  integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==
-  dependencies:
-    jsesc "~0.5.0"
+regjsgen@^0.7.1:
+  version "0.7.1"
+  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6"
+  integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==
 
-regjsparser@^0.8.2:
-  version "0.8.4"
-  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f"
-  integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==
+regjsparser@^0.9.1:
+  version "0.9.1"
+  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709"
+  integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==
   dependencies:
     jsesc "~0.5.0"
 
@@ -7091,7 +6840,7 @@ request@^2.74.0, request@^2.85.0, request@^2.87.0:
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
-  integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+  integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
 
 require-from-string@^2.0.2:
   version "2.0.2"
@@ -7101,7 +6850,7 @@ require-from-string@^2.0.2:
 require-main-filename@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
-  integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
+  integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
 
 require-main-filename@^2.0.0:
   version "2.0.0"
@@ -7111,7 +6860,7 @@ require-main-filename@^2.0.0:
 requires-port@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
-  integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
+  integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
 
 resolve-cwd@^3.0.0:
   version "3.0.0"
@@ -7123,7 +6872,7 @@ resolve-cwd@^3.0.0:
 resolve-from@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
-  integrity sha1-six699nWiBvItuZTM17rywoYh0g=
+  integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==
 
 resolve-from@^4.0.0:
   version "4.0.0"
@@ -7135,17 +6884,21 @@ resolve-from@^5.0.0:
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
   integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
 
-resolve-pathname@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
-  integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
-
 resolve@^1.10.0, resolve@^1.14.2, resolve@^1.8.1, resolve@^1.9.0:
-  version "1.21.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f"
-  integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==
+  version "1.22.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
+  integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
   dependencies:
-    is-core-module "^2.8.0"
+    is-core-module "^2.9.0"
+    path-parse "^1.0.7"
+    supports-preserve-symlinks-flag "^1.0.0"
+
+resolve@^2.0.0-next.4:
+  version "2.0.0-next.4"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660"
+  integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==
+  dependencies:
+    is-core-module "^2.9.0"
     path-parse "^1.0.7"
     supports-preserve-symlinks-flag "^1.0.0"
 
@@ -7160,12 +6913,12 @@ restore-cursor@^3.1.0:
 retry@^0.10.0:
   version "0.10.1"
   resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
-  integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=
+  integrity sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ==
 
 retry@^0.12.0:
   version "0.12.0"
   resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
-  integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
+  integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==
 
 retry@^0.13.1:
   version "0.13.1"
@@ -7218,21 +6971,14 @@ run-parallel@^1.1.9:
 run-queue@^1.0.0, run-queue@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
-  integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=
+  integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==
   dependencies:
     aproba "^1.1.1"
 
-rxjs@^7.5.5:
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f"
-  integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==
-  dependencies:
-    tslib "^2.1.0"
-
-rxjs@^7.5.6:
-  version "7.5.6"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc"
-  integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==
+rxjs@^7.5.5, rxjs@^7.5.6:
+  version "7.5.7"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39"
+  integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==
   dependencies:
     tslib "^2.1.0"
 
@@ -7246,6 +6992,15 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0,
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
   integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
 
+safe-regex-test@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295"
+  integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==
+  dependencies:
+    call-bind "^1.0.2"
+    get-intrinsic "^1.1.3"
+    is-regex "^1.1.4"
+
 "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -7260,9 +7015,9 @@ sass-loader@^13.0.2:
     neo-async "^2.6.2"
 
 sass@^1.54.0:
-  version "1.54.0"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.0.tgz#24873673265e2a4fe3d3a997f714971db2fba1f4"
-  integrity sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==
+  version "1.55.0"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c"
+  integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==
   dependencies:
     chokidar ">=3.0.0 <4.0.0"
     immutable "^4.0.0"
@@ -7299,19 +7054,19 @@ schema-utils@^4.0.0:
 select-hose@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
-  integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
+  integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
 
-selfsigned@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56"
-  integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==
+selfsigned@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61"
+  integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==
   dependencies:
     node-forge "^1"
 
 semver-diff@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
-  integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=
+  integrity sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==
   dependencies:
     semver "^5.0.3"
 
@@ -7320,24 +7075,12 @@ semver-diff@^2.0.0:
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
   integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
 
-semver@7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
-  integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-
 semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
   version "6.3.0"
   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
   integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
 
-semver@^7.3.5:
-  version "7.3.5"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
-  integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
-  dependencies:
-    lru-cache "^6.0.0"
-
-semver@^7.3.7:
+semver@^7.3.5, semver@^7.3.7:
   version "7.3.7"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
   integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
@@ -7347,7 +7090,7 @@ semver@^7.3.7:
 semver@~5.3.0:
   version "5.3.0"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
-  integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8=
+  integrity sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==
 
 send@0.18.0:
   version "0.18.0"
@@ -7378,7 +7121,7 @@ serialize-javascript@^6.0.0:
 serve-index@^1.9.1:
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
-  integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
+  integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==
   dependencies:
     accepts "~1.3.4"
     batch "0.6.1"
@@ -7401,7 +7144,7 @@ serve-static@1.15.0:
 set-blocking@^2.0.0, set-blocking@~2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
-  integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+  integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
 
 setprototypeof@1.1.0:
   version "1.1.0"
@@ -7416,7 +7159,7 @@ setprototypeof@1.2.0:
 sha@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae"
-  integrity sha1-YDCCL70smCOUn49y7WQR7lzyWq4=
+  integrity sha512-Lj/GiNro+/4IIvhDvTo2HDqTmQkbqgg/O3lbkM5lMgagriGPpWamxtq1KJPx7mCvyF1/HG6Hs7zaYaj4xpfXbA==
   dependencies:
     graceful-fs "^4.1.2"
     readable-stream "^2.0.2"
@@ -7436,7 +7179,7 @@ shallowequal@^1.0.1:
 shebang-command@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
-  integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
+  integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
   dependencies:
     shebang-regex "^1.0.0"
 
@@ -7450,7 +7193,7 @@ shebang-command@^2.0.0:
 shebang-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
-  integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
+  integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
 
 shebang-regex@^3.0.0:
   version "3.0.0"
@@ -7466,12 +7209,7 @@ side-channel@^1.0.4:
     get-intrinsic "^1.0.2"
     object-inspect "^1.9.0"
 
-signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
-  version "3.0.6"
-  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af"
-  integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==
-
-signal-exit@^3.0.7:
+signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
   version "3.0.7"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
   integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
@@ -7515,12 +7253,12 @@ slice-ansi@^5.0.0:
 slide@^1.1.3, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
-  integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
+  integrity sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==
 
 smart-buffer@^1.0.13:
   version "1.1.15"
   resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16"
-  integrity sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=
+  integrity sha512-1+8bxygjTsNfvQe0/0pNBesTOlSHtOeG6b6LYbvsZCCHDKYZ40zcQo6YTnZBWrBSLWOCbrHljLdEmGMYebu7aQ==
 
 smart-buffer@^4.1.0:
   version "4.2.0"
@@ -7555,7 +7293,7 @@ socks-proxy-agent@^4.0.0:
 socks@^1.1.10:
   version "1.1.10"
   resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a"
-  integrity sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=
+  integrity sha512-ArX4vGPULWjKDKgUnW8YzfI2uXW7kzgkJuB0GnFBA/PfT3exrrOk+7Wk2oeb894Qf20u1PWv9LEgrO0Z82qAzA==
   dependencies:
     ip "^1.1.4"
     smart-buffer "^1.0.13"
@@ -7588,12 +7326,12 @@ sort-package-json@1.57.0:
 sorted-object@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc"
-  integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=
+  integrity sha512-oKAAs26HeTu3qbawzUGCkTOBv/5MRrcuJyRWwbfEnWdpXnXsj+WEM3HTvarV73tMcf9uBEZNZoNDVRL62VLxzA==
 
 sorted-union-stream@~2.1.3:
   version "2.1.3"
   resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7"
-  integrity sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=
+  integrity sha512-RaKskQJZkmVREIwyAFho1RRU+sKjDdg51Crvxg2VxmIyiIrNhPNoJD/by5/pklWBXAZoO6LfAAGv8xd47p9TnQ==
   dependencies:
     from2 "^1.3.0"
     stream-iterate "^1.1.0"
@@ -7603,12 +7341,7 @@ sortpack@^2.3.0:
   resolved "https://registry.yarnpkg.com/sortpack/-/sortpack-2.3.0.tgz#90d4688e61a91fa1da61e1b0f04dab327b94a3e8"
   integrity sha512-BkqYsA2ksQkVlk2xrwEZoWaz8y26ZMLEkrgdUjrkU5GDysCBoFmDt76D+P8hfJsu9AGdsqqK8XrEpH37ZjG7yw==
 
-"source-map-js@>=0.6.2 <2.0.0":
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf"
-  integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==
-
-source-map-js@^1.0.2:
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
   integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
@@ -7621,21 +7354,11 @@ source-map-support@~0.5.20:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
 
-source-map@^0.5.0:
-  version "0.5.7"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-  integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
-source-map@^0.6.0, source-map@^0.6.1:
+source-map@^0.6.0:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
-source-map@~0.7.2:
-  version "0.7.3"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
-  integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
-
 spdx-correct@^3.0.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
@@ -7658,9 +7381,9 @@ spdx-expression-parse@^3.0.0:
     spdx-license-ids "^3.0.0"
 
 spdx-license-ids@^3.0.0:
-  version "3.0.11"
-  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95"
-  integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==
+  version "3.0.12"
+  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779"
+  integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==
 
 spdy-transport@^3.0.0:
   version "3.0.0"
@@ -7693,7 +7416,7 @@ split-on-first@^1.0.0:
 sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
-  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+  integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
 
 sshpk@^1.7.0:
   version "1.17.0"
@@ -7732,7 +7455,7 @@ statuses@2.0.1:
 "statuses@>= 1.4.0 < 2":
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
-  integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
+  integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
 
 stream-each@^1.1.0:
   version "1.2.3"
@@ -7745,7 +7468,7 @@ stream-each@^1.1.0:
 stream-iterate@^1.1.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1"
-  integrity sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=
+  integrity sha512-QVfGkdBQ8NzsSIiL3rV6AoFFWwMvlg1qpTwVQaMGY5XYThDUuNM4hYSzi8pbKlimTsWyQdaWRZE+jwlPsMiiZw==
   dependencies:
     readable-stream "^2.1.5"
     stream-shift "^1.0.0"
@@ -7758,7 +7481,7 @@ stream-shift@^1.0.0:
 strict-uri-encode@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
-  integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
+  integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
 
 string-argv@^0.3.1:
   version "0.3.1"
@@ -7768,7 +7491,7 @@ string-argv@^0.3.1:
 string-width@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
-  integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
+  integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
   dependencies:
     code-point-at "^1.0.0"
     is-fullwidth-code-point "^1.0.0"
@@ -7801,29 +7524,31 @@ string-width@^3.0.0, string-width@^3.1.0:
     strip-ansi "^5.1.0"
 
 string-width@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.0.tgz#5ab00980cfb29f43e736b113a120a73a0fb569d3"
-  integrity sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ==
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
+  integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
   dependencies:
     eastasianwidth "^0.2.0"
     emoji-regex "^9.2.2"
     strip-ansi "^7.0.1"
 
-string.prototype.trimend@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80"
-  integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==
+string.prototype.trimend@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
+  integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
   dependencies:
     call-bind "^1.0.2"
-    define-properties "^1.1.3"
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
 
-string.prototype.trimstart@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
-  integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==
+string.prototype.trimstart@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
+  integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
   dependencies:
     call-bind "^1.0.2"
-    define-properties "^1.1.3"
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
 
 string_decoder@^1.1.1:
   version "1.3.0"
@@ -7835,7 +7560,7 @@ string_decoder@^1.1.1:
 string_decoder@~0.10.x:
   version "0.10.31"
   resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
-  integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
+  integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
 
 string_decoder@~1.1.1:
   version "1.1.1"
@@ -7847,14 +7572,14 @@ string_decoder@~1.1.1:
 strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
-  integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
+  integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
   dependencies:
     ansi-regex "^2.0.0"
 
 strip-ansi@^4.0.0, strip-ansi@~4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
-  integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
+  integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
   dependencies:
     ansi-regex "^3.0.0"
 
@@ -7882,12 +7607,12 @@ strip-ansi@^7.0.1:
 strip-bom@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
-  integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+  integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
 
 strip-eof@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
-  integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
+  integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
 
 strip-final-newline@^2.0.0:
   version "2.0.0"
@@ -7907,7 +7632,7 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
 strip-json-comments@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
-  integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
+  integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
 
 style-loader@^3.3.1:
   version "3.3.1"
@@ -7970,44 +7695,35 @@ tar@^4.4.0, tar@^4.4.2, tar@^4.4.3, tar@^4.4.8:
 term-size@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
-  integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=
+  integrity sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==
   dependencies:
     execa "^0.7.0"
 
 terser-webpack-plugin@^5.1.3:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f"
-  integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==
+  version "5.3.6"
+  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c"
+  integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==
   dependencies:
-    jest-worker "^27.4.1"
+    "@jridgewell/trace-mapping" "^0.3.14"
+    jest-worker "^27.4.5"
     schema-utils "^3.1.1"
     serialize-javascript "^6.0.0"
-    source-map "^0.6.1"
-    terser "^5.7.2"
+    terser "^5.14.1"
 
-terser@^5.14.2:
-  version "5.14.2"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
-  integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==
+terser@^5.14.1, terser@^5.14.2:
+  version "5.15.0"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425"
+  integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==
   dependencies:
     "@jridgewell/source-map" "^0.3.2"
     acorn "^8.5.0"
     commander "^2.20.0"
     source-map-support "~0.5.20"
 
-terser@^5.7.2:
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc"
-  integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==
-  dependencies:
-    commander "^2.20.0"
-    source-map "~0.7.2"
-    source-map-support "~0.5.20"
-
 text-table@^0.2.0, text-table@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
-  integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+  integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
 
 through2@^2.0.0:
   version "2.0.5"
@@ -8020,7 +7736,7 @@ through2@^2.0.0:
 "through@>=2.2.7 <3", through@^2.3.8:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
-  integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+  integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
 
 thunky@^1.0.2:
   version "1.1.0"
@@ -8030,23 +7746,13 @@ thunky@^1.0.2:
 timed-out@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
-  integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
-
-tiny-invariant@^1.0.2:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
-  integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
+  integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
 
 tiny-relative-date@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07"
   integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==
 
-tiny-warning@^1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
-  integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
-
 tippy.js@^6.3.7:
   version "6.3.7"
   resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
@@ -8057,7 +7763,7 @@ tippy.js@^6.3.7:
 to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
-  integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
+  integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
 
 to-regex-range@^5.0.1:
   version "5.0.1"
@@ -8087,7 +7793,7 @@ tough-cookie@~2.5.0:
 tr46@~0.0.3:
   version "0.0.3"
   resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
-  integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
+  integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
 
 tributejs@^5.1.3:
   version "5.1.3"
@@ -8100,9 +7806,9 @@ tslib@^1.8.1:
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
 
 tslib@^2.1.0:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
-  integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+  integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
 
 tsutils@^3.21.0:
   version "3.21.0"
@@ -8114,14 +7820,14 @@ tsutils@^3.21.0:
 tunnel-agent@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
-  integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
+  integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
   dependencies:
     safe-buffer "^5.0.1"
 
 tweetnacl@^0.14.3, tweetnacl@~0.14.0:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
-  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+  integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
 
 type-check@^0.4.0, type-check@~0.4.0:
   version "0.4.0"
@@ -8151,17 +7857,17 @@ type-is@~1.6.18:
 typedarray@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
-  integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+  integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
 
 typescript@^3.2.4:
   version "3.9.10"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
   integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
 
-typescript@^4.7.4:
-  version "4.7.4"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
-  integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
+typescript@^4.8.4:
+  version "4.8.4"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
+  integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
 
 uc.micro@^1.0.1, uc.micro@^1.0.5:
   version "1.0.6"
@@ -8171,21 +7877,21 @@ uc.micro@^1.0.1, uc.micro@^1.0.5:
 uid-number@0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
-  integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=
+  integrity sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w==
 
 umask@^1.1.0, umask@~1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d"
-  integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=
+  integrity sha512-lE/rxOhmiScJu9L6RTNVgB/zZbF+vGC0/p6D3xnkAePI2o0sMyFG966iR5Ki50OI/0mNi2yaRnxfLsPmEZF/JA==
 
-unbox-primitive@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
-  integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==
+unbox-primitive@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
+  integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
   dependencies:
-    function-bind "^1.1.1"
-    has-bigints "^1.0.1"
-    has-symbols "^1.0.2"
+    call-bind "^1.0.2"
+    has-bigints "^1.0.2"
+    has-symbols "^1.0.3"
     which-boxed-primitive "^1.0.2"
 
 unicode-canonical-property-names-ecmascript@^2.0.0:
@@ -8207,9 +7913,9 @@ unicode-match-property-value-ecmascript@^2.0.0:
   integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==
 
 unicode-property-aliases-ecmascript@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8"
-  integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
+  integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
 
 unique-filename@^1.1.0, unique-filename@^1.1.1, unique-filename@~1.1.0:
   version "1.1.1"
@@ -8228,24 +7934,24 @@ unique-slug@^2.0.0:
 unique-string@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a"
-  integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=
+  integrity sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==
   dependencies:
     crypto-random-string "^1.0.0"
 
 unpipe@1.0.0, unpipe@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
-  integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
+  integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
 
 unzip-response@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
-  integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
+  integrity sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==
 
-update-browserslist-db@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38"
-  integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==
+update-browserslist-db@^1.0.9:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18"
+  integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==
   dependencies:
     escalade "^3.1.1"
     picocolors "^1.0.0"
@@ -8276,31 +7982,31 @@ uri-js@^4.2.2:
 url-parse-lax@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
-  integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
+  integrity sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==
   dependencies:
     prepend-http "^1.0.1"
 
 util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+  integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
 
 util-extend@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f"
-  integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=
+  integrity sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==
 
 util-promisify@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53"
-  integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=
+  integrity sha512-K+5eQPYs14b3+E+hmE2J6gCZ4JmMl9DbYS6BeP2CHq6WMuNxErxf5B/n0fz85L8zUuoO6rIzNNmIQDu/j+1OcA==
   dependencies:
     object.getownpropertydescriptors "^2.0.3"
 
 utils-merge@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
-  integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+  integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
 
 uuid@^3.2.1, uuid@^3.3.2:
   version "3.4.0"
@@ -8312,11 +8018,6 @@ uuid@^8.3.2:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
 
-v8-compile-cache@^2.0.3:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
-  integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
-
 validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -8328,24 +8029,19 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3:
 validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"
-  integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34=
+  integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==
   dependencies:
     builtins "^1.0.3"
 
-value-equal@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
-  integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
-
 vary@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
-  integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
+  integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
 
 verror@1.10.0:
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
-  integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
+  integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
   dependencies:
     assert-plus "^1.0.0"
     core-util-is "1.0.2"
@@ -8354,7 +8050,7 @@ verror@1.10.0:
 void-elements@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
-  integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
+  integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==
 
 watchpack@^2.4.0:
   version "2.4.0"
@@ -8374,14 +8070,14 @@ wbuf@^1.1.0, wbuf@^1.7.3:
 wcwidth@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
-  integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
+  integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==
   dependencies:
     defaults "^1.0.3"
 
 webidl-conversions@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
-  integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+  integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
 
 webpack-cli@^4.10.0:
   version "4.10.0"
@@ -8402,20 +8098,20 @@ webpack-cli@^4.10.0:
     webpack-merge "^5.7.3"
 
 webpack-dev-middleware@^5.3.1:
-  version "5.3.1"
-  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f"
-  integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==
+  version "5.3.3"
+  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f"
+  integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==
   dependencies:
     colorette "^2.0.10"
-    memfs "^3.4.1"
+    memfs "^3.4.3"
     mime-types "^2.1.31"
     range-parser "^1.2.1"
     schema-utils "^4.0.0"
 
-webpack-dev-server@4.9.3:
-  version "4.9.3"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9"
-  integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==
+webpack-dev-server@4.11.1:
+  version "4.11.1"
+  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5"
+  integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==
   dependencies:
     "@types/bonjour" "^3.5.9"
     "@types/connect-history-api-fallback" "^1.3.5"
@@ -8440,7 +8136,7 @@ webpack-dev-server@4.9.3:
     p-retry "^4.5.0"
     rimraf "^3.0.2"
     schema-utils "^4.0.0"
-    selfsigned "^2.0.1"
+    selfsigned "^2.1.1"
     serve-index "^1.9.1"
     sockjs "^0.3.24"
     spdy "^4.0.2"
@@ -8517,7 +8213,7 @@ websocket-ts@^1.1.1:
 whatwg-url@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
-  integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
+  integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
   dependencies:
     tr46 "~0.0.3"
     webidl-conversions "^3.0.0"
@@ -8536,7 +8232,7 @@ which-boxed-primitive@^1.0.2:
 which-module@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-  integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
+  integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
 
 which@1, which@^1.2.9, which@^1.3.0, which@^1.3.1, which@~1.3.0:
   version "1.3.1"
@@ -8586,7 +8282,7 @@ worker-farm@^1.6.0:
 wrap-ansi@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
-  integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
+  integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
   dependencies:
     string-width "^1.0.1"
     strip-ansi "^3.0.1"
@@ -8621,7 +8317,7 @@ wrap-ansi@^7.0.0:
 wrappy@1, wrappy@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-  integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+  integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
 
 write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
   version "2.4.3"
@@ -8633,14 +8329,14 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
     signal-exit "^3.0.2"
 
 ws@^8.4.2:
-  version "8.5.0"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
-  integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
+  version "8.9.0"
+  resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e"
+  integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==
 
 xdg-basedir@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
-  integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
+  integrity sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==
 
 xtend@~4.0.1:
   version "4.0.2"
@@ -8660,7 +8356,7 @@ y18n@^4.0.0:
 yallist@^2.1.2:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
-  integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
+  integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==
 
 yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1:
   version "3.1.1"
@@ -8688,7 +8384,7 @@ yargs-parser@^15.0.1:
 yargs-parser@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
-  integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k=
+  integrity sha512-WhzC+xgstid9MbVUktco/bf+KJG+Uu6vMX0LN1sLJvwmbCQVxb4D8LzogobonKycNasCZLdOzTAk1SK7+K7swg==
   dependencies:
     camelcase "^4.1.0"
 
@@ -8712,7 +8408,7 @@ yargs@^14.2.3:
 yargs@^8.0.2:
   version "8.0.2"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
-  integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A=
+  integrity sha512-3RiZrpLpjrzIAKgGdPktBcMP/eG5bDFlkI+PHle1qwzyVXyDQL+pD/eZaMoOOO0Y7LLBfjpucObuUm/icvbpKQ==
   dependencies:
     camelcase "^4.1.0"
     cliui "^3.2.0"
@@ -8727,3 +8423,8 @@ yargs@^8.0.2:
     which-module "^2.0.0"
     y18n "^3.2.1"
     yargs-parser "^7.0.0"
+
+yocto-queue@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+  integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==