{"version":3,"sources":["NoScrollContainer.tsx","Fallback.tsx","MapContainer.tsx","checkWebglSupport.ts","Boxes.tsx","Away.tsx","constants.ts","ColorRamp.tsx","Collapsible.tsx","PlayControl.tsx","TotalTimeSeries.tsx","Timeline.tsx","matchesSearchQuery.ts","LabelsOverlay.tsx","SpinningCircles.tsx","App.tsx","useWindowResize.ts","serviceWorker.ts","index.tsx"],"names":["NoScrollContainer","styled","div","children","style","position","width","height","display","alignItems","justifyContent","flexDirection","marginTop","supportsWebGl","canvas","document","createElement","window","WebGLRenderingContext","getContext","e","checkWebglSupport","MapContainer","embed","Fallback","Column","x","spacing","padding","Row","Absolute","top","left","right","bottom","getBoxStyle","Box","NonPositionedBox","Away","href","className","target","rel","formatDefaultLocale","require","SHOW_RELATIVE","BASE_COLOR","TEXT_COLOR","SHAPE_LINE_COLOR","SHAPE_FILL_COLOR","colorAsRgba","CIRCLE_FILL_COLOR","hcl","darker","formatCount","format","queryParams","queryString","parse","location","search","substr","COUNTRY","country","ANIMATION_DURATION","LANG","lang","CONFIG","_CONFIG","MESSAGES","_MESSAGES","LOCALE","parseDate","timeParse","formatDateIso","timeFormat","formatDate","d","toLocaleDateString","month","year","shortFormatDate","DARK_MODE","dark","FOCUS_PERIOD_START_DATE","focusStartDate","REFERENCE_PERIOD_START_DATE","referenceStartDate","undefined","REFERENCE_WEEKDAY_PATTERN","referenceWeekdayPattern","INITIAL_VIEWSTATE","latitude","longitude","zoom","innerWidth","innerHeight","REF_DATE_WEEKDAYS","CONTROLLER_OPTIONS","base","type","MapController","doubleClickZoom","dragRotate","touchRotate","minZoom","maxZoom","color","c","rgb","Math","floor","r","g","b","round","opacity","flexGrow","border","marginBottom","fontWeight","borderRight","Direction","OuterSvg","svg","cursor","transition","OuterCircle","circle","strokeWidth","stroke","fill","PlayControl","playTimeout","state","isPlaying","start","props","current","end","onChange","setState","scheduleNextStep","stop","clearPlayTimeOut","clearTimeout","stepDuration","setTimeout","nextStep","timeStep","next","offset","this","autoplay","icon","transform","min","onClick","cx","cy","React","Component","TOTAL_TIME_SERIES_MARGIN","Outer","alignSelf","TinyText","text","fontSize","ZeroLine","line","DashedLine","strokeDasharray","DateText","TotalTimeSeries","data","formatValue","selected","margin","timeExtent","extent","date","timeScale","scaleTime","domain","range","valuesExtent","value","yScale","scaleLinear","max","path","y","x1","x2","y1","y2","textAnchor","strokeLinejoin","strokeLinecap","innerMargin","marginLeft","MeasureTarget","overflow","TimelineSvg","eventManager","EventManager","TimelineChart","timeInterval","minTickWidth","chartWidth","svgRef","useRef","_handleMove","evt","getBoundingClientRect","center","invert","handleMove","useEffect","setElement","on","off","ticks","tickLabels","nextTick","step","ceil","length","push","ref","Timeline","useState","dimensions","setDimensions","totalTimeSeriesData","bounds","onResize","contentRect","measureRef","Body","direction","collapsed","LEFT","Content","Rotate","degrees","Button","button","darkMode","Chevron","viewBox","LinkText","Collapsible","bodyRef","handleClick","isCollapsed","getArrow","RIGHT","collapsedView","splitIntoWords","str","toLowerCase","match","Svg","LabelG","LabelText","LabelsOverlay","countsData","viewport","sizeScale","sortedCountsData","useMemo","slice","sort","a","descending","count","index","Flatbush","textNodes","querySelectorAll","i","add","finish","toOmit","Set","has","indices","idx","mercator","WebMercatorViewport","map","project","centroid","scale","pow","name","id","reverse","SpinningCircles","fillRule","attributeName","begin","dur","values","calcMode","repeatCount","fillOpacity","defaultProps","Title","Subtitle","SelectOuter","TermsLink","MainInfoBox","rest","MainInfoBoxContent","SelectedLocationDetails","TooltipBox","MapOuter","CenterBlock","DeckGLOuter","baseMapOpacity","SelectOption","groupLevel","isGroup","fontStyle","paddingLeft","Option","isDisabled","makeDateOption","dateStr","label","dayOfWeek","getDay","getMonth","makeRefDateOption","m","RegExp","exec","indexOf","numWarns","pickRefDate","availableDates","found","desired","ref_date","reference","find","replacement","referenceDatesReplace","console","warn","JSON","stringify","join","formatCountDiff","v","isFinite","moreByCount","fewerByCount","replace","abs","formatCumulativeCountDiff","selectedDate","cumulativeMoreByCount","cumulativeFewerByCount","App","setCollapsed","size","windowSize","setWindowSize","handleResize","addEventListener","removeEventListener","useWindowSize","setViewport","isNarrowScreen","isShortScreen","fetchShapes","useFetch","geoJsonFeatures","topology","feature","objects","mapContainerRef","tooltip","setTooltip","selectedLocation","setSelectedLocation","bbox","initialViewState","fitBounds","fetchCounts","formatter","response","then","tsvParse","dateOptions","columns","ascending","filter","test","lastAvailableDate","millis","getTime","Date","locationNamesById","reduce","set","locationId","Map","datumByLocationByDate","byLocationByDate","byDate","refDate","refCount","countDiff","filterMinCount","relDiff","selectedDateOption","setSelectedDateOption","pickInitialSelectedDate","cumulativeTotalByLocation","rv","dates","entries","sum","get","refDateOption","getDefinedValues","useCallback","features","f","properties","calcTotalRelDiff","calcTotalCountDiff","total","totalDiff","diffExtent","colorScaleDomain","getShapeColor","interpolator","interpolateRgbBasis","interpolateRdYlBu","scaleSequential","clamp","negative","positive","getCountDiff","highlightColor","layers","GeoJsonLayer","stroked","filled","lineWidthUnits","getLineWidth","getLineColor","getFillColor","pickable","onHover","info","object","handleSelectLocation","locationOptionsById","circlesData","scaleSqrt","ScatterplotLayer","radiusUnits","lineWidthScale","lineWidthMinPixels","getPosition","getRadius","autoHighlight","transitions","duration","easing","easeLinear","enter","updateTriggers","locationOptions","startsWith","locationOption","viewState","turfBbox","clientWidth","clientHeight","transitionDuration","transitionInterpolator","FlyToInterpolator","transitionEasing","easeCubic","mapTransition","handleKeyDown","KeyboardEvent","key","moreBy","fewerBy","formatPercentage","cumulativeTotalDiffCount","cumulativeTotal","dangerouslySetInnerHTML","__html","svobodaReference","getMainInfoBoxContent","title","components","isOptionDisabled","options","isSearchable","isClearable","isFixed","menuPortalTarget","body","escapeClearsValue","placeholder","selectCity","filterOption","option","input","query","queryWords","queryWord","textWord","textWords","hasMatch","w","matchesSearchQuery","timeMonth","t","mainInfoBoxContent","initialCollapsed","onMouseLeave","repeat","controller","onViewStateChange","views","MapView","dataSourceUrl","Boolean","hostname","ReactDOM","render","getElementById","navigator","serviceWorker","ready","registration","unregister","catch","error","message"],"mappings":"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","file":"static/js/main.606412e7.chunk.js","sourcesContent":["import styled from '@emotion/styled';\n\nconst NoScrollContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n overflow: hidden;\n`;\n\nexport default NoScrollContainer;\n","import * as React from 'react';\n\nexport default ({ children }: { children: React.ReactChild }) => (\n \n
{children}
\n \n);\n","import React, { ReactNode } from 'react';\nimport NoScrollContainer from './NoScrollContainer';\nimport Fallback from './Fallback';\nimport checkWebglSupport from './checkWebglSupport';\n\ninterface Props {\n embed?: boolean;\n children: ReactNode;\n}\n\nconst supportsWebGl = checkWebglSupport();\n\nconst MapContainer: React.FC = ({ embed, children }) => (\n \n {supportsWebGl ? (\n <>\n {children}\n {/**/}\n {/* */}\n {/**/}\n \n ) : (\n \n Sorry, but your browser doesn't seem to support WebGL which is required for this app.\n \n )}\n \n);\n\nexport default MapContainer;\n","export default function checkWebglSupport() {\n try {\n const canvas = document.createElement('canvas');\n return (\n // @ts-ignore\n !!window.WebGLRenderingContext &&\n !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))\n );\n } catch (e) {\n return false;\n }\n}\n","import styled from '@emotion/styled';\nimport React from 'react';\n\nexport interface AbsoluteProps {\n top?: number;\n left?: number;\n right?: number;\n bottom?: number;\n}\n\nfunction isNumber(x: any): x is number {\n return typeof x === 'number';\n}\n\ntype ColumnProps = { spacing?: number; padding?: number | string };\nexport const Column = styled.div(\n ({ spacing = 0, padding = 0 }: ColumnProps) => `\n display: flex;\n flex-direction: column;\n padding: ${isNumber(padding) ? `${padding}px` : padding};\n & > * + * { margin-top: ${spacing}px; }\n`\n);\n\ntype RowProps = { spacing?: number };\nexport const Row = styled.div(\n ({ spacing = 0 }: RowProps) => `\n display: flex;\n flex-direction: row;\n align-items: center;\n & > * + * { margin-left: ${spacing}px; }\n`\n);\n\nexport const Absolute = styled.div(\n ({ top, left, right, bottom }: AbsoluteProps) => `\n position: absolute;\n ${top != null ? `top: ${top}px;` : ''}\n ${left != null ? `left: ${left}px;` : ''}\n ${right != null ? `right: ${right}px;` : ''}\n ${bottom != null ? `bottom: ${bottom}px;` : ''}\n`\n);\n\nconst getBoxStyle = () => `\n background: rgba(255, 255, 255, 0.9);\n border-radius: 4px;\n font-size: 11px;\n box-shadow: 0 0 5px #aaa; \n`;\n\nexport const Box = styled(Absolute)<{}>(getBoxStyle);\n\nexport const NonPositionedBox = styled.div<{}>(getBoxStyle);\n\nexport const PaddedBox: React.FC = ({ children, ...rest }) =>\n \n \n {children}\n \n ;\n","import * as React from 'react';\n\nconst Away = (\n {\n href,\n className,\n children,\n }: {\n href: string;\n className?: string;\n children: React.ReactChild,\n }) => (\n \n {children}\n \n);\n\nexport default Away;\n","import {formatDefaultLocale} from 'd3-format';\nimport {format} from 'd3-format';\nimport _MESSAGES from './messages.json';\nimport _CONFIG from './config.json';\nimport {timeFormat, timeParse} from 'd3-time-format';\nimport {hcl, rgb} from 'd3-color';\nimport {MapController} from '@deck.gl/core';\nimport queryString from 'querystring';\n\nformatDefaultLocale(require('d3-format/locale/ru-RU.json'));\ntype Country = 'ru';\ntype Language = 'ru';\nexport const SHOW_RELATIVE: boolean = false;\nexport const BASE_COLOR = '#F04E23';\nexport const TEXT_COLOR = '#2D2D2D';\nexport const BACKGROUND_COLOR = '#DDDAD8';\nexport const SHAPE_LINE_COLOR = [150, 100, 100];\nexport const SHAPE_FILL_COLOR = colorAsRgba('#FAEBE5ff');\nexport const CIRCLE_LINE_COLOR = [255, 255, 255];\nexport const CIRCLE_LINE_COLOR__HIGHLIGHTED = colorAsRgba(\n // @ts-ignore\n hcl(BASE_COLOR).darker()\n);\nexport const CIRCLE_FILL_COLOR = colorAsRgba(BASE_COLOR);\nconst FALLBACK_COLOR_RGBA: RGBA = [255, 255, 255, 255];\nexport const formatCount = format(',.0f') as ((v: number | undefined) => string);\nexport const queryParams = queryString.parse(document.location.search.substr(1));\nexport const COUNTRY = (queryParams.country ?? 'ru') as Country;\nexport const ANIMATION_DURATION = 1000;\nconst LANG: Language = (() => {\n if (queryParams.lang) {\n return queryParams.lang as Language;\n }\n switch (COUNTRY) {\n default:\n return 'ru';\n }\n})();\nexport const CONFIG: any = _CONFIG[COUNTRY];\nexport const MESSAGES = _MESSAGES[COUNTRY][LANG]!;\nconst LOCALE = (() => {\n switch (LANG) {\n case 'ru':\n return 'ru';\n }\n})();\nexport const parseDate = timeParse('%Y-%m');\nexport const formatDateIso = timeFormat('%Y-%m');\nexport const formatDate =\n (d: Date) => {\n if (!d) return '…';\n return d.toLocaleDateString(LOCALE, {\n month: 'long',\n year: 'numeric',\n });\n };\nexport const shortFormatDate = (d: Date) => {\n return d.toLocaleDateString(LOCALE, {\n month: 'long',\n });\n};\nexport const COUNTS_FILE_PATH =\n '/data/counts.csv';\n// `https://docs.google.com/spreadsheets/d/e/2PACX-1vRE88iZXese8FnbmB-er-0ldyR9BSdu1zQCBDX4sBpw_nEV2GmuG1u7kOriPicirMZU35xSbGtvixFI/pub?gid=491777008&single=true&output=tsv`;\nexport const DARK_MODE = queryParams.dark ? queryParams.dark === 'true' : false;\nexport const FOCUS_PERIOD_START_DATE = parseDate(CONFIG.focusStartDate)!;\nexport const REFERENCE_PERIOD_START_DATE = CONFIG.referenceStartDate ? parseDate(CONFIG.referenceStartDate) : undefined;\nexport const REFERENCE_WEEKDAY_PATTERN = CONFIG.referenceWeekdayPattern;\nexport const INITIAL_VIEWSTATE = {\n latitude: 0, longitude: 0, zoom: 1,\n width: window.innerWidth,\n height: window.innerHeight,\n};\nconst accessToken = process.env.REACT_APP_MapboxAccessToken;\nconst mapboxMapStyle =\n 'mapbox://styles/ilyabo/ckh8e1jbd1f7s19o2qfr3jizf';\nexport const REF_DATE_WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\nexport const CONTROLLER_OPTIONS = (() => {\n const base = {\n type: MapController,\n doubleClickZoom: false,\n dragRotate: false,\n touchRotate: false,\n };\n\n switch (COUNTRY) {\n case 'ru':\n return {\n ...base,\n minZoom: 0,\n maxZoom: 15,\n };\n }\n})();\ntype RGBA = [number, number, number, number];\n\nexport function colorAsRgba(color: string): RGBA {\n const c = rgb(color);\n return [Math.floor(c.r), Math.floor(c.g), Math.floor(c.b), Math.round(c.opacity * 255)];\n}","import React, { useLayoutEffect, useMemo, useRef } from 'react';\nimport styled from '@emotion/styled';\nimport { scaleLinear } from 'd3-scale';\nimport { Column, Row } from './Boxes';\nimport {MESSAGES} from './constants';\n\nconst ColorRampCanvas = styled.canvas({\n display: 'flex',\n flexGrow: 1,\n border: `1px solid #666`,\n});\n\nconst Title = styled.div({\n marginBottom: 5,\n fontWeight: 'bold',\n});\n\nconst TickRow = styled(Row)({\n width: '100%',\n height: 5,\n position: 'relative',\n '& > div': {\n position: 'absolute',\n borderRight: `1px solid #666`,\n // flexGrow: 1,\n height: '100%',\n },\n});\n\nconst ColorRampTextRow = styled.div({\n width: '100%',\n height: 10,\n position: 'relative',\n '& > *': {\n position: 'absolute',\n },\n});\n\nconst ColorRamp: React.FC<{\n getColor: (v: number) => string;\n domain: [number, number],\n width?: number;\n height?: number;\n reverse?: boolean;\n}> = props => {\n const { width = 60, height = 13, domain, getColor, reverse } = props;\n\n const canvasRef = useRef(null);\n const xScale = useMemo(() =>\n scaleLinear()\n .domain(domain)\n .range([0, width]),\n [width, domain]\n );\n\n useLayoutEffect(() => {\n const { current } = canvasRef;\n if (current) {\n const ctx = current.getContext('2d');\n if (ctx) {\n ctx.clearRect(0, 0, width, height);\n for (let i = 0; i < width; i++) {\n ctx.fillStyle = getColor(xScale.invert(i));\n ctx.fillRect(reverse ? width - i - 1 : i, 0, 1, height);\n }\n }\n }\n });\n\n if (domain[0] === domain[1]) return null;\n return (\n \n \n {MESSAGES.numberOfTrips}\n \n \n {/**/}\n {/*
*/}\n {/*
*/}\n {/*
*/}\n {/**/}\n \n
{formatPercent(domain[0])}
\n {/*
{formatPercent(0)}
*/}\n
{formatPercent(domain[1])}
\n
\n \n );\n};\n\nexport default ColorRamp;\n\n\nfunction formatPercent(x: number) {\n return `${x > 0 ? '+' : ''}${Math.round(x*100)}%`;\n}\n","import * as React from 'react';\nimport styled from '@emotion/styled';\nimport Away from './Away';\nimport {BASE_COLOR} from './constants';\n\nexport enum Direction {\n LEFT,\n RIGHT,\n}\n\nconst DARK_GRAY3 = '#293742';\nconst DARK_GRAY4 = '#30404D';\nconst LIGHT_GRAY4 = '#F5F5F5';\nconst LIGHT_GRAY5 = '#F5F5F5';\n\nexport interface Props {\n height: number;\n initialCollapsed?: boolean;\n direction: Direction;\n darkMode: boolean;\n collapsedView?: React.ReactNode;\n isCollapsed: boolean;\n onChange: (collapsed: boolean) => void;\n}\n\nconst Outer = styled.div`\n display: flex;\n justify-items: center;\n flex-direction: column;\n`;\n\ntype BodyProps = { direction: Direction; collapsed: boolean; height: number };\nconst Body = styled.div(\n ({ direction, collapsed, height }: BodyProps) => `\n order: ${direction === Direction.LEFT ? 2 : 1};\n overflow: hidden;\n max-height: ${collapsed ? 0 : `${height}px`};\n transition: max-width 0.15s ease-out; \n`\n);\n\ntype ContentProps = { direction: Direction; height: number };\nconst Content = styled.div(\n ({ direction, height }: ContentProps) => `\n height: ${height}px;\n`\n);\n\ntype RotateProps = { degrees: number };\nconst Rotate = styled.div(\n ({ degrees }: RotateProps) => `\n transform-origin: center;\n transform: rotate(${degrees}deg)translate(0,3px);\n transition: transform 0.15s ease-out; \n`\n);\n\ntype ButtonProps = {\n collapsed: boolean;\n direction: Direction;\n darkMode: boolean;\n};\n\nconst Button = styled.button(\n ({ collapsed, direction, darkMode }: ButtonProps) => `\n display: flex;\n order: ${direction === Direction.LEFT ? 1 : 2}; \n border: none;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n background-color: transparent;\n // background-color: ${darkMode ? DARK_GRAY4 : LIGHT_GRAY5};\n color: #ccc;\n // border-radius: ${collapsed ? 4 : 0}px;\n border-radius: 4px;\n transition: background-color 0.25s, border-radius 0.15s;\n outline: none; \n &:hover {\n // background-color: ${darkMode ? DARK_GRAY3 : LIGHT_GRAY4};\n }\n`\n);\n\n\nconst Chevron = () => (\n \n \n \n);\nconst LinkText = styled.div`\n font-size: 12px;\n color: ${BASE_COLOR};\n padding: 0 10px;\n min-width: 70px; \n`;\n\nexport default class Collapsible extends React.Component {\n\n bodyRef = React.createRef();\n\n handleClick = () => {\n this.props.onChange(!this.props.isCollapsed);\n };\n\n getArrow = () => {\n const { isCollapsed, direction } = this.props;\n switch (direction) {\n case Direction.LEFT:\n return ;\n case Direction.RIGHT:\n return ;\n }\n };\n\n render() {\n const { isCollapsed, height, direction, darkMode, children, collapsedView } = this.props;\n return (\n \n \n \n {children}\n \n \n {isCollapsed &&\n collapsedView\n }\n \n {this.getArrow()}\n {isCollapsed ? \"по месяцам\" : \"всего\"}\n {this.getArrow()}\n \n \n );\n }\n}\n","import React from 'react'\nimport styled from '@emotion/styled';\nimport { TimeInterval } from 'd3-time';\nimport {BASE_COLOR} from './constants';\n\n\ninterface Props {\n current: Date;\n start: Date;\n end: Date;\n timeStep: TimeInterval;\n autoplay: boolean;\n stepDuration: number;\n onChange: (date: Date) => void;\n}\n\nconst width = 40, height = 40;\n\nconst OuterSvg = styled.svg({\n cursor: 'pointer',\n '& > circle': {\n transition: 'opacity 0.2s',\n opacity: 0.25,\n },\n '&:hover': {\n '& > circle': {\n opacity: 1.0,\n }\n },\n});\n\nconst OuterCircle = styled.circle({\n cursor: 'pointer',\n strokeWidth: 1,\n stroke: BASE_COLOR,\n fill: '#fff',\n});\n\ninterface State {\n isPlaying: boolean;\n}\n\nclass PlayControl extends React.Component {\n\n playTimeout: NodeJS.Timeout | undefined;\n\n state = {\n isPlaying: false,\n };\n\n componentDidMount(): void {\n const { autoplay } = this.props;\n if (autoplay) {\n this.start();\n }\n }\n\n componentWillUnmount(): void {\n this.clearPlayTimeOut();\n }\n\n start = () => {\n const { isPlaying } = this.state;\n if (!isPlaying) {\n const { start, current, end, onChange } = this.props;\n this.setState({ isPlaying: true }, () => {\n this.scheduleNextStep();\n });\n if (current >= end) {\n // rewind\n onChange(start);\n }\n }\n };\n\n stop = () => {\n this.clearPlayTimeOut();\n const { isPlaying } = this.state;\n if (isPlaying) {\n this.setState({ isPlaying: false });\n }\n };\n\n clearPlayTimeOut = () => {\n if (this.playTimeout != null) {\n clearTimeout(this.playTimeout);\n this.playTimeout = undefined;\n }\n };\n\n scheduleNextStep = () => {\n this.clearPlayTimeOut();\n const { stepDuration } = this.props;\n this.playTimeout = setTimeout(this.nextStep, stepDuration);\n };\n\n nextStep = () => {\n const { isPlaying } = this.state;\n if (isPlaying) {\n const { timeStep, end, current, onChange } = this.props;\n const next = timeStep.offset(current, 1);\n if (next > end) {\n this.stop();\n } else {\n onChange(next);\n this.scheduleNextStep();\n }\n }\n };\n\n render() {\n const { isPlaying } = this.state\n const handleTogglePlay = () => {\n if (isPlaying) {\n this.stop();\n } else {\n this.start();\n }\n };\n\n let icon;\n if (!isPlaying) {\n icon = (\n \n );\n } else {\n icon = (\n \n );\n }\n\n const r = Math.min(width, height) * .48;\n return (\n \n \n \n {icon}\n \n \n );\n\n }\n}\n\n\nexport default PlayControl;\n","import React from 'react'\nimport {scaleLinear, scaleTime} from 'd3-scale';\nimport {extent} from 'd3-array';\nimport {line} from 'd3-shape';\nimport styled from '@emotion/styled';\nimport {BASE_COLOR, formatDate} from './constants';\n\n\nconst TOTAL_TIME_SERIES_MARGIN = {\n top: 12,\n right: 65,\n bottom: 20,\n left: 5,\n};\n\nexport interface TimeSeriesDatum {\n date: Date;\n value: number;\n}\n\ninterface Props {\n data: TimeSeriesDatum[];\n selected?: Date;\n width: number;\n height: number;\n formatValue: (v: number | undefined) => string;\n};\n\nconst Outer = styled.div({\n display: 'flex',\n alignSelf: 'center',\n});\n\nconst TinyText = styled.text({\n fontSize: 9,\n fill: BASE_COLOR,\n});\n\nconst ZeroLine = styled.line({\n stroke: BASE_COLOR,\n});\n\nconst DashedLine = styled.line({\n stroke: BASE_COLOR,\n strokeDasharray: \"1,2\",\n});\n\nconst DateText = styled.text({\n fontSize: 12,\n fontWeight: 'bold',\n fill: BASE_COLOR,\n});\n\nconst TotalTimeSeries: React.FC = (\n {\n width,\n height,\n data,\n formatValue,\n selected,\n }\n) => {\n const margin = TOTAL_TIME_SERIES_MARGIN;\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n\n const timeExtent = extent(data, d => d.date);\n if (timeExtent[0] == null || timeExtent[1] == null) return null;\n const timeScale = scaleTime()\n .domain(timeExtent)\n .range([0, innerWidth]);\n\n const valuesExtent = extent(data, d => d.value);\n if (valuesExtent[0] == null || valuesExtent[1] == null) return null;\n const yScale = scaleLinear()\n .domain([valuesExtent[0], Math.max(0, valuesExtent[1])])\n .range([innerHeight, 0]);\n\n // @ts-ignore\n const path = line().x(d => timeScale(d.date)).y(d => yScale(d.value))(data);\n\n return (\n \n \n \n {/**/}\n {/*{*/}\n {/* timeScale.ticks(timeDay).map(tick =>*/}\n {/* */}\n {/* )*/}\n {/*}*/}\n \n \n {/**/}\n {formatValue(0)}\n {formatValue(yScale.domain()[1])}\n {/*{formatPercentageShort(yScale.domain()[0])}*/}\n\n {/*{`↑ ${MESSAGES.moreTrips}`}*/}\n {/*{`↓ ${MESSAGES.fewerTrips}`}*/}\n \n {selected &&\n \n \n \n \n {selected &&\n innerWidth/2)\n ? {x:-8, textAnchor: 'end'}\n : {x:+8, textAnchor: 'start'}\n )}\n y={innerHeight+15}\n >\n {formatDate(selected)}\n }\n \n }\n \n \n\n \n)\n};\n\n\nexport default TotalTimeSeries;\n","import React, { useEffect, useRef, useState } from 'react'\nimport styled from '@emotion/styled';\nimport Measure from 'react-measure';\nimport { scaleTime } from 'd3-scale';\nimport { TimeInterval } from 'd3-time';\nimport { EventManager } from 'mjolnir.js';\nimport PlayControl from './PlayControl';\nimport TotalTimeSeries, {TimeSeriesDatum} from './TotalTimeSeries';\nimport {Absolute, Column, Row} from './Boxes';\n\ninterface Props {\n totalTimeSeriesData: TimeSeriesDatum[];\n current: Date | undefined;\n start: Date | undefined;\n end: Date | undefined;\n formatDate: (d: Date) => string;\n formatValue: (v: number | undefined) => string;\n timeInterval: TimeInterval;\n minTickWidth: number;\n stepDuration: number;\n onChange: (date: Date) => void;\n}\n\ninterface Dimensions {\n width: number;\n height: number;\n}\n\nconst SVG_HEIGHT = 200;\nconst TICK_HEIGHT = 5;\n\nconst innerMargin = {\n top: 0,\n left: 1,\n right: 1,\n bottom: 0,\n};\n\nconst Outer = styled.div({\n display: 'flex',\n // padding: '5px 20px',\n alignItems: 'center',\n '&>*+*': {\n marginLeft: 10,\n }\n});\n\n// const PlayButton = styled.img({\n// border: '1px solid #000',\n// borderRadius: '50%',\n// padding: 10,\n// cursor: 'pointer',\n// opacity: 0.65,\n// transition: 'opacity 0.2s',\n// '&:hover': {\n// opacity: 1.0,\n// }\n// });\n\nconst MeasureTarget = styled.div({\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n overflow: 'hidden',\n});\n\nconst TimelineSvg = styled.svg({\n cursor: 'ew-resize',\n});\n\n// const TickLine = styled.line({\n// fill: 'none',\n// stroke: '#ccc',\n// });\n//\n// const TrianglePath = styled.path({\n// strokeWidth: 1,\n// stroke: 'none',\n// fill: '#ccc',\n// // opacity: 0.65,\n// // transition: 'opacity 0.2s',\n// // '&:hover': {\n// // opacity: 1.0,\n// // }\n// });\n//\n// const AxisPath = styled.path({\n// fill: 'none',\n// stroke: '#ccc',\n// });\n//\n// const TickText = styled.text({\n// fill: '#333',\n// fontSize: 11,\n// textAnchor: 'middle',\n// // textTransform: 'uppercase',\n// });\n\n\nconst eventManager = new EventManager();\n\nconst TimelineChart: React.FC = (props) => {\n\n const {\n width,\n height,\n start,\n end,\n current,\n formatDate,\n timeInterval,\n minTickWidth,\n onChange,\n } = props;\n\n const chartWidth = width - innerMargin.left - innerMargin.right;\n const x = scaleTime()\n x.domain([start, end])\n x.range([0, chartWidth]);\n\n const svgRef = useRef(null);\n\n const _handleMove = useRef<(evt: any) => void>();\n _handleMove.current = (evt: any) => {\n const { current } = svgRef;\n if (current != null) {\n const { left } = current.getBoundingClientRect();\n const { center } = evt;\n let date = timeInterval.round(x.invert(center.x - left - innerMargin.left));\n if (date < start) date = start;\n if (date > end) date = end;\n onChange(date);\n }\n };\n\n const handleMove = (evt: any) => {\n if (_handleMove.current) {\n _handleMove.current(evt);\n }\n };\n\n useEffect(() => {\n eventManager.setElement(svgRef.current);\n eventManager.on('click', handleMove);\n eventManager.on('panstart', handleMove);\n eventManager.on('panmove', handleMove);\n eventManager.on('panend', handleMove);\n return () => {\n eventManager.setElement(null);\n eventManager.off('panstart', handleMove);\n eventManager.off('panmove', handleMove);\n eventManager.off('panend', handleMove);\n };\n }, []);\n\n\n const ticks = x.ticks(timeInterval);\n const tickLabels: Date[] = [];\n\n let nextTick = end;\n const step = -Math.ceil(ticks.length / (chartWidth/minTickWidth));\n while (nextTick >= start) {\n tickLabels.push(nextTick);\n nextTick = timeInterval.offset(nextTick, step);\n }\n\n return (\n \n \n {/**/}\n {/* */}\n {/**/}\n \n {/*{ticks.map((t, i) =>*/}\n {/* */}\n {/*)}*/}\n {/*{tickLabels.map((t, i) =>*/}\n {/* */}\n {/* */}\n {/* {formatDate(t)}*/}\n {/* */}\n {/*)}*/}\n {/**/}\n \n \n \n )\n};\n\nconst Timeline: React.FC = (props) => {\n const [dimensions, setDimensions] = useState();\n\n const {\n start,\n end,\n current,\n totalTimeSeriesData,\n formatValue,\n timeInterval,\n stepDuration,\n onChange,\n } = props;\n\n if (!start || !end || !current) {\n return ;\n }\n\n return (\n \n setDimensions(contentRect.bounds)}\n >\n {(({ measureRef }) => {\n return (\n \n {dimensions &&\n \n
\n \n
\n
\n \n \n \n \n
\n
}\n
\n )\n })}\n \n
\n );\n}\n\nexport default Timeline;\n","const splitIntoWords = ((str: string) => {\n // https://stackoverflow.com/a/25575009/120779\n return (\n str\n .toLowerCase()\n // eslint-disable-next-line\n .match(/([^\\u2000-\\u206F\\u2E00-\\u2E7F\\\\'!\"#$%&()*+,\\-.\\/:;<=>?@\\[\\]^_`{|}~\\s]+)/g)\n );\n});\n\n/**\n * Checks whether the text matches the query. Both are split into words.\n * Returns true if for each query word there is a word in the text which\n * begins with it. Case-insensitive.\n */\nexport function matchesSearchQuery(query: string, text: string) {\n const queryWords = splitIntoWords(query);\n if (!queryWords || queryWords.length === 0) {\n return true;\n }\n const startsWith = (queryWord: string, textWord: string) => textWord.indexOf(queryWord) === 0;\n const textWords = splitIntoWords(text);\n if (!textWords || textWords.length === 0) {\n return false;\n }\n const hasMatch = (queryWord: string) => {\n for (const w of textWords) {\n if (startsWith(queryWord, w)) {\n return true;\n }\n }\n return false;\n };\n\n for (const q of queryWords) {\n if (!hasMatch(q)) {\n return false;\n }\n }\n return true;\n}\n","import React, {useEffect, useMemo, useRef} from 'react';\nimport WebMercatorViewport from 'viewport-mercator-project'\nimport {ViewState} from 'react-map-gl';\nimport {ScalePower} from 'd3-scale';\nimport Flatbush from 'flatbush';\nimport styled from '@emotion/styled';\nimport {ascending, descending} from 'd3-array';\nimport {formatCount, TEXT_COLOR} from './constants';\n\ninterface Props {\n countsData: { id: string, name:string, centroid: [number,number], count: number | undefined }[] | undefined;\n viewport: ViewState;\n sizeScale: ScalePower | undefined;\n}\n\nconst Svg = styled.svg(`\n position: absolute;\n left:0;top:0;\n width: 100%;height:100%;\n`);\nconst LabelG = styled.g(`\n opacity: 0;\n`);\n\nconst LabelText = styled.text(`\n transition: opacity 0.5s;\n text-anchor: middle;\n alignment-baseline: middle;\n font-size: 8px;\n paint-order: stroke;\n fill: ${TEXT_COLOR};\n stroke: #fff;\n stroke-width: 1px;\n stroke-linecap: butt;\n stroke-linejoin: miter;\n // font-weight: normal;\n font-weight: bold;\n`);\n\nconst pad = 5;\n\nconst LabelsOverlay: React.FC = (props) => {\n const {countsData, viewport, sizeScale} = props;\n const ref = useRef(null);\n\n const sortedCountsData = useMemo(() => {\n if (!countsData) return undefined;\n return countsData.slice()\n .sort((a,b)=>descending(a.count||0,b.count||0));\n },[countsData]);\n useEffect(() => {\n if (ref.current && sortedCountsData) {\n const index = new Flatbush(sortedCountsData.length);\n const textNodes = ref.current.querySelectorAll('.label');\n for (let i = 0; i < textNodes.length; i++) {\n const {left, top, right, bottom} = textNodes[i].getBoundingClientRect();\n index.add(left, top, right, bottom);\n }\n index.finish();\n\n const toOmit = new Set();\n // assuming they are sorted by size\n for (let i = textNodes.length - 1; i >= 0 ; i--) {\n if (toOmit.has(i)) continue;\n const textNode = textNodes[i];\n const {left, top, right, bottom} = textNode.getBoundingClientRect();\n const indices = index.search(left - pad, top - pad, right + pad, bottom + pad);\n for (const idx of indices) {\n if (idx !== i) {\n toOmit.add(idx);\n }\n }\n }\n for (let i = 0; i < textNodes.length; i++) {\n // @ts-ignore\n textNodes[i].style.opacity = toOmit.has(i) ? '0' : '1';\n }\n }\n }, [viewport.zoom, ref.current, sortedCountsData])\n\n if (!sortedCountsData || !sizeScale) return null;\n\n const mercator = new WebMercatorViewport(viewport);\n // @ts-ignore\n const {width,height} = viewport;\n return (\n \n \n {sortedCountsData\n .map((d, i) => {\n const [cx, cy] = mercator.project(d.centroid);\n const r = sizeScale(d.count || 0);\n const scale = Math.max(1,Math.min(2.5,Math.pow(viewport.zoom,3)*r/300))/1.5;\n return (\n \n \n {d.name}\n \n \n {formatCount(d.count)}\n \n \n );\n }).reverse()}\n \n \n );\n};\n\nexport default LabelsOverlay;","import React from 'react';\nimport PropTypes from 'prop-types';\n\n// From https://github.com/ajwann/svg-loaders-react\n\nconst size = 32;\nconst SpinningCircles = ({}: any) => (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n);\n\nSpinningCircles.propTypes = {\n className: PropTypes.string,\n};\n\nSpinningCircles.defaultProps = {\n className: undefined,\n};\n\nexport { SpinningCircles };","import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {MapView} from '@deck.gl/core';\nimport MapContainer from './MapContainer';\nimport {DeckGL} from '@deck.gl/react';\nimport {GeoJsonLayer, ScatterplotLayer} from '@deck.gl/layers';\nimport styled from '@emotion/styled';\nimport {FlyToInterpolator, ViewState, ViewStateChangeInfo} from 'react-map-gl';\nimport {feature} from 'topojson-client';\nimport useFetch from 'react-fetch-hook';\nimport {Feature, FeatureCollection} from 'geojson';\nimport {Topology} from 'topojson-specification';\nimport {tsvParse} from 'd3-dsv';\nimport {scaleLinear, scaleSequential, scaleSqrt} from 'd3-scale';\nimport {interpolateRdYlBu} from 'd3-scale-chromatic';\nimport {ascending, extent, max, sum} from 'd3-array';\nimport {Box, Column, PaddedBox, Row} from './Boxes';\nimport Select, {components as selectComponents} from 'react-select';\nimport {easeCubic, easeLinear} from 'd3-ease';\nimport Away from './Away';\nimport ColorRamp from './ColorRamp';\nimport {TimeSeriesDatum} from './TotalTimeSeries';\nimport {interpolateRgbBasis} from 'd3-interpolate';\nimport NoScrollContainer from './NoScrollContainer';\nimport Timeline from './Timeline';\nimport {timeMonth} from 'd3-time';\nimport Collapsible, {Direction} from './Collapsible';\nimport {fitBounds} from '@math.gl/web-mercator';\nimport turfBbox from '@turf/bbox';\nimport {matchesSearchQuery} from './matchesSearchQuery';\nimport {useWindowSize} from './useWindowResize';\nimport LabelsOverlay from './LabelsOverlay';\nimport {SpinningCircles} from './SpinningCircles';\nimport {\n ANIMATION_DURATION,\n BACKGROUND_COLOR,\n BASE_COLOR,\n CIRCLE_FILL_COLOR,\n colorAsRgba,\n CONFIG,\n CONTROLLER_OPTIONS,\n COUNTRY,\n COUNTS_FILE_PATH,\n DARK_MODE,\n FOCUS_PERIOD_START_DATE,\n formatCount,\n formatDate,\n formatDateIso,\n INITIAL_VIEWSTATE,\n MESSAGES,\n parseDate,\n queryParams,\n REF_DATE_WEEKDAYS,\n REFERENCE_PERIOD_START_DATE,\n REFERENCE_WEEKDAY_PATTERN,\n SHAPE_FILL_COLOR,\n SHAPE_LINE_COLOR,\n shortFormatDate,\n SHOW_RELATIVE,\n TEXT_COLOR\n} from './constants';\n\n\n\ninterface DateOption {\n value: string,\n label: string,\n dayOfWeek: number;\n month?: number;\n date?: Date,\n}\n\ninterface AvailableDates {\n reference: DateOption[];\n rest: DateOption[];\n}\n\ninterface LocationOption {\n value: string,\n label: string,\n feature?: Feature,\n isGroup?: boolean;\n groupLevel?: number;\n}\n\ninterface Datum {\n id: string;\n countDiff: number;\n refCount: number;\n relDiff: number;\n}\n\nexport function mapTransition(duration: number = 2000) {\n return {\n transitionDuration: duration,\n transitionInterpolator: new FlyToInterpolator(),\n transitionEasing: easeCubic,\n };\n}\n\nconst Title = styled.div`\n font-size: 14px;\n font-weight: bold;\n text-align: center;\n color: ${BASE_COLOR};\n`;\n\nconst Subtitle = styled.div`\n font-size: 10px;\n text-align: center;\n font-weight: normal;\n`;\n\nconst SelectOuter = styled.div`\n width: 280px;\n & div {\n color: ${BASE_COLOR} !important;\n border-color: ${BASE_COLOR} !important; \n }\n`;\n\nconst LocationName = styled.div`\n font-weight: bold;\n`;\n\nconst TermsLink = styled(Away)`\n text-align: center;\n color: ${BASE_COLOR};\n cursor: pointer;\n &:hover { \n text-decoration: underline;\n }\n`;\n\nconst MainInfoBox = styled(PaddedBox)`\n max-width: 360px;\n`;\n\nconst MainInfoBoxContent = styled.div({\n alignItems: 'center',\n fontSize: 'medium',\n display: 'flex',\n // width: 270,\n padding: 15,\n flexDirection: 'column',\n '& > *+*': {\n marginTop: 10,\n }\n});\n\nconst ColorRampBox = styled(Box)({\n padding: 10,\n display: 'flex',\n flexDirection: 'column',\n '& > *+*': {\n marginTop: 5,\n }\n});\n\n\nconst SelectedLocationDetails = styled.div`\n font-size: 12px;\n text-align: center;\n //font-weight: bold;\n color: ${TEXT_COLOR};\n small {\n display: block;\n // color: #666;\n font-size: 12px;\n font-weight: normal;\n }\n .huge {\n font-size: 30px;\n font-weight: bold;\n color: ${BASE_COLOR};\n }\n a {\n //color: ${TEXT_COLOR};\n }\n`;\n\nconst TooltipBox = styled(Box)`\n pointer-events: none;\n padding: 10px;\n max-width: 125px;\n text-align: center;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n .huge {\n font-size: 30px;\n font-weight: bold;\n color: ${BASE_COLOR};\n }\n &>* + * {\n margin-top: 5px;\n }\n`;\n\nconst Outer = styled(NoScrollContainer)`\n display: flex;\n flex-direction: column;\n color: ${TEXT_COLOR};\n a {\n color: ${BASE_COLOR};\n }\n`;\n\nconst MapOuter = styled.div({\n display: 'flex',\n flexGrow: 1,\n position: 'relative',\n});\n\nconst CenterBlock = styled.div`\n position: absolute;\n top: 0; left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-items: center;\n justify-content: center;\n`;\n\n\nconst DeckGLOuter = styled.div<{\n darkMode: boolean;\n baseMapOpacity: number;\n cursor: 'crosshair' | 'pointer' | undefined;\n}>(\n ({ cursor, baseMapOpacity, darkMode }) => `\n #deckgl-wrapper {\n background: ${BACKGROUND_COLOR};\n }\n & #deckgl-overlay {\n // mix-blend-mode: ${darkMode ? 'screen' : 'multiply'};\n }\n & .mapboxgl-map {\n opacity: ${baseMapOpacity}\n }\n ${cursor != null ? `& #view-default-view { cursor: ${cursor}; }` : ''},\n`\n);\n\nconst SelectOption: React.FC = (props) => {\n const {\n groupLevel,\n isGroup,\n } = props.data as LocationOption;\n return (\n \n \n
\n );\n}\n\nfunction makeDateOption(dateStr: string): DateOption {\n const date = parseDate(dateStr)!;\n return {\n value: dateStr,\n label: formatDate(date),\n date: date,\n dayOfWeek: date?.getDay(),\n month: date?.getMonth(),\n };\n}\n\nfunction makeRefDateOption(dateStr: string): DateOption {\n if (REFERENCE_WEEKDAY_PATTERN) {\n let dayOfWeek = -1, month = -1;\n const m = new RegExp(REFERENCE_WEEKDAY_PATTERN).exec(dateStr);\n if (m && m[1] && m[2]) {\n month = +m[1] - 1;\n dayOfWeek = REF_DATE_WEEKDAYS.indexOf(m[2]);\n }\n return {\n value: dateStr,\n label: dateStr,\n date: undefined,\n dayOfWeek,\n month,\n };\n } else {\n return makeDateOption(dateStr);\n }\n}\n\n\nfunction pickInitialSelectedDate(availableDates: AvailableDates): DateOption {\n const desired = queryParams.date as string | undefined;\n let found;\n if (desired) {\n found = availableDates.rest.find(date => date.value === desired);\n }\n if (!found) found = availableDates.rest[availableDates.rest.length - 1];\n return found;\n}\n\nlet numWarns = 0;\nfunction pickRefDate(availableDates: AvailableDates, date: Date): DateOption | undefined {\n const dayOfWeek = date.getDay();\n const desired = queryParams.ref_date as string | undefined;\n let found;\n\n if (desired) {\n found = availableDates.reference.find(date => date.value === desired);\n }\n if (!found) {\n found = availableDates.reference.find((d) => {\n if (REFERENCE_WEEKDAY_PATTERN) {\n return date.getMonth() === d.month;\n } else if (REFERENCE_PERIOD_START_DATE) {\n return (\n d.date &&\n date.getMonth() === d.month &&\n d.date >= REFERENCE_PERIOD_START_DATE\n );\n }\n return false;\n }\n );\n }\n if (!REFERENCE_WEEKDAY_PATTERN && found) {\n const replacement =\n CONFIG.referenceDatesReplace &&\n (CONFIG.referenceDatesReplace as {[key: string]: string})[found.value];\n if (replacement) {\n found = availableDates.reference.find(date => date.value === replacement);\n }\n }\n if (!found && numWarns < 100) {\n numWarns++;\n console.warn(\n `No ref date for dayOfWeek ${dayOfWeek}`+\n ` ref weekday pattern = ${REFERENCE_WEEKDAY_PATTERN}`+\n ` ref period start = ${REFERENCE_PERIOD_START_DATE}`+\n ` ref dates = ${availableDates.reference.map(d => JSON.stringify(d)).join('\\n')}`\n );\n }\n return found;\n}\n\nconst NOCOLOR = [155, 155, 155, 50];\n\ninterface CircleItem {\n id: string;\n centroid: [number,number];\n count: number;\n}\n\nfunction App() {\n const [isCollapsed, setCollapsed] = useState(true);\n\n const size = useWindowSize();\n useEffect(() => {\n if (size) // not sure why this doesn't fire from react-map-gl\n setViewport({\n ...viewport,\n ...size,\n });\n },[size?.width, size?.height]);\n\n const isNarrowScreen = size?.width != undefined && size.width < 400;\n const isShortScreen = size?.height != undefined && size.height < 600\n\n const fetchShapes = useFetch(`/data/${COUNTRY}/shapes.topo.json`);\n const geoJsonFeatures = useMemo(() => {\n const topology = fetchShapes.data as Topology;\n if (topology) {\n return feature(topology, topology.objects['zones']) as any as FeatureCollection;\n }\n return undefined;\n }, [fetchShapes.data]);\n\n const mapContainerRef = useRef(null);\n const [ tooltip, setTooltip ] = useState();\n const [selectedLocation, setSelectedLocation] = useState();\n const [x1,y1,x2,y2] = CONFIG.bbox;\n const [viewport, setViewport] = useState(INITIAL_VIEWSTATE);\n const initialViewState = fitBounds({\n width: window.innerWidth,\n height: window.innerHeight - 74,\n bounds: [[x1, y1], [x2, y2]],\n padding: window.innerWidth * 0.1,\n });\n useEffect(() => {\n setViewport(initialViewState);\n }, []);\n\n\n const fetchCounts = useFetch(\n COUNTS_FILE_PATH,\n { formatter: (response) =>\n response.text().then(text => tsvParse(text))\n }\n );\n\n const availableDates = useMemo(() => {\n if (!fetchCounts.data) return undefined;\n\n const dates = fetchCounts.data.columns.slice(1) as string[];\n const dateOptions = dates.sort((a, b) => ascending(a, b));\n return {\n reference: dateOptions.filter(d => {\n if (queryParams.ref_date) {\n return d === queryParams.ref_date;\n }\n if (REFERENCE_WEEKDAY_PATTERN) {\n return new RegExp(REFERENCE_WEEKDAY_PATTERN).test(d);\n }\n if (REFERENCE_PERIOD_START_DATE) {\n return parseDate(d)! >= REFERENCE_PERIOD_START_DATE;\n }\n return false;\n }).map(makeRefDateOption),\n rest: dateOptions\n .map(makeDateOption)\n .filter(d => d.date && d.date >= FOCUS_PERIOD_START_DATE)\n ,\n }\n },\n [fetchCounts.data]\n );\n\n const lastAvailableDate = useMemo(() => {\n if (availableDates) {\n const millis = max(availableDates.rest!.map(d => d.date?.getTime() || 0));\n if (millis) return new Date(millis);\n }\n return undefined;\n }, [availableDates]);\n\n const locationNamesById = useMemo(() => {\n if (!fetchCounts.data) return undefined;\n return fetchCounts.data.reduce((m: Map, r: any) => {\n m.set(r.locationId, r.name);\n return m;\n }, new Map());\n },\n [fetchCounts.data]\n );\n\n\n const datumByLocationByDate = useMemo(() => {\n if (!fetchCounts.data || !availableDates) return undefined;\n return fetchCounts.data\n .reduce((byLocationByDate, r: any) => {\n byLocationByDate.set(r.locationId,\n availableDates.rest.reduce((byDate, { date, value: dateStr }) => {\n const count = +(r[dateStr]|| 5);\n const refDate = date ? pickRefDate(availableDates, date)?.value : undefined;\n if (refDate) {\n const refCount = +(r[refDate]|| 5);\n const countDiff = count - refCount;\n\n if (CONFIG.filterMinCount == null ||\n (count >= CONFIG.filterMinCount && refCount >= CONFIG.filterMinCount)\n ) {\n byDate.set(dateStr, {\n id: r.locationId,\n countDiff,\n refCount,\n relDiff: countDiff / refCount,\n });\n }\n }\n return byDate;\n }, new Map())\n );\n return byLocationByDate;\n }, new Map>());\n }, [fetchCounts.data, availableDates]);\n\n const [selectedDateOption, setSelectedDateOption] = useState();\n if (availableDates != null && !selectedDateOption) {\n setSelectedDateOption(pickInitialSelectedDate(availableDates));\n }\n\n const cumulativeTotalByLocation = useMemo(() => {\n const selectedDate = selectedDateOption?.value;\n if (!datumByLocationByDate || !availableDates || !selectedDate) return undefined;\n const rv = new Map();\n const dates = availableDates.rest.filter(d => d.value != null /* && d.value <= selectedDate*/).map(d => d.value);\n for (const [locationId, byDate] of datumByLocationByDate.entries()) {\n rv.set(\n locationId,\n sum(dates, d => byDate.get(d)?.countDiff || 0)\n );\n }\n return rv;\n }, [datumByLocationByDate, availableDates, selectedDateOption]);\n\n const refDateOption = useMemo(() => {\n if (!availableDates || !selectedDateOption?.date) return undefined;\n return pickRefDate(availableDates, selectedDateOption.date);\n }, [availableDates, selectedDateOption]);\n\n\n const getDefinedValues = useCallback(\n (date: string) => {\n if (!geoJsonFeatures || !datumByLocationByDate || !selectedDateOption) return undefined;\n\n const values: Datum[] = [];\n for (const f of geoJsonFeatures.features) {\n const d = datumByLocationByDate.get(f.properties!.id)?.get(date);\n if (d && d.relDiff != null) {\n values.push(d);\n }\n }\n\n if (values.length === 0) {\n console.warn(`No defined values for date ${date}`);\n }\n return values;\n },\n [geoJsonFeatures, datumByLocationByDate, selectedDateOption]\n );\n\n const calcTotalRelDiff = useCallback((date: string) => {\n if (!geoJsonFeatures || !datumByLocationByDate) return undefined;\n\n return datumByLocationByDate\n .get(selectedLocation ? selectedLocation.value : 'total')\n ?.get(date)\n ?.relDiff;\n\n }, [geoJsonFeatures, datumByLocationByDate, selectedLocation]);\n\n const calcTotalCountDiff = useCallback((date: string) => {\n if (!geoJsonFeatures || !datumByLocationByDate) return undefined;\n\n return datumByLocationByDate\n .get(selectedLocation ? selectedLocation.value : 'total')\n ?.get(date)\n ?.countDiff;\n\n }, [geoJsonFeatures, datumByLocationByDate, selectedLocation]);\n\n const totalTimeSeriesData = useMemo(\n () => {\n if (!availableDates) return undefined;\n const data: TimeSeriesDatum[] = [];\n for (const { value, date } of availableDates.rest) {\n const total = SHOW_RELATIVE ? calcTotalRelDiff(value) : calcTotalCountDiff(value);\n if (total != null) {\n data.push({\n date: date!,\n value: total,\n });\n }\n }\n return data;\n },\n [availableDates, calcTotalRelDiff, calcTotalCountDiff]\n );\n\n const totalDiff = useMemo(\n () => {\n if (!selectedDateOption) return undefined;\n return calcTotalRelDiff(selectedDateOption.value)\n },\n [calcTotalRelDiff, selectedDateOption]\n );\n\n const diffExtent = useMemo(\n () => {\n if (CONFIG.colorScaleDomain) return CONFIG.colorScaleDomain;\n\n if (!availableDates || !getDefinedValues) return undefined;\n\n let min: number | undefined = undefined;\n let max: number | undefined= undefined;\n for (const { value: date } of availableDates.rest) {\n const values = getDefinedValues(date);\n if (values) {\n const [a, b] = extent(values, (d: Datum) => d.relDiff);\n if (a != null && (min == null || a < min)) min = a;\n if (b != null && (max == null || b > max)) max = b;\n }\n }\n return [min, max];\n },\n [getDefinedValues, availableDates]\n );\n\n\n const colorScaleDomain = useMemo(() => {\n // [Math.abs(diffExtent[0]),-Math.abs(diffExtent[0])]\n // [totalDiff + width/2, totalDiff - width/2]\n // [totalDiff - width/2, totalDiff + width/2]\n\n // [.60,-.60]\n // return [-.8, .8] as [number, number];\n // return diffExtent as [number, number];\n return [0, diffExtent[1]] as [number, number];\n\n }, [diffExtent]);\n\n const getShapeColor = useMemo(() => {\n if (!colorScaleDomain) return undefined;\n // const width = Math.min(diffExtent[1] - diffExtent[0], 1);\n\n const interpolator = !DARK_MODE\n ? interpolateRdYlBu\n : interpolateRgbBasis(\n ['#5ffbb8', '#4ab686', '#357558', '#203b2e', '#000000', '#3e1a10', '#7a2a17', '#ba391d', '#ff4821'] // https://vis4.net/palettes/#/9|d|5ffbb8,000000|000000,ff4821|1|1\n );\n\n\n const color = scaleSequential(interpolator)\n .clamp(true);\n\n const negative = scaleLinear()\n .domain([colorScaleDomain[0], 0])\n .range([1.0, 0.5])\n .clamp(true);\n\n const positive = scaleLinear()\n .domain([0, colorScaleDomain[1]])\n .range([0.5, 0])\n .clamp(true);\n\n return (x: number) => {\n if (x < 0) {\n return color(negative(x));\n }\n return color(positive(x));\n };\n },\n [colorScaleDomain]\n );\n\n\n const getCountDiff = (f: Feature) => {\n if (datumByLocationByDate && selectedDateOption) {\n const countDiff = datumByLocationByDate\n .get(f.properties!.id)\n ?.get(selectedDateOption.value)\n ?.countDiff;\n if (countDiff != null && isFinite(countDiff)) {\n return countDiff;\n }\n }\n return undefined;\n };\n\n\n const highlightColor = colorAsRgba('#ff9645');\n const layers = [];\n if (geoJsonFeatures != null) {\n const lineColor = [170, 100, 100];\n layers.push(\n new GeoJsonLayer({\n id: 'choropleth',\n data: geoJsonFeatures.features,\n stroked: true,\n filled: true,\n opacity: 1.0,\n lineWidthUnits: 'pixels',\n getLineWidth: 0.5,\n // getLineColor: [255, 100, 100],\n getLineColor: SHAPE_LINE_COLOR,\n getFillColor: SHAPE_FILL_COLOR,\n pickable: true,\n // highlightColor: colorAsRgba('#a04e70'),\n // autoHighlight: true,\n onHover: (info: any) => {\n const id = info.object?.properties.id;\n setTooltip({\n ...info,\n id,\n });\n },\n onClick: (info: any) => {\n const id = info.object?.properties.id;\n if (selectedLocation && selectedLocation.value === id) {\n handleSelectLocation(undefined);\n } else {\n handleSelectLocation(locationOptionsById?.get(id));\n }\n },\n }),\n );\n }\n\n const circlesData = useMemo(() => {\n if (geoJsonFeatures != null && cumulativeTotalByLocation != null) {\n return geoJsonFeatures\n .features\n // .sort((a,b) =>\n // descending(getCountDiff(a), getCountDiff(b)))\n .map(\n (d: Feature) => ({\n id: d.properties!.id,\n name: d.properties!.name,\n centroid: d.properties!.centroid,\n count: isCollapsed\n ? cumulativeTotalByLocation.get(d.properties!.id)\n : getCountDiff(d) || 0\n })\n )\n }\n return undefined;\n }, [geoJsonFeatures, datumByLocationByDate, selectedDateOption, isCollapsed]);\n\n\n\n const sizeScale = scaleSqrt().range(\n [0,isNarrowScreen ? 25 : 50]\n ).domain([0,isCollapsed ? 50000 : 5000])\n if (circlesData != null) {\n\n layers.push(\n new ScatterplotLayer({\n id: 'scatterplot-layer',\n data: circlesData,\n pickable: true,\n // opacity: 0.8,\n stroked: true,\n filled: true,\n radiusUnits: 'pixels',\n lineWidthScale: 1,\n lineWidthMinPixels: 1,\n lineWidthUnits: 'pixels',\n getPosition: (d: CircleItem) => d.centroid,\n getLineColor: [255, 255, 255],\n getRadius: (d: CircleItem) => sizeScale(d.count),\n // getFillColor: colorAsRgba('#D72327'),\n highlightColor: highlightColor,\n autoHighlight: true,\n getFillColor: CIRCLE_FILL_COLOR,\n // getFillColor: !SHOW_RELATIVE ? colorAsRgba('#a04e70') : (d: CircleItem) => {\n // if (getShapeColor && datumByLocationByDate && selectedDateOption)\n // {\n // const relDiff = datumByLocationByDate\n // .get(d.id)\n // ?.get(selectedDateOption.value)\n // ?.relDiff;\n //\n // if (relDiff != null && isFinite(relDiff)) {\n // return colorAsRgba(getShapeColor(relDiff));\n // }\n // }\n // return NOCOLOR;\n // },\n transitions: {\n getFillColor: {\n duration: ANIMATION_DURATION,\n // easing: easeCubicInOut,\n easing: easeLinear,\n enter: (value: any) => [value[0], value[1], value[2], 0] // fade in\n },\n getRadius: {\n duration: ANIMATION_DURATION,\n // easing: easeCubicInOut,\n easing: easeLinear,\n },\n },\n updateTriggers: {\n getRadius: { circlesData },\n getFillColor: { getShapeColor, selectedDateOption }\n },\n onHover: (info: any) => {\n const id = info.object?.id;\n setTooltip({\n ...info,\n id,\n });\n },\n onClick: (info: any) => {\n const id = info.object?.id;\n if (selectedLocation && selectedLocation.value === id) {\n handleSelectLocation(undefined);\n } else {\n handleSelectLocation(locationOptionsById?.get(id));\n }\n }\n })\n );\n\n\n if (selectedLocation) {\n layers.push(\n new GeoJsonLayer({\n id: 'selected-outline',\n data: selectedLocation.feature,\n stroked: true,\n lineWidthUnits: 'pixels',\n getLineWidth: 3,\n filled: false,\n opacity: 1.0,\n getLineColor: highlightColor,\n pickable: false,\n }),\n )\n\n }\n }\n\n\n\n const locationOptions = useMemo(\n () => {\n if (!geoJsonFeatures || !datumByLocationByDate) return undefined;\n\n const locations = geoJsonFeatures.features\n .filter(f => f.properties ? datumByLocationByDate.get(f.properties.id) != null : false)\n .map(f =>\n ({\n value: f.properties!.id,\n label: locationNamesById?.get(f.properties!.id) || f.properties!.name,\n feature: f,\n } as LocationOption)\n )\n .sort((a,b) => {\n if (a.label.startsWith('г.')) return -1;\n if (b.label.startsWith('г.')) return 1;\n return ascending(a.label, b.label)\n });\n\n return locations;\n },\n [geoJsonFeatures, datumByLocationByDate, locationNamesById]\n );\n\n\n const locationOptionsById = useMemo(\n () => {\n if (!locationOptions) return undefined;\n return locationOptions.reduce(\n (m, d) => { m.set(d.value, d); return m},\n new Map(),\n )\n },\n [locationOptions]\n );\n\n const handleSelectLocation = (locationOption: LocationOption | undefined) => {\n let viewState;\n if (locationOption) {\n const { current } = mapContainerRef;\n if (current) {\n const [x1, y1, x2, y2] = turfBbox(locationOption.feature);\n viewState = fitBounds({\n width: current.clientWidth,\n height: current.clientHeight,\n bounds: [[x1, y1], [x2, y2]],\n padding: 50,\n });\n }\n } else {\n viewState = initialViewState;\n }\n\n if (viewState) {\n setViewport({\n ...viewState,\n ...mapTransition(),\n });\n setSelectedLocation(locationOption);\n }\n };\n\n const handleKeyDown = (evt: Event) => {\n if (evt instanceof KeyboardEvent && evt.key === 'Escape') {\n if (selectedLocation) {\n handleSelectLocation(undefined);\n }\n if (tooltip) {\n setTooltip(undefined);\n }\n }\n };\n useEffect(() => {\n window.addEventListener('keydown', handleKeyDown);\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n });\n\n const handleViewStateChange = ({ viewState }: ViewStateChangeInfo) => {\n setViewport(viewState);\n // setSelectedLocation(null);\n setTooltip(undefined);\n };\n\n\n const formattedTotalPercentage = formatPercentage(\n selectedLocation && datumByLocationByDate && selectedDateOption\n ? datumByLocationByDate\n .get(selectedLocation.value)\n ?.get(selectedDateOption.value)\n ?.relDiff\n : totalDiff\n );\n\n if (!fetchCounts.data || !fetchShapes.data) {\n return \n \n \n \n ;\n\n }\n\n const cumulativeTotalDiffCount =\n cumulativeTotalByLocation?.get(selectedLocation != null ? selectedLocation.value : 'total');\n\n const cumulativeTotal = selectedDateOption?.date && (\n
);\n\n const svobodaReference = (\n
Большинство из этих смертей - \n от COVID-19.\n
\n );\n\n // const collapsedInfoBoxContent = (\n // \n // {selectedLocation ? selectedLocation.label : MESSAGES.country }\n // {/**/}\n // {/* {formatDate(selectedDateOption?.date!)}*/}\n // {/**/}\n // \n // {SHOW_RELATIVE ? formattedTotalPercentage :\n // cumulativeTotal\n // }\n // \n // {(cumulativeTotalDiffCount || 0) > 0 &&\n // {svobodaReference}}\n // \n // );\n //\n\n\n const getMainInfoBoxContent = (collapsed: boolean) => {\n return (\n \n \n {MESSAGES.title}\n \n с марта 2020 {lastAvailableDate ? `по ${formatDate(lastAvailableDate)}` : ''} (в сравнении с 2019 г.)\n \n \n\n {/*{selectedLocation ? selectedLocation.label : MESSAGES.country }*/}\n\n \n \n \n // @ts-ignore\n components={{Option: SelectOption}}\n // @ts-ignore\n isOptionDisabled={locationOption => locationOption.isGroup}\n onChange={handleSelectLocation as any}\n value={selectedLocation}\n options={locationOptions}\n isSearchable={isShortScreen}\n isClearable={true}\n isFixed={true}\n menuPortalTarget={document.body}\n escapeClearsValue={true}\n placeholder={MESSAGES.selectCity}\n filterOption={(option, input) => matchesSearchQuery(input, option.label)}\n />\n \n \n\n\n {!collapsed && totalTimeSeriesData &&\n
\n {\n const found = availableDates?.rest?.find(d => d.value === formatDateIso(t));\n if (found) {\n setSelectedDateOption(found);\n }\n }}\n />\n
\n }\n\n {!collapsed && \n {SHOW_RELATIVE && formattedTotalPercentage}\n
\n {/*{` умерли за ${selectedDateOption?.label}`}*/}\n }\n\n {/**/}\n {/* {*/}\n {/* cumulativeTotalDiffCount != null && selectedDateOption?.date &&*/}\n {/* */}\n {/* {cumulativeTotal}*/}\n {/* */}\n {/* }*/}\n {/**/}\n {/*{(cumulativeTotalDiffCount || 0) > 0 &&*/}\n {/*{svobodaReference}}*/}\n\n {collapsed &&\n <>\n \n {SHOW_RELATIVE ? formattedTotalPercentage :\n cumulativeTotal\n }\n \n {(cumulativeTotalDiffCount || 0) > 0 &&\n {svobodaReference}}\n \n }\n\n \n )\n }\n\n\n const mainInfoBoxContent = (\n \n {getMainInfoBoxContent(false)}\n \n );\n\n return (\n \n \n \n\n
\n {isNarrowScreen && mainInfoBoxContent}\n
\n setTooltip(undefined)}\n >\n\n \n \n {/**/}\n \n \n
\n
\n\n\n {tooltip && tooltip.object && datumByLocationByDate && selectedDateOption && (\n \n
\n {locationNamesById?.get(tooltip.id)}\n
\n {selectedDateOption && datumByLocationByDate &&\n \n }\n
\n )}\n\n\n {SHOW_RELATIVE && colorScaleDomain && getShapeColor && (\n \n \n \n )}\n\n\n \n \n \n Источник данных: Росстат\n \n \n Разработка: Илья Бояндин\n \n \n \n\n {mainInfoBoxContent && !isNarrowScreen &&\n \n {mainInfoBoxContent}\n \n }\n\n
\n \n\n
\n );\n}\n\n\n\nfunction formatPercentage(x: number | undefined) {\n if (x == null || !isFinite(x)) {\n return '…';\n }\n const v = Math.round(x*100);\n return (v > 0 ? MESSAGES.moreBy : MESSAGES.fewerBy).replace('{0}', `${Math.abs(v)}%`);\n}\n\nfunction formatCountDiff(v: number | undefined) {\n if (v == null || !isFinite(v)) {\n return '…';\n }\n return (v > 0 ? MESSAGES.moreByCount : MESSAGES.fewerByCount).replace('{0}', `${formatCount(Math.abs(v))}`);\n}\n\nfunction formatCumulativeCountDiff(v: number | undefined, selectedDate: string) {\n if (v == null || !isFinite(v)) {\n return '…';\n }\n return (\n v > 0\n ? MESSAGES.cumulativeMoreByCount\n : MESSAGES.cumulativeFewerByCount\n )\n .replace('{0}', selectedDate)\n .replace('{1}', `${formatCount(Math.abs(v))}`)\n ;\n}\n\nexport function formatPercentageShort(x: number | undefined) {\n if (x == null || !isFinite(x)) {\n return '…';\n }\n const v = Math.round(x*100);\n return `${v > 0 ? '+' : '-'}${Math.abs(v)}%`;\n}\n\nexport default App;\n\n","import {useEffect, useState} from 'react';\n\nexport interface Dimensions {\n width: number | undefined;\n height: number | undefined;\n}\n\nexport function useWindowSize() {\n // Initialize state with undefined width/height so server and client renders match\n // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/\n const [windowSize, setWindowSize] = useState({\n width: undefined,\n height: undefined,\n });\n\n useEffect(() => {\n // Handler to call on window resize\n function handleResize() {\n // Set window width/height to state\n setWindowSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n }\n\n // Add event listener\n window.addEventListener(\"resize\", handleResize);\n\n // Call handler right away so state gets updated with initial window size\n handleResize();\n\n // Remove event listener on cleanup\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []); // Empty array ensures that effect is only run on mount\n\n return windowSize;\n}","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(\n process.env.PUBLIC_URL,\n window.location.href\n );\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\nimport 'mapbox-gl/dist/mapbox-gl.css';\n\nReactDOM.render(, document.getElementById('root'));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}