diff --git a/frontend/images.d.ts b/frontend/images.d.ts deleted file mode 100644 index 397cc9b..0000000 --- a/frontend/images.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module '*.svg' -declare module '*.png' -declare module '*.jpg' diff --git a/frontend/package.json b/frontend/package.json index 88d55e6..79f1a6b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,15 +17,14 @@ } }, "lint-staged": { - "src/**/*.{ts,tsx,json,css}": [ + "src/**/*.{ts,tsx}": [ "yarn pretty", "yarn lint:fix", "git add" ] }, "prettier": { - "printWidth": 120, - "parser": "typescript" + "printWidth": 120 }, "dependencies": { "@blueprintjs/core": "^3.4.0", @@ -39,12 +38,14 @@ "react": "^16.4.2", "react-dom": "^16.4.2", "react-redux": "^7.0.2", + "react-router-dom": "^5.0.0", "react-scripts-ts": "3.1.0", "react-sigma": "^1.2.30", "react-virtualized": "^9.20.1", "redux": "^4.0.0", "redux-thunk": "^2.3.0", - "sanitize-html": "^1.18.4" + "sanitize-html": "^1.18.4", + "styled-components": "^4.2.0" }, "devDependencies": { "@blueprintjs/tslint-config": "^1.8.0", @@ -55,8 +56,10 @@ "@types/react": "^16.4.12", "@types/react-dom": "^16.0.7", "@types/react-redux": "^7.0.6", + "@types/react-router-dom": "^4.3.2", "@types/react-virtualized": "^9.18.7", "@types/sanitize-html": "^1.18.0", + "@types/styled-components": "4.1.8", "husky": "^1.3.1", "lint-staged": "^8.1.5", "tslint-eslint-rules": "^5.4.0", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx deleted file mode 100644 index 2d43460..0000000 --- a/frontend/src/App.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import * as React from "react"; -import { connect } from "react-redux"; -import { Dispatch } from "redux"; - -import { Button, Classes, Dialog, NonIdealState, Spinner } from "@blueprintjs/core"; -import { IconNames } from "@blueprintjs/icons"; - -import { ErrorState } from "./components/ErrorState"; -import { Graph } from "./components/Graph"; -import { Nav } from "./components/Nav"; -import { Sidebar } from "./components/Sidebar"; -import { DESKTOP_WIDTH_THRESHOLD } from "./constants"; -import { fetchGraph, fetchInstances } from "./redux/actions"; -import { IAppState, IGraph, IInstance } from "./redux/types"; - -interface IAppProps { - graph?: IGraph; - instances?: IInstance[]; - isLoadingGraph: boolean; - isLoadingInstances: boolean; - graphLoadError: boolean; - fetchInstances: () => void; - fetchGraph: () => void; -} -interface IAppLocalState { - mobileDialogOpen: boolean; -} -class AppImpl extends React.Component { - constructor(props: IAppProps) { - super(props); - this.state = { mobileDialogOpen: false }; - } - - public render() { - let body =
; - if (this.props.isLoadingInstances || this.props.isLoadingGraph) { - body = this.loadingState("Loading..."); - } else { - body = this.graphState(); - } - return ( -
-
- ); - } - - public componentDidMount() { - if (window.innerWidth < DESKTOP_WIDTH_THRESHOLD) { - this.handleMobileDialogOpen(); - } - this.load(); - } - - public componentDidUpdate() { - this.load(); - } - - private load = () => { - if (!this.props.instances && !this.props.isLoadingInstances && !this.props.graphLoadError) { - this.props.fetchInstances(); - } - if (!this.props.graph && !this.props.isLoadingGraph && !this.props.graphLoadError) { - this.props.fetchGraph(); - } - }; - - private graphState = () => { - const content = this.props.graphLoadError ? : ; - return ( -
- - {content} -
- ); - }; - - private loadingState = (title?: string) => { - return } title={title || "Loading..."} />; - }; - - private renderMobileDialog = () => { - return ( - -
-

- fediverse.space is optimized for desktop computers. Feel free to check it out on your phone (ideally in - landscape mode) but for best results, open it on a computer. -

-
-
-
-
-
-
- ); - }; - - private handleMobileDialogOpen = () => { - this.setState({ mobileDialogOpen: true }); - }; - - private handleMobileDialogClose = () => { - this.setState({ mobileDialogOpen: false }); - }; -} - -const mapStateToProps = (state: IAppState) => ({ - graph: state.data.graph, - graphLoadError: state.data.error, - instances: state.data.instances, - isLoadingGraph: state.data.isLoadingGraph, - isLoadingInstances: state.data.isLoadingInstances -}); -const mapDispatchToProps = (dispatch: Dispatch) => ({ - fetchGraph: () => dispatch(fetchGraph() as any), - fetchInstances: () => dispatch(fetchInstances() as any) -}); -export const App = connect( - mapStateToProps, - mapDispatchToProps -)(AppImpl); diff --git a/frontend/src/AppRouter.tsx b/frontend/src/AppRouter.tsx new file mode 100644 index 0000000..e78cd2b --- /dev/null +++ b/frontend/src/AppRouter.tsx @@ -0,0 +1,71 @@ +import * as React from "react"; + +import { Button, Classes, Dialog } from "@blueprintjs/core"; +import { IconNames } from "@blueprintjs/icons"; + +import { BrowserRouter, Route } from "react-router-dom"; +import { Nav } from "./components/Nav"; +import { AboutScreen } from "./components/screens/AboutScreen"; +import { GraphScreen } from "./components/screens/GraphScreen"; +import { DESKTOP_WIDTH_THRESHOLD } from "./constants"; + +interface IAppLocalState { + mobileDialogOpen: boolean; +} +export class AppRouter extends React.Component<{}, IAppLocalState> { + constructor(props: {}) { + super(props); + this.state = { mobileDialogOpen: false }; + } + + public render() { + return ( + +
+
+
+ ); + } + + public componentDidMount() { + if (window.innerWidth < DESKTOP_WIDTH_THRESHOLD) { + this.handleMobileDialogOpen(); + } + } + + private renderMobileDialog = () => { + return ( + +
+

+ fediverse.space is optimized for desktop computers. Feel free to check it out on your phone (ideally in + landscape mode) but for best results, open it on a computer. +

+
+
+
+
+
+
+ ); + }; + + private handleMobileDialogOpen = () => { + this.setState({ mobileDialogOpen: true }); + }; + + private handleMobileDialogClose = () => { + this.setState({ mobileDialogOpen: false }); + }; +} diff --git a/frontend/src/components/InstanceSearch.tsx b/frontend/src/components/InstanceSearch.tsx index a65eeae..1833460 100644 --- a/frontend/src/components/InstanceSearch.tsx +++ b/frontend/src/components/InstanceSearch.tsx @@ -6,10 +6,11 @@ import { Button, MenuItem } from "@blueprintjs/core"; import { IconNames } from "@blueprintjs/icons"; import { IItemRendererProps, ItemPredicate, Select } from "@blueprintjs/select"; +import { RouteComponentProps, withRouter } from "react-router"; import { selectAndLoadInstance } from "../redux/actions"; import { IAppState, IInstance } from "../redux/types"; -interface IInstanceSearchProps { +interface IInstanceSearchProps extends RouteComponentProps { currentInstanceName: string | null; instances?: IInstance[]; selectAndLoadInstance: (instanceName: string) => void; @@ -25,7 +26,7 @@ class InstanceSearchImpl extends React.Component { itemRenderer={this.itemRenderer} onItemSelect={this.onItemSelect} itemPredicate={this.itemPredicate} - disabled={!this.props.instances} + disabled={!this.props.instances || this.props.location.pathname !== "/"} initialContent={this.renderInitialContent()} noResults={this.renderNoResults()} popoverProps={{ popoverClassName: "fediverse-instance-search-popover" }} @@ -76,7 +77,9 @@ const mapStateToProps = (state: IAppState) => ({ const mapDispatchToProps = (dispatch: Dispatch) => ({ selectAndLoadInstance: (instanceName: string) => dispatch(selectAndLoadInstance(instanceName) as any) }); -export const InstanceSearch = connect( - mapStateToProps, - mapDispatchToProps -)(InstanceSearchImpl); +export const InstanceSearch = withRouter( + connect( + mapStateToProps, + mapDispatchToProps + )(InstanceSearchImpl) +); diff --git a/frontend/src/components/Nav.tsx b/frontend/src/components/Nav.tsx index edf9c26..509b028 100644 --- a/frontend/src/components/Nav.tsx +++ b/frontend/src/components/Nav.tsx @@ -1,8 +1,10 @@ import * as React from "react"; -import { Alignment, Button, Classes, Code, Dialog, H2, H4, Icon, Navbar } from "@blueprintjs/core"; +import { Alignment, Button, Navbar } from "@blueprintjs/core"; import { IconNames } from "@blueprintjs/icons"; +import { Link } from "react-router-dom"; +import styled from "styled-components"; import { InstanceSearch } from "./InstanceSearch"; interface INavState { @@ -15,26 +17,20 @@ export class Nav extends React.Component<{}, INavState> { } public render() { + const StyledLink = styled(Link)` + color: white !important; + `; return ( - - - fediverse.space - + fediverse.space -
- - - ); - }; - - private handleAboutOpen = () => { - this.setState({ aboutIsOpen: true }); - }; - - private handleAboutClose = () => { - this.setState({ aboutIsOpen: false }); - }; } diff --git a/frontend/src/components/Page.tsx b/frontend/src/components/Page.tsx new file mode 100644 index 0000000..bc7096a --- /dev/null +++ b/frontend/src/components/Page.tsx @@ -0,0 +1,7 @@ +import styled from "styled-components"; + +export const Page = styled.div` + max-width: 800px; + margin: auto; + padding: 2em; +`; diff --git a/frontend/src/components/screens/AboutScreen.tsx b/frontend/src/components/screens/AboutScreen.tsx new file mode 100644 index 0000000..3cbdcaa --- /dev/null +++ b/frontend/src/components/screens/AboutScreen.tsx @@ -0,0 +1,83 @@ +import { Classes, Code, H1, H2, H4 } from "@blueprintjs/core"; +import * as React from "react"; +import { Page } from "../Page"; + +export const AboutScreen: React.FC = () => ( + +

About

+

+ fediverse.space is a tool to visualize networks and communities on the{" "} + + fediverse + + . It works by crawling every instance it can find and aggregating statistics on communication between these. +

+ +

FAQ

+ +

Why can't I see details about my instance?

+

+ Currently, fediverse.space only supports Mastodon and Pleroma instances. In addition, instances with 10 or fewer + users won't be scraped -- it's a tool for understanding communities, not individuals. +

+ +

+ When is $OTHER_ACTIVITYPUB_SERVER going to be added? +

+

+ Check out{" "} + + this GitLab issue + + . +

+ +

How do I add my personal instance?

+

+ Send a DM to{" "} + + @fediversespace + {" "} + on Mastodon. Make sure to send it from the account that's listed as the instance admin. +

+ +

How do you calculate the strength of relationships between instances?

+

+ fediverse.space scrapes the last 5000 statuses from within the last month on the public timeline of each instance. + It looks at the ratio of + mentions of an instance / total statuses. It uses a ratio rather than an absolute number of mentions + to reflect that smaller instances can play a large role in a community. +

+ +

Credits

+

+ This site is inspired by several other sites in the same vein: +

+ The source code for fediverse.space is available on{" "} + + GitLab + + ; issues and pull requests are welcome! +

+
+); diff --git a/frontend/src/components/screens/GraphScreen.tsx b/frontend/src/components/screens/GraphScreen.tsx new file mode 100644 index 0000000..cc04500 --- /dev/null +++ b/frontend/src/components/screens/GraphScreen.tsx @@ -0,0 +1,79 @@ +import * as React from "react"; +import { connect } from "react-redux"; +import { Dispatch } from "redux"; + +import { NonIdealState, Spinner } from "@blueprintjs/core"; + +import { fetchGraph, fetchInstances } from "../../redux/actions"; +import { IAppState, IGraph, IInstance } from "../../redux/types"; +import { ErrorState } from "../ErrorState"; +import { Graph } from "../Graph"; +import { Sidebar } from "../Sidebar"; + +interface IGraphScreenProps { + graph?: IGraph; + instances?: IInstance[]; + isLoadingGraph: boolean; + isLoadingInstances: boolean; + graphLoadError: boolean; + fetchInstances: () => void; + fetchGraph: () => void; +} +class GraphScreenImpl extends React.Component { + public render() { + let body =
; + if (this.props.isLoadingInstances || this.props.isLoadingGraph) { + body = this.loadingState("Loading..."); + } else { + body = this.graphState(); + } + return
{body}
; + } + + public componentDidMount() { + this.load(); + } + + public componentDidUpdate() { + this.load(); + } + + private load = () => { + if (!this.props.instances && !this.props.isLoadingInstances && !this.props.graphLoadError) { + this.props.fetchInstances(); + } + if (!this.props.graph && !this.props.isLoadingGraph && !this.props.graphLoadError) { + this.props.fetchGraph(); + } + }; + + private graphState = () => { + const content = this.props.graphLoadError ? : ; + return ( +
+ + {content} +
+ ); + }; + + private loadingState = (title?: string) => { + return } title={title || "Loading..."} />; + }; +} + +const mapStateToProps = (state: IAppState) => ({ + graph: state.data.graph, + graphLoadError: state.data.error, + instances: state.data.instances, + isLoadingGraph: state.data.isLoadingGraph, + isLoadingInstances: state.data.isLoadingInstances +}); +const mapDispatchToProps = (dispatch: Dispatch) => ({ + fetchGraph: () => dispatch(fetchGraph() as any), + fetchInstances: () => dispatch(fetchInstances() as any) +}); +export const GraphScreen = connect( + mapStateToProps, + mapDispatchToProps +)(GraphScreenImpl); diff --git a/frontend/src/index.css b/frontend/src/index.css index b15a965..d0b86ee 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,19 +1,13 @@ -html, body { +html, +body { margin: 0; padding: 50px 0 0 0; font-family: sans-serif; /*background-color: #30404D;*/ background-color: #293742; height: 100%; - font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif; -} - -.fediverse-heading-icon { - margin-right: 8px; -} - -.fediverse-about-dialog { - top: 100px; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, + Icons16, sans-serif; } .fediverse-instance-search-popover { @@ -33,7 +27,7 @@ html, body { overflow: scroll; overflow-x: hidden; transition-property: all; - transition-duration: .5s; + transition-duration: 0.5s; transition-timing-function: cubic-bezier(0, 1, 0.5, 1); } @@ -44,10 +38,10 @@ html, body { .fediverse-sidebar-toggle-button { position: absolute; top: 50px; - right:400px; + right: 400px; z-index: 20; transition-property: all; - transition-duration: .5s; + transition-duration: 0.5s; transition-timing-function: cubic-bezier(0, 1, 0.5, 1); } @@ -67,4 +61,4 @@ html, body { .fediverse-sidebar-toggle-button { right: 25%; } -} \ No newline at end of file +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 03fb130..09a7ed6 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -12,7 +12,7 @@ import thunk from "redux-thunk"; import { FocusStyleManager } from "@blueprintjs/core"; -import { App } from "./App"; +import { AppRouter } from "./AppRouter"; import { rootReducer } from "./redux/reducers"; // https://blueprintjs.com/docs/#core/accessibility.focus-management @@ -25,7 +25,7 @@ const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk))) ReactDOM.render( - + , document.getElementById("root") as HTMLElement ); diff --git a/frontend/tsconfig.prod.json b/frontend/tsconfig.prod.json deleted file mode 100644 index 4144216..0000000 --- a/frontend/tsconfig.prod.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "./tsconfig.json" -} \ No newline at end of file diff --git a/frontend/tsconfig.test.json b/frontend/tsconfig.test.json deleted file mode 100644 index 65ffdd4..0000000 --- a/frontend/tsconfig.test.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "commonjs" - } -} \ No newline at end of file diff --git a/frontend/tslint.json b/frontend/tslint.json index d791653..799fb02 100644 --- a/frontend/tslint.json +++ b/frontend/tslint.json @@ -5,5 +5,8 @@ "tslint-react", "@blueprintjs/tslint-config/blueprint-rules", "tslint-config-prettier" + ], + "exclude": [ + "**/*.css" ] } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index b09f43c..f7477ae 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -9,6 +9,20 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" @@ -32,6 +46,15 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/types@^7.0.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" + integrity sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + "@blueprintjs/core@^3.15.0", "@blueprintjs/core@^3.4.0": version "3.15.1" resolved "https://registry.yarnpkg.com/@blueprintjs/core/-/core-3.15.1.tgz#9792e9fb7e2e066dd5339fadeaf2f85b1485832a" @@ -76,6 +99,23 @@ tslint-plugin-prettier "^2.0.1" tslint-react "^3.6.0" +"@emotion/is-prop-valid@^0.7.3": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz#a6bf4fa5387cbba59d44e698a4680f481a8da6cc" + integrity sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA== + dependencies: + "@emotion/memoize" "0.7.1" + +"@emotion/memoize@0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" + integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg== + +"@emotion/unitless@^0.7.0": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.3.tgz#6310a047f12d21a1036fb031317219892440416f" + integrity sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg== + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -105,6 +145,11 @@ dependencies: "@types/domhandler" "*" +"@types/history@*": + version "4.7.2" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.2.tgz#0e670ea254d559241b6eeb3894f8754991e73220" + integrity sha512-ui3WwXmjTaY73fOQ3/m3nnajU/Orhi6cEu5rzX+BrAAJxa3eITXZ5ch9suPqtM03OWhAHhPSyBGCN4UKoxO20Q== + "@types/hoist-non-react-statics@^3.3.0": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" @@ -170,6 +215,23 @@ "@types/react" "*" redux "^4.0.0" +"@types/react-router-dom@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.3.2.tgz#52c17c3682597638f31c17c42620403dc5c2a3f5" + integrity sha512-biesHodFxPgDxku2m08XwPeAfUYBcxAnrQG7pwFikuA3L2e3u2OKAb+Sb16bJuU3L5CTHd+Ivap+ke4mmGsHqQ== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "4.4.5" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.5.tgz#1166997dc7eef2917b5ebce890ebecb32ee5c1b3" + integrity sha512-12+VOu1+xiC8RPc9yrgHCyLI79VswjtuqeS2gPrMcywH6tkc8rGIUhs4LaL3AJPqo5d+RPnfRpNKiJ7MK2Qhcg== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-virtualized@^9.18.7": version "9.21.1" resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.1.tgz#c85770f5bb0ccaeb3496d97ff2a2d9028c8ed1fd" @@ -193,6 +255,15 @@ dependencies: "@types/htmlparser2" "*" +"@types/styled-components@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-4.1.8.tgz#15c8a53bb4b9066e528fafb7558963dee5690ae0" + integrity sha512-NrG0wmB9Rafy5i00GFxUM/uEge148bX2QPr+Q/MI2fXrew6WOp1hN2A3YEG0AeT45z47CMdJ3BEffPsdQCWayA== + dependencies: + "@types/node" "*" + "@types/react" "*" + csstype "^2.2.0" + abab@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -826,6 +897,16 @@ babel-plugin-jest-hoist@^22.4.4: resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz#b9851906eab34c7bf6f8c895a2b08bea1a844c0b" integrity sha512-DUvGfYaAIlkdnygVIEl0O4Av69NtuQWcrjMOv6DODPuhuGLDnbsARz3AwiiI/EkIMMlxQDUcrZ9yoyJvTNjcVQ== +"babel-plugin-styled-components@>= 1": + version "1.10.0" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.0.tgz#ff1f42ad2cc78c21f26b62266b8f564dbc862939" + integrity sha512-sQVKG8irFXx14ZfaK1bBePirfkacl3j8nZwSZK+ZjsbnadRHKQTbhXbe/RB1vT6Vgkz45E+V95LBq4KqdhZUNw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-module-imports" "^7.0.0" + babel-plugin-syntax-jsx "^6.18.0" + lodash "^4.17.10" + babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -851,7 +932,7 @@ babel-plugin-syntax-flow@^6.18.0: resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: +babel-plugin-syntax-jsx@^6.18.0, babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= @@ -1690,6 +1771,11 @@ camelcase@^4.0.0, camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelize@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -2230,6 +2316,14 @@ create-react-context@<=0.2.2: fbjs "^0.8.0" gud "^1.0.0" +create-react-context@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3" + integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag== + dependencies: + fbjs "^0.8.0" + gud "^1.0.0" + cross-fetch@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.2.tgz#b7136491967031949c7f86b15903aef4fa3f1768" @@ -2280,6 +2374,11 @@ crypto-random-string@^1.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= + css-color-names@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" @@ -2324,6 +2423,15 @@ css-selector-tokenizer@^0.7.0: fastparse "^1.1.1" regexpu-core "^1.0.0" +css-to-react-native@^2.2.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.0.tgz#bf80d24ec4a08e430306ef429c0586e6ed5485f7" + integrity sha512-IhR7bNIrCFwbJbKZOAjNDZdwpsbjTN6f1agXeELHDqg1wHPA8c2QLruttKOW7hgMGetkfraRJCIEMrptifBfVw== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^3.3.0" + css-what@2.1: version "2.1.3" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" @@ -3915,6 +4023,18 @@ he@1.2.x: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +history@^4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca" + integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^2.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^0.4.0" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3924,7 +4044,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.3.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== @@ -5608,7 +5728,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.0, loose-envify@^1.3.1, 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== @@ -5710,6 +5830,11 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +memoize-one@^5.0.0: + version "5.0.4" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.4.tgz#005928aced5c43d890a4dfab18ca908b0ec92cbc" + integrity sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA== + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -6572,7 +6697,7 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@^1.0.1: +path-to-regexp@^1.0.1, 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= @@ -7092,7 +7217,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -7309,7 +7434,7 @@ react-error-overlay@^4.0.1: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.1.tgz#417addb0814a90f3a7082eacba7cee588d00da89" integrity sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw== -react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== @@ -7343,6 +7468,35 @@ react-redux@^7.0.2: prop-types "^15.7.2" react-is "^16.8.6" +react-router-dom@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.0.0.tgz#542a9b86af269a37f0b87218c4c25ea8dcf0c073" + integrity sha512-wSpja5g9kh5dIteZT3tUoggjnsa+TPFHSMrpHXMpFsaHhQkm/JNVGh2jiF9Dkh4+duj4MKCkwO6H08u6inZYgQ== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.0.0.tgz#349863f769ffc2fa10ee7331a4296e86bc12879d" + integrity sha512-6EQDakGdLG/it2x9EaCt9ZpEEPxnd0OCLBHQ1AcITAAx7nCnyvnzf76jKWG1s2/oJ7SSviUgfWHofdYljFexsA== + dependencies: + "@babel/runtime" "^7.1.2" + create-react-context "^0.2.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-scripts-ts@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/react-scripts-ts/-/react-scripts-ts-3.1.0.tgz#3f285c54b242ff6ecbfb91785060db10660ee7b0" @@ -7757,6 +7911,11 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-pathname@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" + integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -8483,6 +8642,33 @@ style-loader@0.19.0: loader-utils "^1.0.2" schema-utils "^0.3.0" +styled-components@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.2.0.tgz#811fbbec4d64c7189f6c7482b9eb6fefa7fefef7" + integrity sha512-L/LzkL3ZbBhqIVHdR7DbYujy4tqvTNRfc+4JWDCYyhTatI+8CRRQUmdaR0+ARl03DWsfKLhjewll5uNLrqrl4A== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/is-prop-valid" "^0.7.3" + "@emotion/unitless" "^0.7.0" + babel-plugin-styled-components ">= 1" + css-to-react-native "^2.2.2" + memoize-one "^5.0.0" + prop-types "^15.5.4" + react-is "^16.6.0" + stylis "^3.5.0" + stylis-rule-sheet "^0.0.10" + supports-color "^5.5.0" + +stylis-rule-sheet@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== + +stylis@^3.5.0: + version "3.5.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== + subarg@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" @@ -8509,7 +8695,7 @@ supports-color@^4.2.1: dependencies: has-flag "^2.0.0" -supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -8665,6 +8851,16 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-invariant@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.4.tgz#346b5415fd93cb696b0c4e8a96697ff590f92463" + integrity sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g== + +tiny-warning@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.2.tgz#1dfae771ee1a04396bdfde27a3adcebc6b648b28" + integrity sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -8687,6 +8883,11 @@ to-fast-properties@^1.0.3: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= +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= + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -9178,6 +9379,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +value-equal@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" + integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"