From 633521da2faf7488199c39f3ceae12a1f4653905 Mon Sep 17 00:00:00 2001 From: sg3847 Date: Tue, 30 May 2023 09:28:37 -0400 Subject: [PATCH 01/12] Ongoing work for search UI --- backend/cic/settings/base.py | 5 +- backend/cic/views.py | 2 +- backend/search/urls.py | 2 + backend/search/views.py | 6 + backend/templates/grants/index.html | 40 ++ frontend/search/package.json | 3 +- frontend/search/src/app.tsx | 32 ++ frontend/search/src/components/GrantTable.tsx | 9 +- frontend/search/src/components/SearchBar.tsx | 56 +- frontend/search/src/grants_index.tsx | 481 ++++++++++++++++ frontend/search/src/home.tsx | 27 + frontend/search/src/index.tsx | 516 +----------------- frontend/search/src/layout.tsx | 34 ++ frontend/search/src/main.css | 4 +- 14 files changed, 701 insertions(+), 516 deletions(-) create mode 100644 backend/templates/grants/index.html create mode 100644 frontend/search/src/app.tsx create mode 100644 frontend/search/src/grants_index.tsx create mode 100644 frontend/search/src/home.tsx create mode 100644 frontend/search/src/layout.tsx diff --git a/backend/cic/settings/base.py b/backend/cic/settings/base.py index 894d554..d8af89f 100644 --- a/backend/cic/settings/base.py +++ b/backend/cic/settings/base.py @@ -73,7 +73,10 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(BASE_DIR), 'templates')], + 'DIRS': [ + os.path.join(os.path.dirname(BASE_DIR), 'templates'), + os.path.join(os.path.dirname(BASE_DIR), 'grants/templates') + ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ diff --git a/backend/cic/views.py b/backend/cic/views.py index 3154129..3fe7929 100644 --- a/backend/cic/views.py +++ b/backend/cic/views.py @@ -61,7 +61,7 @@ def index(request): """Home view callable, for the home page.""" - return render(request, 'index.html', {'keywords': request.GET.get('keywords', '')}) + return render(request, 'grants/index.html', {'keywords': request.GET.get('keywords', '')}) def detail(request, grant_id): diff --git a/backend/search/urls.py b/backend/search/urls.py index 3c38d6c..a2ac843 100644 --- a/backend/search/urls.py +++ b/backend/search/urls.py @@ -1,7 +1,9 @@ from django.urls import path from . import views +from search.views import index urlpatterns = [ + path('', index), path('grants', views.search_grants, name='search_grants'), path('facets', views.get_facet_by_field, name='search_grants'), path('publications', views.search_publications, name='search_publications'), diff --git a/backend/search/views.py b/backend/search/views.py index 96cef95..ba3538f 100644 --- a/backend/search/views.py +++ b/backend/search/views.py @@ -2,6 +2,12 @@ from django.conf import settings from opensearchpy.client import OpenSearch from dateutil import parser +from django.shortcuts import render + + +def index(request): + return render(request, 'index.html', {'keywords': request.GET.get('keywords', '')}) + def get_facet_by_field(request) : field_name = request.GET.get('field', None) diff --git a/backend/templates/grants/index.html b/backend/templates/grants/index.html new file mode 100644 index 0000000..706ebab --- /dev/null +++ b/backend/templates/grants/index.html @@ -0,0 +1,40 @@ +{% load static %} + + + +{% block content %} + + + + + + + + + + + + + + + + + + + + Covid Information Commons + + + {% include "cic_header.html" %} +
+
+ + + + {% include "cic_footer.html" %} + +{% endblock content %} + diff --git a/frontend/search/package.json b/frontend/search/package.json index df1de1e..c1d96f7 100644 --- a/frontend/search/package.json +++ b/frontend/search/package.json @@ -27,6 +27,7 @@ "mini-css-extract-plugin": "^2.6.0", "node-sass": "^7.0.1", "path": "^0.12.7", + "react-router-dom": "^6.11.2", "sass-loader": "^12.6.0", "style-loader": "^3.3.1", "ts-loader": "^9.2.7", @@ -44,13 +45,13 @@ "@mui/material": "^5.5.0", "@types/react-table": "^7.7.9", "axios": "^0.26.1", + "axios-retry": "^3.5.0", "material-table": "^1.69.3", "react": "^17.0.2", "react-data-table-component": "^7.4.7", "react-dom": "^17.0.2", "react-highlight-words": "^0.18.0", "react-number-format": "^4.9.3", - "react-router-dom": "^6.3.0", "styled-components": "^5.3.3", "typescript": "^4.6.2" } diff --git a/frontend/search/src/app.tsx b/frontend/search/src/app.tsx new file mode 100644 index 0000000..ecdf0a2 --- /dev/null +++ b/frontend/search/src/app.tsx @@ -0,0 +1,32 @@ +import { useNavigate } from "react-router-dom"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import Home from './home'; +import Grants from './grants_index'; + +export default function App() { + const navigate = useNavigate(); + + function handleChange(event:any) { + console.log('//////') + console.log(event) + const params = new URLSearchParams(window.location.search) + console.log(params.get('keyword')) + let url = '/search/grants?keyword='+params.get('keyword') + navigate(url) + } + + return ( +
+ + + } /> + } /> + +
+ ); +} \ No newline at end of file diff --git a/frontend/search/src/components/GrantTable.tsx b/frontend/search/src/components/GrantTable.tsx index e7dd94b..0ee73f0 100644 --- a/frontend/search/src/components/GrantTable.tsx +++ b/frontend/search/src/components/GrantTable.tsx @@ -1,5 +1,6 @@ import { Component } from "react"; import MaterialTable, { MTableToolbar } from "material-table"; +//import MaterialTable from '@material-table/core'; import { TablePagination } from "@material-ui/core"; import { css } from '@emotion/react' import { Link as MaterialLink} from '@mui/material'; @@ -82,9 +83,6 @@ class GrantsTable extends Component { data={ this.props.data } page={ this.props.pageIndex } totalCount={ this.props.totalCount } - onChangePage={ (page, pageSize) => { - this.props.pageChangeHandler(page, pageSize) - } } columns={[ { title: "Awards", @@ -139,7 +137,7 @@ class GrantsTable extends Component { paging: true, showTitle: false, search: false, - exportButton: false, + //exportButton: false, pageSize: 20, exportAllData: false } @@ -150,6 +148,9 @@ class GrantsTable extends Component { { + this.props.pageChangeHandler(page, pageSize) + } } /> ), } diff --git a/frontend/search/src/components/SearchBar.tsx b/frontend/search/src/components/SearchBar.tsx index bf49819..b60f99f 100644 --- a/frontend/search/src/components/SearchBar.tsx +++ b/frontend/search/src/components/SearchBar.tsx @@ -1,13 +1,59 @@ import React, { Component } from "react"; +import TextField from '@mui/material/TextField'; +//import { createContext } from "react"; -class SearchBar extends React.Component { +interface SearchState { + keyword: string, + search_in_progress: boolean, + totalCount: number +} + +class SearchBar extends React.Component { + + state:SearchState = { + keyword: (window as any)['keywords'], + search_in_progress: false, + totalCount: 0 + } + + enterHandler = (e:any) => { + if (e.key === 'Enter') { + e.preventDefault(); + //this.get_grants_data() + } + } + searchHandler = (event:any) => { + event.preventDefault() + const keyword = (document.getElementById('outlined-search') as HTMLInputElement).value; + this.setState({'keyword': keyword}) + //this.get_grants_data(keyword) + } render() { return ( - +
+ +
+ + +
+
+ { + this.state.search_in_progress == false ? +
+ Showing { this.state.totalCount } results. +
+ :
Waiting for results... +
+ } +
+
); } } diff --git a/frontend/search/src/grants_index.tsx b/frontend/search/src/grants_index.tsx new file mode 100644 index 0000000..93dac6c --- /dev/null +++ b/frontend/search/src/grants_index.tsx @@ -0,0 +1,481 @@ +import React, { Component, useContext } from "react"; +import { GrantsFilter, Facet } from './components/GrantsFilter'; +import axios from "axios"; +import Button from '@mui/material/Button'; +import DownloadIcon from '@mui/icons-material/Download'; +import axiosRetry from 'axios-retry'; +import GrantsTable from './components/GrantTable'; +import SearchBar from './components/SearchBar'; + +interface Filter { + nsf_division?: string + nih_division?: string + funder_division?: string + start_date?: Date + end_date?: Date + awardee_organization?: string + org_state?: string + pi_name?: string + po_name?: string + funder_name?: string +} + +interface Grant { + id: number + title: string + award_amount: number + abstract: string + award_id: string + pi: string + funder_name: string + awardee_org: string +} + +interface AppState { + data: Grant[] + url: string + totalCount: number + pageIndex: number + awardee_org_names: Facet[] + funder_divisions: Facet[] + pi_names: Facet[] + po_names: Facet[] + filter: Filter + keyword: string + funder_names: Facet[] + search_in_progress: boolean +} + +let url = '' +if (process.env.NODE_ENV == 'production') { + url = "https://cic-apps.datascience.columbia.edu"; +} else if (process.env.NODE_ENV == 'development') { + url = "https://cice-dev.paas.cc.columbia.edu"; +} else { + url = "http://127.0.0.1:8000" +} + +axiosRetry(axios, {retries: 3}); + +const styles = { + // See MUI Button CSS classes at https://mui.com/material-ui/api/button/ + "&.MuiButton-contained": { + color: "#FFFFFF", + backgroundColor: "#2C6BAC", + minWidth: "max-content", + whiteSpace: "nowrap", + textTransform: "none" + }, +}; + +class Grants extends Component { + + state:AppState = { + data: [], + url: url, + totalCount: 0, + pageIndex: 0, + awardee_org_names: [], + funder_divisions: [], + pi_names: [], + po_names: [], + //keyword: (window as any)['keywords'], + keyword: '', + filter: {}, + funder_names: [], + search_in_progress: false + } + + + constructor(props:any) { + super(props) + this.pageChangeHandler = this.pageChangeHandler.bind(this) + this.filterChangeHandler = this.filterChangeHandler.bind(this) + } + + componentDidMount = () => { + this.get_grants_data() + this.get_org_name_facet() + this.get_pi_name_facet() + this.get_po_name_facet() + this.get_funder_division_facet() + this.get_funder_facet() + } + + get_org_name_facet() { + var url = this.state.url.concat('/search/facets?field=awardee_organization.name') + axios.get(url).then(results => { + this.setState({ awardee_org_names: results.data.aggregations.patterns.buckets }) + }) + } + + get_funder_division_facet() { + var url = this.state.url.concat('/search/facets?field=funder_divisions') + axios.get(url).then(results => { + this.setState({ funder_divisions: results.data.aggregations.patterns.buckets }) + }) + } + + get_pi_name_facet(): Facet[] { + var url = this.state.url.concat('/search/facets?field=principal_investigator.full_name') + let pi_facet: Facet[] = []; + axios.get(url).then(results => { + this.setState({ pi_names: results.data.aggregations.patterns.buckets }) + pi_facet = results.data.aggregations.patterns.buckets + }) + return pi_facet; + } + + get_po_name_facet(): Facet[] { + var url = this.state.url.concat('/search/facets?field=program_officials.full_name') + let po_facet: Facet[] = []; + axios.get(url).then(results => { + this.setState({ po_names: results.data.aggregations.patterns.buckets }) + po_facet = results.data.aggregations.patterns.buckets + + }) + return po_facet; + } + + get_funder_facet(): Facet[] { + var url = this.state.url.concat('/search/facets?field=funder.name') + let funder_facet: Facet[] = []; + axios.get(url).then(results => { + this.setState({ funder_names: results.data.aggregations.patterns.buckets }) + funder_facet = results.data.aggregations.patterns.buckets + + }) + return funder_facet; + } + + + pageChangeHandler(page:number, pageSize: number) { + this.setState({ + pageIndex: page + }) + this.get_grants_data() + } + + filterChangeHandler(fieldName?:string, value?:any, reset?:boolean) { + if (reset) { + this.state.filter = {} + this.get_grants_data() + return + } + var currentFilter = this.state.filter + if (fieldName == 'nsf_division') { + if (!value || value.length === 0) { + delete currentFilter.nsf_division; + } else { + currentFilter['nsf_division'] = value + } + } + if (fieldName == 'nih_division') { + if (!value || value.length === 0) { + delete currentFilter.nih_division; + } else { + currentFilter['nih_division'] = value + } + } + if (fieldName == 'funder_division') { + if (!value || value.length === 0) { + delete currentFilter.funder_division; + } else { + currentFilter['funder_division'] = value + } + } + if (fieldName == 'awardee_organization') { + if (!value || value.length === 0) { + delete currentFilter.awardee_organization; + } else { + currentFilter['awardee_organization'] = value + } + } + if (fieldName == 'startDate') { + if (value) { + currentFilter['start_date'] = this.removeTime(value) + } else { + delete currentFilter.start_date; + } + } + if (fieldName == 'endDate') { + if (value) { + currentFilter['end_date'] = this.removeTime(value) + } else { + delete currentFilter.end_date; + } + } + if (fieldName == 'org_state') { + if (!value || value.length === 0) { + delete currentFilter.org_state; + } else { + currentFilter['org_state'] = value + } + } + if (fieldName == 'pi_name') { + if (!value || value.length === 0) { + delete currentFilter.pi_name; + } else { + currentFilter['pi_name'] = value + } + } + if (fieldName == 'po_name') { + if (!value || value.length === 0) { + delete currentFilter.po_name; + } else { + currentFilter['po_name'] = value + } + } + if (fieldName == 'funder_name') { + if (!value || value.length === 0) { + delete currentFilter.funder_name; + } else { + currentFilter['funder_name'] = value + } + } + console.log(currentFilter) + this.setState({filter: currentFilter}) + this.get_grants_data() + } + + get_grants_data = (kw?:string) => { + console.log('***** '); + kw = 'covid' + this.setState({ + search_in_progress: true + }) + var url = this.state.url.concat('/search/grants') + var params: { [key: string]: any } = {}; + + let from:number = 0 + + if (this.state.pageIndex > 0) { + from = (this.state.pageIndex * 20) + 1 + } + params.from = from + if (!kw) { + kw = (document.getElementById('outlined-search') as HTMLInputElement).value; + } + if (kw && kw.length > 0) { + params.keyword = kw + } + + let property: keyof typeof this.state.filter + for (property in this.state.filter) { + if (this.state.filter[property]) { + params[property] = this.state.filter[property] + } + } + + axios.get(url, {params: params}).then(results => { + this.setState({ + search_in_progress: false + }) + this.setState({ totalCount: results.data.hits.total.value }) + + var newArray = results.data.hits.hits.map(function(val:any) { + let pi_name = '' + let pi_id = '' + let funder_name = '' + let pi_private_emails = '' + if (val['_source']['principal_investigator'] != null) { + pi_name = val['_source']['principal_investigator']['full_name'] + pi_id = val['_source']['principal_investigator']['id'] + pi_private_emails = val['_source']['principal_investigator']['private_emails'] + } + return { + id: val['_source']['id'], + title: val['_source']['title'], + award_id: val['_source']['award_id'], + pi: pi_name, + pi_id: pi_id, + pi_private_emails: pi_private_emails, + abstract: val['_source']['abstract'], + award_amount: (val['_source']['award_amount'] !== null) ? val['_source']['award_amount'] : 0, + funder_name: ('name' in val['_source']['funder']) ? val['_source']['funder']['name'] : '', + awardee_org: val['_source']['awardee_organization']['name'] + } + }) + this.setState({ data: newArray }) + }) + } + + getDataPromise() { + var params: { [key: string]: any } = {}; + params.from = 0 + params.size = 1000 + let keyword = (document.getElementById('outlined-search') as HTMLInputElement).value; + if (keyword && keyword.length > 0) { + params.keyword = keyword + } + let property: keyof typeof this.state.filter + for (property in this.state.filter) { + if (this.state.filter[property]) { + params[property] = this.state.filter[property] + } + } + return axios({ + url: url + '/search/grants', + method: 'get', + headers: { + 'Content-Type': 'application/json', + }, + params: params + }) + .then(res => { + var newArray = res.data.hits.hits.map(function(val:any) { + let pi_name = '' + let pi_id = '' + let funder_name = '' + let pi_private_emails = '' + if (val['_source']['principal_investigator'] != null) { + pi_name = val['_source']['principal_investigator']['full_name'] + pi_id = val['_source']['principal_investigator']['id'] + pi_private_emails = val['_source']['principal_investigator']['private_emails'] + } + return { + id: val['_source']['id'], + title: val['_source']['title'], + award_id: val['_source']['award_id'], + pi: pi_name, + pi_id: pi_id, + pi_private_emails: pi_private_emails, + abstract: val['_source']['abstract'], + award_amount: (val['_source']['award_amount'] !== null) ? val['_source']['award_amount'] : 0, + funder_name: ('name' in val['_source']['funder']) ? val['_source']['funder']['name'] : '', + awardee_org: val['_source']['awardee_organization']['name'] + } + }) + return newArray + }) + + .catch (err => { + console.error(err) + }) + } + + exportToCsv = (event:any) => { + event.preventDefault() + // Headers for each column + let headers = ['Funder, Award ID, Award Amount, Title, PI Name, Awardee Organization, Abstract, CIC ID'] + // Convert grants data to csv + this.getDataPromise().then(res => { + let grantsCsv = res.reduce((acc:any, grant:any) => { + let grant_to_add:Grant = grant + let abstract = grant_to_add.abstract + if (abstract) { + abstract = grant_to_add.abstract.replaceAll('"', "'") + } + let awardee_org = grant_to_add.awardee_org + if (awardee_org) { + if (awardee_org.indexOf(',') > -1) { + awardee_org = grant_to_add.awardee_org.replaceAll(',', '') + } + } + let pi_name = grant_to_add.pi + if (pi_name) { + if (pi_name.indexOf(',') > -1) { + pi_name = grant_to_add.pi.replaceAll(',', '') + } + } + acc.push([ + grant_to_add.funder_name, + grant_to_add.award_id, + grant_to_add.award_amount, + '"' + grant_to_add.title + '"', + pi_name, + awardee_org, + '"' + abstract + '"', + grant_to_add.id + ] + .join(',')) + return acc + }, []) + this.downloadFile([...headers, ...grantsCsv].join('\n'), 'grants.csv', 'text/csv') + }) + } + + downloadFile = (data:any, fileName:any, fileType:any) => { + const blob = new Blob([data], { type: fileType }) + const a = document.createElement('a') + a.download = fileName + a.href = window.URL.createObjectURL(blob) + const clickEvt = new MouseEvent('click', { + view: window, + bubbles: true, + cancelable: true, + }) + a.dispatchEvent(clickEvt) + a.remove() + } + + + removeTime(date:Date) { + return new Date( + date.getFullYear(), + date.getMonth(), + date.getDate() + ) + } + + render() { + console.log('...1...') + console.log('...2...') + console.log('...3...') + + return ( +
+ +
+
+ { + this.state.search_in_progress == false ? +
+ Showing { this.state.totalCount } results. +
+ :
Waiting for results... +
+ } + +
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+
+ ); + } +} + +export default Grants; + + + diff --git a/frontend/search/src/home.tsx b/frontend/search/src/home.tsx new file mode 100644 index 0000000..f7175fe --- /dev/null +++ b/frontend/search/src/home.tsx @@ -0,0 +1,27 @@ +import SearchBar from './components/SearchBar'; +import Box from '@mui/material/Box'; +import React, { Component } from "react"; +import { useParams } from 'react-router-dom' + +const Home = () => { + const routeParams = useParams(); + console.log('****') + console.log(routeParams) + return ( +
+ + + +
+ ) + } + +export default Home; \ No newline at end of file diff --git a/frontend/search/src/index.tsx b/frontend/search/src/index.tsx index 95a8941..ccb1873 100644 --- a/frontend/search/src/index.tsx +++ b/frontend/search/src/index.tsx @@ -1,514 +1,26 @@ import ReactDOM from 'react-dom'; import "./main.css" import GrantsTable from './components/GrantTable'; +import SearchBar from './components/SearchBar'; import { GrantsFilter, Facet } from './components/GrantsFilter'; import Box from '@mui/material/Box'; +import Layout from './layout'; +import Home from './home'; +import Grants from './grants_index'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; import React, { Component } from "react"; import axios from "axios"; import DownloadIcon from '@mui/icons-material/Download'; import axiosRetry from 'axios-retry'; - -axiosRetry(axios, {retries: 3}); - -const styles = { - // See MUI Button CSS classes at https://mui.com/material-ui/api/button/ - "&.MuiButton-contained": { - color: "#FFFFFF", - backgroundColor: "#2C6BAC", - minWidth: "max-content", - whiteSpace: "nowrap", - textTransform: "none" - }, -}; - -interface Grant { - id: number - title: string - award_amount: number - abstract: string - award_id: string - pi: string - funder_name: string - awardee_org: string -} - -interface AppState { - data: Grant[] - url: string - totalCount: number - pageIndex: number - awardee_org_names: Facet[] - funder_divisions: Facet[] - pi_names: Facet[] - po_names: Facet[] - filter: Filter - keyword: string - funder_names: Facet[] - search_in_progress: boolean -} - -interface Filter { - nsf_division?: string - nih_division?: string - funder_division?: string - start_date?: Date - end_date?: Date - awardee_organization?: string - org_state?: string - pi_name?: string - po_name?: string - funder_name?: string -} - -let url = '' -if (process.env.NODE_ENV == 'production') { - url = "https://cic-apps.datascience.columbia.edu"; -} else if (process.env.NODE_ENV == 'development') { - url = "https://cice-dev.paas.cc.columbia.edu"; -} else { - url = "http://127.0.0.1:8000" -} - -class App extends Component { - state:AppState = { - data: [], - url: url, - totalCount: 0, - pageIndex: 0, - awardee_org_names: [], - funder_divisions: [], - pi_names: [], - po_names: [], - keyword: (window as any)['keywords'], - filter: {}, - funder_names: [], - search_in_progress: false - } - - constructor(props:any) { - super(props) - this.pageChangeHandler = this.pageChangeHandler.bind(this) - this.filterChangeHandler = this.filterChangeHandler.bind(this) - } - - componentDidMount = () => { - this.get_grants_data() - this.get_org_name_facet() - this.get_pi_name_facet() - this.get_po_name_facet() - this.get_funder_division_facet() - this.get_funder_facet() - } - - searchHandler = (event:any) => { - event.preventDefault() - const keyword = (document.getElementById('outlined-search') as HTMLInputElement).value; - this.setState({'keyword': keyword}) - this.get_grants_data(keyword) - } - - get_org_name_facet() { - var url = this.state.url.concat('/search/facets?field=awardee_organization.name') - axios.get(url).then(results => { - this.setState({ awardee_org_names: results.data.aggregations.patterns.buckets }) - }) - } - - get_funder_division_facet() { - var url = this.state.url.concat('/search/facets?field=funder_divisions') - axios.get(url).then(results => { - this.setState({ funder_divisions: results.data.aggregations.patterns.buckets }) - }) - } - - get_pi_name_facet(): Facet[] { - var url = this.state.url.concat('/search/facets?field=principal_investigator.full_name') - let pi_facet: Facet[] = []; - axios.get(url).then(results => { - this.setState({ pi_names: results.data.aggregations.patterns.buckets }) - pi_facet = results.data.aggregations.patterns.buckets - }) - return pi_facet; - } - - get_po_name_facet(): Facet[] { - var url = this.state.url.concat('/search/facets?field=program_officials.full_name') - let po_facet: Facet[] = []; - axios.get(url).then(results => { - this.setState({ po_names: results.data.aggregations.patterns.buckets }) - po_facet = results.data.aggregations.patterns.buckets - - }) - return po_facet; - } - - get_funder_facet(): Facet[] { - var url = this.state.url.concat('/search/facets?field=funder.name') - let funder_facet: Facet[] = []; - axios.get(url).then(results => { - this.setState({ funder_names: results.data.aggregations.patterns.buckets }) - funder_facet = results.data.aggregations.patterns.buckets - - }) - return funder_facet; - } - - getDataPromise() { - var params: { [key: string]: any } = {}; - params.from = 0 - params.size = 1000 - let keyword = (document.getElementById('outlined-search') as HTMLInputElement).value; - if (keyword && keyword.length > 0) { - params.keyword = keyword - } - let property: keyof typeof this.state.filter - for (property in this.state.filter) { - if (this.state.filter[property]) { - params[property] = this.state.filter[property] - } - } - return axios({ - url: url + '/search/grants', - method: 'get', - headers: { - 'Content-Type': 'application/json', - }, - params: params - }) - .then(res => { - var newArray = res.data.hits.hits.map(function(val:any) { - let pi_name = '' - let pi_id = '' - let funder_name = '' - let pi_private_emails = '' - if (val['_source']['principal_investigator'] != null) { - pi_name = val['_source']['principal_investigator']['full_name'] - pi_id = val['_source']['principal_investigator']['id'] - pi_private_emails = val['_source']['principal_investigator']['private_emails'] - } - return { - id: val['_source']['id'], - title: val['_source']['title'], - award_id: val['_source']['award_id'], - pi: pi_name, - pi_id: pi_id, - pi_private_emails: pi_private_emails, - abstract: val['_source']['abstract'], - award_amount: (val['_source']['award_amount'] !== null) ? val['_source']['award_amount'] : 0, - funder_name: ('name' in val['_source']['funder']) ? val['_source']['funder']['name'] : '', - awardee_org: val['_source']['awardee_organization']['name'] - } - }) - return newArray - }) - - .catch (err => { - console.error(err) - }) - } - - get_grants_data = (keyword?:string) => { - this.setState({ - search_in_progress: true - }) - var url = this.state.url.concat('/search/grants') - var params: { [key: string]: any } = {}; - - let from:number = 0 - - if (this.state.pageIndex > 0) { - from = (this.state.pageIndex * 20) + 1 - } - params.from = from - if (!keyword) { - keyword = (document.getElementById('outlined-search') as HTMLInputElement).value; - } - if (keyword && keyword.length > 0) { - params.keyword = keyword - } - - let property: keyof typeof this.state.filter - for (property in this.state.filter) { - if (this.state.filter[property]) { - params[property] = this.state.filter[property] - } - } - - axios.get(url, {params: params}).then(results => { - this.setState({ - search_in_progress: false - }) - this.setState({ totalCount: results.data.hits.total.value }) - - var newArray = results.data.hits.hits.map(function(val:any) { - let pi_name = '' - let pi_id = '' - let funder_name = '' - let pi_private_emails = '' - if (val['_source']['principal_investigator'] != null) { - pi_name = val['_source']['principal_investigator']['full_name'] - pi_id = val['_source']['principal_investigator']['id'] - pi_private_emails = val['_source']['principal_investigator']['private_emails'] - } - return { - id: val['_source']['id'], - title: val['_source']['title'], - award_id: val['_source']['award_id'], - pi: pi_name, - pi_id: pi_id, - pi_private_emails: pi_private_emails, - abstract: val['_source']['abstract'], - award_amount: (val['_source']['award_amount'] !== null) ? val['_source']['award_amount'] : 0, - funder_name: ('name' in val['_source']['funder']) ? val['_source']['funder']['name'] : '', - awardee_org: val['_source']['awardee_organization']['name'] - } - }) - this.setState({ data: newArray }) - }) - } - - downloadFile = (data:any, fileName:any, fileType:any) => { - const blob = new Blob([data], { type: fileType }) - const a = document.createElement('a') - a.download = fileName - a.href = window.URL.createObjectURL(blob) - const clickEvt = new MouseEvent('click', { - view: window, - bubbles: true, - cancelable: true, - }) - a.dispatchEvent(clickEvt) - a.remove() - } - - exportToCsv = (event:any) => { - event.preventDefault() - // Headers for each column - let headers = ['Funder, Award ID, Award Amount, Title, PI Name, Awardee Organization, Abstract, CIC ID'] - // Convert grants data to csv - this.getDataPromise().then(res => { - let grantsCsv = res.reduce((acc:any, grant:any) => { - let grant_to_add:Grant = grant - let abstract = grant_to_add.abstract - if (abstract) { - abstract = grant_to_add.abstract.replaceAll('"', "'") - } - let awardee_org = grant_to_add.awardee_org - if (awardee_org) { - if (awardee_org.indexOf(',') > -1) { - awardee_org = grant_to_add.awardee_org.replaceAll(',', '') - } - } - let pi_name = grant_to_add.pi - if (pi_name) { - if (pi_name.indexOf(',') > -1) { - pi_name = grant_to_add.pi.replaceAll(',', '') - } - } - acc.push([ - grant_to_add.funder_name, - grant_to_add.award_id, - grant_to_add.award_amount, - '"' + grant_to_add.title + '"', - pi_name, - awardee_org, - '"' + abstract + '"', - grant_to_add.id - ] - .join(',')) - return acc - }, []) - this.downloadFile([...headers, ...grantsCsv].join('\n'), 'grants.csv', 'text/csv') - }) - } - - enterHandler = (e:any) => { - if (e.key === 'Enter') { - e.preventDefault(); - this.get_grants_data() - } - } - - pageChangeHandler(page:number, pageSize: number) { - this.setState({ - pageIndex: page - }) - this.get_grants_data() - } - - - filterChangeHandler(fieldName?:string, value?:any, reset?:boolean) { - if (reset) { - this.state.filter = {} - this.get_grants_data() - return - } - var currentFilter = this.state.filter - if (fieldName == 'nsf_division') { - if (!value || value.length === 0) { - delete currentFilter.nsf_division; - } else { - currentFilter['nsf_division'] = value - } - } - if (fieldName == 'nih_division') { - if (!value || value.length === 0) { - delete currentFilter.nih_division; - } else { - currentFilter['nih_division'] = value - } - } - if (fieldName == 'funder_division') { - if (!value || value.length === 0) { - delete currentFilter.funder_division; - } else { - currentFilter['funder_division'] = value - } - } - if (fieldName == 'awardee_organization') { - if (!value || value.length === 0) { - delete currentFilter.awardee_organization; - } else { - currentFilter['awardee_organization'] = value - } - } - if (fieldName == 'startDate') { - if (value) { - currentFilter['start_date'] = this.removeTime(value) - } else { - delete currentFilter.start_date; - } - } - if (fieldName == 'endDate') { - if (value) { - currentFilter['end_date'] = this.removeTime(value) - } else { - delete currentFilter.end_date; - } - } - if (fieldName == 'org_state') { - if (!value || value.length === 0) { - delete currentFilter.org_state; - } else { - currentFilter['org_state'] = value - } - } - if (fieldName == 'pi_name') { - if (!value || value.length === 0) { - delete currentFilter.pi_name; - } else { - currentFilter['pi_name'] = value - } - } - if (fieldName == 'po_name') { - if (!value || value.length === 0) { - delete currentFilter.po_name; - } else { - currentFilter['po_name'] = value - } - } - if (fieldName == 'funder_name') { - if (!value || value.length === 0) { - delete currentFilter.funder_name; - } else { - currentFilter['funder_name'] = value - } - } - console.log(currentFilter) - this.setState({filter: currentFilter}) - this.get_grants_data() - } - - removeTime(date:Date) { - return new Date( - date.getFullYear(), - date.getMonth(), - date.getDate() - ) - } - - render() { - return ( - -
- -
- - - {/* */} - -
-
- { - this.state.search_in_progress == false ? -
- Showing { this.state.totalCount } results. -
- :
Waiting for results... -
- } - -
- -
-
-
-
-
- -
-
-
- -
-
-
- -
-
- ); - } - -} - -const rootElement = document.getElementById("root"); -ReactDOM.render(, rootElement); +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; +import App from './app'; + +ReactDOM.render( + + + , + document.getElementById('root') +) diff --git a/frontend/search/src/layout.tsx b/frontend/search/src/layout.tsx new file mode 100644 index 0000000..6c30989 --- /dev/null +++ b/frontend/search/src/layout.tsx @@ -0,0 +1,34 @@ +import { Outlet, Link } from "react-router-dom"; +import { useNavigate } from 'react-router-dom'; + +function handleChange(e:any){ + let navigate = useNavigate(); + navigate('/grants') +} + +const Layout = () => { + return ( + <> + + {/* */} + + + + ) +}; + +export default Layout; \ No newline at end of file diff --git a/frontend/search/src/main.css b/frontend/search/src/main.css index 42dce8c..0bc77a2 100644 --- a/frontend/search/src/main.css +++ b/frontend/search/src/main.css @@ -195,12 +195,12 @@ header h1 { } .download-csv { - text-align: center; + text-align: right; padding-bottom: 10px; } .download-button { - width: 50%; + width: 15%; height: 40px; } From 2cf48ce29f1aba4beba4ce495b19462446ade2e3 Mon Sep 17 00:00:00 2001 From: sg3847 Date: Tue, 6 Jun 2023 11:44:31 -0400 Subject: [PATCH 02/12] Ongoing work for new search UI --- backend/pi_survey/static/pi_survey/main.js | 2 +- backend/templates/cic_header.html | 2 +- frontend/search/src/app.tsx | 31 ++++++------ frontend/search/src/components/SearchBar.tsx | 15 +++++- frontend/search/src/datasets_index.tsx | 45 ++++++++++++++++++ frontend/search/src/home.tsx | 50 +++++++++++++++++++- frontend/search/src/index.tsx | 2 - frontend/search/src/layout.tsx | 34 ------------- frontend/search/src/people_index.tsx | 12 +++++ frontend/search/src/publications_index.tsx | 12 +++++ 10 files changed, 147 insertions(+), 58 deletions(-) create mode 100644 frontend/search/src/datasets_index.tsx create mode 100644 frontend/search/src/people_index.tsx create mode 100644 frontend/search/src/publications_index.tsx diff --git a/backend/pi_survey/static/pi_survey/main.js b/backend/pi_survey/static/pi_survey/main.js index eb6ddd6..dff73e9 100644 --- a/backend/pi_survey/static/pi_survey/main.js +++ b/backend/pi_survey/static/pi_survey/main.js @@ -1,2 +1,2 @@ /*! For license information please see main.js.LICENSE.txt */ -(()=>{var __webpack_modules__={"./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _emotion_sheet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @emotion/sheet */ "./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Tokenizer.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Utility.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Middleware.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Serializer.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Enum.js");\n/* harmony import */ var stylis__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! stylis */ "./node_modules/stylis/src/Parser.js");\n/* harmony import */ var _emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @emotion/weak-memoize */ "./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js");\n/* harmony import */ var _emotion_memoize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @emotion/memoize */ "./node_modules/@emotion/memoize/dist/emotion-memoize.browser.esm.js");\n\n\n\n\n\nvar last = function last(arr) {\n return arr.length ? arr[arr.length - 1] : null;\n}; // based on https://github.com/thysultan/stylis.js/blob/e6843c373ebcbbfade25ebcc23f540ed8508da0a/src/Tokenizer.js#L239-L244\n\n\nvar identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) {\n var previous = 0;\n var character = 0;\n\n while (true) {\n previous = character;\n character = (0,stylis__WEBPACK_IMPORTED_MODULE_3__.peek)(); // &\\f\n\n if (previous === 38 && character === 12) {\n points[index] = 1;\n }\n\n if ((0,stylis__WEBPACK_IMPORTED_MODULE_3__.token)(character)) {\n break;\n }\n\n (0,stylis__WEBPACK_IMPORTED_MODULE_3__.next)();\n }\n\n return (0,stylis__WEBPACK_IMPORTED_MODULE_3__.slice)(begin, stylis__WEBPACK_IMPORTED_MODULE_3__.position);\n};\n\nvar toRules = function toRules(parsed, points) {\n // pretend we\'ve started with a comma\n var index = -1;\n var character = 44;\n\n do {\n switch ((0,stylis__WEBPACK_IMPORTED_MODULE_3__.token)(character)) {\n case 0:\n // &\\f\n if (character === 38 && (0,stylis__WEBPACK_IMPORTED_MODULE_3__.peek)() === 12) {\n // this is not 100% correct, we don\'t account for literal sequences here - like for example quoted strings\n // stylis inserts \\f after & to know when & where it should replace this sequence with the context selector\n // and when it should just concatenate the outer and inner selectors\n // it\'s very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here\n points[index] = 1;\n }\n\n parsed[index] += identifierWithPointTracking(stylis__WEBPACK_IMPORTED_MODULE_3__.position - 1, points, index);\n break;\n\n case 2:\n parsed[index] += (0,stylis__WEBPACK_IMPORTED_MODULE_3__.delimit)(character);\n break;\n\n case 4:\n // comma\n if (character === 44) {\n // colon\n parsed[++index] = (0,stylis__WEBPACK_IMPORTED_MODULE_3__.peek)() === 58 ? \'&\\f\' : \'\';\n points[index] = parsed[index].length;\n break;\n }\n\n // fallthrough\n\n default:\n parsed[index] += (0,stylis__WEBPACK_IMPORTED_MODULE_4__.from)(character);\n }\n } while (character = (0,stylis__WEBPACK_IMPORTED_MODULE_3__.next)());\n\n return parsed;\n};\n\nvar getRules = function getRules(value, points) {\n return (0,stylis__WEBPACK_IMPORTED_MODULE_3__.dealloc)(toRules((0,stylis__WEBPACK_IMPORTED_MODULE_3__.alloc)(value), points));\n}; // WeakSet would be more appropriate, but only WeakMap is supported in IE11\n\n\nvar fixedElements = /* #__PURE__ */new WeakMap();\nvar compat = function compat(element) {\n if (element.type !== \'rule\' || !element.parent || // positive .length indicates that this rule contains pseudo\n // negative .length indicates that this rule has been already prefixed\n element.length < 1) {\n return;\n }\n\n var value = element.value,\n parent = element.parent;\n var isImplicitRule = element.column === parent.column && element.line === parent.line;\n\n while (parent.type !== \'rule\') {\n parent = parent.parent;\n if (!parent) return;\n } // short-circuit for the simplest case\n\n\n if (element.props.length === 1 && value.charCodeAt(0) !== 58\n /* colon */\n && !fixedElements.get(parent)) {\n return;\n } // if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level)\n // then the props has already been manipulated beforehand as they that array is shared between it and its "rule parent"\n\n\n if (isImplicitRule) {\n return;\n }\n\n fixedElements.set(element, true);\n var points = [];\n var rules = getRules(value, points);\n var parentRules = parent.props;\n\n for (var i = 0, k = 0; i < rules.length; i++) {\n for (var j = 0; j < parentRules.length; j++, k++) {\n element.props[k] = points[i] ? rules[i].replace(/&\\f/g, parentRules[j]) : parentRules[j] + " " + rules[i];\n }\n }\n};\nvar removeLabel = function removeLabel(element) {\n if (element.type === \'decl\') {\n var value = element.value;\n\n if ( // charcode for l\n value.charCodeAt(0) === 108 && // charcode for b\n value.charCodeAt(2) === 98) {\n // this ignores label\n element["return"] = \'\';\n element.value = \'\';\n }\n }\n};\nvar ignoreFlag = \'emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason\';\n\nvar isIgnoringComment = function isIgnoringComment(element) {\n return !!element && element.type === \'comm\' && element.children.indexOf(ignoreFlag) > -1;\n};\n\nvar createUnsafeSelectorsAlarm = function createUnsafeSelectorsAlarm(cache) {\n return function (element, index, children) {\n if (element.type !== \'rule\') return;\n var unsafePseudoClasses = element.value.match(/(:first|:nth|:nth-last)-child/g);\n\n if (unsafePseudoClasses && cache.compat !== true) {\n var prevElement = index > 0 ? children[index - 1] : null;\n\n if (prevElement && isIgnoringComment(last(prevElement.children))) {\n return;\n }\n\n unsafePseudoClasses.forEach(function (unsafePseudoClass) {\n console.error("The pseudo class \\"" + unsafePseudoClass + "\\" is potentially unsafe when doing server-side rendering. Try changing it to \\"" + unsafePseudoClass.split(\'-child\')[0] + "-of-type\\".");\n });\n }\n };\n};\n\nvar isImportRule = function isImportRule(element) {\n return element.type.charCodeAt(1) === 105 && element.type.charCodeAt(0) === 64;\n};\n\nvar isPrependedWithRegularRules = function isPrependedWithRegularRules(index, children) {\n for (var i = index - 1; i >= 0; i--) {\n if (!isImportRule(children[i])) {\n return true;\n }\n }\n\n return false;\n}; // use this to remove incorrect elements from further processing\n// so they don\'t get handed to the `sheet` (or anything else)\n// as that could potentially lead to additional logs which in turn could be overhelming to the user\n\n\nvar nullifyElement = function nullifyElement(element) {\n element.type = \'\';\n element.value = \'\';\n element["return"] = \'\';\n element.children = \'\';\n element.props = \'\';\n};\n\nvar incorrectImportAlarm = function incorrectImportAlarm(element, index, children) {\n if (!isImportRule(element)) {\n return;\n }\n\n if (element.parent) {\n console.error("`@import` rules can\'t be nested inside other rules. Please move it to the top level and put it before regular rules. Keep in mind that they can only be used within global styles.");\n nullifyElement(element);\n } else if (isPrependedWithRegularRules(index, children)) {\n console.error("`@import` rules can\'t be after other rules. Please put your `@import` rules before your other rules.");\n nullifyElement(element);\n }\n};\n\nvar defaultStylisPlugins = [stylis__WEBPACK_IMPORTED_MODULE_5__.prefixer];\n\nvar createCache = function createCache(options) {\n var key = options.key;\n\n if ( true && !key) {\n throw new Error("You have to configure `key` for your cache. Please make sure it\'s unique (and not equal to \'css\') as it\'s used for linking styles to your cache.\\n" + "If multiple caches share the same key they might \\"fight\\" for each other\'s style elements.");\n }\n\n if ( key === \'css\') {\n var ssrStyles = document.querySelectorAll("style[data-emotion]:not([data-s])"); // get SSRed styles out of the way of React\'s hydration\n // document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)\n // note this very very intentionally targets all style elements regardless of the key to ensure\n // that creating a cache works inside of render of a React component\n\n Array.prototype.forEach.call(ssrStyles, function (node) {\n // we want to only move elements which have a space in the data-emotion attribute value\n // because that indicates that it is an Emotion 11 server-side rendered style elements\n // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector\n // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)\n // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles\n // will not result in the Emotion 10 styles being destroyed\n var dataEmotionAttribute = node.getAttribute(\'data-emotion\');\n\n if (dataEmotionAttribute.indexOf(\' \') === -1) {\n return;\n }\n document.head.appendChild(node);\n node.setAttribute(\'data-s\', \'\');\n });\n }\n\n var stylisPlugins = options.stylisPlugins || defaultStylisPlugins;\n\n if (true) {\n // $FlowFixMe\n if (/[^a-z-]/.test(key)) {\n throw new Error("Emotion key must only contain lower case alphabetical characters and - but \\"" + key + "\\" was passed");\n }\n }\n\n var inserted = {};\n var container;\n var nodesToHydrate = [];\n\n {\n container = options.container || document.head;\n Array.prototype.forEach.call( // this means we will ignore elements which don\'t have a space in them which\n // means that the style elements we\'re looking at are only Emotion 11 server-rendered style elements\n document.querySelectorAll("style[data-emotion^=\\"" + key + " \\"]"), function (node) {\n var attrib = node.getAttribute("data-emotion").split(\' \'); // $FlowFixMe\n\n for (var i = 1; i < attrib.length; i++) {\n inserted[attrib[i]] = true;\n }\n\n nodesToHydrate.push(node);\n });\n }\n\n var _insert;\n\n var omnipresentPlugins = [compat, removeLabel];\n\n if (true) {\n omnipresentPlugins.push(createUnsafeSelectorsAlarm({\n get compat() {\n return cache.compat;\n }\n\n }), incorrectImportAlarm);\n }\n\n {\n var currentSheet;\n var finalizingPlugins = [stylis__WEBPACK_IMPORTED_MODULE_6__.stringify, true ? function (element) {\n if (!element.root) {\n if (element["return"]) {\n currentSheet.insert(element["return"]);\n } else if (element.value && element.type !== stylis__WEBPACK_IMPORTED_MODULE_7__.COMMENT) {\n // insert empty rule in non-production environments\n // so @emotion/jest can grab `key` from the (JS)DOM for caches without any rules inserted yet\n currentSheet.insert(element.value + "{}");\n }\n }\n } : 0];\n var serializer = (0,stylis__WEBPACK_IMPORTED_MODULE_5__.middleware)(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins));\n\n var stylis = function stylis(styles) {\n return (0,stylis__WEBPACK_IMPORTED_MODULE_6__.serialize)((0,stylis__WEBPACK_IMPORTED_MODULE_8__.compile)(styles), serializer);\n };\n\n _insert = function insert(selector, serialized, sheet, shouldCache) {\n currentSheet = sheet;\n\n if ( true && serialized.map !== undefined) {\n currentSheet = {\n insert: function insert(rule) {\n sheet.insert(rule + serialized.map);\n }\n };\n }\n\n stylis(selector ? selector + "{" + serialized.styles + "}" : serialized.styles);\n\n if (shouldCache) {\n cache.inserted[serialized.name] = true;\n }\n };\n }\n\n var cache = {\n key: key,\n sheet: new _emotion_sheet__WEBPACK_IMPORTED_MODULE_0__.StyleSheet({\n key: key,\n container: container,\n nonce: options.nonce,\n speedy: options.speedy,\n prepend: options.prepend,\n insertionPoint: options.insertionPoint\n }),\n nonce: options.nonce,\n inserted: inserted,\n registered: {},\n insert: _insert\n };\n cache.sheet.hydrate(nodesToHydrate);\n return cache;\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createCache);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js?')},"./node_modules/@emotion/hash/dist/hash.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* eslint-disable */\n// Inspired by https://github.com/garycourt/murmurhash-js\n// Ported from https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp#L37-L86\nfunction murmur2(str) {\n // 'm' and 'r' are mixing constants generated offline.\n // They're not really 'magic', they just happen to work well.\n // const m = 0x5bd1e995;\n // const r = 24;\n // Initialize the hash\n var h = 0; // Mix 4 bytes at a time into the hash\n\n var k,\n i = 0,\n len = str.length;\n\n for (; len >= 4; ++i, len -= 4) {\n k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24;\n k =\n /* Math.imul(k, m): */\n (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16);\n k ^=\n /* k >>> r: */\n k >>> 24;\n h =\n /* Math.imul(k, m): */\n (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16) ^\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n } // Handle the last few bytes of the input array\n\n\n switch (len) {\n case 3:\n h ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n\n case 2:\n h ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n\n case 1:\n h ^= str.charCodeAt(i) & 0xff;\n h =\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n } // Do a few final mixes of the hash to ensure the last few\n // bytes are well-incorporated.\n\n\n h ^= h >>> 13;\n h =\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n return ((h ^ h >>> 15) >>> 0).toString(36);\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (murmur2);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/hash/dist/hash.browser.esm.js?")},"./node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _emotion_memoize__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @emotion/memoize */ "./node_modules/@emotion/memoize/dist/emotion-memoize.browser.esm.js");\n\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar isPropValid = /* #__PURE__ */(0,_emotion_memoize__WEBPACK_IMPORTED_MODULE_0__["default"])(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isPropValid);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.browser.esm.js?')},"./node_modules/@emotion/memoize/dist/emotion-memoize.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction memoize(fn) {\n var cache = Object.create(null);\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (memoize);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/memoize/dist/emotion-memoize.browser.esm.js?')},"./node_modules/@emotion/react/_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! hoist-non-react-statics */ "./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js");\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_0__);\n\n\n// this file isolates this package that is not tree-shakeable\n// and if this module doesn\'t actually contain any logic of its own\n// then Rollup just use \'hoist-non-react-statics\' directly in other chunks\n\nvar hoistNonReactStatics = (function (targetComponent, sourceComponent) {\n return hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_0___default()(targetComponent, sourceComponent);\n});\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hoistNonReactStatics);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/react/_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js?')},"./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("var react__WEBPACK_IMPORTED_MODULE_0___namespace_cache;\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"C\": () => (/* binding */ CacheProvider),\n/* harmony export */ \"E\": () => (/* binding */ Emotion),\n/* harmony export */ \"T\": () => (/* binding */ ThemeContext),\n/* harmony export */ \"_\": () => (/* binding */ __unsafe_useEmotionCache),\n/* harmony export */ \"a\": () => (/* binding */ useTheme),\n/* harmony export */ \"b\": () => (/* binding */ ThemeProvider),\n/* harmony export */ \"c\": () => (/* binding */ createEmotionProps),\n/* harmony export */ \"d\": () => (/* binding */ withTheme),\n/* harmony export */ \"h\": () => (/* binding */ hasOwnProperty),\n/* harmony export */ \"u\": () => (/* binding */ useInsertionEffectMaybe),\n/* harmony export */ \"w\": () => (/* binding */ withEmotionCache)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var _emotion_cache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @emotion/cache */ \"./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js\");\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ \"./node_modules/@babel/runtime/helpers/esm/extends.js\");\n/* harmony import */ var _emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @emotion/weak-memoize */ \"./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js\");\n/* harmony import */ var _isolated_hnrs_dist_emotion_react_isolated_hnrs_browser_esm_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js */ \"./node_modules/@emotion/react/_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js\");\n/* harmony import */ var _emotion_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @emotion/utils */ \"./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js\");\n/* harmony import */ var _emotion_serialize__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @emotion/serialize */ \"./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js\");\n\n\n\n\n\n\n\n\n\nvar hasOwnProperty = {}.hasOwnProperty;\n\nvar EmotionCacheContext = /* #__PURE__ */(0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)( // we're doing this to avoid preconstruct's dead code elimination in this one case\n// because this module is primarily intended for the browser and node\n// but it's also required in react native and similar environments sometimes\n// and we could have a special build just for that\n// but this is much easier and the native packages\n// might use a different theme context in the future anyway\ntypeof HTMLElement !== 'undefined' ? /* #__PURE__ */(0,_emotion_cache__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n key: 'css'\n}) : null);\n\nif (true) {\n EmotionCacheContext.displayName = 'EmotionCacheContext';\n}\n\nvar CacheProvider = EmotionCacheContext.Provider;\nvar __unsafe_useEmotionCache = function useEmotionCache() {\n return (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EmotionCacheContext);\n};\n\nvar withEmotionCache = function withEmotionCache(func) {\n // $FlowFixMe\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(function (props, ref) {\n // the cache will never be null in the browser\n var cache = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EmotionCacheContext);\n return func(props, cache, ref);\n });\n};\n\nvar ThemeContext = /* #__PURE__ */(0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({});\n\nif (true) {\n ThemeContext.displayName = 'EmotionThemeContext';\n}\n\nvar useTheme = function useTheme() {\n return (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ThemeContext);\n};\n\nvar getTheme = function getTheme(outerTheme, theme) {\n if (typeof theme === 'function') {\n var mergedTheme = theme(outerTheme);\n\n if ( true && (mergedTheme == null || typeof mergedTheme !== 'object' || Array.isArray(mergedTheme))) {\n throw new Error('[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!');\n }\n\n return mergedTheme;\n }\n\n if ( true && (theme == null || typeof theme !== 'object' || Array.isArray(theme))) {\n throw new Error('[ThemeProvider] Please make your theme prop a plain object');\n }\n\n return (0,_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_2__[\"default\"])({}, outerTheme, theme);\n};\n\nvar createCacheWithTheme = /* #__PURE__ */(0,_emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(function (outerTheme) {\n return (0,_emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(function (theme) {\n return getTheme(outerTheme, theme);\n });\n});\nvar ThemeProvider = function ThemeProvider(props) {\n var theme = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ThemeContext);\n\n if (props.theme !== theme) {\n theme = createCacheWithTheme(theme)(props.theme);\n }\n\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(ThemeContext.Provider, {\n value: theme\n }, props.children);\n};\nfunction withTheme(Component) {\n var componentName = Component.displayName || Component.name || 'Component';\n\n var render = function render(props, ref) {\n var theme = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ThemeContext);\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(Component, (0,_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_2__[\"default\"])({\n theme: theme,\n ref: ref\n }, props));\n }; // $FlowFixMe\n\n\n var WithTheme = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(render);\n WithTheme.displayName = \"WithTheme(\" + componentName + \")\";\n return (0,_isolated_hnrs_dist_emotion_react_isolated_hnrs_browser_esm_js__WEBPACK_IMPORTED_MODULE_6__[\"default\"])(WithTheme, Component);\n}\n\nvar getLastPart = function getLastPart(functionName) {\n // The match may be something like 'Object.createEmotionProps' or\n // 'Loader.prototype.render'\n var parts = functionName.split('.');\n return parts[parts.length - 1];\n};\n\nvar getFunctionNameFromStackTraceLine = function getFunctionNameFromStackTraceLine(line) {\n // V8\n var match = /^\\s+at\\s+([A-Za-z0-9$.]+)\\s/.exec(line);\n if (match) return getLastPart(match[1]); // Safari / Firefox\n\n match = /^([A-Za-z0-9$.]+)@/.exec(line);\n if (match) return getLastPart(match[1]);\n return undefined;\n};\n\nvar internalReactFunctionNames = /* #__PURE__ */new Set(['renderWithHooks', 'processChild', 'finishClassComponent', 'renderToString']); // These identifiers come from error stacks, so they have to be valid JS\n// identifiers, thus we only need to replace what is a valid character for JS,\n// but not for CSS.\n\nvar sanitizeIdentifier = function sanitizeIdentifier(identifier) {\n return identifier.replace(/\\$/g, '-');\n};\n\nvar getLabelFromStackTrace = function getLabelFromStackTrace(stackTrace) {\n if (!stackTrace) return undefined;\n var lines = stackTrace.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n var functionName = getFunctionNameFromStackTraceLine(lines[i]); // The first line of V8 stack traces is just \"Error\"\n\n if (!functionName) continue; // If we reach one of these, we have gone too far and should quit\n\n if (internalReactFunctionNames.has(functionName)) break; // The component name is the first function in the stack that starts with an\n // uppercase letter\n\n if (/^[A-Z]/.test(functionName)) return sanitizeIdentifier(functionName);\n }\n\n return undefined;\n};\n\nvar useInsertionEffect = /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_0__, 2)))['useInsertion' + 'Effect'] ? /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_0__, 2)))['useInsertion' + 'Effect'] : function useInsertionEffect(create) {\n create();\n};\nfunction useInsertionEffectMaybe(create) {\n\n useInsertionEffect(create);\n}\n\nvar typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__';\nvar labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__';\nvar createEmotionProps = function createEmotionProps(type, props) {\n if ( true && typeof props.css === 'string' && // check if there is a css declaration\n props.css.indexOf(':') !== -1) {\n throw new Error(\"Strings are not allowed as css prop values, please wrap it in a css template literal from '@emotion/react' like this: css`\" + props.css + \"`\");\n }\n\n var newProps = {};\n\n for (var key in props) {\n if (hasOwnProperty.call(props, key)) {\n newProps[key] = props[key];\n }\n }\n\n newProps[typePropName] = type; // For performance, only call getLabelFromStackTrace in development and when\n // the label hasn't already been computed\n\n if ( true && !!props.css && (typeof props.css !== 'object' || typeof props.css.name !== 'string' || props.css.name.indexOf('-') === -1)) {\n var label = getLabelFromStackTrace(new Error().stack);\n if (label) newProps[labelPropName] = label;\n }\n\n return newProps;\n};\n\nvar Insertion = function Insertion(_ref) {\n var cache = _ref.cache,\n serialized = _ref.serialized,\n isStringTag = _ref.isStringTag;\n (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_4__.registerStyles)(cache, serialized, isStringTag);\n var rules = useInsertionEffectMaybe(function () {\n return (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_4__.insertStyles)(cache, serialized, isStringTag);\n });\n\n return null;\n};\n\nvar Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {\n var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works\n // not passing the registered cache to serializeStyles because it would\n // make certain babel optimisations not possible\n\n if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) {\n cssProp = cache.registered[cssProp];\n }\n\n var WrappedComponent = props[typePropName];\n var registeredStyles = [cssProp];\n var className = '';\n\n if (typeof props.className === 'string') {\n className = (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_4__.getRegisteredStyles)(cache.registered, registeredStyles, props.className);\n } else if (props.className != null) {\n className = props.className + \" \";\n }\n\n var serialized = (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_5__.serializeStyles)(registeredStyles, undefined, (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ThemeContext));\n\n if ( true && serialized.name.indexOf('-') === -1) {\n var labelFromStack = props[labelPropName];\n\n if (labelFromStack) {\n serialized = (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_5__.serializeStyles)([serialized, 'label:' + labelFromStack + ';']);\n }\n }\n\n className += cache.key + \"-\" + serialized.name;\n var newProps = {};\n\n for (var key in props) {\n if (hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && ( false || key !== labelPropName)) {\n newProps[key] = props[key];\n }\n }\n\n newProps.ref = ref;\n newProps.className = className;\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(Insertion, {\n cache: cache,\n serialized: serialized,\n isStringTag: typeof WrappedComponent === 'string'\n }), /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(WrappedComponent, newProps));\n});\n\nif (true) {\n Emotion.displayName = 'EmotionCssPropInternal';\n}\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js?")},"./node_modules/@emotion/react/dist/emotion-react.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('var react__WEBPACK_IMPORTED_MODULE_0___namespace_cache;\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "CacheProvider": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.C),\n/* harmony export */ "ClassNames": () => (/* binding */ ClassNames),\n/* harmony export */ "Global": () => (/* binding */ Global),\n/* harmony export */ "ThemeContext": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.T),\n/* harmony export */ "ThemeProvider": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.b),\n/* harmony export */ "__unsafe_useEmotionCache": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__._),\n/* harmony export */ "createElement": () => (/* binding */ jsx),\n/* harmony export */ "css": () => (/* binding */ css),\n/* harmony export */ "jsx": () => (/* binding */ jsx),\n/* harmony export */ "keyframes": () => (/* binding */ keyframes),\n/* harmony export */ "useTheme": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.a),\n/* harmony export */ "withEmotionCache": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.w),\n/* harmony export */ "withTheme": () => (/* reexport safe */ _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.d)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");\n/* harmony import */ var _emotion_cache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @emotion/cache */ "./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js");\n/* harmony import */ var _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./emotion-element-cbed451f.browser.esm.js */ "./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js");\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js");\n/* harmony import */ var _emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @emotion/weak-memoize */ "./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js");\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! hoist-non-react-statics */ "./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js");\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _emotion_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @emotion/utils */ "./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js");\n/* harmony import */ var _emotion_serialize__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @emotion/serialize */ "./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js");\n\n\n\n\n\n\n\n\n\n\n\n\nvar pkg = {\n\tname: "@emotion/react",\n\tversion: "11.9.3",\n\tmain: "dist/emotion-react.cjs.js",\n\tmodule: "dist/emotion-react.esm.js",\n\tbrowser: {\n\t\t"./dist/emotion-react.cjs.js": "./dist/emotion-react.browser.cjs.js",\n\t\t"./dist/emotion-react.esm.js": "./dist/emotion-react.browser.esm.js"\n\t},\n\ttypes: "types/index.d.ts",\n\tfiles: [\n\t\t"src",\n\t\t"dist",\n\t\t"jsx-runtime",\n\t\t"jsx-dev-runtime",\n\t\t"_isolated-hnrs",\n\t\t"types/*.d.ts",\n\t\t"macro.js",\n\t\t"macro.d.ts",\n\t\t"macro.js.flow"\n\t],\n\tsideEffects: false,\n\tauthor: "Emotion Contributors",\n\tlicense: "MIT",\n\tscripts: {\n\t\t"test:typescript": "dtslint types"\n\t},\n\tdependencies: {\n\t\t"@babel/runtime": "^7.13.10",\n\t\t"@emotion/babel-plugin": "^11.7.1",\n\t\t"@emotion/cache": "^11.9.3",\n\t\t"@emotion/serialize": "^1.0.4",\n\t\t"@emotion/utils": "^1.1.0",\n\t\t"@emotion/weak-memoize": "^0.2.5",\n\t\t"hoist-non-react-statics": "^3.3.1"\n\t},\n\tpeerDependencies: {\n\t\t"@babel/core": "^7.0.0",\n\t\treact: ">=16.8.0"\n\t},\n\tpeerDependenciesMeta: {\n\t\t"@babel/core": {\n\t\t\toptional: true\n\t\t},\n\t\t"@types/react": {\n\t\t\toptional: true\n\t\t}\n\t},\n\tdevDependencies: {\n\t\t"@babel/core": "^7.13.10",\n\t\t"@definitelytyped/dtslint": "0.0.112",\n\t\t"@emotion/css": "11.9.0",\n\t\t"@emotion/css-prettifier": "1.0.1",\n\t\t"@emotion/server": "11.4.0",\n\t\t"@emotion/styled": "11.9.3",\n\t\t"html-tag-names": "^1.1.2",\n\t\treact: "16.14.0",\n\t\t"svg-tag-names": "^1.1.1",\n\t\ttypescript: "^4.5.5"\n\t},\n\trepository: "https://github.com/emotion-js/emotion/tree/main/packages/react",\n\tpublishConfig: {\n\t\taccess: "public"\n\t},\n\t"umd:main": "dist/emotion-react.umd.min.js",\n\tpreconstruct: {\n\t\tentrypoints: [\n\t\t\t"./index.js",\n\t\t\t"./jsx-runtime.js",\n\t\t\t"./jsx-dev-runtime.js",\n\t\t\t"./_isolated-hnrs.js"\n\t\t],\n\t\tumdName: "emotionReact"\n\t}\n};\n\nvar jsx = function jsx(type, props) {\n var args = arguments;\n\n if (props == null || !_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.h.call(props, \'css\')) {\n // $FlowFixMe\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement.apply(undefined, args);\n }\n\n var argsLength = args.length;\n var createElementArgArray = new Array(argsLength);\n createElementArgArray[0] = _emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.E;\n createElementArgArray[1] = (0,_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.c)(type, props);\n\n for (var i = 2; i < argsLength; i++) {\n createElementArgArray[i] = args[i];\n } // $FlowFixMe\n\n\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement.apply(null, createElementArgArray);\n};\n\nvar useInsertionEffect = /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_0__, 2)))[\'useInsertion\' + \'Effect\'] ? /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_0___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_0__, 2)))[\'useInsertion\' + \'Effect\'] : react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect;\nvar warnedAboutCssPropForGlobal = false; // maintain place over rerenders.\n// initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn\'t been inserted there yet, appendChild\n// initial client-side render from SSR, use place of hydrating tag\n\nvar Global = /* #__PURE__ */(0,_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.w)(function (props, cache) {\n if ( true && !warnedAboutCssPropForGlobal && ( // check for className as well since the user is\n // probably using the custom createElement which\n // means it will be turned into a className prop\n // $FlowFixMe I don\'t really want to add it to the type since it shouldn\'t be used\n props.className || props.css)) {\n console.error("It looks like you\'re using the css prop on Global, did you mean to use the styles prop instead?");\n warnedAboutCssPropForGlobal = true;\n }\n\n var styles = props.styles;\n var serialized = (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_7__.serializeStyles)([styles], undefined, (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.T));\n // but it is based on a constant that will never change at runtime\n // it\'s effectively like having two implementations and switching them out\n // so it\'s not actually breaking anything\n\n\n var sheetRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)();\n useInsertionEffect(function () {\n var key = cache.key + "-global"; // use case of https://github.com/emotion-js/emotion/issues/2675\n\n var sheet = new cache.sheet.constructor({\n key: key,\n nonce: cache.sheet.nonce,\n container: cache.sheet.container,\n speedy: cache.sheet.isSpeedy\n });\n var rehydrating = false; // $FlowFixMe\n\n var node = document.querySelector("style[data-emotion=\\"" + key + " " + serialized.name + "\\"]");\n\n if (cache.sheet.tags.length) {\n sheet.before = cache.sheet.tags[0];\n }\n\n if (node !== null) {\n rehydrating = true; // clear the hash so this node won\'t be recognizable as rehydratable by other s\n\n node.setAttribute(\'data-emotion\', key);\n sheet.hydrate([node]);\n }\n\n sheetRef.current = [sheet, rehydrating];\n return function () {\n sheet.flush();\n };\n }, [cache]);\n useInsertionEffect(function () {\n var sheetRefCurrent = sheetRef.current;\n var sheet = sheetRefCurrent[0],\n rehydrating = sheetRefCurrent[1];\n\n if (rehydrating) {\n sheetRefCurrent[1] = false;\n return;\n }\n\n if (serialized.next !== undefined) {\n // insert keyframes\n (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_6__.insertStyles)(cache, serialized.next, true);\n }\n\n if (sheet.tags.length) {\n // if this doesn\'t exist then it will be null so the style element will be appended\n var element = sheet.tags[sheet.tags.length - 1].nextElementSibling;\n sheet.before = element;\n sheet.flush();\n }\n\n cache.insert("", serialized, sheet, false);\n }, [cache, serialized.name]);\n return null;\n});\n\nif (true) {\n Global.displayName = \'EmotionGlobal\';\n}\n\nfunction css() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_7__.serializeStyles)(args);\n}\n\nvar keyframes = function keyframes() {\n var insertable = css.apply(void 0, arguments);\n var name = "animation-" + insertable.name; // $FlowFixMe\n\n return {\n name: name,\n styles: "@keyframes " + name + "{" + insertable.styles + "}",\n anim: 1,\n toString: function toString() {\n return "_EMO_" + this.name + "_" + this.styles + "_EMO_";\n }\n };\n};\n\nvar classnames = function classnames(args) {\n var len = args.length;\n var i = 0;\n var cls = \'\';\n\n for (; i < len; i++) {\n var arg = args[i];\n if (arg == null) continue;\n var toAdd = void 0;\n\n switch (typeof arg) {\n case \'boolean\':\n break;\n\n case \'object\':\n {\n if (Array.isArray(arg)) {\n toAdd = classnames(arg);\n } else {\n if ( true && arg.styles !== undefined && arg.name !== undefined) {\n console.error(\'You have passed styles created with `css` from `@emotion/react` package to the `cx`.\\n\' + \'`cx` is meant to compose class names (strings) so you should convert those styles to a class name by passing them to the `css` received from component.\');\n }\n\n toAdd = \'\';\n\n for (var k in arg) {\n if (arg[k] && k) {\n toAdd && (toAdd += \' \');\n toAdd += k;\n }\n }\n }\n\n break;\n }\n\n default:\n {\n toAdd = arg;\n }\n }\n\n if (toAdd) {\n cls && (cls += \' \');\n cls += toAdd;\n }\n }\n\n return cls;\n};\n\nfunction merge(registered, css, className) {\n var registeredStyles = [];\n var rawClassName = (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_6__.getRegisteredStyles)(registered, registeredStyles, className);\n\n if (registeredStyles.length < 2) {\n return className;\n }\n\n return rawClassName + css(registeredStyles);\n}\n\nvar Insertion = function Insertion(_ref) {\n var cache = _ref.cache,\n serializedArr = _ref.serializedArr;\n var rules = (0,_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.u)(function () {\n\n for (var i = 0; i < serializedArr.length; i++) {\n var res = (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_6__.insertStyles)(cache, serializedArr[i], false);\n }\n });\n\n return null;\n};\n\nvar ClassNames = /* #__PURE__ */(0,_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.w)(function (props, cache) {\n var hasRendered = false;\n var serializedArr = [];\n\n var css = function css() {\n if (hasRendered && "development" !== \'production\') {\n throw new Error(\'css can only be used during render\');\n }\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var serialized = (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_7__.serializeStyles)(args, cache.registered);\n serializedArr.push(serialized); // registration has to happen here as the result of this might get consumed by `cx`\n\n (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_6__.registerStyles)(cache, serialized, false);\n return cache.key + "-" + serialized.name;\n };\n\n var cx = function cx() {\n if (hasRendered && "development" !== \'production\') {\n throw new Error(\'cx can only be used during render\');\n }\n\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return merge(cache.registered, css, classnames(args));\n };\n\n var content = {\n css: css,\n cx: cx,\n theme: (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_2__.T)\n };\n var ele = props.children(content);\n hasRendered = true;\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(Insertion, {\n cache: cache,\n serializedArr: serializedArr\n }), ele);\n});\n\nif (true) {\n ClassNames.displayName = \'EmotionClassNames\';\n}\n\nif (true) {\n var isBrowser = "object" !== \'undefined\'; // #1727 for some reason Jest evaluates modules twice if some consuming module gets mocked with jest.mock\n\n var isJest = typeof jest !== \'undefined\';\n\n if (isBrowser && !isJest) {\n // globalThis has wide browser support - https://caniuse.com/?search=globalThis, Node.js 12 and later\n var globalContext = // $FlowIgnore\n typeof globalThis !== \'undefined\' ? globalThis // eslint-disable-line no-undef\n : isBrowser ? window : __webpack_require__.g;\n var globalKey = "__EMOTION_REACT_" + pkg.version.split(\'.\')[0] + "__";\n\n if (globalContext[globalKey]) {\n console.warn(\'You are loading @emotion/react when it is already loaded. Running \' + \'multiple instances may cause problems. This can happen if multiple \' + \'versions are used, or if multiple builds of the same version are \' + \'used.\');\n }\n\n globalContext[globalKey] = true;\n }\n}\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/react/dist/emotion-react.browser.esm.js?')},"./node_modules/@emotion/react/jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Fragment": () => (/* binding */ Fragment),\n/* harmony export */ "jsx": () => (/* binding */ jsx),\n/* harmony export */ "jsxs": () => (/* binding */ jsxs)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");\n/* harmony import */ var _emotion_cache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @emotion/cache */ "./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js");\n/* harmony import */ var _dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../dist/emotion-element-cbed451f.browser.esm.js */ "./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js");\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js");\n/* harmony import */ var _emotion_weak_memoize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @emotion/weak-memoize */ "./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js");\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! hoist-non-react-statics */ "./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js");\n/* harmony import */ var hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(hoist_non_react_statics__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _emotion_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @emotion/utils */ "./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js");\n/* harmony import */ var _emotion_serialize__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @emotion/serialize */ "./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js");\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! react/jsx-runtime */ "./node_modules/react/jsx-runtime.js");\n\n\n\n\n\n\n\n\n\n\n\nvar Fragment = react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__.Fragment;\nfunction jsx(type, props, key) {\n if (!_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.h.call(props, \'css\')) {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__.jsx)(type, props, key);\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__.jsx)(_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.E, (0,_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.c)(type, props), key);\n}\nfunction jsxs(type, props, key) {\n if (!_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.h.call(props, \'css\')) {\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxs)(type, props, key);\n }\n\n return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxs)(_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.E, (0,_dist_emotion_element_cbed451f_browser_esm_js__WEBPACK_IMPORTED_MODULE_8__.c)(type, props), key);\n}\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/react/jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js?')},"./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"serializeStyles\": () => (/* binding */ serializeStyles)\n/* harmony export */ });\n/* harmony import */ var _emotion_hash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @emotion/hash */ \"./node_modules/@emotion/hash/dist/hash.browser.esm.js\");\n/* harmony import */ var _emotion_unitless__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @emotion/unitless */ \"./node_modules/@emotion/unitless/dist/unitless.browser.esm.js\");\n/* harmony import */ var _emotion_memoize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @emotion/memoize */ \"./node_modules/@emotion/memoize/dist/emotion-memoize.browser.esm.js\");\n\n\n\n\nvar ILLEGAL_ESCAPE_SEQUENCE_ERROR = \"You have illegal escape sequence in your template literal, most likely inside content's property value.\\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \\\"content: '\\\\00d7';\\\" should become \\\"content: '\\\\\\\\00d7';\\\".\\nYou can read more about this here:\\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences\";\nvar UNDEFINED_AS_OBJECT_KEY_ERROR = \"You have passed in falsy value as style object's key (can happen when in example you pass unexported component as computed key).\";\nvar hyphenateRegex = /[A-Z]|^ms/g;\nvar animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g;\n\nvar isCustomProperty = function isCustomProperty(property) {\n return property.charCodeAt(1) === 45;\n};\n\nvar isProcessableValue = function isProcessableValue(value) {\n return value != null && typeof value !== 'boolean';\n};\n\nvar processStyleName = /* #__PURE__ */(0,_emotion_memoize__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(function (styleName) {\n return isCustomProperty(styleName) ? styleName : styleName.replace(hyphenateRegex, '-$&').toLowerCase();\n});\n\nvar processStyleValue = function processStyleValue(key, value) {\n switch (key) {\n case 'animation':\n case 'animationName':\n {\n if (typeof value === 'string') {\n return value.replace(animationRegex, function (match, p1, p2) {\n cursor = {\n name: p1,\n styles: p2,\n next: cursor\n };\n return p1;\n });\n }\n }\n }\n\n if (_emotion_unitless__WEBPACK_IMPORTED_MODULE_1__[\"default\"][key] !== 1 && !isCustomProperty(key) && typeof value === 'number' && value !== 0) {\n return value + 'px';\n }\n\n return value;\n};\n\nif (true) {\n var contentValuePattern = /(var|attr|counters?|url|(((repeating-)?(linear|radial))|conic)-gradient)\\(|(no-)?(open|close)-quote/;\n var contentValues = ['normal', 'none', 'initial', 'inherit', 'unset'];\n var oldProcessStyleValue = processStyleValue;\n var msPattern = /^-ms-/;\n var hyphenPattern = /-(.)/g;\n var hyphenatedCache = {};\n\n processStyleValue = function processStyleValue(key, value) {\n if (key === 'content') {\n if (typeof value !== 'string' || contentValues.indexOf(value) === -1 && !contentValuePattern.test(value) && (value.charAt(0) !== value.charAt(value.length - 1) || value.charAt(0) !== '\"' && value.charAt(0) !== \"'\")) {\n throw new Error(\"You seem to be using a value for 'content' without quotes, try replacing it with `content: '\\\"\" + value + \"\\\"'`\");\n }\n }\n\n var processed = oldProcessStyleValue(key, value);\n\n if (processed !== '' && !isCustomProperty(key) && key.indexOf('-') !== -1 && hyphenatedCache[key] === undefined) {\n hyphenatedCache[key] = true;\n console.error(\"Using kebab-case for css properties in objects is not supported. Did you mean \" + key.replace(msPattern, 'ms-').replace(hyphenPattern, function (str, _char) {\n return _char.toUpperCase();\n }) + \"?\");\n }\n\n return processed;\n };\n}\n\nvar noComponentSelectorMessage = 'Component selectors can only be used in conjunction with ' + '@emotion/babel-plugin, the swc Emotion plugin, or another Emotion-aware ' + 'compiler transform.';\n\nfunction handleInterpolation(mergedProps, registered, interpolation) {\n if (interpolation == null) {\n return '';\n }\n\n if (interpolation.__emotion_styles !== undefined) {\n if ( true && interpolation.toString() === 'NO_COMPONENT_SELECTOR') {\n throw new Error(noComponentSelectorMessage);\n }\n\n return interpolation;\n }\n\n switch (typeof interpolation) {\n case 'boolean':\n {\n return '';\n }\n\n case 'object':\n {\n if (interpolation.anim === 1) {\n cursor = {\n name: interpolation.name,\n styles: interpolation.styles,\n next: cursor\n };\n return interpolation.name;\n }\n\n if (interpolation.styles !== undefined) {\n var next = interpolation.next;\n\n if (next !== undefined) {\n // not the most efficient thing ever but this is a pretty rare case\n // and there will be very few iterations of this generally\n while (next !== undefined) {\n cursor = {\n name: next.name,\n styles: next.styles,\n next: cursor\n };\n next = next.next;\n }\n }\n\n var styles = interpolation.styles + \";\";\n\n if ( true && interpolation.map !== undefined) {\n styles += interpolation.map;\n }\n\n return styles;\n }\n\n return createStringFromObject(mergedProps, registered, interpolation);\n }\n\n case 'function':\n {\n if (mergedProps !== undefined) {\n var previousCursor = cursor;\n var result = interpolation(mergedProps);\n cursor = previousCursor;\n return handleInterpolation(mergedProps, registered, result);\n } else if (true) {\n console.error('Functions that are interpolated in css calls will be stringified.\\n' + 'If you want to have a css call based on props, create a function that returns a css call like this\\n' + 'let dynamicStyle = (props) => css`color: ${props.color}`\\n' + 'It can be called directly with props or interpolated in a styled call like this\\n' + \"let SomeComponent = styled('div')`${dynamicStyle}`\");\n }\n\n break;\n }\n\n case 'string':\n if (true) {\n var matched = [];\n var replaced = interpolation.replace(animationRegex, function (match, p1, p2) {\n var fakeVarName = \"animation\" + matched.length;\n matched.push(\"const \" + fakeVarName + \" = keyframes`\" + p2.replace(/^@keyframes animation-\\w+/, '') + \"`\");\n return \"${\" + fakeVarName + \"}\";\n });\n\n if (matched.length) {\n console.error('`keyframes` output got interpolated into plain string, please wrap it with `css`.\\n\\n' + 'Instead of doing this:\\n\\n' + [].concat(matched, [\"`\" + replaced + \"`\"]).join('\\n') + '\\n\\nYou should wrap it with `css` like this:\\n\\n' + (\"css`\" + replaced + \"`\"));\n }\n }\n\n break;\n } // finalize string values (regular strings and functions interpolated into css calls)\n\n\n if (registered == null) {\n return interpolation;\n }\n\n var cached = registered[interpolation];\n return cached !== undefined ? cached : interpolation;\n}\n\nfunction createStringFromObject(mergedProps, registered, obj) {\n var string = '';\n\n if (Array.isArray(obj)) {\n for (var i = 0; i < obj.length; i++) {\n string += handleInterpolation(mergedProps, registered, obj[i]) + \";\";\n }\n } else {\n for (var _key in obj) {\n var value = obj[_key];\n\n if (typeof value !== 'object') {\n if (registered != null && registered[value] !== undefined) {\n string += _key + \"{\" + registered[value] + \"}\";\n } else if (isProcessableValue(value)) {\n string += processStyleName(_key) + \":\" + processStyleValue(_key, value) + \";\";\n }\n } else {\n if (_key === 'NO_COMPONENT_SELECTOR' && \"development\" !== 'production') {\n throw new Error(noComponentSelectorMessage);\n }\n\n if (Array.isArray(value) && typeof value[0] === 'string' && (registered == null || registered[value[0]] === undefined)) {\n for (var _i = 0; _i < value.length; _i++) {\n if (isProcessableValue(value[_i])) {\n string += processStyleName(_key) + \":\" + processStyleValue(_key, value[_i]) + \";\";\n }\n }\n } else {\n var interpolated = handleInterpolation(mergedProps, registered, value);\n\n switch (_key) {\n case 'animation':\n case 'animationName':\n {\n string += processStyleName(_key) + \":\" + interpolated + \";\";\n break;\n }\n\n default:\n {\n if ( true && _key === 'undefined') {\n console.error(UNDEFINED_AS_OBJECT_KEY_ERROR);\n }\n\n string += _key + \"{\" + interpolated + \"}\";\n }\n }\n }\n }\n }\n }\n\n return string;\n}\n\nvar labelPattern = /label:\\s*([^\\s;\\n{]+)\\s*(;|$)/g;\nvar sourceMapPattern;\n\nif (true) {\n sourceMapPattern = /\\/\\*#\\ssourceMappingURL=data:application\\/json;\\S+\\s+\\*\\//g;\n} // this is the cursor for keyframes\n// keyframes are stored on the SerializedStyles object as a linked list\n\n\nvar cursor;\nvar serializeStyles = function serializeStyles(args, registered, mergedProps) {\n if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && args[0].styles !== undefined) {\n return args[0];\n }\n\n var stringMode = true;\n var styles = '';\n cursor = undefined;\n var strings = args[0];\n\n if (strings == null || strings.raw === undefined) {\n stringMode = false;\n styles += handleInterpolation(mergedProps, registered, strings);\n } else {\n if ( true && strings[0] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles += strings[0];\n } // we start at 1 since we've already handled the first arg\n\n\n for (var i = 1; i < args.length; i++) {\n styles += handleInterpolation(mergedProps, registered, args[i]);\n\n if (stringMode) {\n if ( true && strings[i] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles += strings[i];\n }\n }\n\n var sourceMap;\n\n if (true) {\n styles = styles.replace(sourceMapPattern, function (match) {\n sourceMap = match;\n return '';\n });\n } // using a global regex with .exec is stateful so lastIndex has to be reset each time\n\n\n labelPattern.lastIndex = 0;\n var identifierName = '';\n var match; // https://esbench.com/bench/5b809c2cf2949800a0f61fb5\n\n while ((match = labelPattern.exec(styles)) !== null) {\n identifierName += '-' + // $FlowFixMe we know it's not null\n match[1];\n }\n\n var name = (0,_emotion_hash__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(styles) + identifierName;\n\n if (true) {\n // $FlowFixMe SerializedStyles type doesn't have toString property (and we don't want to add it)\n return {\n name: name,\n styles: styles,\n map: sourceMap,\n next: cursor,\n toString: function toString() {\n return \"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop).\";\n }\n };\n }\n\n return {\n name: name,\n styles: styles,\n next: cursor\n };\n};\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js?")},"./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"StyleSheet\": () => (/* binding */ StyleSheet)\n/* harmony export */ });\n/*\n\nBased off glamor's StyleSheet, thanks Sunil ❤️\n\nhigh performance StyleSheet for css-in-js systems\n\n- uses multiple style tags behind the scenes for millions of rules\n- uses `insertRule` for appending in production for *much* faster performance\n\n// usage\n\nimport { StyleSheet } from '@emotion/sheet'\n\nlet styleSheet = new StyleSheet({ key: '', container: document.head })\n\nstyleSheet.insert('#box { border: 1px solid red; }')\n- appends a css rule into the stylesheet\n\nstyleSheet.flush()\n- empties the stylesheet of all its contents\n\n*/\n// $FlowFixMe\nfunction sheetForTag(tag) {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet;\n } // this weirdness brought to you by firefox\n\n /* istanbul ignore next */\n\n\n for (var i = 0; i < document.styleSheets.length; i++) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i];\n }\n }\n}\n\nfunction createStyleElement(options) {\n var tag = document.createElement('style');\n tag.setAttribute('data-emotion', options.key);\n\n if (options.nonce !== undefined) {\n tag.setAttribute('nonce', options.nonce);\n }\n\n tag.appendChild(document.createTextNode(''));\n tag.setAttribute('data-s', '');\n return tag;\n}\n\nvar StyleSheet = /*#__PURE__*/function () {\n // Using Node instead of HTMLElement since container may be a ShadowRoot\n function StyleSheet(options) {\n var _this = this;\n\n this._insertTag = function (tag) {\n var before;\n\n if (_this.tags.length === 0) {\n if (_this.insertionPoint) {\n before = _this.insertionPoint.nextSibling;\n } else if (_this.prepend) {\n before = _this.container.firstChild;\n } else {\n before = _this.before;\n }\n } else {\n before = _this.tags[_this.tags.length - 1].nextSibling;\n }\n\n _this.container.insertBefore(tag, before);\n\n _this.tags.push(tag);\n };\n\n this.isSpeedy = options.speedy === undefined ? \"development\" === 'production' : options.speedy;\n this.tags = [];\n this.ctr = 0;\n this.nonce = options.nonce; // key is the value of the data-emotion attribute, it's used to identify different sheets\n\n this.key = options.key;\n this.container = options.container;\n this.prepend = options.prepend;\n this.insertionPoint = options.insertionPoint;\n this.before = null;\n }\n\n var _proto = StyleSheet.prototype;\n\n _proto.hydrate = function hydrate(nodes) {\n nodes.forEach(this._insertTag);\n };\n\n _proto.insert = function insert(rule) {\n // the max length is how many rules we have per style tag, it's 65000 in speedy mode\n // it's 1 in dev because we insert source maps that map a single rule to a location\n // and you can only have one source map per style tag\n if (this.ctr % (this.isSpeedy ? 65000 : 1) === 0) {\n this._insertTag(createStyleElement(this));\n }\n\n var tag = this.tags[this.tags.length - 1];\n\n if (true) {\n var isImportRule = rule.charCodeAt(0) === 64 && rule.charCodeAt(1) === 105;\n\n if (isImportRule && this._alreadyInsertedOrderInsensitiveRule) {\n // this would only cause problem in speedy mode\n // but we don't want enabling speedy to affect the observable behavior\n // so we report this error at all times\n console.error(\"You're attempting to insert the following rule:\\n\" + rule + '\\n\\n`@import` rules must be before all other types of rules in a stylesheet but other rules have already been inserted. Please ensure that `@import` rules are before all other rules.');\n }\n this._alreadyInsertedOrderInsensitiveRule = this._alreadyInsertedOrderInsensitiveRule || !isImportRule;\n }\n\n if (this.isSpeedy) {\n var sheet = sheetForTag(tag);\n\n try {\n // this is the ultrafast version, works across browsers\n // the big drawback is that the css won't be editable in devtools\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch (e) {\n if ( true && !/:(-moz-placeholder|-moz-focus-inner|-moz-focusring|-ms-input-placeholder|-moz-read-write|-moz-read-only|-ms-clear){/.test(rule)) {\n console.error(\"There was a problem inserting the following rule: \\\"\" + rule + \"\\\"\", e);\n }\n }\n } else {\n tag.appendChild(document.createTextNode(rule));\n }\n\n this.ctr++;\n };\n\n _proto.flush = function flush() {\n // $FlowFixMe\n this.tags.forEach(function (tag) {\n return tag.parentNode && tag.parentNode.removeChild(tag);\n });\n this.tags = [];\n this.ctr = 0;\n\n if (true) {\n this._alreadyInsertedOrderInsensitiveRule = false;\n }\n };\n\n return StyleSheet;\n}();\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js?")},"./node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('var react__WEBPACK_IMPORTED_MODULE_1___namespace_cache;\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");\n/* harmony import */ var _emotion_is_prop_valid__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @emotion/is-prop-valid */ "./node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.browser.esm.js");\n/* harmony import */ var _emotion_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @emotion/react */ "./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js");\n/* harmony import */ var _emotion_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @emotion/utils */ "./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js");\n/* harmony import */ var _emotion_serialize__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @emotion/serialize */ "./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js");\n\n\n\n\n\n\n\n\nvar testOmitPropsOnStringTag = _emotion_is_prop_valid__WEBPACK_IMPORTED_MODULE_2__["default"];\n\nvar testOmitPropsOnComponent = function testOmitPropsOnComponent(key) {\n return key !== \'theme\';\n};\n\nvar getDefaultShouldForwardProp = function getDefaultShouldForwardProp(tag) {\n return typeof tag === \'string\' && // 96 is one less than the char code\n // for "a" so this is checking that\n // it\'s a lowercase character\n tag.charCodeAt(0) > 96 ? testOmitPropsOnStringTag : testOmitPropsOnComponent;\n};\nvar composeShouldForwardProps = function composeShouldForwardProps(tag, options, isReal) {\n var shouldForwardProp;\n\n if (options) {\n var optionsShouldForwardProp = options.shouldForwardProp;\n shouldForwardProp = tag.__emotion_forwardProp && optionsShouldForwardProp ? function (propName) {\n return tag.__emotion_forwardProp(propName) && optionsShouldForwardProp(propName);\n } : optionsShouldForwardProp;\n }\n\n if (typeof shouldForwardProp !== \'function\' && isReal) {\n shouldForwardProp = tag.__emotion_forwardProp;\n }\n\n return shouldForwardProp;\n};\n\nvar useInsertionEffect = /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_1__, 2)))[\'useInsertion\' + \'Effect\'] ? /*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_1__, 2)))[\'useInsertion\' + \'Effect\'] : function useInsertionEffect(create) {\n create();\n};\nfunction useInsertionEffectMaybe(create) {\n\n useInsertionEffect(create);\n}\n\nvar ILLEGAL_ESCAPE_SEQUENCE_ERROR = "You have illegal escape sequence in your template literal, most likely inside content\'s property value.\\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \\"content: \'\\\\00d7\';\\" should become \\"content: \'\\\\\\\\00d7\';\\".\\nYou can read more about this here:\\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences";\n\nvar Insertion = function Insertion(_ref) {\n var cache = _ref.cache,\n serialized = _ref.serialized,\n isStringTag = _ref.isStringTag;\n (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_3__.registerStyles)(cache, serialized, isStringTag);\n var rules = useInsertionEffectMaybe(function () {\n return (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_3__.insertStyles)(cache, serialized, isStringTag);\n });\n\n return null;\n};\n\nvar createStyled = function createStyled(tag, options) {\n if (true) {\n if (tag === undefined) {\n throw new Error(\'You are trying to create a styled element with an undefined component.\\nYou may have forgotten to import it.\');\n }\n }\n\n var isReal = tag.__emotion_real === tag;\n var baseTag = isReal && tag.__emotion_base || tag;\n var identifierName;\n var targetClassName;\n\n if (options !== undefined) {\n identifierName = options.label;\n targetClassName = options.target;\n }\n\n var shouldForwardProp = composeShouldForwardProps(tag, options, isReal);\n var defaultShouldForwardProp = shouldForwardProp || getDefaultShouldForwardProp(baseTag);\n var shouldUseAs = !defaultShouldForwardProp(\'as\');\n return function () {\n var args = arguments;\n var styles = isReal && tag.__emotion_styles !== undefined ? tag.__emotion_styles.slice(0) : [];\n\n if (identifierName !== undefined) {\n styles.push("label:" + identifierName + ";");\n }\n\n if (args[0] == null || args[0].raw === undefined) {\n styles.push.apply(styles, args);\n } else {\n if ( true && args[0][0] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles.push(args[0][0]);\n var len = args.length;\n var i = 1;\n\n for (; i < len; i++) {\n if ( true && args[0][i] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles.push(args[i], args[0][i]);\n }\n } // $FlowFixMe: we need to cast StatelessFunctionalComponent to our PrivateStyledComponent class\n\n\n var Styled = (0,_emotion_react__WEBPACK_IMPORTED_MODULE_5__.w)(function (props, cache, ref) {\n var FinalTag = shouldUseAs && props.as || baseTag;\n var className = \'\';\n var classInterpolations = [];\n var mergedProps = props;\n\n if (props.theme == null) {\n mergedProps = {};\n\n for (var key in props) {\n mergedProps[key] = props[key];\n }\n\n mergedProps.theme = (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(_emotion_react__WEBPACK_IMPORTED_MODULE_5__.T);\n }\n\n if (typeof props.className === \'string\') {\n className = (0,_emotion_utils__WEBPACK_IMPORTED_MODULE_3__.getRegisteredStyles)(cache.registered, classInterpolations, props.className);\n } else if (props.className != null) {\n className = props.className + " ";\n }\n\n var serialized = (0,_emotion_serialize__WEBPACK_IMPORTED_MODULE_4__.serializeStyles)(styles.concat(classInterpolations), cache.registered, mergedProps);\n className += cache.key + "-" + serialized.name;\n\n if (targetClassName !== undefined) {\n className += " " + targetClassName;\n }\n\n var finalShouldForwardProp = shouldUseAs && shouldForwardProp === undefined ? getDefaultShouldForwardProp(FinalTag) : defaultShouldForwardProp;\n var newProps = {};\n\n for (var _key in props) {\n if (shouldUseAs && _key === \'as\') continue;\n\n if ( // $FlowFixMe\n finalShouldForwardProp(_key)) {\n newProps[_key] = props[_key];\n }\n }\n\n newProps.className = className;\n newProps.ref = ref;\n return /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.createElement)(react__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.createElement)(Insertion, {\n cache: cache,\n serialized: serialized,\n isStringTag: typeof FinalTag === \'string\'\n }), /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.createElement)(FinalTag, newProps));\n });\n Styled.displayName = identifierName !== undefined ? identifierName : "Styled(" + (typeof baseTag === \'string\' ? baseTag : baseTag.displayName || baseTag.name || \'Component\') + ")";\n Styled.defaultProps = tag.defaultProps;\n Styled.__emotion_real = Styled;\n Styled.__emotion_base = baseTag;\n Styled.__emotion_styles = styles;\n Styled.__emotion_forwardProp = shouldForwardProp;\n Object.defineProperty(Styled, \'toString\', {\n value: function value() {\n if (targetClassName === undefined && "development" !== \'production\') {\n return \'NO_COMPONENT_SELECTOR\';\n } // $FlowFixMe: coerce undefined to string\n\n\n return "." + targetClassName;\n }\n });\n\n Styled.withComponent = function (nextTag, nextOptions) {\n return createStyled(nextTag, (0,_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, nextOptions, {\n shouldForwardProp: composeShouldForwardProps(Styled, nextOptions, true)\n })).apply(void 0, styles);\n };\n\n return Styled;\n };\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createStyled);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js?')},"./node_modules/@emotion/styled/dist/emotion-styled.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/extends */ \"./node_modules/@babel/runtime/helpers/esm/extends.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var _emotion_is_prop_valid__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @emotion/is-prop-valid */ \"./node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.browser.esm.js\");\n/* harmony import */ var _base_dist_emotion_styled_base_browser_esm_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base/dist/emotion-styled-base.browser.esm.js */ \"./node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js\");\n/* harmony import */ var _emotion_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @emotion/utils */ \"./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js\");\n/* harmony import */ var _emotion_serialize__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @emotion/serialize */ \"./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js\");\n\n\n\n\n\n\n\n\nvar tags = ['a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr', // SVG\n'circle', 'clipPath', 'defs', 'ellipse', 'foreignObject', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg', 'text', 'tspan'];\n\nvar newStyled = _base_dist_emotion_styled_base_browser_esm_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"].bind();\ntags.forEach(function (tagName) {\n // $FlowFixMe: we can ignore this because its exposed type is defined by the CreateStyled type\n newStyled[tagName] = newStyled(tagName);\n});\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (newStyled);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/styled/dist/emotion-styled.browser.esm.js?")},"./node_modules/@emotion/unitless/dist/unitless.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nvar unitlessKeys = {\n animationIterationCount: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (unitlessKeys);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/unitless/dist/unitless.browser.esm.js?')},"./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "getRegisteredStyles": () => (/* binding */ getRegisteredStyles),\n/* harmony export */ "insertStyles": () => (/* binding */ insertStyles),\n/* harmony export */ "registerStyles": () => (/* binding */ registerStyles)\n/* harmony export */ });\nvar isBrowser = "object" !== \'undefined\';\nfunction getRegisteredStyles(registered, registeredStyles, classNames) {\n var rawClassName = \'\';\n classNames.split(\' \').forEach(function (className) {\n if (registered[className] !== undefined) {\n registeredStyles.push(registered[className] + ";");\n } else {\n rawClassName += className + " ";\n }\n });\n return rawClassName;\n}\nvar registerStyles = function registerStyles(cache, serialized, isStringTag) {\n var className = cache.key + "-" + serialized.name;\n\n if ( // we only need to add the styles to the registered cache if the\n // class name could be used further down\n // the tree but if it\'s a string tag, we know it won\'t\n // so we don\'t have to add it to registered cache.\n // this improves memory usage since we can avoid storing the whole style string\n (isStringTag === false || // we need to always store it if we\'re in compat mode and\n // in node since emotion-server relies on whether a style is in\n // the registered cache to know whether a style is global or not\n // also, note that this check will be dead code eliminated in the browser\n isBrowser === false ) && cache.registered[className] === undefined) {\n cache.registered[className] = serialized.styles;\n }\n};\nvar insertStyles = function insertStyles(cache, serialized, isStringTag) {\n registerStyles(cache, serialized, isStringTag);\n var className = cache.key + "-" + serialized.name;\n\n if (cache.inserted[serialized.name] === undefined) {\n var current = serialized;\n\n do {\n var maybeStyles = cache.insert(serialized === current ? "." + className : \'\', current, cache.sheet, true);\n\n current = current.next;\n } while (current !== undefined);\n }\n};\n\n\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js?')},"./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nvar weakMemoize = function weakMemoize(func) {\n // $FlowFixMe flow doesn\'t include all non-primitive types as allowed for weakmaps\n var cache = new WeakMap();\n return function (arg) {\n if (cache.has(arg)) {\n // $FlowFixMe\n return cache.get(arg);\n }\n\n var ret = func(arg);\n cache.set(arg, ret);\n return ret;\n };\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (weakMemoize);\n\n\n//# sourceURL=webpack://frontend/./node_modules/@emotion/weak-memoize/dist/weak-memoize.browser.esm.js?')},"./node_modules/@material-ui/core/esm/Button/Button.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"styles\": () => (/* binding */ styles)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_esm_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/objectWithoutProperties */ \"./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js\");\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ \"./node_modules/@babel/runtime/helpers/esm/extends.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! clsx */ \"./node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _styles_withStyles__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../styles/withStyles */ \"./node_modules/@material-ui/core/esm/styles/withStyles.js\");\n/* harmony import */ var _styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../styles/colorManipulator */ \"./node_modules/@material-ui/core/esm/styles/colorManipulator.js\");\n/* harmony import */ var _ButtonBase__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../ButtonBase */ \"./node_modules/@material-ui/core/esm/ButtonBase/ButtonBase.js\");\n/* harmony import */ var _utils_capitalize__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/capitalize */ \"./node_modules/@material-ui/core/esm/utils/capitalize.js\");\n\n\n\n\n\n\n\n\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: (0,_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({}, theme.typography.button, {\n boxSizing: 'border-box',\n minWidth: 64,\n padding: '6px 16px',\n borderRadius: theme.shape.borderRadius,\n color: theme.palette.text.primary,\n transition: theme.transitions.create(['background-color', 'box-shadow', 'border'], {\n duration: theme.transitions.duration.short\n }),\n '&:hover': {\n textDecoration: 'none',\n backgroundColor: (0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.text.primary, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n },\n '&$disabled': {\n backgroundColor: 'transparent'\n }\n },\n '&$disabled': {\n color: theme.palette.action.disabled\n }\n }),\n\n /* Styles applied to the span element that wraps the children. */\n label: {\n width: '100%',\n // Ensure the correct width for iOS Safari\n display: 'inherit',\n alignItems: 'inherit',\n justifyContent: 'inherit'\n },\n\n /* Styles applied to the root element if `variant=\"text\"`. */\n text: {\n padding: '6px 8px'\n },\n\n /* Styles applied to the root element if `variant=\"text\"` and `color=\"primary\"`. */\n textPrimary: {\n color: theme.palette.primary.main,\n '&:hover': {\n backgroundColor: (0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.primary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n }\n },\n\n /* Styles applied to the root element if `variant=\"text\"` and `color=\"secondary\"`. */\n textSecondary: {\n color: theme.palette.secondary.main,\n '&:hover': {\n backgroundColor: (0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.secondary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n }\n },\n\n /* Styles applied to the root element if `variant=\"outlined\"`. */\n outlined: {\n padding: '5px 15px',\n border: \"1px solid \".concat(theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'),\n '&$disabled': {\n border: \"1px solid \".concat(theme.palette.action.disabledBackground)\n }\n },\n\n /* Styles applied to the root element if `variant=\"outlined\"` and `color=\"primary\"`. */\n outlinedPrimary: {\n color: theme.palette.primary.main,\n border: \"1px solid \".concat((0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.primary.main, 0.5)),\n '&:hover': {\n border: \"1px solid \".concat(theme.palette.primary.main),\n backgroundColor: (0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.primary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n }\n },\n\n /* Styles applied to the root element if `variant=\"outlined\"` and `color=\"secondary\"`. */\n outlinedSecondary: {\n color: theme.palette.secondary.main,\n border: \"1px solid \".concat((0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.secondary.main, 0.5)),\n '&:hover': {\n border: \"1px solid \".concat(theme.palette.secondary.main),\n backgroundColor: (0,_styles_colorManipulator__WEBPACK_IMPORTED_MODULE_4__.alpha)(theme.palette.secondary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n },\n '&$disabled': {\n border: \"1px solid \".concat(theme.palette.action.disabled)\n }\n },\n\n /* Styles applied to the root element if `variant=\"contained\"`. */\n contained: {\n color: theme.palette.getContrastText(theme.palette.grey[300]),\n backgroundColor: theme.palette.grey[300],\n boxShadow: theme.shadows[2],\n '&:hover': {\n backgroundColor: theme.palette.grey.A100,\n boxShadow: theme.shadows[4],\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n boxShadow: theme.shadows[2],\n backgroundColor: theme.palette.grey[300]\n },\n '&$disabled': {\n backgroundColor: theme.palette.action.disabledBackground\n }\n },\n '&$focusVisible': {\n boxShadow: theme.shadows[6]\n },\n '&:active': {\n boxShadow: theme.shadows[8]\n },\n '&$disabled': {\n color: theme.palette.action.disabled,\n boxShadow: theme.shadows[0],\n backgroundColor: theme.palette.action.disabledBackground\n }\n },\n\n /* Styles applied to the root element if `variant=\"contained\"` and `color=\"primary\"`. */\n containedPrimary: {\n color: theme.palette.primary.contrastText,\n backgroundColor: theme.palette.primary.main,\n '&:hover': {\n backgroundColor: theme.palette.primary.dark,\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: theme.palette.primary.main\n }\n }\n },\n\n /* Styles applied to the root element if `variant=\"contained\"` and `color=\"secondary\"`. */\n containedSecondary: {\n color: theme.palette.secondary.contrastText,\n backgroundColor: theme.palette.secondary.main,\n '&:hover': {\n backgroundColor: theme.palette.secondary.dark,\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: theme.palette.secondary.main\n }\n }\n },\n\n /* Styles applied to the root element if `disableElevation={true}`. */\n disableElevation: {\n boxShadow: 'none',\n '&:hover': {\n boxShadow: 'none'\n },\n '&$focusVisible': {\n boxShadow: 'none'\n },\n '&:active': {\n boxShadow: 'none'\n },\n '&$disabled': {\n boxShadow: 'none'\n }\n },\n\n /* Pseudo-class applied to the ButtonBase root element if the button is keyboard focused. */\n focusVisible: {},\n\n /* Pseudo-class applied to the root element if `disabled={true}`. */\n disabled: {},\n\n /* Styles applied to the root element if `color=\"inherit\"`. */\n colorInherit: {\n color: 'inherit',\n borderColor: 'currentColor'\n },\n\n /* Styles applied to the root element if `size=\"small\"` and `variant=\"text\"`. */\n textSizeSmall: {\n padding: '4px 5px',\n fontSize: theme.typography.pxToRem(13)\n },\n\n /* Styles applied to the root element if `size=\"large\"` and `variant=\"text\"`. */\n textSizeLarge: {\n padding: '8px 11px',\n fontSize: theme.typography.pxToRem(15)\n },\n\n /* Styles applied to the root element if `size=\"small\"` and `variant=\"outlined\"`. */\n outlinedSizeSmall: {\n padding: '3px 9px',\n fontSize: theme.typography.pxToRem(13)\n },\n\n /* Styles applied to the root element if `size=\"large\"` and `variant=\"outlined\"`. */\n outlinedSizeLarge: {\n padding: '7px 21px',\n fontSize: theme.typography.pxToRem(15)\n },\n\n /* Styles applied to the root element if `size=\"small\"` and `variant=\"contained\"`. */\n containedSizeSmall: {\n padding: '4px 10px',\n fontSize: theme.typography.pxToRem(13)\n },\n\n /* Styles applied to the root element if `size=\"large\"` and `variant=\"contained\"`. */\n containedSizeLarge: {\n padding: '8px 22px',\n fontSize: theme.typography.pxToRem(15)\n },\n\n /* Styles applied to the root element if `size=\"small\"`. */\n sizeSmall: {},\n\n /* Styles applied to the root element if `size=\"large\"`. */\n sizeLarge: {},\n\n /* Styles applied to the root element if `fullWidth={true}`. */\n fullWidth: {\n width: '100%'\n },\n\n /* Styles applied to the startIcon element if supplied. */\n startIcon: {\n display: 'inherit',\n marginRight: 8,\n marginLeft: -4,\n '&$iconSizeSmall': {\n marginLeft: -2\n }\n },\n\n /* Styles applied to the endIcon element if supplied. */\n endIcon: {\n display: 'inherit',\n marginRight: -4,\n marginLeft: 8,\n '&$iconSizeSmall': {\n marginRight: -2\n }\n },\n\n /* Styles applied to the icon element if supplied and `size=\"small\"`. */\n iconSizeSmall: {\n '& > *:first-child': {\n fontSize: 18\n }\n },\n\n /* Styles applied to the icon element if supplied and `size=\"medium\"`. */\n iconSizeMedium: {\n '& > *:first-child': {\n fontSize: 20\n }\n },\n\n /* Styles applied to the icon element if supplied and `size=\"large\"`. */\n iconSizeLarge: {\n '& > *:first-child': {\n fontSize: 22\n }\n }\n };\n};\nvar Button = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.forwardRef(function Button(props, ref) {\n var children = props.children,\n classes = props.classes,\n className = props.className,\n _props$color = props.color,\n color = _props$color === void 0 ? 'default' : _props$color,\n _props$component = props.component,\n component = _props$component === void 0 ? 'button' : _props$component,\n _props$disabled = props.disabled,\n disabled = _props$disabled === void 0 ? false : _props$disabled,\n _props$disableElevati = props.disableElevation,\n disableElevation = _props$disableElevati === void 0 ? false : _props$disableElevati,\n _props$disableFocusRi = props.disableFocusRipple,\n disableFocusRipple = _props$disableFocusRi === void 0 ? false : _props$disableFocusRi,\n endIconProp = props.endIcon,\n focusVisibleClassName = props.focusVisibleClassName,\n _props$fullWidth = props.fullWidth,\n fullWidth = _props$fullWidth === void 0 ? false : _props$fullWidth,\n _props$size = props.size,\n size = _props$size === void 0 ? 'medium' : _props$size,\n startIconProp = props.startIcon,\n _props$type = props.type,\n type = _props$type === void 0 ? 'button' : _props$type,\n _props$variant = props.variant,\n variant = _props$variant === void 0 ? 'text' : _props$variant,\n other = (0,_babel_runtime_helpers_esm_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(props, [\"children\", \"classes\", \"className\", \"color\", \"component\", \"disabled\", \"disableElevation\", \"disableFocusRipple\", \"endIcon\", \"focusVisibleClassName\", \"fullWidth\", \"size\", \"startIcon\", \"type\", \"variant\"]);\n\n var startIcon = startIconProp && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.createElement(\"span\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(classes.startIcon, classes[\"iconSize\".concat((0,_utils_capitalize__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(size))])\n }, startIconProp);\n var endIcon = endIconProp && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.createElement(\"span\", {\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(classes.endIcon, classes[\"iconSize\".concat((0,_utils_capitalize__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(size))])\n }, endIconProp);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.createElement(_ButtonBase__WEBPACK_IMPORTED_MODULE_6__[\"default\"], (0,_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(classes.root, classes[variant], className, color === 'inherit' ? classes.colorInherit : color !== 'default' && classes[\"\".concat(variant).concat((0,_utils_capitalize__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(color))], size !== 'medium' && [classes[\"\".concat(variant, \"Size\").concat((0,_utils_capitalize__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(size))], classes[\"size\".concat((0,_utils_capitalize__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(size))]], disableElevation && classes.disableElevation, disabled && classes.disabled, fullWidth && classes.fullWidth),\n component: component,\n disabled: disabled,\n focusRipple: !disableFocusRipple,\n focusVisibleClassName: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(classes.focusVisible, focusVisibleClassName),\n ref: ref,\n type: type\n }, other), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.createElement(\"span\", {\n className: classes.label\n }, startIcon, children, endIcon));\n});\n true ? Button.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the d.ts file and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n\n /**\n * The content of the button.\n */\n children: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().node),\n\n /**\n * Override or extend the styles applied to the component.\n * See [CSS API](#css) below for more details.\n */\n classes: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().object),\n\n /**\n * @ignore\n */\n className: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().string),\n\n /**\n * The color of the component. It supports those theme colors that make sense for this component.\n */\n color: prop_types__WEBPACK_IMPORTED_MODULE_7___default().oneOf(['default', 'inherit', 'primary', 'secondary']),\n\n /**\n * The component used for the root node.\n * Either a string to use a HTML element or a component.\n */\n component: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().elementType),\n\n /**\n * If `true`, the button will be disabled.\n */\n disabled: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().bool),\n\n /**\n * If `true`, no elevation is used.\n */\n disableElevation: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().bool),\n\n /**\n * If `true`, the keyboard focus ripple will be disabled.\n */\n disableFocusRipple: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().bool),\n\n /**\n * If `true`, the ripple effect will be disabled.\n *\n * ⚠️ Without a ripple there is no styling for :focus-visible by default. Be sure\n * to highlight the element by applying separate styles with the `focusVisibleClassName`.\n */\n disableRipple: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().bool),\n\n /**\n * Element placed after the children.\n */\n endIcon: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().node),\n\n /**\n * @ignore\n */\n focusVisibleClassName: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().string),\n\n /**\n * If `true`, the button will take up the full width of its container.\n */\n fullWidth: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().bool),\n\n /**\n * The URL to link to when the button is clicked.\n * If defined, an `a` element will be used as the root node.\n */\n href: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().string),\n\n /**\n * The size of the button.\n * `small` is equivalent to the dense button styling.\n */\n size: prop_types__WEBPACK_IMPORTED_MODULE_7___default().oneOf(['large', 'medium', 'small']),\n\n /**\n * Element placed before the children.\n */\n startIcon: (prop_types__WEBPACK_IMPORTED_MODULE_7___default().node),\n\n /**\n * @ignore\n */\n type: prop_types__WEBPACK_IMPORTED_MODULE_7___default().oneOfType([prop_types__WEBPACK_IMPORTED_MODULE_7___default().oneOf(['button', 'reset', 'submit']), (prop_types__WEBPACK_IMPORTED_MODULE_7___default().string)]),\n\n /**\n * The variant to use.\n */\n variant: prop_types__WEBPACK_IMPORTED_MODULE_7___default().oneOf(['contained', 'outlined', 'text'])\n} : 0;\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,_styles_withStyles__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(styles, {\n name: 'MuiButton'\n})(Button));\n\n//# sourceURL=webpack://frontend/./node_modules/@material-ui/core/esm/Button/Button.js?")},"./node_modules/@material-ui/core/esm/ButtonBase/ButtonBase.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ "styles": () => (/* binding */ styles)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js");\n/* harmony import */ var _babel_runtime_helpers_esm_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/esm/objectWithoutProperties */ "./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! prop-types */ "./node_modules/prop-types/index.js");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ "./node_modules/clsx/dist/clsx.m.js");\n/* harmony import */ var _material_ui_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @material-ui/utils */ "./node_modules/@material-ui/utils/esm/refType.js");\n/* harmony import */ var _material_ui_utils__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @material-ui/utils */ "./node_modules/@material-ui/utils/esm/elementTypeAcceptingRef.js");\n/* harmony import */ var _utils_useForkRef__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/useForkRef */ "./node_modules/@material-ui/core/esm/utils/useForkRef.js");\n/* harmony import */ var _utils_useEventCallback__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/useEventCallback */ "./node_modules/@material-ui/core/esm/utils/useEventCallback.js");\n/* harmony import */ var _utils_deprecatedPropType__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/deprecatedPropType */ "./node_modules/@material-ui/core/esm/utils/deprecatedPropType.js");\n/* harmony import */ var _styles_withStyles__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../styles/withStyles */ "./node_modules/@material-ui/core/esm/styles/withStyles.js");\n/* harmony import */ var _utils_useIsFocusVisible__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/useIsFocusVisible */ "./node_modules/@material-ui/core/esm/utils/useIsFocusVisible.js");\n/* harmony import */ var _TouchRipple__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./TouchRipple */ "./node_modules/@material-ui/core/esm/ButtonBase/TouchRipple.js");\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar styles = {\n /* Styles applied to the root element. */\n root: {\n display: \'inline-flex\',\n alignItems: \'center\',\n justifyContent: \'center\',\n position: \'relative\',\n WebkitTapHighlightColor: \'transparent\',\n backgroundColor: \'transparent\',\n // Reset default value\n // We disable the focus ring for mouse, touch and keyboard users.\n outline: 0,\n border: 0,\n margin: 0,\n // Remove the margin in Safari\n borderRadius: 0,\n padding: 0,\n // Remove the padding in Firefox\n cursor: \'pointer\',\n userSelect: \'none\',\n verticalAlign: \'middle\',\n \'-moz-appearance\': \'none\',\n // Reset\n \'-webkit-appearance\': \'none\',\n // Reset\n textDecoration: \'none\',\n // So we take precedent over the style of a native element.\n color: \'inherit\',\n \'&::-moz-focus-inner\': {\n borderStyle: \'none\' // Remove Firefox dotted outline.\n\n },\n \'&$disabled\': {\n pointerEvents: \'none\',\n // Disable link interactions\n cursor: \'default\'\n },\n \'@media print\': {\n colorAdjust: \'exact\'\n }\n },\n\n /* Pseudo-class applied to the root element if `disabled={true}`. */\n disabled: {},\n\n /* Pseudo-class applied to the root element if keyboard focused. */\n focusVisible: {}\n};\n/**\n * `ButtonBase` contains as few styles as possible.\n * It aims to be a simple building block for creating a button.\n * It contains a load of style reset and some focus/ripple logic.\n */\n\nvar ButtonBase = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__.forwardRef(function ButtonBase(props, ref) {\n var action = props.action,\n buttonRefProp = props.buttonRef,\n _props$centerRipple = props.centerRipple,\n centerRipple = _props$centerRipple === void 0 ? false : _props$centerRipple,\n children = props.children,\n classes = props.classes,\n className = props.className,\n _props$component = props.component,\n component = _props$component === void 0 ? \'button\' : _props$component,\n _props$disabled = props.disabled,\n disabled = _props$disabled === void 0 ? false : _props$disabled,\n _props$disableRipple = props.disableRipple,\n disableRipple = _props$disableRipple === void 0 ? false : _props$disableRipple,\n _props$disableTouchRi = props.disableTouchRipple,\n disableTouchRipple = _props$disableTouchRi === void 0 ? false : _props$disableTouchRi,\n _props$focusRipple = props.focusRipple,\n focusRipple = _props$focusRipple === void 0 ? false : _props$focusRipple,\n focusVisibleClassName = props.focusVisibleClassName,\n onBlur = props.onBlur,\n onClick = props.onClick,\n onFocus = props.onFocus,\n onFocusVisible = props.onFocusVisible,\n onKeyDown = props.onKeyDown,\n onKeyUp = props.onKeyUp,\n onMouseDown = props.onMouseDown,\n onMouseLeave = props.onMouseLeave,\n onMouseUp = props.onMouseUp,\n onTouchEnd = props.onTouchEnd,\n onTouchMove = props.onTouchMove,\n onTouchStart = props.onTouchStart,\n onDragLeave = props.onDragLeave,\n _props$tabIndex = props.tabIndex,\n tabIndex = _props$tabIndex === void 0 ? 0 : _props$tabIndex,\n TouchRippleProps = props.TouchRippleProps,\n _props$type = props.type,\n type = _props$type === void 0 ? \'button\' : _props$type,\n other = (0,_babel_runtime_helpers_esm_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__["default"])(props, ["action", "buttonRef", "centerRipple", "children", "classes", "className", "component", "disabled", "disableRipple", "disableTouchRipple", "focusRipple", "focusVisibleClassName", "onBlur", "onClick", "onFocus", "onFocusVisible", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseLeave", "onMouseUp", "onTouchEnd", "onTouchMove", "onTouchStart", "onDragLeave", "tabIndex", "TouchRippleProps", "type"]);\n\n var buttonRef = react__WEBPACK_IMPORTED_MODULE_2__.useRef(null);\n\n function getButtonNode() {\n // #StrictMode ready\n return react_dom__WEBPACK_IMPORTED_MODULE_3__.findDOMNode(buttonRef.current);\n }\n\n var rippleRef = react__WEBPACK_IMPORTED_MODULE_2__.useRef(null);\n\n var _React$useState = react__WEBPACK_IMPORTED_MODULE_2__.useState(false),\n focusVisible = _React$useState[0],\n setFocusVisible = _React$useState[1];\n\n if (disabled && focusVisible) {\n setFocusVisible(false);\n }\n\n var _useIsFocusVisible = (0,_utils_useIsFocusVisible__WEBPACK_IMPORTED_MODULE_5__["default"])(),\n isFocusVisible = _useIsFocusVisible.isFocusVisible,\n onBlurVisible = _useIsFocusVisible.onBlurVisible,\n focusVisibleRef = _useIsFocusVisible.ref;\n\n react__WEBPACK_IMPORTED_MODULE_2__.useImperativeHandle(action, function () {\n return {\n focusVisible: function focusVisible() {\n setFocusVisible(true);\n buttonRef.current.focus();\n }\n };\n }, []);\n react__WEBPACK_IMPORTED_MODULE_2__.useEffect(function () {\n if (focusVisible && focusRipple && !disableRipple) {\n rippleRef.current.pulsate();\n }\n }, [disableRipple, focusRipple, focusVisible]);\n\n function useRippleHandler(rippleAction, eventCallback) {\n var skipRippleAction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : disableTouchRipple;\n return (0,_utils_useEventCallback__WEBPACK_IMPORTED_MODULE_6__["default"])(function (event) {\n if (eventCallback) {\n eventCallback(event);\n }\n\n var ignore = skipRippleAction;\n\n if (!ignore && rippleRef.current) {\n rippleRef.current[rippleAction](event);\n }\n\n return true;\n });\n }\n\n var handleMouseDown = useRippleHandler(\'start\', onMouseDown);\n var handleDragLeave = useRippleHandler(\'stop\', onDragLeave);\n var handleMouseUp = useRippleHandler(\'stop\', onMouseUp);\n var handleMouseLeave = useRippleHandler(\'stop\', function (event) {\n if (focusVisible) {\n event.preventDefault();\n }\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n });\n var handleTouchStart = useRippleHandler(\'start\', onTouchStart);\n var handleTouchEnd = useRippleHandler(\'stop\', onTouchEnd);\n var handleTouchMove = useRippleHandler(\'stop\', onTouchMove);\n var handleBlur = useRippleHandler(\'stop\', function (event) {\n if (focusVisible) {\n onBlurVisible(event);\n setFocusVisible(false);\n }\n\n if (onBlur) {\n onBlur(event);\n }\n }, false);\n var handleFocus = (0,_utils_useEventCallback__WEBPACK_IMPORTED_MODULE_6__["default"])(function (event) {\n // Fix for https://github.com/facebook/react/issues/7769\n if (!buttonRef.current) {\n buttonRef.current = event.currentTarget;\n }\n\n if (isFocusVisible(event)) {\n setFocusVisible(true);\n\n if (onFocusVisible) {\n onFocusVisible(event);\n }\n }\n\n if (onFocus) {\n onFocus(event);\n }\n });\n\n var isNonNativeButton = function isNonNativeButton() {\n var button = getButtonNode();\n return component && component !== \'button\' && !(button.tagName === \'A\' && button.href);\n };\n /**\n * IE 11 shim for https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat\n */\n\n\n var keydownRef = react__WEBPACK_IMPORTED_MODULE_2__.useRef(false);\n var handleKeyDown = (0,_utils_useEventCallback__WEBPACK_IMPORTED_MODULE_6__["default"])(function (event) {\n // Check if key is already down to avoid repeats being counted as multiple activations\n if (focusRipple && !keydownRef.current && focusVisible && rippleRef.current && event.key === \' \') {\n keydownRef.current = true;\n event.persist();\n rippleRef.current.stop(event, function () {\n rippleRef.current.start(event);\n });\n }\n\n if (event.target === event.currentTarget && isNonNativeButton() && event.key === \' \') {\n event.preventDefault();\n }\n\n if (onKeyDown) {\n onKeyDown(event);\n } // Keyboard accessibility for non interactive elements\n\n\n if (event.target === event.currentTarget && isNonNativeButton() && event.key === \'Enter\' && !disabled) {\n event.preventDefault();\n\n if (onClick) {\n onClick(event);\n }\n }\n });\n var handleKeyUp = (0,_utils_useEventCallback__WEBPACK_IMPORTED_MODULE_6__["default"])(function (event) {\n // calling preventDefault in keyUp on a