mirror of
https://github.com/quepasaevents/qpa-client.git
synced 2023-12-14 05:33:02 +01:00
Add Server Side Rendering
This commit is contained in:
parent
5a38dfce08
commit
231c6a9333
6
@types/graphql.d.ts
vendored
6
@types/graphql.d.ts
vendored
|
@ -0,0 +1,6 @@
|
|||
// tslint:disable
|
||||
// graphql typescript definitions
|
||||
|
||||
|
||||
|
||||
// tslint:enable
|
3
@types/index.d.ts
vendored
3
@types/index.d.ts
vendored
|
@ -1,7 +1,6 @@
|
|||
export type EventStatus = 'confirmed' | 'canceled'
|
||||
// tslint:disable
|
||||
// graphql typescript definitions
|
||||
|
||||
declare namespace GQL {
|
||||
interface IGraphQLResponseRoot {
|
||||
data?: IQuery | IMutation;
|
||||
|
@ -95,7 +94,6 @@ declare namespace GQL {
|
|||
event: ICalendarEvent;
|
||||
start: string;
|
||||
end: string;
|
||||
timeZone: string;
|
||||
}
|
||||
|
||||
interface IEventMeta {
|
||||
|
@ -215,5 +213,4 @@ declare namespace GQL {
|
|||
status?: string | null;
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:enable
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import * as React from "react"
|
||||
import {
|
||||
Redirect,
|
||||
Route,
|
||||
Switch,
|
||||
} from "react-router-dom"
|
||||
import { Redirect, Route, Switch } from "react-router-dom"
|
||||
import Calendar from "../Calendar/Calendar"
|
||||
import CreateEvent from "../Event/CreateEvent"
|
||||
import EditEvent from "../Event/EditEvent"
|
||||
|
@ -16,21 +12,35 @@ import InitializeSession from "./Auth/InitializeSession"
|
|||
import Signup from "./Auth/Signup"
|
||||
import Signout from "./Auth/Signout"
|
||||
import OccurrenceDetails from "./Occurrence/OccurrenceDetails"
|
||||
|
||||
import { Global, css } from "@emotion/core"
|
||||
|
||||
const App = () => (
|
||||
<Root>
|
||||
<Global
|
||||
styles={css`
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
}
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
<StyledHeader />
|
||||
<Content>
|
||||
<Switch>
|
||||
<Route path="/create" component={CreateEvent} />
|
||||
<Route
|
||||
path="/event/:eventId/edit"
|
||||
render={(
|
||||
routeProps: RouteComponentProps<{ eventId: string }>
|
||||
) => <EditEvent eventId={routeProps.match.params.eventId} />}
|
||||
render={(routeProps: RouteComponentProps<{ eventId: string }>) => (
|
||||
<EditEvent eventId={routeProps.match.params.eventId} />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path="/o/:sanitizedEventName/:occurrenceId"
|
||||
component={OccurrenceDetails}
|
||||
/>
|
||||
<Route path="/o/:sanitizedEventName/:occurrenceId" component={OccurrenceDetails}/>
|
||||
<Route path="/init-session/:hash" component={InitializeSession} />
|
||||
<Route path="/login" component={Login} />
|
||||
<Route path="/signup" component={Signup} />
|
||||
|
@ -59,9 +69,9 @@ const Content = styled.div`
|
|||
`
|
||||
|
||||
const StyledFooter = styled(Footer)`
|
||||
grid-row: footer
|
||||
grid-row: footer;
|
||||
`
|
||||
const StyledHeader = styled(Header)`
|
||||
grid-row: header
|
||||
grid-row: header;
|
||||
`
|
||||
export default App
|
||||
|
|
|
@ -21,7 +21,7 @@ const InitializeSession = (props: Props) => {
|
|||
setResponseCode(res.status)
|
||||
setLoading(false)
|
||||
if (res.status === 200) {
|
||||
// props.history.replace("/my-events")
|
||||
props.history.replace("/my-events")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -32,7 +32,7 @@ const InitializeSession = (props: Props) => {
|
|||
{loading
|
||||
? "Loading..."
|
||||
: responseCode === 200
|
||||
? "You will be redirected now"
|
||||
? "You will be redirected now"
|
||||
: "Validation failed. Please try to log in again."}
|
||||
</Root>
|
||||
)
|
||||
|
|
|
@ -12,16 +12,15 @@ const Signup = () => {
|
|||
<form
|
||||
onSubmit={(e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
const data = new FormData(e.target as HTMLFormElement)
|
||||
|
||||
const form = e.target as any
|
||||
fetch("/api/signup", {
|
||||
method: "post",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: data.get("name"),
|
||||
email: data.get("email")
|
||||
name: form.name.value,
|
||||
email: form.email.value
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.status === 200) {
|
||||
|
|
|
@ -9,13 +9,15 @@ const { Provider, Consumer } = React.createContext<IAppContext>({ me: null })
|
|||
|
||||
const AppContextProvider = props => (
|
||||
<MeQuery>
|
||||
{({ data, loading, error }) => (
|
||||
<Provider value={data}>
|
||||
{
|
||||
props.children
|
||||
}
|
||||
</Provider>
|
||||
)}
|
||||
{({ data, loading, error }) => {
|
||||
return (
|
||||
<Provider value={data}>
|
||||
{
|
||||
props.children
|
||||
}
|
||||
</Provider>
|
||||
)
|
||||
}}
|
||||
</MeQuery>
|
||||
)
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@ const OccurrenceDetails = (props: Props) => {
|
|||
if (loading) {
|
||||
return <p>loading...</p>
|
||||
}
|
||||
if (error) {
|
||||
return <p>{error.message}</p>
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{ data.occurrence.event.info[0].title}
|
||||
|
|
|
@ -7,7 +7,6 @@ const query = gql`
|
|||
id
|
||||
start
|
||||
end
|
||||
timeZone
|
||||
event {
|
||||
id
|
||||
owner {
|
||||
|
@ -29,7 +28,6 @@ export interface OccurrenceDetailsData {
|
|||
id: string
|
||||
start: string
|
||||
end: string
|
||||
timeZone: string
|
||||
event: {
|
||||
owner: {
|
||||
id: string
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
import * as React from 'react'
|
||||
import {AppContextProvider} from "./Context/AppContext"
|
||||
import {BrowserRouter as Router, Redirect, Route, Switch} from "react-router-dom"
|
||||
import {BrowserRouter as Router} from "react-router-dom"
|
||||
import {ApolloProvider} from "react-apollo"
|
||||
import {HttpLink} from "apollo-link-http"
|
||||
import {ApolloClient} from "apollo-client"
|
||||
import {InMemoryCache} from "apollo-cache-inmemory"
|
||||
import fetch from 'node-fetch'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactChild | React.ReactChildren
|
||||
}
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: "/graphql"
|
||||
uri: "/graphql",
|
||||
fetch
|
||||
})
|
||||
|
||||
const graphqlClient = new ApolloClient({
|
||||
connectToDevTools: true,
|
||||
link: httpLink,
|
||||
cache: new InMemoryCache()
|
||||
cache: new InMemoryCache().restore(window.__APOLLO_DATA__)
|
||||
}) as ApolloClient<any>
|
||||
|
||||
|
||||
const Providers = (props: Props) => (
|
||||
<ApolloProvider client={graphqlClient}>
|
||||
<AppContextProvider>
|
||||
|
|
|
@ -2,30 +2,12 @@ import * as React from "react"
|
|||
import * as ReactDOM from "react-dom"
|
||||
import App from "./App"
|
||||
import Providers from "./Providers"
|
||||
import css from '@emotion/css'
|
||||
import css from "@emotion/css"
|
||||
|
||||
const appWrapper = document.createElement("div")
|
||||
appWrapper.id = 'appcontainer'
|
||||
document.body.appendChild(appWrapper)
|
||||
|
||||
ReactDOM.render(
|
||||
const container = document.getElementById("app")
|
||||
ReactDOM.hydrate(
|
||||
<Providers>
|
||||
<App />
|
||||
</Providers>,
|
||||
appWrapper
|
||||
container
|
||||
)
|
||||
|
||||
const styled = css`
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
}
|
||||
#appcontainer {
|
||||
height: 100%;
|
||||
}
|
||||
`
|
||||
|
||||
const styleElem = document.createElement('style')
|
||||
styleElem.innerText = styled.styles;
|
||||
document.body.appendChild(styleElem)
|
||||
export default App
|
||||
|
|
|
@ -22,29 +22,32 @@ const endOfThisMonth = (
|
|||
)()
|
||||
|
||||
|
||||
const Calendar = (props: Props) => (
|
||||
<OccurrencesQuery
|
||||
variables={{
|
||||
filter: {
|
||||
from: beginningOfThisMonth,
|
||||
to: endOfThisMonth
|
||||
}
|
||||
}}
|
||||
>
|
||||
{({data, error, loading}) => {
|
||||
if (loading) {
|
||||
return "I am a Spinner"
|
||||
}
|
||||
if (error) {
|
||||
return error.message
|
||||
}
|
||||
const Calendar = (props: Props) => {
|
||||
return (
|
||||
<OccurrencesQuery
|
||||
variables={{
|
||||
filter: {
|
||||
from: "2019-06-01",
|
||||
to: "2019-06-30"
|
||||
}
|
||||
}}
|
||||
>
|
||||
{({data, error, loading}) => {
|
||||
if (loading) {
|
||||
return "I am a Spinner"
|
||||
}
|
||||
if (error) {
|
||||
return error.message
|
||||
}
|
||||
|
||||
if (!data.occurrences.length) {
|
||||
return <p>No occurrences</p>
|
||||
}
|
||||
return <List occurrences={data.occurrences}/>
|
||||
}}
|
||||
</OccurrencesQuery>
|
||||
)
|
||||
if (!data.occurrences.length) {
|
||||
return <p>No occurrences</p>
|
||||
}
|
||||
return <List occurrences={data.occurrences}/>
|
||||
}}
|
||||
</OccurrencesQuery>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default Calendar
|
||||
|
|
|
@ -2,13 +2,13 @@ import * as React from "react"
|
|||
import { OccurrenceData } from "../../Event/OccurrencesQuery"
|
||||
import { AppContext } from "../../App/Context/AppContext"
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from '@emotion/styled'
|
||||
|
||||
interface Props {
|
||||
occurrence: OccurrenceData
|
||||
}
|
||||
|
||||
const sanitizeEventName = (name: string) => {
|
||||
encodeURIComponent
|
||||
return encodeURIComponent(name.trim().toLocaleLowerCase()
|
||||
.replace(/\s+/g,'-'))
|
||||
|
||||
|
@ -29,7 +29,7 @@ const ListItem = (props: Props) => {
|
|||
</Link>
|
||||
{
|
||||
me && me.events.find(myEvent => myEvent.id === event.id) ? (
|
||||
<Link to={`/event/${event.id}/edit`}>Edit</Link>
|
||||
<EditLink to={`/event/${event.id}/edit`}>Edit</EditLink>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
|
@ -38,4 +38,9 @@ const ListItem = (props: Props) => {
|
|||
)
|
||||
}
|
||||
|
||||
const EditLink = styled(Link)`
|
||||
margin-left: 8px;
|
||||
font-size: 0.6em;
|
||||
`
|
||||
|
||||
export default ListItem
|
||||
|
|
25
client/SSR/SSRProviders.tsx
Normal file
25
client/SSR/SSRProviders.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import * as React from 'react'
|
||||
import {AppContextProvider} from "../App/Context/AppContext"
|
||||
import {ApolloProvider} from "react-apollo"
|
||||
import {ApolloClient} from "apollo-client"
|
||||
import {InMemoryCache} from "apollo-cache-inmemory"
|
||||
import { StaticRouter } from 'react-router'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactChild | React.ReactChildren
|
||||
graphqlClient: ApolloClient<InMemoryCache>
|
||||
location: string
|
||||
}
|
||||
|
||||
const SSRProviders = (props: Props) => (
|
||||
<ApolloProvider client={props.graphqlClient}>
|
||||
<AppContextProvider>
|
||||
<StaticRouter location={props.location}>
|
||||
{ props.children }
|
||||
</StaticRouter>
|
||||
</AppContextProvider>
|
||||
</ApolloProvider>
|
||||
)
|
||||
|
||||
|
||||
export default SSRProviders
|
57
client/SSR/handler.tsx
Normal file
57
client/SSR/handler.tsx
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Request, Response } from "express-serve-static-core"
|
||||
import * as ReactDOMServer from "react-dom/server"
|
||||
import { renderStylesToString } from "emotion-server"
|
||||
import App from "../App/App"
|
||||
import * as React from "react"
|
||||
import SSRProviders from "./SSRProviders"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import * as Mustache from "mustache"
|
||||
import { ApolloClient } from "apollo-client"
|
||||
import { InMemoryCache } from "apollo-cache-inmemory"
|
||||
import { HttpLink } from "apollo-link-http"
|
||||
import fetch from "node-fetch"
|
||||
import { getDataFromTree } from "react-apollo"
|
||||
import apolloLogger from "apollo-link-logger"
|
||||
import { ApolloLink } from "apollo-link"
|
||||
export const httpSSRHandler = async (req: Request, res: Response) => {
|
||||
res.status(200)
|
||||
const httpLink = new HttpLink({
|
||||
uri: "http://localhost:4000/graphql",
|
||||
fetch,
|
||||
headers: {
|
||||
cookie: req.header("Cookie")
|
||||
}
|
||||
})
|
||||
|
||||
const link = ApolloLink.from([apolloLogger, httpLink])
|
||||
|
||||
const graphqlClient = new ApolloClient({
|
||||
connectToDevTools: true,
|
||||
link,
|
||||
cache: new InMemoryCache(),
|
||||
ssrMode: true,
|
||||
}) as ApolloClient<any>
|
||||
|
||||
const app = (
|
||||
<SSRProviders location={req.path} graphqlClient={graphqlClient}>
|
||||
<App />
|
||||
</SSRProviders>
|
||||
)
|
||||
|
||||
const appWithData = await getDataFromTree(app)
|
||||
|
||||
const appBody = renderStylesToString(appWithData)
|
||||
const initialState = graphqlClient.extract()
|
||||
|
||||
const template = fs.readFileSync(
|
||||
path.join(__dirname, "./index.html.mustache"),
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
const result = Mustache.render(template, {
|
||||
appBody,
|
||||
apolloData: JSON.stringify(initialState)
|
||||
})
|
||||
res.send(result)
|
||||
}
|
14
client/SSR/index.html.mustache
Normal file
14
client/SSR/index.html.mustache
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Quepasa Alpujarra</title>
|
||||
<script type="application/javascript">
|
||||
__APOLLO_DATA__ = {{{ apolloData }}};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">{{{ appBody }}}</div>
|
||||
<script type="application/javascript" src="/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
8
client/SSR/index.tsx
Normal file
8
client/SSR/index.tsx
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as React from 'react'
|
||||
import * as express from 'express'
|
||||
import { httpSSRHandler } from './handler'
|
||||
|
||||
const app = express()
|
||||
app.get('/*', httpSSRHandler)
|
||||
app.listen(5000)
|
||||
console.log('alrigh')
|
|
@ -1,19 +1,25 @@
|
|||
{
|
||||
"name": "cc-web-client",
|
||||
"version": "1.0.0",
|
||||
"name": "client",
|
||||
"version": "0.0.1",
|
||||
"main": "index.ts",
|
||||
"license": "private",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=development webpack-dev-server --config ./webpack.config.ts --hot --progress"
|
||||
"start": "NODE_ENV=development webpack-dev-server --config ./webpack.config.ts --hot --progress",
|
||||
"ssr": "ts-node SSR/index.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "^10.0.12",
|
||||
"@types/mustache": "^0.8.32",
|
||||
"@types/react-router-dom": "^4.3.3",
|
||||
"apollo-cache-inmemory": "^1.3.8",
|
||||
"apollo-client": "^2.4.5",
|
||||
"apollo-link": "^1.2.12",
|
||||
"apollo-link-http": "^1.5.14",
|
||||
"apollo-link-logger": "^1.2.3",
|
||||
"date-fns": "^1.29.0",
|
||||
"emotion-server": "^10.0.14",
|
||||
"express": "^4.17.1",
|
||||
"formik": "^1.4.1",
|
||||
"graphql": "^14.0.2",
|
||||
"graphql-tag": "^2.9.2",
|
||||
|
@ -21,6 +27,9 @@
|
|||
"jest": "^24.1.0",
|
||||
"jest-cli": "24.1.0",
|
||||
"keycode": "^2.2.0",
|
||||
"mustache": "^3.0.1",
|
||||
"node-fetch": "^2.6.0",
|
||||
"nodemon": "^1.19.1",
|
||||
"ramda": "^0.26.1",
|
||||
"react": "^16.8.6",
|
||||
"react-apollo": "^2.2.4",
|
||||
|
@ -44,6 +53,7 @@
|
|||
"@types/jest": "^24.0.6",
|
||||
"@types/node": "^11.9.4",
|
||||
"@types/react": "^16.4.18",
|
||||
"@types/react-dom": "^16.8.4",
|
||||
"@types/react-loadable": "^5.4.1",
|
||||
"@types/react-router": "^4.0.31",
|
||||
"@types/styled-components": "^4.1.10",
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import * as webpack from 'webpack'
|
||||
import * as path from "path"
|
||||
import * as HtmlWebpackPlugin from 'html-webpack-plugin'
|
||||
import * as express from 'express'
|
||||
import * as WebpackDevServer from "webpack-dev-server"
|
||||
import {httpSSRHandler} from "./SSR/handler"
|
||||
|
||||
const config: webpack.Configuration = {
|
||||
entry: './App/index.tsx',
|
||||
|
@ -10,6 +13,10 @@ const config: webpack.Configuration = {
|
|||
devServer: {
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
before: (app: express.Application, server: WebpackDevServer) => {
|
||||
//todo: improve the regex
|
||||
app.get(/^((?!\.\w+).)*$/, httpSSRHandler)
|
||||
},
|
||||
proxy: {
|
||||
'/graphql': {
|
||||
redirect: false,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
],
|
||||
"scripts": {
|
||||
"codegen": "gql2ts ./schema.graphql -o ./@types/graphql.d.ts",
|
||||
"ssr": "(cd client; yarn ssr)",
|
||||
"server": "(cd server; yarn start)",
|
||||
"client": "(cd client; yarn start)"
|
||||
},
|
||||
|
|
|
@ -54,7 +54,6 @@ type EventOccurrence {
|
|||
event: CalendarEvent!
|
||||
start: String!
|
||||
end: String!
|
||||
timeZone: String!
|
||||
}
|
||||
|
||||
type Location {
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
{
|
||||
"type": "postgres",
|
||||
"host": "localhost",
|
||||
"database": "qpa",
|
||||
"username": "qpa",
|
||||
"password": "qpa",
|
||||
"database": "qpa-dev",
|
||||
"entities": ["src/**/*.entity.ts"],
|
||||
"migrations": ["migrations/*.ts"],
|
||||
"cli": {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"apollo-server": "^2.4.8",
|
||||
"apollo-server-testing": "^2.4.8",
|
||||
"atob": "^2.1.2",
|
||||
"client": "0.0.1",
|
||||
"axios": "^0.18.0",
|
||||
"cookie": "^0.3.1",
|
||||
"cors": "^2.8.4",
|
||||
|
@ -32,6 +33,7 @@
|
|||
"pg": "^7.8.2",
|
||||
"random-string": "^0.2.0",
|
||||
"randomstring": "^1.1.5",
|
||||
"react-dom": "^16.8.6",
|
||||
"rrule": "^2.6.0",
|
||||
"superagent": "^3.8.3",
|
||||
"typeorm": "^0.2.14",
|
||||
|
@ -61,7 +63,9 @@
|
|||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
"testMatch": ["**/*.spec.ts"],
|
||||
"testMatch": [
|
||||
"**/*.spec.ts"
|
||||
],
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
|
|
|
@ -159,7 +159,4 @@ export class EventOccurrence extends BaseEntity {
|
|||
@Column()
|
||||
end: string
|
||||
|
||||
@Column({nullable: true})
|
||||
timeZone: string
|
||||
|
||||
}
|
||||
|
|
174
yarn.lock
174
yarn.lock
|
@ -971,6 +971,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.1.tgz#8529b7412a6eb4b48bdf6e720cc1b8e6e1e17628"
|
||||
integrity sha512-8M3VN0hetwhsJ8dH8VkVy7xo5/1VoBsDOk/T4SJOeXwTO1c4uIqVNx2qyecLFnnUWD5vvUqHQ1gASSeUN6zcTg==
|
||||
|
||||
"@emotion/utils@0.11.2":
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.2.tgz#713056bfdffb396b0a14f1c8f18e7b4d0d200183"
|
||||
integrity sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA==
|
||||
|
||||
"@emotion/weak-memoize@0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.2.tgz#63985d3d8b02530e0869962f4da09142ee8e200e"
|
||||
|
@ -1497,30 +1502,25 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/node@*", "@types/node@^11.11.0":
|
||||
"@types/mustache@^0.8.32":
|
||||
version "0.8.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/mustache/-/mustache-0.8.32.tgz#7db3b81f2bf450bd38805f596d20eca97c4ed595"
|
||||
integrity sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==
|
||||
|
||||
"@types/node@*", "@types/node@>=6", "@types/node@^11.11.0", "@types/node@^11.9.4":
|
||||
version "11.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.0.tgz#070e9ce7c90e727aca0e0c14e470f9a93ffe9390"
|
||||
integrity sha512-D5Rt+HXgEywr3RQJcGlZUCTCx1qVbCZpVk3/tOOA6spLNZdGm8BU+zRgdRYDoF1pO3RuXLxADzMrF903JlQXqg==
|
||||
|
||||
"@types/node@>=6":
|
||||
version "12.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.4.tgz#46832183115c904410c275e34cf9403992999c32"
|
||||
integrity sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw==
|
||||
|
||||
"@types/node@^10.1.0":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
|
||||
"@types/node@^11.9.4":
|
||||
version "11.13.13"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.13.tgz#a3d2a8a908ce322f24f0f8c88160b44c7dd5c452"
|
||||
integrity sha512-GFWH7e4Q/OGLAO545bupVju+nE1YtLSwYAdLfSzAXnTPqoqKoXCOEtB7Cluvg9B/h2nGLhyzCDyCInYvrOE2nw==
|
||||
version "10.14.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f"
|
||||
integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg==
|
||||
|
||||
"@types/node@^8.0.7":
|
||||
version "8.10.49"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.49.tgz#f331afc5efed0796798e5591d6e0ece636969b7b"
|
||||
integrity sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==
|
||||
version "8.10.50"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.50.tgz#f3d68482b1f54b5f4fba8daaac385db12bb6a706"
|
||||
integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA==
|
||||
|
||||
"@types/prettier@1.15.2":
|
||||
version "1.15.2"
|
||||
|
@ -1537,6 +1537,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||
|
||||
"@types/react-dom@^16.8.4":
|
||||
version "16.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.4.tgz#7fb7ba368857c7aa0f4e4511c4710ca2c5a12a88"
|
||||
integrity sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-loadable@^5.4.1":
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-loadable/-/react-loadable-5.5.1.tgz#f04a262f16e9f088098ddad1aa50682ad0984aa7"
|
||||
|
@ -2120,6 +2127,11 @@ apollo-link-http@^1.5.14:
|
|||
apollo-link-http-common "^0.2.13"
|
||||
tslib "^1.9.3"
|
||||
|
||||
apollo-link-logger@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-logger/-/apollo-link-logger-1.2.3.tgz#1f3e6f7849ce7a7e3aa822141fe062cfa278b1e1"
|
||||
integrity sha512-GaVwdHyXmawfvBlHfZkFkBHH3+YH7wibzSCc4/YpIbPVtbtZqi0Qop18w++jgpw385W083DMOdYe2eJsKkZdag==
|
||||
|
||||
apollo-link@^1.0.0, apollo-link@^1.2.11:
|
||||
version "1.2.11"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.11.tgz#493293b747ad3237114ccd22e9f559e5e24a194d"
|
||||
|
@ -2130,6 +2142,16 @@ apollo-link@^1.0.0, apollo-link@^1.2.11:
|
|||
tslib "^1.9.3"
|
||||
zen-observable-ts "^0.8.18"
|
||||
|
||||
apollo-link@^1.2.12:
|
||||
version "1.2.12"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.12.tgz#014b514fba95f1945c38ad4c216f31bcfee68429"
|
||||
integrity sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==
|
||||
dependencies:
|
||||
apollo-utilities "^1.3.0"
|
||||
ts-invariant "^0.4.0"
|
||||
tslib "^1.9.3"
|
||||
zen-observable-ts "^0.8.19"
|
||||
|
||||
apollo-link@^1.2.3:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.9.tgz#40a8f0b90716ce3fd6beb27b7eae1108b92e0054"
|
||||
|
@ -3024,6 +3046,11 @@ buffer-from@1.x, buffer-from@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
|
||||
buffer-from@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-0.1.2.tgz#15f4b9bcef012044df31142c14333caf6e0260d0"
|
||||
integrity sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==
|
||||
|
||||
buffer-indexof@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
|
||||
|
@ -3303,7 +3330,7 @@ chokidar@2.0.4:
|
|||
optionalDependencies:
|
||||
fsevents "^1.2.2"
|
||||
|
||||
chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.6:
|
||||
chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.5, chokidar@^2.1.6:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5"
|
||||
integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==
|
||||
|
@ -3785,6 +3812,16 @@ create-ecdh@^4.0.0:
|
|||
bn.js "^4.1.0"
|
||||
elliptic "^6.0.0"
|
||||
|
||||
create-emotion-server@10.0.14:
|
||||
version "10.0.14"
|
||||
resolved "https://registry.yarnpkg.com/create-emotion-server/-/create-emotion-server-10.0.14.tgz#51378f2f5a38d55b6da403a7f975d51b7cf221b5"
|
||||
integrity sha512-wYPojM+irHtmIZuRmYeKYaJSttC3/3Cj4DI8B1JmYq8P9IQ5FZCyfahdHhI3OSrNHIkWAX1Kjt4kbbqxVbUjPw==
|
||||
dependencies:
|
||||
"@emotion/utils" "0.11.2"
|
||||
html-tokenize "^2.0.0"
|
||||
multipipe "^1.0.2"
|
||||
through "^2.3.8"
|
||||
|
||||
create-emotion@^10.0.9:
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-10.0.9.tgz#290c2036126171c9566fa24f49c9241d54625138"
|
||||
|
@ -4357,6 +4394,13 @@ dotenv@^5.0.1:
|
|||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
|
||||
integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==
|
||||
|
||||
duplexer2@^0.1.2:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
|
||||
integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=
|
||||
dependencies:
|
||||
readable-stream "^2.0.2"
|
||||
|
||||
duplexer3@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||
|
@ -4420,6 +4464,13 @@ emojis-list@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
|
||||
|
||||
emotion-server@^10.0.14:
|
||||
version "10.0.14"
|
||||
resolved "https://registry.yarnpkg.com/emotion-server/-/emotion-server-10.0.14.tgz#dd4146f1e827c7dcb1861bbd92e420d50167e83f"
|
||||
integrity sha512-lxRyEISpiF8G7Q3Dt8xnK+flWfWeimo2PDRO8Me3zosUDJe8J2AzYe7pe80pFs3GMeOES98oV7/Ah5tiCTAGjw==
|
||||
dependencies:
|
||||
create-emotion-server "10.0.14"
|
||||
|
||||
emotion@^10.0.9:
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.9.tgz#2c37598af13df31dcd35a1957eaa8830f368c066"
|
||||
|
@ -5868,6 +5919,17 @@ html-minifier@^3.2.3:
|
|||
relateurl "0.2.x"
|
||||
uglify-js "3.4.x"
|
||||
|
||||
html-tokenize@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tokenize/-/html-tokenize-2.0.0.tgz#8b3a9a5deb475cae6a6f9671600d2c20ab298251"
|
||||
integrity sha1-izqaXetHXK5qb5ZxYA0sIKspglE=
|
||||
dependencies:
|
||||
buffer-from "~0.1.1"
|
||||
inherits "~2.0.1"
|
||||
minimist "~0.0.8"
|
||||
readable-stream "~1.0.27-1"
|
||||
through2 "~0.4.1"
|
||||
|
||||
html-webpack-plugin@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b"
|
||||
|
@ -8327,7 +8389,7 @@ minimist@^1.1.1, minimist@^1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
|
||||
minimist@~0.0.1:
|
||||
minimist@~0.0.1, minimist@~0.0.8:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
|
||||
integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
|
||||
|
@ -8425,6 +8487,19 @@ multicast-dns@^6.0.1:
|
|||
dns-packet "^1.3.1"
|
||||
thunky "^1.0.2"
|
||||
|
||||
multipipe@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-1.0.2.tgz#cc13efd833c9cda99f224f868461b8e1a3fd939d"
|
||||
integrity sha1-zBPv2DPJzamfIk+GhGG44aP9k50=
|
||||
dependencies:
|
||||
duplexer2 "^0.1.2"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
mustache@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.0.1.tgz#873855f23aa8a95b150fb96d9836edbc5a1d248a"
|
||||
integrity sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==
|
||||
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
@ -8525,6 +8600,11 @@ node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0:
|
|||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
|
||||
integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==
|
||||
|
||||
node-fetch@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
||||
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
|
||||
|
||||
node-forge@0.7.5:
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
|
||||
|
@ -8640,6 +8720,22 @@ nodemon@^1.18.10:
|
|||
undefsafe "^2.0.2"
|
||||
update-notifier "^2.5.0"
|
||||
|
||||
nodemon@^1.19.1:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.19.1.tgz#576f0aad0f863aabf8c48517f6192ff987cd5071"
|
||||
integrity sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==
|
||||
dependencies:
|
||||
chokidar "^2.1.5"
|
||||
debug "^3.1.0"
|
||||
ignore-by-default "^1.0.1"
|
||||
minimatch "^3.0.4"
|
||||
pstree.remy "^1.1.6"
|
||||
semver "^5.5.0"
|
||||
supports-color "^5.2.0"
|
||||
touch "^3.1.0"
|
||||
undefsafe "^2.0.2"
|
||||
update-notifier "^2.5.0"
|
||||
|
||||
nopt@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
|
||||
|
@ -8753,6 +8849,11 @@ object-keys@^1.0.12:
|
|||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032"
|
||||
integrity sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==
|
||||
|
||||
object-keys@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
|
||||
integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=
|
||||
|
||||
object-path@^0.11.4:
|
||||
version "0.11.4"
|
||||
resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949"
|
||||
|
@ -9942,6 +10043,16 @@ readable-stream@^3.0.6:
|
|||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@~1.0.17, readable-stream@~1.0.27-1:
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
|
||||
integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readdirp@^2.0.0, readdirp@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
|
||||
|
@ -11249,7 +11360,15 @@ through2@^2.0.0:
|
|||
readable-stream "~2.3.6"
|
||||
xtend "~4.0.1"
|
||||
|
||||
through@2, through@^2.3.6:
|
||||
through2@~0.4.1:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b"
|
||||
integrity sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=
|
||||
dependencies:
|
||||
readable-stream "~1.0.17"
|
||||
xtend "~2.1.1"
|
||||
|
||||
through@2, through@^2.3.6, 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=
|
||||
|
@ -12313,6 +12432,13 @@ xtend@^4.0.0, xtend@~4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
|
||||
|
||||
xtend@~2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b"
|
||||
integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os=
|
||||
dependencies:
|
||||
object-keys "~0.4.0"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
|
@ -12461,6 +12587,14 @@ zen-observable-ts@^0.8.18:
|
|||
tslib "^1.9.3"
|
||||
zen-observable "^0.8.0"
|
||||
|
||||
zen-observable-ts@^0.8.19:
|
||||
version "0.8.19"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz#c094cd20e83ddb02a11144a6e2a89706946b5694"
|
||||
integrity sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==
|
||||
dependencies:
|
||||
tslib "^1.9.3"
|
||||
zen-observable "^0.8.0"
|
||||
|
||||
zen-observable@^0.8.0:
|
||||
version "0.8.13"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.13.tgz#a9f1b9dbdfd2d60a08761ceac6a861427d44ae2e"
|
||||
|
|
Loading…
Reference in a new issue