diff --git a/components/Error.tsx b/components/_shared/Error.tsx similarity index 100% rename from components/Error.tsx rename to components/_shared/Error.tsx diff --git a/components/_shared/Table.tsx b/components/_shared/Table.tsx new file mode 100644 index 00000000..cc0ca0e4 --- /dev/null +++ b/components/_shared/Table.tsx @@ -0,0 +1,38 @@ +import React from 'react'; + +interface TableProps { + columns: Array; + data: Array; + className?: string; +} + +const Table: React.FC = ({ columns, data, className }) => { + return ( + + + + {columns.map(({ key, name }) => ( + + ))} + + + + {data.map((item) => ( + + {columns.map(({ key, render }) => ( + + ))} + + ))} + +
+ {name} +
+ {(render && typeof render === 'function' && render(item)) || + item[key] || + ''} +
+ ); +}; + +export default Table; diff --git a/components/_shared/index.ts b/components/_shared/index.ts new file mode 100644 index 00000000..9d5cf16c --- /dev/null +++ b/components/_shared/index.ts @@ -0,0 +1,4 @@ +import Table from './Table'; +import ErrorMessage from './Error'; + +export { Table, ErrorMessage }; diff --git a/components/dataset/About.tsx b/components/dataset/About.tsx index 188aba21..52ebb01e 100644 --- a/components/dataset/About.tsx +++ b/components/dataset/About.tsx @@ -1,23 +1,38 @@ -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; +import { Table, ErrorMessage } from '../_shared'; +import { GET_DATAPACKAGE_QUERY } from '../../graphql/queries'; -export const GET_DATAPACKAGE_QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - name - title - size - metadata_created - metadata_modified - resources { - name - } - } - } - } -`; +const columns = [ + { + name: 'Files', + key: 'files', + render: ({ resources }) => (resources && resources.length) || 0, + }, + { + name: 'Size', + key: 'size', + }, + { + name: 'Format', + key: 'format', + }, + { + name: 'Created', + key: 'metadata_created', + }, + { + name: 'Updated', + key: 'metadata_modified', + }, + { + name: 'License', + key: 'license', + }, + { + name: 'Source', + key: 'source', + }, +]; export default function About({ variables }) { const { loading, error, data } = useQuery(GET_DATAPACKAGE_QUERY, { @@ -32,32 +47,5 @@ export default function About({ variables }) { if (loading) return
Loading
; const { result } = data.dataset; - return ( - <> - - - - - - - - - - - - - - - - - - - - - - - -
FilesSizeFormatCreatedUpdatedLicenseSource
{result.resources.length}{result.size || 'NA'}{result.metadata_created}{result.metadata_modified}
- - ); + return ; } diff --git a/components/dataset/Org.tsx b/components/dataset/Org.tsx index 2cd90b64..69314426 100644 --- a/components/dataset/Org.tsx +++ b/components/dataset/Org.tsx @@ -1,21 +1,7 @@ import Link from 'next/link'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -export const GET_ORG_QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - organization { - name - title - image_url - } - } - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_ORG_QUERY } from '../../graphql/queries'; export default function Org({ variables }) { const { loading, error, data } = useQuery(GET_ORG_QUERY, { diff --git a/components/dataset/Resources.tsx b/components/dataset/Resources.tsx index 2ed6425f..f42c70ef 100644 --- a/components/dataset/Resources.tsx +++ b/components/dataset/Resources.tsx @@ -1,27 +1,43 @@ import Link from 'next/link'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; +import { Table, ErrorMessage } from '../_shared'; +import { GET_RESOURCES_QUERY } from '../../graphql/queries'; -export const GET_DATAPACKAGE_QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - name - resources { - name - title - format - created - last_modified - } - } - } - } -`; +const columns = [ + { + name: 'File', + key: 'file', + render: ({ name: resName, title, parentName }) => ( + + {title || resName} + + ), + }, + { + name: 'Format', + key: 'format', + }, + { + name: 'Created', + key: 'created', + }, + { + name: 'Updated', + key: 'last_modified', + }, + { + name: 'Link', + key: 'link', + render: ({ name: resName, parentName }) => ( + + Preview + + ), + }, +]; export default function Resources({ variables }) { - const { loading, error, data } = useQuery(GET_DATAPACKAGE_QUERY, { + const { loading, error, data } = useQuery(GET_RESOURCES_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching @@ -37,36 +53,13 @@ export default function Resources({ variables }) { return ( <>

Data Files

-
- - - - - - - - - - - {result.resources.map((resource, index) => ( - - - - - - - - ))} - -
FileFormatCreatedUpdatedLink
- - {resource.title || resource.name} - - {resource.format}{resource.created}{resource.last_modified} - - Preview - -
+ ({ + ...resource, + parentName: result.name, + }))} + /> ); } diff --git a/components/home/Recent.tsx b/components/home/Recent.tsx index c784aff8..c67f7281 100644 --- a/components/home/Recent.tsx +++ b/components/home/Recent.tsx @@ -1,29 +1,10 @@ import Link from 'next/link'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -export const QUERY = gql` - query search($q: String, $sort: String, $rows: Int) { - search(q: $q, sort: $sort, rows: $rows) - @rest(type: "Search", path: "package_search?{args}") { - result { - results { - name - title - organization { - name - title - description - } - } - } - } - } -`; +import { ErrorMessage } from '../_shared'; +import { SEARCH_QUERY } from '../../graphql/queries'; function Recent() { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(SEARCH_QUERY, { variables: { sort: 'metadata_created desc', rows: 3, diff --git a/components/resource/About.tsx b/components/resource/About.tsx index 04a2827e..1b4f6b7d 100644 --- a/components/resource/About.tsx +++ b/components/resource/About.tsx @@ -1,30 +1,53 @@ -import Link from 'next/link'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; +import { Table, ErrorMessage } from '../_shared'; +import { GET_RESOURCES_QUERY } from '../../graphql/queries'; -const QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - resources { - name - id - title - description - format - size - created - last_modified - url - } - } - } - } -`; +const columns = [ + { + name: 'Name', + key: 'name', + render: ({ name, id }) => name || id, + }, + { + name: 'Title', + key: 'title', + }, + { + name: 'Description', + key: 'description', + }, + { + name: 'Format', + key: 'format', + }, + { + name: 'Size', + key: 'size', + }, + { + name: 'Created', + key: 'created', + }, + { + name: 'Updated', + key: 'last_modified', + }, + { + name: 'Download', + key: 'download', + render: ({ url, format }) => ( + + {format} + + ), + }, +]; export default function About({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_RESOURCES_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching @@ -39,41 +62,5 @@ export default function About({ variables }) { const resource = result.resources.find( (item) => item.name === variables.resource ); - return ( - <> -
- - - - - - - - - - - - - - - - - - - - - - - - -
NameTitleDescriptionFormatSizeCreatedUpdatedDownload
{resource.name || resource.id}{resource.title || ''}{resource.description || ''}{resource.format}{resource.size}{resource.created}{resource.last_modified || ''} - - {resource.format} - -
- - ); + return ; } diff --git a/components/resource/DataExplorer.tsx b/components/resource/DataExplorer.tsx index c35e117e..7062a933 100644 --- a/components/resource/DataExplorer.tsx +++ b/components/resource/DataExplorer.tsx @@ -1,30 +1,9 @@ -import Link from 'next/link'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - resources { - name - id - title - description - format - size - created - last_modified - url - } - } - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_RESOURCES_QUERY } from '../../graphql/queries'; export default function DataExplorer({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_RESOURCES_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching diff --git a/components/search/List.tsx b/components/search/List.tsx index 294e7791..b13e1f85 100644 --- a/components/search/List.tsx +++ b/components/search/List.tsx @@ -1,28 +1,10 @@ -import Item from './Item'; -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query search($q: String, $sort: String) { - search(q: $q, sort: $sort) - @rest(type: "Search", path: "package_search?{args}") { - result { - results { - name - title - organization { - name - title - } - } - } - } - } -`; +import Item from './Item'; +import { ErrorMessage } from '../_shared'; +import { SEARCH_QUERY } from '../../graphql/queries'; export default function List({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(SEARCH_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching diff --git a/components/search/Total.tsx b/components/search/Total.tsx index dfd88609..0e688021 100644 --- a/components/search/Total.tsx +++ b/components/search/Total.tsx @@ -1,20 +1,9 @@ -import ErrorMessage from '../Error'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query search($q: String, $sort: String) { - search(q: $q, sort: $sort) - @rest(type: "Search", path: "package_search?{args}") { - result { - count - } - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_TOTAL_COUNT_QUERY } from '../../graphql/queries'; export default function Total({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_TOTAL_COUNT_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching diff --git a/components/static/List.tsx b/components/static/List.tsx index 32fa3787..db73b895 100644 --- a/components/static/List.tsx +++ b/components/static/List.tsx @@ -1,19 +1,10 @@ -import ErrorMessage from '../Error'; import parse from 'html-react-parser'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query posts { - posts @rest(type: "Posts", path: "", endpoint: "wordpress-posts") { - found - posts - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_POSTS_QUERY } from '../../graphql/queries'; export default function List() { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_POSTS_QUERY, { // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching // more data diff --git a/components/static/Page.tsx b/components/static/Page.tsx index 75635550..81c4122f 100644 --- a/components/static/Page.tsx +++ b/components/static/Page.tsx @@ -1,22 +1,10 @@ -import ErrorMessage from '../Error'; import parse from 'html-react-parser'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query page($slug: String) { - page(slug: $slug) - @rest(type: "Page", path: "{args.slug}", endpoint: "wordpress") { - title - content - modified - featured_image - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_PAGE_QUERY } from '../../graphql/queries'; export default function Page({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_PAGE_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching diff --git a/components/static/Post.tsx b/components/static/Post.tsx index ea1e934d..a698e1b1 100644 --- a/components/static/Post.tsx +++ b/components/static/Post.tsx @@ -1,22 +1,10 @@ -import ErrorMessage from '../Error'; import parse from 'html-react-parser'; import { useQuery } from '@apollo/react-hooks'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query page($slug: String) { - page(slug: $slug) - @rest(type: "Page", path: "{args.slug}", endpoint: "wordpress") { - title - content - modified - featured_image - } - } -`; +import { ErrorMessage } from '../_shared'; +import { GET_PAGE_QUERY } from '../../graphql/queries'; export default function Post({ variables }) { - const { loading, error, data } = useQuery(QUERY, { + const { loading, error, data } = useQuery(GET_PAGE_QUERY, { variables, // Setting this value to true will make the component rerender when // the "networkStatus" changes, so we are able to know if it is fetching diff --git a/graphql/queries.ts b/graphql/queries.ts new file mode 100644 index 00000000..34948561 --- /dev/null +++ b/graphql/queries.ts @@ -0,0 +1,149 @@ +import gql from 'graphql-tag'; + +export const GET_ORG_QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result { + organization { + name + title + image_url + } + } + } + } +`; + +export const GET_DATAPACKAGE_QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result { + name + title + size + metadata_created + metadata_modified + resources { + name + } + } + } + } +`; + +export const GET_RESOURCES_QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result { + name + resources { + name + id + title + description + format + size + created + last_modified + url + } + } + } + } +`; + +export const SEARCH_QUERY = gql` + query search($q: String, $sort: String, $rows: Int) { + search(q: $q, sort: $sort, rows: $rows) + @rest(type: "Search", path: "package_search?{args}") { + result { + count + results { + name + title + organization { + name + title + description + } + } + } + } + } +`; + +export const GET_TOTAL_COUNT_QUERY = gql` + query search($q: String, $sort: String) { + search(q: $q, sort: $sort) + @rest(type: "Search", path: "package_search?{args}") { + result { + count + } + } + } +`; + +export const GET_POSTS_QUERY = gql` + query posts { + posts @rest(type: "Posts", path: "", endpoint: "wordpress-posts") { + found + posts + meta + } + } +`; + +export const GET_PAGE_QUERY = gql` + query page($slug: String) { + page(slug: $slug) + @rest(type: "Page", path: "{args.slug}", endpoint: "wordpress") { + title + content + excerpt + slug + date + modified + featured_image + } + } +`; + +export const GET_DATASET_QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result { + name + title + size + metadata_created + metadata_modified + resources { + name + title + format + created + last_modified + } + organization { + name + title + image_url + } + } + } + } +`; + +export const GET_POST_QUERY = gql` + query post($slug: String) { + post(slug: $slug) + @rest(type: "Post", path: "{args.slug}", endpoint: "wordpress") { + title + content + excerpt + slug + date + modified + } + } +`; diff --git a/pages/[org]/[dataset]/index.tsx b/pages/[org]/[dataset]/index.tsx index 5122fca8..ee59d2bd 100644 --- a/pages/[org]/[dataset]/index.tsx +++ b/pages/[org]/[dataset]/index.tsx @@ -1,42 +1,15 @@ import { GetServerSideProps } from 'next'; import { useQuery } from '@apollo/react-hooks'; -import { initializeApollo } from '../../../lib/apolloClient'; -import utils from '../../../utils'; import Head from 'next/head'; +import { initializeApollo } from '../../../lib/apolloClient'; import Nav from '../../../components/home/Nav'; import About from '../../../components/dataset/About'; import Org from '../../../components/dataset/Org'; import Resources from '../../../components/dataset/Resources'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - name - title - size - metadata_created - metadata_modified - resources { - name - title - format - created - last_modified - } - organization { - name - title - image_url - } - } - } - } -`; +import { GET_DATASET_QUERY } from '../../../graphql/queries'; function Dataset({ variables }) { - const { data, loading } = useQuery(QUERY, { variables }); + const { data, loading } = useQuery(GET_DATASET_QUERY, { variables }); if (loading) return
Loading
; const { result } = data.dataset; @@ -67,7 +40,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { }; await apolloClient.query({ - query: QUERY, + query: GET_DATASET_QUERY, variables, }); diff --git a/pages/[org]/[dataset]/r/[resource]/index.tsx b/pages/[org]/[dataset]/r/[resource]/index.tsx index 8fe092db..1ab7ec8c 100644 --- a/pages/[org]/[dataset]/r/[resource]/index.tsx +++ b/pages/[org]/[dataset]/r/[resource]/index.tsx @@ -1,35 +1,14 @@ import { GetServerSideProps } from 'next'; -import gql from 'graphql-tag'; import { useQuery } from '@apollo/react-hooks'; -import { initializeApollo } from '../../../../../lib/apolloClient'; -import utils from '../../../../../utils'; import Head from 'next/head'; +import { initializeApollo } from '../../../../../lib/apolloClient'; import Nav from '../../../../../components/home/Nav'; import About from '../../../../../components/resource/About'; import DataExplorer from '../../../../../components/resource/DataExplorer'; - -const QUERY = gql` - query dataset($id: String) { - dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { - result { - resources { - name - id - title - description - format - size - created - last_modified - url - } - } - } - } -`; +import { GET_RESOURCES_QUERY } from '../../../../../graphql/queries'; function Resource({ variables }) { - const { data, loading } = useQuery(QUERY, { variables }); + const { data, loading } = useQuery(GET_RESOURCES_QUERY, { variables }); if (loading) return
Loading
; const result = data.dataset.result; @@ -63,7 +42,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { }; await apolloClient.query({ - query: QUERY, + query: GET_RESOURCES_QUERY, variables, }); diff --git a/pages/blog/[post]/index.tsx b/pages/blog/[post]/index.tsx index a71cd5c2..d9c55b20 100644 --- a/pages/blog/[post]/index.tsx +++ b/pages/blog/[post]/index.tsx @@ -1,23 +1,9 @@ import { GetServerSideProps } from 'next'; -import { initializeApollo } from '../../../lib/apolloClient'; import Head from 'next/head'; +import { initializeApollo } from '../../../lib/apolloClient'; import Nav from '../../../components/home/Nav'; import Post from '../../../components/static/Post'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query post($slug: String) { - post(slug: $slug) - @rest(type: "Post", path: "{args.slug}", endpoint: "wordpress") { - title - content - excerpt - slug - date - modified - } - } -`; +import { GET_POST_QUERY } from '../../../graphql/queries'; function PostItem({ variables }) { return ( @@ -42,7 +28,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const apolloClient = initializeApollo(); await apolloClient.query({ - query: QUERY, + query: GET_POST_QUERY, variables, }); diff --git a/pages/blog/index.tsx b/pages/blog/index.tsx index cb63683e..38676345 100644 --- a/pages/blog/index.tsx +++ b/pages/blog/index.tsx @@ -1,19 +1,9 @@ import { GetServerSideProps } from 'next'; -import { initializeApollo } from '../../lib/apolloClient'; import Head from 'next/head'; +import { initializeApollo } from '../../lib/apolloClient'; import Nav from '../../components/home/Nav'; import List from '../../components/static/List'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query posts { - posts @rest(type: "Posts", path: "", endpoint: "wordpress-posts") { - found - posts - meta - } - } -`; +import { GET_POSTS_QUERY } from '../../graphql/queries'; function PostList() { return ( @@ -34,7 +24,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const apolloClient = initializeApollo(); await apolloClient.query({ - query: QUERY, + query: GET_POSTS_QUERY, }); return { diff --git a/pages/index.tsx b/pages/index.tsx index 86507a1d..b2db91ec 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,9 +1,10 @@ import { GetServerSideProps } from 'next'; -import { initializeApollo } from '../lib/apolloClient'; import Head from 'next/head'; +import { initializeApollo } from '../lib/apolloClient'; import Nav from '../components/home/Nav'; -import Recent, { QUERY } from '../components/home/Recent'; +import Recent from '../components/home/Recent'; import Form from '../components/search/Form'; +import { SEARCH_QUERY } from '../graphql/queries'; function Home() { return ( @@ -39,7 +40,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const apolloClient = initializeApollo(); await apolloClient.query({ - query: QUERY, + query: SEARCH_QUERY, variables: { sort: 'metadata_created desc', rows: 3, diff --git a/pages/p/[page]/index.tsx b/pages/p/[page]/index.tsx index ffaf17ba..ea613032 100644 --- a/pages/p/[page]/index.tsx +++ b/pages/p/[page]/index.tsx @@ -1,23 +1,9 @@ import { GetServerSideProps } from 'next'; -import { initializeApollo } from '../../../lib/apolloClient'; import Head from 'next/head'; +import { initializeApollo } from '../../../lib/apolloClient'; import Nav from '../../../components/home/Nav'; import Page from '../../../components/static/Page'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query page($slug: String) { - page(slug: $slug) - @rest(type: "Page", path: "{args.slug}", endpoint: "wordpress") { - title - content - excerpt - slug - date - modified - } - } -`; +import { GET_PAGE_QUERY } from '../../../graphql/queries'; function PageItem({ variables }) { return ( @@ -42,7 +28,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const apolloClient = initializeApollo(); await apolloClient.query({ - query: QUERY, + query: GET_PAGE_QUERY, variables, }); diff --git a/pages/search.tsx b/pages/search.tsx index 419f1b9c..9b66b2e4 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -6,26 +6,7 @@ import Nav from '../components/home/Nav'; import Form from '../components/search/Form'; import Total from '../components/search/Total'; import List from '../components/search/List'; -import gql from 'graphql-tag'; - -const QUERY = gql` - query search($q: String, $sort: String) { - search(q: $q, sort: $sort) - @rest(type: "Search", path: "package_search?{args}") { - result { - count - results { - name - title - organization { - name - title - } - } - } - } - } -`; +import { SEARCH_QUERY } from '../graphql/queries'; function Search({ variables }) { return ( @@ -51,7 +32,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const apolloClient = initializeApollo(); await apolloClient.query({ - query: QUERY, + query: SEARCH_QUERY, variables, });